Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

ovl: fix uid/gid when creating over whiteout

Fix a regression when creating a file over a whiteout. The new
file/directory needs to use the current fsuid/fsgid, not the ones from the
mounter's credentials.

The refcounting is a bit tricky: prepare_creds() sets an original refcount,
override_creds() gets one more, which revert_cred() drops. So

1) we need to expicitly put the mounter's credentials when overriding
with the updated one

2) we need to put the original ref to the updated creds (and this can
safely be done before revert_creds(), since we'll still have the ref
from override_creds()).

Reported-by: Stephen Smalley <sds@tycho.nsa.gov>
Fixes: 3fe6e52f0626 ("ovl: override creds with the ones from the superblock mounter")
Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>

+11 -2
+11 -2
fs/overlayfs/dir.c
··· 405 405 err = ovl_create_upper(dentry, inode, &stat, link, hardlink); 406 406 } else { 407 407 const struct cred *old_cred; 408 + struct cred *override_cred; 408 409 409 410 old_cred = ovl_override_creds(dentry->d_sb); 410 411 411 - err = ovl_create_over_whiteout(dentry, inode, &stat, link, 412 - hardlink); 412 + err = -ENOMEM; 413 + override_cred = prepare_creds(); 414 + if (override_cred) { 415 + override_cred->fsuid = old_cred->fsuid; 416 + override_cred->fsgid = old_cred->fsgid; 417 + put_cred(override_creds(override_cred)); 418 + put_cred(override_cred); 413 419 420 + err = ovl_create_over_whiteout(dentry, inode, &stat, 421 + link, hardlink); 422 + } 414 423 revert_creds(old_cred); 415 424 } 416 425