[git commit] hush: fix umask: umask(022) was setting umask(755)

Denys Vlasenko vda.linux at googlemail.com
Wed Oct 7 14:56:20 UTC 2015


commit: http://git.busybox.net/busybox/commit/?id=6283f9828320ef5e0be0b060b7f26522b529ed42
branch: http://git.busybox.net/busybox/commit/?id=refs/heads/master

Based on the patch by Rich Felker <dalias at libc.org>

function                                             old     new   delta
builtin_umask                                        121     161     +40
umaskcmd                                             318     279     -39

Signed-off-by: Denys Vlasenko <vda.linux at googlemail.com>
---
 shell/ash.c  |   36 ++++++++++++++----------------------
 shell/hush.c |   10 +++++++---
 2 files changed, 21 insertions(+), 25 deletions(-)

diff --git a/shell/ash.c b/shell/ash.c
index b34dcc1..2669157 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 752080a..8b8d5fc 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


More information about the busybox-cvs mailing list