unzip: clear SUID/GID bits, implement -K to not clear them

function                                             old     new   delta
unzip_main                                          2656    2715     +59
packed_usage                                       34517   34552     +35
.rodata                                           105250  105251      +1
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 3/0 up/down: 95/0)               Total: 95 bytes

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This commit is contained in:
Denys Vlasenko 2023-02-22 10:50:14 +01:00
parent f15dfd86c4
commit c0bb90e2fe

View File

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