Add a credential guard for copy up. This will allows us to waste struct struct ovl_cu_creds and simplify the code. Signed-off-by: Christian Brauner --- fs/overlayfs/copy_up.c | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/fs/overlayfs/copy_up.c b/fs/overlayfs/copy_up.c index bb0231fc61fc..cc77498fa8ca 100644 --- a/fs/overlayfs/copy_up.c +++ b/fs/overlayfs/copy_up.c @@ -755,6 +755,33 @@ static void ovl_revert_cu_creds(struct ovl_cu_creds *cc) } } +static const struct cred *ovl_prepare_copy_up_creds(struct dentry *dentry) +{ + struct cred *copy_up_cred = NULL; + int err; + + err = security_inode_copy_up(dentry, ©_up_cred); + if (err < 0) + return ERR_PTR(err); + + if (!copy_up_cred) + return NULL; + + return override_creds(copy_up_cred); +} + +static void ovl_revert_copy_up_creds(const struct cred *orig_cred) +{ + const struct cred *copy_up_cred; + + copy_up_cred = revert_creds(orig_cred); + put_cred(copy_up_cred); +} + +DEFINE_CLASS(copy_up_creds, const struct cred *, + if (!IS_ERR_OR_NULL(_T)) ovl_revert_copy_up_creds(_T), + ovl_prepare_copy_up_creds(dentry), struct dentry *dentry) + /* * Copyup using workdir to prepare temp file. Used when copying up directories, * special files or when upper fs doesn't support O_TMPFILE. -- 2.47.3 Remove the complicated struct ovl_cu_creds dance and use our new copy up cred guard. Signed-off-by: Christian Brauner --- fs/overlayfs/copy_up.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/fs/overlayfs/copy_up.c b/fs/overlayfs/copy_up.c index cc77498fa8ca..665c5f24e228 100644 --- a/fs/overlayfs/copy_up.c +++ b/fs/overlayfs/copy_up.c @@ -792,7 +792,6 @@ static int ovl_copy_up_workdir(struct ovl_copy_up_ctx *c) struct inode *inode; struct path path = { .mnt = ovl_upper_mnt(ofs) }; struct dentry *temp, *upper, *trap; - struct ovl_cu_creds cc; int err; struct ovl_cattr cattr = { /* Can't properly set mode on creation because of the umask */ @@ -801,14 +800,14 @@ static int ovl_copy_up_workdir(struct ovl_copy_up_ctx *c) .link = c->link }; - err = ovl_prep_cu_creds(c->dentry, &cc); - if (err) - return err; + scoped_class(copy_up_creds, copy_up_creds, c->dentry) { + if (IS_ERR(copy_up_creds)) + return PTR_ERR(copy_up_creds); ovl_start_write(c->dentry); temp = ovl_create_temp(ofs, c->workdir, &cattr); ovl_end_write(c->dentry); - ovl_revert_cu_creds(&cc); + } if (IS_ERR(temp)) return PTR_ERR(temp); -- 2.47.3 They will become unused in the next patch and we'll drop them after the conversion is finished together with the struct. This keeps the changes small and reviewable. Signed-off-by: Christian Brauner --- fs/overlayfs/copy_up.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fs/overlayfs/copy_up.c b/fs/overlayfs/copy_up.c index 665c5f24e228..9acc1549d46d 100644 --- a/fs/overlayfs/copy_up.c +++ b/fs/overlayfs/copy_up.c @@ -732,7 +732,7 @@ struct ovl_cu_creds { struct cred *new; }; -static int ovl_prep_cu_creds(struct dentry *dentry, struct ovl_cu_creds *cc) +static int __maybe_unused ovl_prep_cu_creds(struct dentry *dentry, struct ovl_cu_creds *cc) { int err; @@ -747,7 +747,7 @@ static int ovl_prep_cu_creds(struct dentry *dentry, struct ovl_cu_creds *cc) return 0; } -static void ovl_revert_cu_creds(struct ovl_cu_creds *cc) +static void __maybe_unused ovl_revert_cu_creds(struct ovl_cu_creds *cc) { if (cc->new) { revert_creds(cc->old); -- 2.47.3 Remove the complicated struct ovl_cu_creds dance and use our new copy up cred guard. Signed-off-by: Christian Brauner --- fs/overlayfs/copy_up.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/fs/overlayfs/copy_up.c b/fs/overlayfs/copy_up.c index 9acc1549d46d..2176903d4538 100644 --- a/fs/overlayfs/copy_up.c +++ b/fs/overlayfs/copy_up.c @@ -892,17 +892,17 @@ static int ovl_copy_up_tmpfile(struct ovl_copy_up_ctx *c) struct inode *udir = d_inode(c->destdir); struct dentry *temp, *upper; struct file *tmpfile; - struct ovl_cu_creds cc; int err; - err = ovl_prep_cu_creds(c->dentry, &cc); - if (err) - return err; + scoped_class(copy_up_creds, copy_up_creds, c->dentry) { + if (IS_ERR(copy_up_creds)) + return PTR_ERR(copy_up_creds); ovl_start_write(c->dentry); tmpfile = ovl_do_tmpfile(ofs, c->workdir, c->stat.mode); ovl_end_write(c->dentry); - ovl_revert_cu_creds(&cc); + } + if (IS_ERR(tmpfile)) return PTR_ERR(tmpfile); -- 2.47.3 Now that we have this all ported to a cred guard remove the struct and the associated helpers. Signed-off-by: Christian Brauner --- fs/overlayfs/copy_up.c | 28 ---------------------------- 1 file changed, 28 deletions(-) diff --git a/fs/overlayfs/copy_up.c b/fs/overlayfs/copy_up.c index 2176903d4538..537295b17af8 100644 --- a/fs/overlayfs/copy_up.c +++ b/fs/overlayfs/copy_up.c @@ -727,34 +727,6 @@ static int ovl_copy_up_metadata(struct ovl_copy_up_ctx *c, struct dentry *temp) return err; } -struct ovl_cu_creds { - const struct cred *old; - struct cred *new; -}; - -static int __maybe_unused ovl_prep_cu_creds(struct dentry *dentry, struct ovl_cu_creds *cc) -{ - int err; - - cc->old = cc->new = NULL; - err = security_inode_copy_up(dentry, &cc->new); - if (err < 0) - return err; - - if (cc->new) - cc->old = override_creds(cc->new); - - return 0; -} - -static void __maybe_unused ovl_revert_cu_creds(struct ovl_cu_creds *cc) -{ - if (cc->new) { - revert_creds(cc->old); - put_cred(cc->new); - } -} - static const struct cred *ovl_prepare_copy_up_creds(struct dentry *dentry) { struct cred *copy_up_cred = NULL; -- 2.47.3