diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2019-12-15 19:50:23 -0800 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2019-12-16 08:42:39 -0800 |
commit | 7de7de7ca0ae0fc70515ee3154af33af75edae2c (patch) | |
tree | 2110b58dec314ad3e65240a5a9e61efb2aba40e7 /init/do_mounts.c | |
parent | d1eef1c619749b2a57e514a3fa67d9a516ffa919 (diff) |
Fix root mounting with no mount options
The "trivial conversion" in commit cccaa5e33525 ("init: use do_mount()
instead of ksys_mount()") was totally broken, since it didn't handle the
case of a NULL mount data pointer. And while I had "tested" it (and
presumably Dominik had too) that bug was hidden by me having options.
Cc: Dominik Brodowski <linux@dominikbrodowski.net>
Cc: Arnd Bergmann <arnd@arndb.de>
Reported-by: Ondřej Jirman <megi@xff.cz>
Reported-by: Guenter Roeck <linux@roeck-us.net>
Reported-by: Naresh Kamboju <naresh.kamboju@linaro.org>
Reported-and-tested-by: Borislav Petkov <bp@suse.de>
Tested-by: Chris Clayton <chris2553@googlemail.com>
Tested-by: Eric Biggers <ebiggers@kernel.org>
Tested-by: Geert Uytterhoeven <geert@linux-m68k.org>
Tested-by: Guido Günther <agx@sigxcpu.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'init/do_mounts.c')
-rw-r--r-- | init/do_mounts.c | 23 |
1 files changed, 13 insertions, 10 deletions
diff --git a/init/do_mounts.c b/init/do_mounts.c index f55cbd9cb818..0ae9cc22f2ae 100644 --- a/init/do_mounts.c +++ b/init/do_mounts.c @@ -391,17 +391,19 @@ static int __init do_mount_root(const char *name, const char *fs, const int flags, const void *data) { struct super_block *s; - char *data_page; - struct page *p; + struct page *p = NULL; + char *data_page = NULL; int ret; - /* do_mount() requires a full page as fifth argument */ - p = alloc_page(GFP_KERNEL); - if (!p) - return -ENOMEM; - - data_page = page_address(p); - strncpy(data_page, data, PAGE_SIZE - 1); + if (data) { + /* do_mount() requires a full page as fifth argument */ + p = alloc_page(GFP_KERNEL); + if (!p) + return -ENOMEM; + data_page = page_address(p); + /* zero-pad. do_mount() will make sure it's terminated */ + strncpy(data_page, data, PAGE_SIZE); + } ret = do_mount(name, "/root", fs, flags, data_page); if (ret) @@ -417,7 +419,8 @@ static int __init do_mount_root(const char *name, const char *fs, MAJOR(ROOT_DEV), MINOR(ROOT_DEV)); out: - put_page(p); + if (p) + put_page(p); return ret; } |