Skip to content

Commit

Permalink
Merge branch 'work.init' of git://git.kernel.org/pub/scm/linux/kernel…
Browse files Browse the repository at this point in the history
…/git/viro/vfs

Pull vfs fixes from Al Viro:
 "Followups to nodev root stuff from this merge window"

* 'work.init' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs:
  init: don't panic if mount_nodev_root failed
  init/do_mounts.c: Harden split_fs_names() against buffer overflow
  • Loading branch information
torvalds committed Sep 24, 2021
2 parents e61b2ad + 40c8ee6 commit a801695
Showing 1 changed file with 16 additions and 14 deletions.
30 changes: 16 additions & 14 deletions init/do_mounts.c
Original file line number Diff line number Diff line change
Expand Up @@ -338,20 +338,19 @@ __setup("rootflags=", root_data_setup);
__setup("rootfstype=", fs_names_setup);
__setup("rootdelay=", root_delay_setup);

static int __init split_fs_names(char *page, char *names)
/* This can return zero length strings. Caller should check */
static int __init split_fs_names(char *page, size_t size, char *names)
{
int count = 0;
int count = 1;
char *p = page;

strcpy(p, root_fs_names);
strlcpy(p, root_fs_names, size);
while (*p++) {
if (p[-1] == ',')
if (p[-1] == ',') {
p[-1] = '\0';
count++;
}
}
*p = '\0';

for (p = page; *p; p += strlen(p)+1)
count++;

return count;
}
Expand Down Expand Up @@ -404,12 +403,16 @@ void __init mount_block_root(char *name, int flags)
scnprintf(b, BDEVNAME_SIZE, "unknown-block(%u,%u)",
MAJOR(ROOT_DEV), MINOR(ROOT_DEV));
if (root_fs_names)
num_fs = split_fs_names(fs_names, root_fs_names);
num_fs = split_fs_names(fs_names, PAGE_SIZE, root_fs_names);
else
num_fs = list_bdev_fs_names(fs_names, PAGE_SIZE);
retry:
for (i = 0, p = fs_names; i < num_fs; i++, p += strlen(p)+1) {
int err = do_mount_root(name, p, flags, root_mount_data);
int err;

if (!*p)
continue;
err = do_mount_root(name, p, flags, root_mount_data);
switch (err) {
case 0:
goto out;
Expand Down Expand Up @@ -543,19 +546,18 @@ static int __init mount_nodev_root(void)
fs_names = (void *)__get_free_page(GFP_KERNEL);
if (!fs_names)
return -EINVAL;
num_fs = split_fs_names(fs_names, root_fs_names);
num_fs = split_fs_names(fs_names, PAGE_SIZE, root_fs_names);

for (i = 0, fstype = fs_names; i < num_fs;
i++, fstype += strlen(fstype) + 1) {
if (!*fstype)
continue;
if (!fs_is_nodev(fstype))
continue;
err = do_mount_root(root_device_name, fstype, root_mountflags,
root_mount_data);
if (!err)
break;
if (err != -EACCES && err != -EINVAL)
panic("VFS: Unable to mount root \"%s\" (%s), err=%d\n",
root_device_name, fstype, err);
}

free_page((unsigned long)fs_names);
Expand Down

0 comments on commit a801695

Please sign in to comment.