From: Alan Cox Date: Sat, 22 Dec 2018 10:55:19 +0000 (+0000) Subject: syscall_fs2: fix the chown logic to match modern Unix X-Git-Url: https://git.ndcode.org/public/gitweb.cgi?a=commitdiff_plain;h=c3d0bd1512b5d04c17980f5b3e2c443cbff4a4b9;p=FUZIX.git syscall_fs2: fix the chown logic to match modern Unix --- diff --git a/Kernel/syscall_fs2.c b/Kernel/syscall_fs2.c index 0bac3e59..2ee0512e 100644 --- a/Kernel/syscall_fs2.c +++ b/Kernel/syscall_fs2.c @@ -245,15 +245,27 @@ arg_t _fchmod(void) static int chown_op(inoptr ino) { - if ((ino->c_node.i_uid != udata.u_euid || - (group != udata.u_gid && !in_group(group))) && esuper()) - return (-1); if (ino->c_flags & CRDONLY) { udata.u_error = EROFS; return -1; } - ino->c_node.i_uid = owner; - ino->c_node.i_gid = group; + /* Owner change must be superuser rights */ + if (owner != -1) { + if (esuper()) + return -1; + ino->c_node.i_uid = owner; + /* owner = group = -1 is a no-op */ + } else if (group == -1) + return 0; + /* Group change */ + if (group != -1) { + /* We must be in the target group (and file owner) */ + if ((ino->c_node.i_uid != udata.u_euid || + group != udata.u_egid && !in_group(group)) && esuper()) + return -1; + ino->c_node.i_gid = group; + } + ino->c_node.i_mode &= ~(SET_GID|SET_UID); setftime(ino, C_TIME); return 0; }