diff --git a/fs/overlayfs/dir.c b/fs/overlayfs/dir.c index eedacae889b9..b4498b95234c 100644 --- a/fs/overlayfs/dir.c +++ b/fs/overlayfs/dir.c @@ -407,7 +407,7 @@ static int ovl_create_or_link(struct dentry *dentry, int mode, dev_t rdev, if (!ovl_dentry_is_opaque(dentry)) { err = ovl_create_upper(dentry, inode, &stat, link, hardlink); } else { - const struct cred *old_cred; + const struct cred *old_cred, *hold_cred = NULL; struct cred *override_cred; old_cred = ovl_override_creds(dentry->d_sb); @@ -415,15 +415,22 @@ static int ovl_create_or_link(struct dentry *dentry, int mode, dev_t rdev, err = -ENOMEM; override_cred = prepare_creds(); if (override_cred) { - override_cred->fsuid = old_cred->fsuid; - override_cred->fsgid = old_cred->fsgid; - put_cred(override_creds(override_cred)); + const struct cred *our_cred; + + our_cred = old_cred; + if (!our_cred) + our_cred = current_cred(); + override_cred->fsuid = our_cred->fsuid; + override_cred->fsgid = our_cred->fsgid; + hold_cred = override_creds(override_cred); put_cred(override_cred); err = ovl_create_over_whiteout(dentry, inode, &stat, link, hardlink); } - revert_creds(old_cred); + ovl_revert_creds(old_cred ?: hold_cred); + if (old_cred && hold_cred) + put_cred(hold_cred); } if (!err)