From 02ca39fdf8b42ff58f603707b55dfa997767efac Mon Sep 17 00:00:00 2001 From: Kaz Kylheku Date: Fri, 7 Feb 2020 20:36:06 -0800 Subject: chmod: fix broken umask application for implicit all. * sysif.c (chmod_wrap): The umask logic is not activating after the first iteration through the loop, because when who is zero, we clobber it by adding the bits for u, g, and o. Then on subsequent iterations, who is no longer zero. Instead, let us leave the value of who alone, and in all the relevant places, check for it being zero. --- sysif.c | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/sysif.c b/sysif.c index 11c07ce5..286dcca6 100644 --- a/sysif.c +++ b/sysif.c @@ -637,34 +637,31 @@ static val chmod_wrap(val target, val mode) { mode_t bits = 0; mode_t mask = 0; - int do_um = (who == 0); - - if (do_um) - who = CHM_U | CHM_G | CHM_O; + int implicit_all = (who == 0); if ((srcm & 020)) bits |= S_ISVTX; - if ((who & CHM_U) != 0) { + if (implicit_all || (who & CHM_U) != 0) { mask |= 0700; if ((srcm & 010)) bits |= S_ISUID; bits |= (srcm & 7) << 6; } - if ((who & CHM_G) != 0) { + if (implicit_all || (who & CHM_G) != 0) { mask |= 0070; if ((srcm & 010)) bits |= S_ISGID; bits |= (srcm & 7) << 3; } - if ((who & CHM_O) != 0) { + if (implicit_all || (who & CHM_O) != 0) { mask |= 0007; bits |= (srcm & 7); } - if (do_um) { + if (implicit_all) { mode_t um = umask(0777); umask(um); bits &= ~um; @@ -675,7 +672,7 @@ static val chmod_wrap(val target, val mode) case chm_sub: cmode &= ~bits; break; case chm_set: cmode &= ~mask; - if ((who & CHM_O) != 0) + if (implicit_all || (who & CHM_O) != 0) cmode &= ~S_ISVTX; /* GNU Coreutils 8.28 chmod behavior */ if (!S_ISDIR(cmode)) cmode &= ~(S_ISUID | S_ISGID); -- cgit v1.2.3