summaryrefslogtreecommitdiffstats
path: root/sysif.c
diff options
context:
space:
mode:
authorKaz Kyheku <kaz@kylheku.com>2020-02-07 23:15:25 -0800
committerKaz Kylheku <kaz@kylheku.com>2020-02-07 23:15:25 -0800
commit7b094eccd23ab67c39c4569ffd8e0ce7533038bb (patch)
tree73000ca000f9d2ae1640bdf0abc4e80ee1e9bbbe /sysif.c
parenta5fd4b908bf6ad193c5d68dfa3c0eda81aa7802a (diff)
downloadtxr-7b094eccd23ab67c39c4569ffd8e0ce7533038bb.tar.gz
txr-7b094eccd23ab67c39c4569ffd8e0ce7533038bb.tar.bz2
txr-7b094eccd23ab67c39c4569ffd8e0ce7533038bb.zip
chmod: setuid/setgid bit bugfix and new tests.
* sysif.c (chmod_wrap): Again, related to the = operator, we must not punch a hole in the suid and sgid bits for all non-directory objects. This was based on a misinterpretation of some coreutils documentation, and doesn't match the actual behavior. Rather, if the owner is a target (including implicitly) then we mask out suid; and if the group owner is a targe, then we mask out sgid. Thus when we are doing a permission set not targetting the owner we don't touch suid, and similarly for the group owner and setgid. * tests/018/chmod.tl: Failed test diagnostics now identify which mode string was used. Some existing tests involving the suid/sgid bits have to be revised because this commit reflects a correction in the requirements. One new test is added.
Diffstat (limited to 'sysif.c')
-rw-r--r--sysif.c6
1 files changed, 2 insertions, 4 deletions
diff --git a/sysif.c b/sysif.c
index ee219ff3..44e236d7 100644
--- a/sysif.c
+++ b/sysif.c
@@ -643,14 +643,14 @@ static val chmod_wrap(val target, val mode)
bits |= S_ISVTX;
if (implicit_all || (who & CHM_U) != 0) {
- mask |= 0700;
+ mask |= (0700 | S_ISUID);
if ((srcm & 010))
bits |= S_ISUID;
bits |= (srcm & 7) << 6;
}
if (implicit_all || (who & CHM_G) != 0) {
- mask |= 0070;
+ mask |= (0070 | S_ISGID);
if ((srcm & 010))
bits |= S_ISGID;
bits |= (srcm & 7) << 3;
@@ -675,8 +675,6 @@ static val chmod_wrap(val target, val mode)
cmode &= ~mask;
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);
}
cmode |= bits;
break;