Skip to content

Commit fc95cda

Browse files
committed
ovl: refactor ovl_fill_super()
Split the core into a separate helper in preparation of converting the caller to the scoped ovl cred guard. Link: https://patch.msgid.link/20251117-work-ovl-cred-guard-v4-40-b31603935724@kernel.org Reviewed-by: Amir Goldstein <amir73il@gmail.com> Signed-off-by: Christian Brauner <brauner@kernel.org>
1 parent db7cfe8 commit fc95cda

1 file changed

Lines changed: 50 additions & 45 deletions

File tree

fs/overlayfs/super.c

Lines changed: 50 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1364,53 +1364,35 @@ static void ovl_set_d_op(struct super_block *sb)
13641364
set_default_d_op(sb, &ovl_dentry_operations);
13651365
}
13661366

1367-
int ovl_fill_super(struct super_block *sb, struct fs_context *fc)
1367+
static int ovl_fill_super_creds(struct fs_context *fc, struct super_block *sb)
13681368
{
13691369
struct ovl_fs *ofs = sb->s_fs_info;
1370+
struct cred *creator_cred = (struct cred *)ofs->creator_cred;
13701371
struct ovl_fs_context *ctx = fc->fs_private;
1371-
const struct cred *old_cred = NULL;
1372-
struct dentry *root_dentry;
1373-
struct ovl_entry *oe;
13741372
struct ovl_layer *layers;
1375-
struct cred *cred;
1373+
struct ovl_entry *oe = NULL;
13761374
int err;
13771375

1378-
err = -EIO;
1379-
if (WARN_ON(fc->user_ns != current_user_ns()))
1380-
goto out_err;
1381-
1382-
ovl_set_d_op(sb);
1383-
1384-
err = -ENOMEM;
1385-
if (!ofs->creator_cred)
1386-
ofs->creator_cred = cred = prepare_creds();
1387-
else
1388-
cred = (struct cred *)ofs->creator_cred;
1389-
if (!cred)
1390-
goto out_err;
1391-
1392-
old_cred = ovl_override_creds(sb);
1393-
13941376
err = ovl_fs_params_verify(ctx, &ofs->config);
13951377
if (err)
1396-
goto out_err;
1378+
return err;
13971379

13981380
err = -EINVAL;
13991381
if (ctx->nr == 0) {
14001382
if (!(fc->sb_flags & SB_SILENT))
14011383
pr_err("missing 'lowerdir'\n");
1402-
goto out_err;
1384+
return err;
14031385
}
14041386

14051387
err = -ENOMEM;
14061388
layers = kcalloc(ctx->nr + 1, sizeof(struct ovl_layer), GFP_KERNEL);
14071389
if (!layers)
1408-
goto out_err;
1390+
return err;
14091391

14101392
ofs->config.lowerdirs = kcalloc(ctx->nr + 1, sizeof(char *), GFP_KERNEL);
14111393
if (!ofs->config.lowerdirs) {
14121394
kfree(layers);
1413-
goto out_err;
1395+
return err;
14141396
}
14151397
ofs->layers = layers;
14161398
/*
@@ -1443,26 +1425,26 @@ int ovl_fill_super(struct super_block *sb, struct fs_context *fc)
14431425
err = -EINVAL;
14441426
if (!ofs->config.workdir) {
14451427
pr_err("missing 'workdir'\n");
1446-
goto out_err;
1428+
return err;
14471429
}
14481430

14491431
err = ovl_get_upper(sb, ofs, &layers[0], &ctx->upper);
14501432
if (err)
1451-
goto out_err;
1433+
return err;
14521434

14531435
upper_sb = ovl_upper_mnt(ofs)->mnt_sb;
14541436
if (!ovl_should_sync(ofs)) {
14551437
ofs->errseq = errseq_sample(&upper_sb->s_wb_err);
14561438
if (errseq_check(&upper_sb->s_wb_err, ofs->errseq)) {
14571439
err = -EIO;
14581440
pr_err("Cannot mount volatile when upperdir has an unseen error. Sync upperdir fs to clear state.\n");
1459-
goto out_err;
1441+
return err;
14601442
}
14611443
}
14621444

14631445
err = ovl_get_workdir(sb, ofs, &ctx->upper, &ctx->work);
14641446
if (err)
1465-
goto out_err;
1447+
return err;
14661448

14671449
if (!ofs->workdir)
14681450
sb->s_flags |= SB_RDONLY;
@@ -1473,7 +1455,7 @@ int ovl_fill_super(struct super_block *sb, struct fs_context *fc)
14731455
oe = ovl_get_lowerstack(sb, ctx, ofs, layers);
14741456
err = PTR_ERR(oe);
14751457
if (IS_ERR(oe))
1476-
goto out_err;
1458+
return err;
14771459

14781460
/* If the upper fs is nonexistent, we mark overlayfs r/o too */
14791461
if (!ovl_upper_mnt(ofs))
@@ -1526,7 +1508,7 @@ int ovl_fill_super(struct super_block *sb, struct fs_context *fc)
15261508
sb->s_export_op = &ovl_export_fid_operations;
15271509

15281510
/* Never override disk quota limits or use reserved space */
1529-
cap_lower(cred->cap_effective, CAP_SYS_RESOURCE);
1511+
cap_lower(creator_cred->cap_effective, CAP_SYS_RESOURCE);
15301512

15311513
sb->s_magic = OVERLAYFS_SUPER_MAGIC;
15321514
sb->s_xattr = ovl_xattr_handlers(ofs);
@@ -1544,27 +1526,50 @@ int ovl_fill_super(struct super_block *sb, struct fs_context *fc)
15441526
sb->s_iflags |= SB_I_EVM_HMAC_UNSUPPORTED;
15451527

15461528
err = -ENOMEM;
1547-
root_dentry = ovl_get_root(sb, ctx->upper.dentry, oe);
1548-
if (!root_dentry)
1529+
sb->s_root = ovl_get_root(sb, ctx->upper.dentry, oe);
1530+
if (!sb->s_root)
15491531
goto out_free_oe;
15501532

1551-
sb->s_root = root_dentry;
1552-
1553-
ovl_revert_creds(old_cred);
15541533
return 0;
15551534

15561535
out_free_oe:
15571536
ovl_free_entry(oe);
1537+
return err;
1538+
}
1539+
1540+
int ovl_fill_super(struct super_block *sb, struct fs_context *fc)
1541+
{
1542+
struct ovl_fs *ofs = sb->s_fs_info;
1543+
const struct cred *old_cred = NULL;
1544+
struct cred *cred;
1545+
int err;
1546+
1547+
err = -EIO;
1548+
if (WARN_ON(fc->user_ns != current_user_ns()))
1549+
goto out_err;
1550+
1551+
ovl_set_d_op(sb);
1552+
1553+
err = -ENOMEM;
1554+
if (!ofs->creator_cred)
1555+
ofs->creator_cred = cred = prepare_creds();
1556+
else
1557+
cred = (struct cred *)ofs->creator_cred;
1558+
if (!cred)
1559+
goto out_err;
1560+
1561+
old_cred = ovl_override_creds(sb);
1562+
1563+
err = ovl_fill_super_creds(fc, sb);
1564+
1565+
ovl_revert_creds(old_cred);
1566+
15581567
out_err:
1559-
/*
1560-
* Revert creds before calling ovl_free_fs() which will call
1561-
* put_cred() and put_cred() requires that the cred's that are
1562-
* put are not the caller's creds, i.e., current->cred.
1563-
*/
1564-
if (old_cred)
1565-
ovl_revert_creds(old_cred);
1566-
ovl_free_fs(ofs);
1567-
sb->s_fs_info = NULL;
1568+
if (err) {
1569+
ovl_free_fs(ofs);
1570+
sb->s_fs_info = NULL;
1571+
}
1572+
15681573
return err;
15691574
}
15701575

0 commit comments

Comments
 (0)