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