[PATCH] attr: validate kuid first in chown_common

[Date Prev] [Date Next] [Thread Prev] [Thread Next] [Date Index] [Thread Index]



Since the commit b27c82e12965 ("attr: port attribute changes to new
types"), chown_common stores vfs{g,u}id which converted from kuid into
iattr::vfs{g,u}id without check of the corresponding fs mapping ids.

When fchownat(2) is called with unmapped {g,u}id, now chown_common
fails later by vfsuid_has_fsmapping in notify_change. Then it returns
EOVERFLOW instead of EINVAL to the caller.

Fix it by validating k{u,g}id whether has valid fs mapping ids in
chown_common so it can return EINVAL early and make fchownat(2)
behave consistently.

This commit fixes fstests/generic/656.

Cc: Christian Brauner (Microsoft) <brauner@xxxxxxxxxx>
Cc: Seth Forshee <sforshee@xxxxxxxxxxxxxxxx>
Fixes: b27c82e12965 ("attr: port attribute changes to new types")
Signed-off-by: Su Yue <glass@xxxxxxxxx>
---
 fs/open.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/fs/open.c b/fs/open.c
index 8a813fa5ca56..967c7aac5aba 100644
--- a/fs/open.c
+++ b/fs/open.c
@@ -715,6 +715,13 @@ int chown_common(const struct path *path, uid_t user, gid_t group)
 	mnt_userns = mnt_user_ns(path->mnt);
 	fs_userns = i_user_ns(inode);
 
+	if ((user != (uid_t)-1) &&
+	     !vfsuid_has_fsmapping(mnt_userns, fs_userns, VFSUIDT_INIT(uid)))
+		return -EINVAL;
+	if ((group != (gid_t)-1) &&
+	    !vfsgid_has_fsmapping(mnt_userns, fs_userns, VFSGIDT_INIT(gid)))
+		return -EINVAL;
+
 retry_deleg:
 	newattrs.ia_valid =  ATTR_CTIME;
 	if ((user != (uid_t)-1) && !setattr_vfsuid(&newattrs, uid))
-- 
2.37.1




[Index of Archives]     [Linux Filesystems Development]     [Linux NFS]     [Linux NILFS]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux