diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2015-10-07 16:56:20 +0200 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2015-10-07 16:56:20 +0200 |
commit | 6283f9828320ef5e0be0b060b7f26522b529ed42 (patch) | |
tree | 9b11416a3cdd3655f2854debe868e4c19d232a88 | |
parent | 9c5410023a9d1920c336ed4d9ceaad586ce43328 (diff) |
hush: fix umask: umask(022) was setting umask(755)
Based on the patch by Rich Felker <dalias@libc.org>
function old new delta
builtin_umask 121 161 +40
umaskcmd 318 279 -39
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r-- | shell/ash.c | 36 | ||||
-rw-r--r-- | shell/hush.c | 10 |
2 files changed, 21 insertions, 25 deletions
diff --git a/shell/ash.c b/shell/ash.c index b34dcc149..2669157bc 100644 --- a/shell/ash.c +++ b/shell/ash.c @@ -12814,7 +12814,7 @@ readcmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM) } static int FAST_FUNC -umaskcmd(int argc UNUSED_PARAM, char **argv) +umaskcmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM) { static const char permuser[3] ALIGN1 = "ugo"; static const char permmode[3] ALIGN1 = "rwx"; @@ -12824,9 +12824,6 @@ umaskcmd(int argc UNUSED_PARAM, char **argv) S_IROTH, S_IWOTH, S_IXOTH }; - /* TODO: use bb_parse_mode() instead */ - - char *ap; mode_t mask; int i; int symbolic_mode = 0; @@ -12840,8 +12837,7 @@ umaskcmd(int argc UNUSED_PARAM, char **argv) umask(mask); INT_ON; - ap = *argptr; - if (ap == NULL) { + if (*argptr == NULL) { if (symbolic_mode) { char buf[18]; char *p = buf; @@ -12858,27 +12854,23 @@ umaskcmd(int argc UNUSED_PARAM, char **argv) } *p++ = ','; } - *--p = 0; + *--p = '\0'; puts(buf); } else { out1fmt("%.4o\n", mask); } } else { - if (isdigit((unsigned char) *ap)) { - mask = 0; - do { - if (*ap >= '8' || *ap < '0') - ash_msg_and_raise_error(msg_illnum, argv[1]); - mask = (mask << 3) + (*ap - '0'); - } while (*++ap != '\0'); - umask(mask); - } else { - mask = ~mask & 0777; - if (!bb_parse_mode(ap, &mask)) { - ash_msg_and_raise_error("illegal mode: %s", ap); - } - umask(~mask & 0777); - } + char *modestr = *argptr; + /* numeric umasks are taken as-is */ + /* symbolic umasks are inverted: "umask a=rx" calls umask(222) */ + if (!isdigit(modestr[0])) + mask ^= 0777; + if (!bb_parse_mode(modestr, &mask) || (unsigned)mask > 0777) { + ash_msg_and_raise_error("illegal mode: %s", modestr); + } + if (!isdigit(modestr[0])) + mask ^= 0777; + umask(mask); } return 0; } diff --git a/shell/hush.c b/shell/hush.c index 752080a64..8b8d5fc8b 100644 --- a/shell/hush.c +++ b/shell/hush.c @@ -8970,10 +8970,14 @@ static int FAST_FUNC builtin_umask(char **argv) if (argv[0]) { mode_t old_mask = mask; - mask ^= 0777; + /* numeric umasks are taken as-is */ + /* symbolic umasks are inverted: "umask a=rx" calls umask(222) */ + if (!isdigit(argv[0][0])) + mask ^= 0777; rc = bb_parse_mode(argv[0], &mask); - mask ^= 0777; - if (rc == 0) { + if (!isdigit(argv[0][0])) + mask ^= 0777; + if (rc == 0 || (unsigned)mask > 0777) { mask = old_mask; /* bash messages: * bash: umask: 'q': invalid symbolic mode operator |