Skip to content

Commit d0deeb8

Browse files
committed
Merge tag 'vfs-6.19-rc1.ovl' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs
Pull overlayfs cred guard conversion from Christian Brauner: "This converts all of overlayfs to use credential guards, eliminating manual credential management throughout the filesystem. Credential guard conversion: - Convert all of overlayfs to use credential guards, replacing the manual ovl_override_creds()/ovl_revert_creds() pattern with scoped guards. This makes credential handling visually explicit and eliminates a class of potential bugs from mismatched override/revert calls. (1) Basic credential guard (with_ovl_creds) (2) Creator credential guard (ovl_override_creator_creds): Introduced a specialized guard for file creation operations that handles the two-phase credential override (mounter credentials, then fs{g,u}id override). The new pattern is much clearer: with_ovl_creds(dentry->d_sb) { scoped_class(prepare_creds_ovl, cred, dentry, inode, mode) { if (IS_ERR(cred)) return PTR_ERR(cred); /* creation operations */ } } (3) Copy-up credential guard (ovl_cu_creds): Introduced a specialized guard for copy-up operations, simplifying the previous struct ovl_cu_creds helper and associated functions. Ported ovl_copy_up_workdir() and ovl_copy_up_tmpfile() to this pattern. Cleanups: - Remove ovl_revert_creds() after all callers converted to guards - Remove struct ovl_cu_creds and associated functions - Drop ovl_setup_cred_for_create() after conversion - Refactor ovl_fill_super(), ovl_lookup(), ovl_iterate(), ovl_rename() for cleaner credential guard scope - Introduce struct ovl_renamedata to simplify rename handling - Don't override credentials for ovl_check_whiteouts() (unnecessary) - Remove unneeded semicolon" * tag 'vfs-6.19-rc1.ovl' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs: (54 commits) ovl: remove unneeded semicolon ovl: remove struct ovl_cu_creds and associated functions ovl: port ovl_copy_up_tmpfile() to cred guard ovl: mark *_cu_creds() as unused temporarily ovl: port ovl_copy_up_workdir() to cred guard ovl: add copy up credential guard ovl: drop ovl_setup_cred_for_create() ovl: port ovl_create_or_link() to new ovl_override_creator_creds cleanup guard ovl: mark ovl_setup_cred_for_create() as unused temporarily ovl: reflow ovl_create_or_link() ovl: port ovl_create_tmpfile() to new ovl_override_creator_creds cleanup guard ovl: add ovl_override_creator_creds cred guard ovl: remove ovl_revert_creds() ovl: port ovl_fill_super() to cred guard ovl: refactor ovl_fill_super() ovl: port ovl_lower_positive() to cred guard ovl: port ovl_lookup() to cred guard ovl: refactor ovl_lookup() ovl: port ovl_copyfile() to cred guard ovl: port ovl_rename() to cred guard ...
2 parents a8058f8 + 2579e21 commit d0deeb8

10 files changed

Lines changed: 629 additions & 672 deletions

File tree

fs/overlayfs/copy_up.c

Lines changed: 33 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -724,34 +724,33 @@ static int ovl_copy_up_metadata(struct ovl_copy_up_ctx *c, struct dentry *temp)
724724
return err;
725725
}
726726

727-
struct ovl_cu_creds {
728-
const struct cred *old;
729-
struct cred *new;
730-
};
731-
732-
static int ovl_prep_cu_creds(struct dentry *dentry, struct ovl_cu_creds *cc)
727+
static const struct cred *ovl_prepare_copy_up_creds(struct dentry *dentry)
733728
{
729+
struct cred *copy_up_cred = NULL;
734730
int err;
735731

736-
cc->old = cc->new = NULL;
737-
err = security_inode_copy_up(dentry, &cc->new);
732+
err = security_inode_copy_up(dentry, &copy_up_cred);
738733
if (err < 0)
739-
return err;
734+
return ERR_PTR(err);
740735

741-
if (cc->new)
742-
cc->old = override_creds(cc->new);
736+
if (!copy_up_cred)
737+
return NULL;
743738

744-
return 0;
739+
return override_creds(copy_up_cred);
745740
}
746741

747-
static void ovl_revert_cu_creds(struct ovl_cu_creds *cc)
742+
static void ovl_revert_copy_up_creds(const struct cred *orig_cred)
748743
{
749-
if (cc->new) {
750-
revert_creds(cc->old);
751-
put_cred(cc->new);
752-
}
744+
const struct cred *copy_up_cred;
745+
746+
copy_up_cred = revert_creds(orig_cred);
747+
put_cred(copy_up_cred);
753748
}
754749

750+
DEFINE_CLASS(copy_up_creds, const struct cred *,
751+
if (!IS_ERR_OR_NULL(_T)) ovl_revert_copy_up_creds(_T),
752+
ovl_prepare_copy_up_creds(dentry), struct dentry *dentry)
753+
755754
/*
756755
* Copyup using workdir to prepare temp file. Used when copying up directories,
757756
* special files or when upper fs doesn't support O_TMPFILE.
@@ -763,7 +762,6 @@ static int ovl_copy_up_workdir(struct ovl_copy_up_ctx *c)
763762
struct path path = { .mnt = ovl_upper_mnt(ofs) };
764763
struct renamedata rd = {};
765764
struct dentry *temp;
766-
struct ovl_cu_creds cc;
767765
int err;
768766
struct ovl_cattr cattr = {
769767
/* Can't properly set mode on creation because of the umask */
@@ -772,14 +770,14 @@ static int ovl_copy_up_workdir(struct ovl_copy_up_ctx *c)
772770
.link = c->link
773771
};
774772

775-
err = ovl_prep_cu_creds(c->dentry, &cc);
776-
if (err)
777-
return err;
773+
scoped_class(copy_up_creds, copy_up_creds, c->dentry) {
774+
if (IS_ERR(copy_up_creds))
775+
return PTR_ERR(copy_up_creds);
778776

779-
ovl_start_write(c->dentry);
780-
temp = ovl_create_temp(ofs, c->workdir, &cattr);
781-
ovl_end_write(c->dentry);
782-
ovl_revert_cu_creds(&cc);
777+
ovl_start_write(c->dentry);
778+
temp = ovl_create_temp(ofs, c->workdir, &cattr);
779+
ovl_end_write(c->dentry);
780+
}
783781

784782
if (IS_ERR(temp))
785783
return PTR_ERR(temp);
@@ -857,17 +855,17 @@ static int ovl_copy_up_tmpfile(struct ovl_copy_up_ctx *c)
857855
struct inode *udir = d_inode(c->destdir);
858856
struct dentry *temp, *upper;
859857
struct file *tmpfile;
860-
struct ovl_cu_creds cc;
861858
int err;
862859

863-
err = ovl_prep_cu_creds(c->dentry, &cc);
864-
if (err)
865-
return err;
860+
scoped_class(copy_up_creds, copy_up_creds, c->dentry) {
861+
if (IS_ERR(copy_up_creds))
862+
return PTR_ERR(copy_up_creds);
863+
864+
ovl_start_write(c->dentry);
865+
tmpfile = ovl_do_tmpfile(ofs, c->workdir, c->stat.mode);
866+
ovl_end_write(c->dentry);
867+
}
866868

867-
ovl_start_write(c->dentry);
868-
tmpfile = ovl_do_tmpfile(ofs, c->workdir, c->stat.mode);
869-
ovl_end_write(c->dentry);
870-
ovl_revert_cu_creds(&cc);
871869
if (IS_ERR(tmpfile))
872870
return PTR_ERR(tmpfile);
873871

@@ -1203,7 +1201,6 @@ static int ovl_copy_up_one(struct dentry *parent, struct dentry *dentry,
12031201
static int ovl_copy_up_flags(struct dentry *dentry, int flags)
12041202
{
12051203
int err = 0;
1206-
const struct cred *old_cred;
12071204
bool disconnected = (dentry->d_flags & DCACHE_DISCONNECTED);
12081205

12091206
/*
@@ -1223,7 +1220,6 @@ static int ovl_copy_up_flags(struct dentry *dentry, int flags)
12231220
if (err)
12241221
return err;
12251222

1226-
old_cred = ovl_override_creds(dentry->d_sb);
12271223
while (!err) {
12281224
struct dentry *next;
12291225
struct dentry *parent = NULL;
@@ -1243,12 +1239,12 @@ static int ovl_copy_up_flags(struct dentry *dentry, int flags)
12431239
next = parent;
12441240
}
12451241

1246-
err = ovl_copy_up_one(parent, next, flags);
1242+
with_ovl_creds(dentry->d_sb)
1243+
err = ovl_copy_up_one(parent, next, flags);
12471244

12481245
dput(parent);
12491246
dput(next);
12501247
}
1251-
ovl_revert_creds(old_cred);
12521248

12531249
return err;
12541250
}

0 commit comments

Comments
 (0)