unzip: clear SUID/GID bits, implement -K to not clear them
No binary (build failed)
—
(log yok)
| @@ -56,7 +56,7 @@ | |
| //kbuild:lib-$(CONFIG_UNZIP) += unzip.o | |
| //usage:#define unzip_trivial_usage | |
| - | //usage: "[-lnojpq] FILE[.zip] [FILE]... [-x FILE]... [-d DIR]" |
| + | //usage: "[-lnojpqK] FILE[.zip] [FILE]... [-x FILE]... [-d DIR]" |
| //usage:#define unzip_full_usage "\n\n" | |
| //usage: "Extract FILEs from ZIP archive\n" | |
| //usage: "\n -l List contents (with -q for short form)" | |
| @@ -66,6 +66,7 @@ | |
| //usage: "\n -p Write to stdout" | |
| //usage: "\n -t Test" | |
| //usage: "\n -q Quiet" | |
| + | //usage: "\n -K Do not clear SUID bit" |
| //usage: "\n -x FILE Exclude FILEs" | |
| //usage: "\n -d DIR Extract into DIR" | |
| @@ -494,6 +495,7 @@ int unzip_main(int argc, char **argv) | |
| OPT_l = (1 << 0), | |
| OPT_x = (1 << 1), | |
| OPT_j = (1 << 2), | |
| + | OPT_K = (1 << 3), |
| }; | |
| unsigned opts; | |
| smallint quiet = 0; | |
| @@ -559,7 +561,7 @@ int unzip_main(int argc, char **argv) | |
| opts = 0; | |
| /* '-' makes getopt return 1 for non-options */ | |
| - | while ((i = getopt(argc, argv, "-d:lnotpqxjv")) != -1) { |
| + | while ((i = getopt(argc, argv, "-d:lnotpqxjvK")) != -1) { |
| switch (i) { | |
| case 'd': /* Extract to base directory */ | |
| base_dir = optarg; | |
| @@ -602,6 +604,10 @@ int unzip_main(int argc, char **argv) | |
| opts |= OPT_j; | |
| break; | |
| + | case 'K': |
| + | opts |= OPT_K; |
| + | break; |
| + | |
| case 1: | |
| if (!src_fn) { | |
| /* The zip file */ | |
| @@ -819,7 +825,10 @@ int unzip_main(int argc, char **argv) | |
| # endif | |
| if ((cdf.fmt.version_made_by >> 8) == 3) { | |
| /* This archive is created on Unix */ | |
| - | dir_mode = file_mode = (cdf.fmt.external_attributes >> 16); |
| + | file_mode = (cdf.fmt.external_attributes >> 16); |
| + | if (!(opts & OPT_K)) |
| + | file_mode &= ~(mode_t)(S_ISUID | S_ISGID); |
| + | dir_mode = file_mode; |
| } | |
| } | |
| #endif | |