diff options
author | Linus Torvalds <[email protected]> | 2019-12-15 19:50:23 -0800 |
---|---|---|
committer | Linus Torvalds <[email protected]> | 2019-12-16 08:42:39 -0800 |
commit | 7de7de7ca0ae0fc70515ee3154af33af75edae2c (patch) | |
tree | 2110b58dec314ad3e65240a5a9e61efb2aba40e7 | |
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 <[email protected]>
Cc: Arnd Bergmann <[email protected]>
Reported-by: Ondřej Jirman <[email protected]>
Reported-by: Guenter Roeck <[email protected]>
Reported-by: Naresh Kamboju <[email protected]>
Reported-and-tested-by: Borislav Petkov <[email protected]>
Tested-by: Chris Clayton <[email protected]>
Tested-by: Eric Biggers <[email protected]>
Tested-by: Geert Uytterhoeven <[email protected]>
Tested-by: Guido Günther <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
-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; } |