From c3d0bd1512b5d04c17980f5b3e2c443cbff4a4b9 Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Sat, 22 Dec 2018 10:55:19 +0000 Subject: [PATCH] syscall_fs2: fix the chown logic to match modern Unix --- Kernel/syscall_fs2.c | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) 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; } -- 2.34.1