Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ZipArchive extract lost permission on linux #12730

Closed
kocoten1992 opened this issue Nov 20, 2023 · 7 comments
Closed

ZipArchive extract lost permission on linux #12730

kocoten1992 opened this issue Nov 20, 2023 · 7 comments

Comments

@kocoten1992
Copy link

Description

Hello, I notice when using ZipArchive on linux, it lost permission of the file, for example, this file:

https://chromedriver.storage.googleapis.com/114.0.5735.90/chromedriver_linux64.zip

When I use unzip command line tool:

computer /tmp stat chromedriver
  File: chromedriver
  Size: 15039112  	Blocks: 29376      IO Block: 4096   regular file
Device: 8,18	Inode: 6160498     Links: 1
Access: (0755/-rwxr-xr-x)  Uid: ( 1000/kocoten1992)   Gid: ( 1000/kocoten1992)
Access: 2023-05-27 07:10:14.000000000 +0700
Modify: 2023-05-27 07:10:14.000000000 +0700
Change: 2023-11-20 15:08:49.114203850 +0700
 Birth: 2023-11-20 15:08:49.026201520 +0700

computer /tmp stat LICENSE.chromedriver
  File: LICENSE.chromedriver
  Size: 326542    	Blocks: 640        IO Block: 4096   regular file
Device: 8,18	Inode: 6160513     Links: 1
Access: (0644/-rw-r--r--)  Uid: ( 1000/kocoten1992)   Gid: ( 1000/kocoten1992)
Access: 2023-05-27 07:10:14.000000000 +0700
Modify: 2023-05-27 07:10:14.000000000 +0700
Change: 2023-11-20 15:08:49.114203850 +0700
 Birth: 2023-11-20 15:08:49.114203850 +0700

File chromedriver have permission 0755, however when use this code:

<?php

$zip = new ZipArchive;

$zip->open('chromedriver_linux64.zip');

$zip->extractTo('/tmp/');

Now chromedriver have permission 0644, meaning - it lost information previously there and I can't find how to preserve that info (permission) uzing ZipArchive api.

@remicollet
Copy link
Contributor

@remicollet
Copy link
Contributor

remicollet commented Nov 20, 2023

A simple fix will be possible (IMHO not suitable for stable version)

@@ -256,9 +256,21 @@ static int php_zip_extract_file(struct zip * za, char *dest, char *file, size_t
 
        if (stream->wrapper->wops->stream_metadata) {
                struct utimbuf ut;
+               zip_uint8_t opsys;
+               zip_uint32_t attr;
+               zip_int64_t idx;
+               zend_long mode;
 
                ut.modtime = ut.actime = sb.mtime;
                stream->wrapper->wops->stream_metadata(stream->wrapper, fullpath, PHP_STREAM_META_TOUCH, &ut, NULL);
+
+               idx = zip_name_locate(za, file, 0);
+               if (idx >= 0 &&
+                       zip_file_get_external_attributes(za, idx, 0, &opsys, &attr) >= 0
+                       && opsys == ZIP_OPSYS_UNIX) {
+                       mode = (attr >> 16) & 0777;
+                       stream->wrapper->wops->stream_metadata(stream->wrapper, fullpath, PHP_STREAM_META_ACCESS, &mode, NULL);
+               }
        }
 
        php_stream_close(stream);

But this is an important behavior change
and need to think to security implications (creation of executable file) from not trusted archive.

@remicollet
Copy link
Contributor

For tests => https://github.com/pierrejoye/php_zip/commits/issue-12730

@remicollet
Copy link
Contributor

WIP: PR #12739

@remicollet
Copy link
Contributor

@kocoten1992
Copy link
Author

Hi @remicollet, thanks for trying this. I'll clarify what I saw on your PR for later reader, if have a directory like this:

abc (000)
|_xyz (755)

Then suddenly you can't delete directory abc anymore, linux moment right there..

@remicollet
Copy link
Contributor

FYI for the future add a note in documentation about this
php/doc-en#2973

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants