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

[programs] set chmod 600 after opening destination file #1644

Merged
merged 2 commits into from
Jun 14, 2019
Merged

[programs] set chmod 600 after opening destination file #1644

merged 2 commits into from
Jun 14, 2019

Conversation

chungy
Copy link
Contributor

@chungy chungy commented Jun 9, 2019

This resolves a race condition where zstd or unzstd may expose read
permissions beyond the original file allowed. Mode 600 is used
temporarily during the compression and decompression write stage
and the new file inherits the original file’s mode at the end.

Fixes #1630

chmod() should silently fail in situations where it isn't possible to set mode 600, such as on FAT file systems. I'm also not really able to tell if this builds okay on Windows. mingw-w64 seems to build it fine (as long as I changed timefn.h to have <windows.h> instead of <Windows.h>), but i don't know if chmod() has any effect on that OS -- it's well possible that someone should make a Windows-specific equivalent to this.

This resolves a race condition where zstd or unzstd may expose read
permissions beyond the original file allowed.  Mode 600 is used
temporarily during the compression and decompression write stage
and the new file inherits the original file’s mode at the end.

Fixes #1630
@facebook-github-bot
Copy link

Thank you for your pull request and welcome to our community. We require contributors to sign our Contributor License Agreement, and we don't seem to have you on file. In order for us to review and merge your code, please sign up at https://code.facebook.com/cla. If you are contributing on behalf of someone else (eg your employer), the individual CLA may not be sufficient and your employer may need the corporate CLA signed.

If you have received this in error or have any questions, please contact us at cla@fb.com. Thanks!

@facebook-github-bot
Copy link

Thank you for signing our Contributor License Agreement. We can now accept your code for this (and any) Facebook open source project. Thanks!

@Cyan4973
Copy link
Contributor

Cyan4973 commented Jun 9, 2019

Thanks @chungy .
Thankfully, we have automated Windows tests, using both mingw and Visual Studio.
It seems your patch passed them, which suggests compilation (at least) works fine.

chmod is a Unix command, but it seems to have a corresponding Windows hook.
We already use it in multiple other places, so if it was a bad thing, we would have already triggered some bug reports.

Also, it would have been great if it was possible to ship a test case alongside the patch, as to ensure the property remains verified after future changes. However, I must admit I'm completely out of idea on how to test this specific property (using a reasonably simple test).

cc @felixhandte for the review.

@@ -566,6 +566,7 @@ static FILE* FIO_openDstFile(FIO_prefs_t* const prefs, const char* srcFileName,
{ FILE* const f = fopen( dstFileName, "wb" );
if (f == NULL)
DISPLAYLEVEL(1, "zstd: %s: %s\n", dstFileName, strerror(errno));
chmod(dstFileName, 00600);
Copy link
Contributor

@Cyan4973 Cyan4973 Jun 9, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I understand that chmod() can fail silently,
yet it would feel cleaner if chmod() wasn't attempted when f == NULL.
An if { } else { } should do the trick.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Totally right, I did miss that. :)

@felixhandte
Copy link
Contributor

I wonder about the race condition that is potentially introduced here, where zstd first opens a file with liberal permissions, and then closes them down. It seems like a malicious process could open the file during that gap and then read the contents as they are written.

An alternative approach would be to temporarily set the process umask to umask | 00077, do the open, and then restore the original umask. It seems though that windows does not have an equivalent of umask, so that approach would be less portable.

What do you think?

@Cyan4973
Copy link
Contributor

I believe this patch solves the more pressing issue of ensuring that the temporary file cannot be read during compression, which is a long time compared to the very tiny window of opportunity between file creation and rights setting.
Also, this simple patch does not introduce additional dependencies nor portability complexity.

@Cyan4973 Cyan4973 merged commit b059202 into facebook:dev Jun 14, 2019
@svenha
Copy link

svenha commented Aug 19, 2019

This PR causes an unexpected change in 1.4.2 and 1.4.1 (compared to 1.4.0 and before): if compressing from stdin to a file, the file always has final rights 0600 instead of umask. This breaks a lot of code I fear.
Example:

echo "123456789" | zstd -14 -f -q -o test.zst

@chungy
Copy link
Contributor Author

chungy commented Aug 19, 2019

Possible workaround: use shell redirection (zstd > test.zst) instead of -o test.zst

Though yes, it is a new bug and you should file a regular issue on it so it doesn't become forgotten in this merged PR :)

dongsupark added a commit to flatcar/scripts that referenced this pull request Aug 10, 2023
Since #950 was merged,
tarball files `flatcar-{packages,sdk}-*.tar.zst` have been created
with mode 0600 instead of 0644. As a result, the files with mode 0600
were uploaded to bincache, but afterwards `copy-to-origin.sh` that in
turn runs rsync from bincache to the origin server could not read the
tarballs.

To fix that, it is necessary to chmod from 0600 to 0644 to make it
readable by rsync during the release process.

All of that happens because zstd sets the mode of the output file to
0600 in case of temporary files to avoid race condition.

See also facebook/zstd#1644.
dongsupark added a commit to flatcar/scripts that referenced this pull request Aug 10, 2023
Since #950 was merged,
tarball files `flatcar-{packages,sdk}-*.tar.zst` have been created
with mode 0600 instead of 0644. As a result, the files with mode 0600
were uploaded to bincache, but afterwards `copy-to-origin.sh` that in
turn runs rsync from bincache to the origin server could not read the
tarballs.

To fix that, it is necessary to chmod from 0600 to 0644 to make it
readable by rsync during the release process.

All of that happens because zstd sets the mode of the output file to
0600 in case of temporary files to avoid race condition.

See also facebook/zstd#1644.
dongsupark added a commit to flatcar/scripts that referenced this pull request Aug 11, 2023
Since #950 was merged,
tarball files `flatcar-{packages,sdk}-*.tar.zst` have been created
with mode 0600 instead of 0644. As a result, the files with mode 0600
were uploaded to bincache, but afterwards `copy-to-origin.sh` that in
turn runs rsync from bincache to the origin server could not read the
tarballs.

To fix that, it is necessary to chmod from 0600 to 0644 to make it
readable by rsync during the release process.

All of that happens because zstd sets the mode of the output file to
0600 in case of temporary files to avoid race condition.

See also facebook/zstd#1644,
facebook/zstd#3432.
dongsupark added a commit to flatcar/scripts that referenced this pull request Aug 11, 2023
Since #950 was merged,
tarball files `flatcar-{packages,sdk}-*.tar.zst` have been created
with mode 0600 instead of 0644. As a result, the files with mode 0600
were uploaded to bincache, but afterwards `copy-to-origin.sh` that in
turn runs rsync from bincache to the origin server could not read the
tarballs.

To fix that, it is necessary to chmod from 0600 to 0644 to make it
readable by rsync during the release process.

All of that happens because zstd sets the mode of the output file to
0600 in case of temporary files to avoid race condition.

See also facebook/zstd#1644,
facebook/zstd#3432.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

zstd adds read permissions to files while being compressed or uncompressed
5 participants