Skip to content

Commit b8e42a6

Browse files
author
Miklos Szeredi
committed
ovl: get rid of redundant members in struct ovl_fs
ofs->upper_mnt is copied to ->layers[0].mnt and ->layers[0].trap could be used instead of a separate ->upperdir_trap. Split the lowerdir option early to get the number of layers, then allocate the ->layers array, and finally fill the upper and lower layers, as before. Get rid of path_put_init() in ovl_lower_dir(), since the only caller will take care of that. [Colin Ian King] Fix null pointer dereference on null stack pointer on error return found by Coverity. Signed-off-by: Miklos Szeredi <[email protected]>
1 parent 08f4c7c commit b8e42a6

File tree

2 files changed

+48
-55
lines changed

2 files changed

+48
-55
lines changed

fs/overlayfs/ovl_entry.h

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,6 @@ struct ovl_path {
4646

4747
/* private information held for overlayfs's superblock */
4848
struct ovl_fs {
49-
struct vfsmount *upper_mnt;
5049
unsigned int numlayer;
5150
/* Number of unique fs among layers including upper fs */
5251
unsigned int numfs;
@@ -70,7 +69,6 @@ struct ovl_fs {
7069
bool workdir_locked;
7170
bool share_whiteout;
7271
/* Traps in ovl inode cache */
73-
struct inode *upperdir_trap;
7472
struct inode *workbasedir_trap;
7573
struct inode *workdir_trap;
7674
struct inode *indexdir_trap;
@@ -84,7 +82,7 @@ struct ovl_fs {
8482

8583
static inline struct vfsmount *ovl_upper_mnt(struct ovl_fs *ofs)
8684
{
87-
return ofs->upper_mnt;
85+
return ofs->layers[0].mnt;
8886
}
8987

9088
static inline struct ovl_fs *OVL_FS(struct super_block *sb)

fs/overlayfs/super.c

Lines changed: 47 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -216,7 +216,6 @@ static void ovl_free_fs(struct ovl_fs *ofs)
216216
iput(ofs->workbasedir_trap);
217217
iput(ofs->indexdir_trap);
218218
iput(ofs->workdir_trap);
219-
iput(ofs->upperdir_trap);
220219
dput(ofs->whiteout);
221220
dput(ofs->indexdir);
222221
dput(ofs->workdir);
@@ -225,8 +224,7 @@ static void ovl_free_fs(struct ovl_fs *ofs)
225224
dput(ofs->workbasedir);
226225
if (ofs->upperdir_locked)
227226
ovl_inuse_unlock(ovl_upper_mnt(ofs)->mnt_root);
228-
mntput(ofs->upper_mnt);
229-
for (i = 1; i < ofs->numlayer; i++) {
227+
for (i = 0; i < ofs->numlayer; i++) {
230228
iput(ofs->layers[i].trap);
231229
mntput(ofs->layers[i].mnt);
232230
}
@@ -837,11 +835,11 @@ static int ovl_lower_dir(const char *name, struct path *path,
837835

838836
err = ovl_mount_dir_noesc(name, path);
839837
if (err)
840-
goto out;
838+
return err;
841839

842840
err = ovl_check_namelen(path, ofs, name);
843841
if (err)
844-
goto out_put;
842+
return err;
845843

846844
*stack_depth = max(*stack_depth, path->mnt->mnt_sb->s_stack_depth);
847845

@@ -863,11 +861,6 @@ static int ovl_lower_dir(const char *name, struct path *path,
863861
ofs->xino_mode = -1;
864862

865863
return 0;
866-
867-
out_put:
868-
path_put_init(path);
869-
out:
870-
return err;
871864
}
872865

873866
/* Workdir should not be subdir of upperdir and vice versa */
@@ -1074,7 +1067,7 @@ static int ovl_report_in_use(struct ovl_fs *ofs, const char *name)
10741067
}
10751068

10761069
static int ovl_get_upper(struct super_block *sb, struct ovl_fs *ofs,
1077-
struct path *upperpath)
1070+
struct ovl_layer *upper_layer, struct path *upperpath)
10781071
{
10791072
struct vfsmount *upper_mnt;
10801073
int err;
@@ -1094,7 +1087,7 @@ static int ovl_get_upper(struct super_block *sb, struct ovl_fs *ofs,
10941087
if (err)
10951088
goto out;
10961089

1097-
err = ovl_setup_trap(sb, upperpath->dentry, &ofs->upperdir_trap,
1090+
err = ovl_setup_trap(sb, upperpath->dentry, &upper_layer->trap,
10981091
"upperdir");
10991092
if (err)
11001093
goto out;
@@ -1108,7 +1101,9 @@ static int ovl_get_upper(struct super_block *sb, struct ovl_fs *ofs,
11081101

11091102
/* Don't inherit atime flags */
11101103
upper_mnt->mnt_flags &= ~(MNT_NOATIME | MNT_NODIRATIME | MNT_RELATIME);
1111-
ofs->upper_mnt = upper_mnt;
1104+
upper_layer->mnt = upper_mnt;
1105+
upper_layer->idx = 0;
1106+
upper_layer->fsid = 0;
11121107

11131108
/*
11141109
* Inherit SB_NOSEC flag from upperdir.
@@ -1458,30 +1453,20 @@ static int ovl_get_fsid(struct ovl_fs *ofs, const struct path *path)
14581453
}
14591454

14601455
static int ovl_get_layers(struct super_block *sb, struct ovl_fs *ofs,
1461-
struct path *stack, unsigned int numlower)
1456+
struct path *stack, unsigned int numlower,
1457+
struct ovl_layer *layers)
14621458
{
14631459
int err;
14641460
unsigned int i;
1465-
struct ovl_layer *layers;
14661461

14671462
err = -ENOMEM;
1468-
layers = kcalloc(numlower + 1, sizeof(struct ovl_layer), GFP_KERNEL);
1469-
if (!layers)
1470-
goto out;
1471-
ofs->layers = layers;
1472-
14731463
ofs->fs = kcalloc(numlower + 1, sizeof(struct ovl_sb), GFP_KERNEL);
14741464
if (ofs->fs == NULL)
14751465
goto out;
14761466

14771467
/* idx/fsid 0 are reserved for upper fs even with lower only overlay */
14781468
ofs->numfs++;
14791469

1480-
layers[0].mnt = ovl_upper_mnt(ofs);
1481-
layers[0].idx = 0;
1482-
layers[0].fsid = 0;
1483-
ofs->numlayer = 1;
1484-
14851470
/*
14861471
* All lower layers that share the same fs as upper layer, use the same
14871472
* pseudo_dev as upper layer. Allocate fs[0].pseudo_dev even for lower
@@ -1579,44 +1564,30 @@ static int ovl_get_layers(struct super_block *sb, struct ovl_fs *ofs,
15791564
}
15801565

15811566
static struct ovl_entry *ovl_get_lowerstack(struct super_block *sb,
1582-
struct ovl_fs *ofs)
1567+
const char *lower, unsigned int numlower,
1568+
struct ovl_fs *ofs, struct ovl_layer *layers)
15831569
{
15841570
int err;
1585-
char *lowertmp, *lower;
15861571
struct path *stack = NULL;
1587-
unsigned int stacklen, numlower = 0, i;
1572+
unsigned int i;
15881573
struct ovl_entry *oe;
15891574

1590-
err = -ENOMEM;
1591-
lowertmp = kstrdup(ofs->config.lowerdir, GFP_KERNEL);
1592-
if (!lowertmp)
1593-
goto out_err;
1594-
1595-
err = -EINVAL;
1596-
stacklen = ovl_split_lowerdirs(lowertmp);
1597-
if (stacklen > OVL_MAX_STACK) {
1598-
pr_err("too many lower directories, limit is %d\n",
1599-
OVL_MAX_STACK);
1600-
goto out_err;
1601-
} else if (!ofs->config.upperdir && stacklen == 1) {
1575+
if (!ofs->config.upperdir && numlower == 1) {
16021576
pr_err("at least 2 lowerdir are needed while upperdir nonexistent\n");
1603-
goto out_err;
1577+
return ERR_PTR(-EINVAL);
16041578
} else if (!ofs->config.upperdir && ofs->config.nfs_export &&
16051579
ofs->config.redirect_follow) {
16061580
pr_warn("NFS export requires \"redirect_dir=nofollow\" on non-upper mount, falling back to nfs_export=off.\n");
16071581
ofs->config.nfs_export = false;
16081582
}
16091583

1610-
err = -ENOMEM;
1611-
stack = kcalloc(stacklen, sizeof(struct path), GFP_KERNEL);
1584+
stack = kcalloc(numlower, sizeof(struct path), GFP_KERNEL);
16121585
if (!stack)
1613-
goto out_err;
1586+
return ERR_PTR(-ENOMEM);
16141587

16151588
err = -EINVAL;
1616-
lower = lowertmp;
1617-
for (numlower = 0; numlower < stacklen; numlower++) {
1618-
err = ovl_lower_dir(lower, &stack[numlower], ofs,
1619-
&sb->s_stack_depth);
1589+
for (i = 0; i < numlower; i++) {
1590+
err = ovl_lower_dir(lower, &stack[i], ofs, &sb->s_stack_depth);
16201591
if (err)
16211592
goto out_err;
16221593

@@ -1630,7 +1601,7 @@ static struct ovl_entry *ovl_get_lowerstack(struct super_block *sb,
16301601
goto out_err;
16311602
}
16321603

1633-
err = ovl_get_layers(sb, ofs, stack, numlower);
1604+
err = ovl_get_layers(sb, ofs, stack, numlower, layers);
16341605
if (err)
16351606
goto out_err;
16361607

@@ -1648,7 +1619,6 @@ static struct ovl_entry *ovl_get_lowerstack(struct super_block *sb,
16481619
for (i = 0; i < numlower; i++)
16491620
path_put(&stack[i]);
16501621
kfree(stack);
1651-
kfree(lowertmp);
16521622

16531623
return oe;
16541624

@@ -1772,7 +1742,10 @@ static int ovl_fill_super(struct super_block *sb, void *data, int silent)
17721742
struct dentry *root_dentry;
17731743
struct ovl_entry *oe;
17741744
struct ovl_fs *ofs;
1745+
struct ovl_layer *layers;
17751746
struct cred *cred;
1747+
char *splitlower = NULL;
1748+
unsigned int numlower;
17761749
int err;
17771750

17781751
sb->s_d_op = &ovl_dentry_operations;
@@ -1804,6 +1777,26 @@ static int ovl_fill_super(struct super_block *sb, void *data, int silent)
18041777
goto out_err;
18051778
}
18061779

1780+
err = -ENOMEM;
1781+
splitlower = kstrdup(ofs->config.lowerdir, GFP_KERNEL);
1782+
if (!splitlower)
1783+
goto out_err;
1784+
1785+
numlower = ovl_split_lowerdirs(splitlower);
1786+
if (numlower > OVL_MAX_STACK) {
1787+
pr_err("too many lower directories, limit is %d\n",
1788+
OVL_MAX_STACK);
1789+
goto out_err;
1790+
}
1791+
1792+
layers = kcalloc(numlower + 1, sizeof(struct ovl_layer), GFP_KERNEL);
1793+
if (!layers)
1794+
goto out_err;
1795+
1796+
ofs->layers = layers;
1797+
/* Layer 0 is reserved for upper even if there's no upper */
1798+
ofs->numlayer = 1;
1799+
18071800
sb->s_stack_depth = 0;
18081801
sb->s_maxbytes = MAX_LFS_FILESIZE;
18091802
atomic_long_set(&ofs->last_ino, 1);
@@ -1825,7 +1818,7 @@ static int ovl_fill_super(struct super_block *sb, void *data, int silent)
18251818
goto out_err;
18261819
}
18271820

1828-
err = ovl_get_upper(sb, ofs, &upperpath);
1821+
err = ovl_get_upper(sb, ofs, &layers[0], &upperpath);
18291822
if (err)
18301823
goto out_err;
18311824

@@ -1840,7 +1833,7 @@ static int ovl_fill_super(struct super_block *sb, void *data, int silent)
18401833
sb->s_time_gran = ovl_upper_mnt(ofs)->mnt_sb->s_time_gran;
18411834

18421835
}
1843-
oe = ovl_get_lowerstack(sb, ofs);
1836+
oe = ovl_get_lowerstack(sb, splitlower, numlower, ofs, layers);
18441837
err = PTR_ERR(oe);
18451838
if (IS_ERR(oe))
18461839
goto out_err;
@@ -1903,6 +1896,7 @@ static int ovl_fill_super(struct super_block *sb, void *data, int silent)
19031896
goto out_free_oe;
19041897

19051898
mntput(upperpath.mnt);
1899+
kfree(splitlower);
19061900

19071901
sb->s_root = root_dentry;
19081902

@@ -1912,6 +1906,7 @@ static int ovl_fill_super(struct super_block *sb, void *data, int silent)
19121906
ovl_entry_stack_free(oe);
19131907
kfree(oe);
19141908
out_err:
1909+
kfree(splitlower);
19151910
path_put(&upperpath);
19161911
ovl_free_fs(ofs);
19171912
out:

0 commit comments

Comments
 (0)