diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2020-02-07 20:36:06 -0800 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2020-02-07 20:36:06 -0800 |
commit | 6d6bb0cae29be50cb3e69d85df6cc0b6fee1ab9d (patch) | |
tree | 5a27a7e5b9d66ba03ea55ba31a70717a177d3a76 /sysif.c | |
parent | 9dddf656328b2bcd76292aabc44112e99ad1b25a (diff) | |
download | txr-6d6bb0cae29be50cb3e69d85df6cc0b6fee1ab9d.tar.gz txr-6d6bb0cae29be50cb3e69d85df6cc0b6fee1ab9d.tar.bz2 txr-6d6bb0cae29be50cb3e69d85df6cc0b6fee1ab9d.zip |
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.
Diffstat (limited to 'sysif.c')
-rw-r--r-- | sysif.c | 15 |
1 files changed, 6 insertions, 9 deletions
@@ -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); |