From: W. Felix Handte Date: Wed, 18 Jan 2023 00:37:30 +0000 (-0800) Subject: Mimic gzip chown(gid), chmod(), chown(uid) Behavior X-Git-Tag: v1.5.4^2~37^2~1 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=0d2d46022336b267e87d6bfb078ccc34d0ca8aad;p=thirdparty%2Fzstd.git Mimic gzip chown(gid), chmod(), chown(uid) Behavior Avoids a race condition in which we unintentionally open up permissions to the wrong group. --- diff --git a/programs/util.c b/programs/util.c index 7402b75d2..d0411e68d 100644 --- a/programs/util.c +++ b/programs/util.c @@ -249,11 +249,23 @@ int UTIL_setFileStat(const char *filename, const stat_t *statbuf) /* set access and modification times */ res += UTIL_utime(filename, statbuf); + /* Mimic gzip's behavior: + * + * "Change the group first, then the permissions, then the owner. + * That way, the permissions will be correct on systems that allow + * users to give away files, without introducing a security hole. + * Security depends on permissions not containing the setuid or + * setgid bits." */ + #if !defined(_WIN32) - res += chown(filename, statbuf->st_uid, statbuf->st_gid); /* Copy ownership */ + res += chown(filename, -1, statbuf->st_gid); /* Apply group ownership */ #endif - res += UTIL_chmod(filename, &curStatBuf, statbuf->st_mode & 07777); /* Copy file permissions */ + res += UTIL_chmod(filename, &curStatBuf, statbuf->st_mode & 0777); /* Copy file permissions */ + +#if !defined(_WIN32) + res += chown(filename, statbuf->st_uid, -1); /* Apply user ownership */ +#endif errno = 0; UTIL_TRACE_RET(-res); diff --git a/tests/cli-tests/file-stat/compress-file-to-file.sh b/tests/cli-tests/file-stat/compress-file-to-file.sh index 949f34ff1..c5f590031 100755 --- a/tests/cli-tests/file-stat/compress-file-to-file.sh +++ b/tests/cli-tests/file-stat/compress-file-to-file.sh @@ -3,6 +3,7 @@ set -e datagen > file +chmod 642 file zstd file -q --trace-file-stat -o file.zst zstd -tq file.zst diff --git a/tests/cli-tests/file-stat/compress-file-to-file.sh.stderr.exact b/tests/cli-tests/file-stat/compress-file-to-file.sh.stderr.exact index 8944e4cb4..49a8152f3 100644 --- a/tests/cli-tests/file-stat/compress-file-to-file.sh.stderr.exact +++ b/tests/cli-tests/file-stat/compress-file-to-file.sh.stderr.exact @@ -35,7 +35,7 @@ Trace:FileStat: > UTIL_stat(file.zst) Trace:FileStat: < 1 Trace:FileStat: > UTIL_utime(file.zst) Trace:FileStat: < 0 -Trace:FileStat: > UTIL_chmod(file.zst, 420) +Trace:FileStat: > UTIL_chmod(file.zst, 418) Trace:FileStat: > chmod Trace:FileStat: < 0 Trace:FileStat: < 0 diff --git a/tests/cli-tests/file-stat/decompress-file-to-file.sh b/tests/cli-tests/file-stat/decompress-file-to-file.sh index 3e08c247b..9e68f8f33 100755 --- a/tests/cli-tests/file-stat/decompress-file-to-file.sh +++ b/tests/cli-tests/file-stat/decompress-file-to-file.sh @@ -3,5 +3,6 @@ set -e datagen | zstd -q > file.zst +chmod 642 file.zst zstd -dq --trace-file-stat file.zst diff --git a/tests/cli-tests/file-stat/decompress-file-to-file.sh.stderr.exact b/tests/cli-tests/file-stat/decompress-file-to-file.sh.stderr.exact index 3b9d69922..65547537a 100644 --- a/tests/cli-tests/file-stat/decompress-file-to-file.sh.stderr.exact +++ b/tests/cli-tests/file-stat/decompress-file-to-file.sh.stderr.exact @@ -31,7 +31,7 @@ Trace:FileStat: > UTIL_stat(file) Trace:FileStat: < 1 Trace:FileStat: > UTIL_utime(file) Trace:FileStat: < 0 -Trace:FileStat: > UTIL_chmod(file, 420) +Trace:FileStat: > UTIL_chmod(file, 418) Trace:FileStat: > chmod Trace:FileStat: < 0 Trace:FileStat: < 0