diff options
Diffstat (limited to 'init')
-rw-r--r-- | init/Kconfig | 18 | ||||
-rw-r--r-- | init/do_mounts.c | 33 | ||||
-rw-r--r-- | init/do_mounts_initrd.c | 11 | ||||
-rw-r--r-- | init/main.c | 56 |
4 files changed, 88 insertions, 30 deletions
diff --git a/init/Kconfig b/init/Kconfig index a34064a031a5..24b23d843df1 100644 --- a/init/Kconfig +++ b/init/Kconfig @@ -54,11 +54,12 @@ config CC_DISABLE_WARN_MAYBE_UNINITIALIZED config CONSTRUCTORS bool + depends on !UML config IRQ_WORK bool -config BUILDTIME_EXTABLE_SORT +config BUILDTIME_TABLE_SORT bool config THREAD_INFO_IN_TASK @@ -1080,6 +1081,14 @@ config UTS_NS In this namespace tasks see different info provided with the uname() system call +config TIME_NS + bool "TIME namespace" + depends on GENERIC_VDSO_TIME_NS + default y + help + In this namespace boottime and monotonic clocks can be set. + The time will keep going with the same pace. + config IPC_NS bool "IPC namespace" depends on (SYSVIPC || POSIX_MQUEUE) @@ -1604,6 +1613,9 @@ config BPF_SYSCALL Enable the bpf() system call that allows to manipulate eBPF programs and maps via file descriptors. +config ARCH_WANT_DEFAULT_BPF_JIT + bool + config BPF_JIT_ALWAYS_ON bool "Permanently enable BPF JIT and remove BPF interpreter" depends on BPF_SYSCALL && HAVE_EBPF_JIT && BPF_JIT @@ -1611,6 +1623,10 @@ config BPF_JIT_ALWAYS_ON Enables BPF JIT and removes BPF interpreter to avoid speculative execution of BPF instructions by the interpreter +config BPF_JIT_DEFAULT_ON + def_bool ARCH_WANT_DEFAULT_BPF_JIT || BPF_JIT_ALWAYS_ON + depends on HAVE_EBPF_JIT && BPF_JIT + config USERFAULTFD bool "Enable userfaultfd() system call" depends on MMU diff --git a/init/do_mounts.c b/init/do_mounts.c index af9cda887a23..0ae9cc22f2ae 100644 --- a/init/do_mounts.c +++ b/init/do_mounts.c @@ -387,12 +387,27 @@ static void __init get_fs_names(char *page) *s = '\0'; } -static int __init do_mount_root(char *name, char *fs, int flags, void *data) +static int __init do_mount_root(const char *name, const char *fs, + const int flags, const void *data) { struct super_block *s; - int err = ksys_mount(name, "/root", fs, flags, data); - if (err) - return err; + struct page *p = NULL; + char *data_page = NULL; + int ret; + + 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) + goto out; ksys_chdir("/root"); s = current->fs->pwd.dentry->d_sb; @@ -402,7 +417,11 @@ static int __init do_mount_root(char *name, char *fs, int flags, void *data) s->s_type->name, sb_rdonly(s) ? " readonly" : "", MAJOR(ROOT_DEV), MINOR(ROOT_DEV)); - return 0; + +out: + if (p) + put_page(p); + return ret; } void __init mount_block_root(char *name, int flags) @@ -670,8 +689,8 @@ void __init prepare_namespace(void) mount_root(); out: - devtmpfs_mount("dev"); - ksys_mount(".", "/", NULL, MS_MOVE, NULL); + devtmpfs_mount(); + do_mount(".", "/", NULL, MS_MOVE, NULL); ksys_chroot("."); } diff --git a/init/do_mounts_initrd.c b/init/do_mounts_initrd.c index a9c6cc56f505..dab8b1151b56 100644 --- a/init/do_mounts_initrd.c +++ b/init/do_mounts_initrd.c @@ -48,13 +48,10 @@ early_param("initrd", early_initrd); static int init_linuxrc(struct subprocess_info *info, struct cred *new) { ksys_unshare(CLONE_FS | CLONE_FILES); - /* stdin/stdout/stderr for /linuxrc */ - ksys_open("/dev/console", O_RDWR, 0); - ksys_dup(0); - ksys_dup(0); + console_on_rootfs(); /* move initrd over / and chdir/chroot in initrd root */ ksys_chdir("/root"); - ksys_mount(".", "/", NULL, MS_MOVE, NULL); + do_mount(".", "/", NULL, MS_MOVE, NULL); ksys_chroot("."); ksys_setsid(); return 0; @@ -89,7 +86,7 @@ static void __init handle_initrd(void) current->flags &= ~PF_FREEZER_SKIP; /* move initrd to rootfs' /old */ - ksys_mount("..", ".", NULL, MS_MOVE, NULL); + do_mount("..", ".", NULL, MS_MOVE, NULL); /* switch root and cwd back to / of rootfs */ ksys_chroot(".."); @@ -103,7 +100,7 @@ static void __init handle_initrd(void) mount_root(); printk(KERN_NOTICE "Trying to move old root to /initrd ... "); - error = ksys_mount("/old", "/root/initrd", NULL, MS_MOVE, NULL); + error = do_mount("/old", "/root/initrd", NULL, MS_MOVE, NULL); if (!error) printk("okay\n"); else { diff --git a/init/main.c b/init/main.c index 91f6ebb30ef0..d8c7e86c2d28 100644 --- a/init/main.c +++ b/init/main.c @@ -63,7 +63,7 @@ #include <linux/lockdep.h> #include <linux/kmemleak.h> #include <linux/pid_namespace.h> -#include <linux/device.h> +#include <linux/device/driver.h> #include <linux/kthread.h> #include <linux/sched.h> #include <linux/sched/init.h> @@ -246,8 +246,7 @@ static int __init loglevel(char *str) early_param("loglevel", loglevel); /* Change NUL term back to "=", to make "param" the whole string. */ -static int __init repair_env_string(char *param, char *val, - const char *unused, void *arg) +static void __init repair_env_string(char *param, char *val) { if (val) { /* param=val or param="val"? */ @@ -256,11 +255,9 @@ static int __init repair_env_string(char *param, char *val, else if (val == param+strlen(param)+2) { val[-2] = '='; memmove(val-1, val, strlen(val)+1); - val--; } else BUG(); } - return 0; } /* Anything after -- gets handed straight to init. */ @@ -272,7 +269,7 @@ static int __init set_init_arg(char *param, char *val, if (panic_later) return 0; - repair_env_string(param, val, unused, NULL); + repair_env_string(param, val); for (i = 0; argv_init[i]; i++) { if (i == MAX_INIT_ARGS) { @@ -292,14 +289,16 @@ static int __init set_init_arg(char *param, char *val, static int __init unknown_bootoption(char *param, char *val, const char *unused, void *arg) { - repair_env_string(param, val, unused, NULL); + size_t len = strlen(param); + + repair_env_string(param, val); /* Handle obsolete-style parameters */ if (obsolete_checksetup(param)) return 0; /* Unused module parameter. */ - if (strchr(param, '.') && (!val || strchr(param, '.') < val)) + if (strnchr(param, len, '.')) return 0; if (panic_later) @@ -313,7 +312,7 @@ static int __init unknown_bootoption(char *param, char *val, panic_later = "env"; panic_param = param; } - if (!strncmp(param, envp_init[i], val - param)) + if (!strncmp(param, envp_init[i], len+1)) break; } envp_init[i] = param; @@ -553,6 +552,7 @@ static void __init mm_init(void) * bigger than MAX_ORDER unless SPARSEMEM. */ page_ext_init_flatmem(); + init_debug_pagealloc(); report_meminit(); mem_init(); kmem_cache_init(); @@ -990,6 +990,12 @@ static const char *initcall_level_names[] __initdata = { "late", }; +static int __init ignore_unknown_bootoption(char *param, char *val, + const char *unused, void *arg) +{ + return 0; +} + static void __init do_initcall_level(int level) { initcall_entry_t *fn; @@ -999,7 +1005,7 @@ static void __init do_initcall_level(int level) initcall_command_line, __start___param, __stop___param - __start___param, level, level, - NULL, &repair_env_string); + NULL, ignore_unknown_bootoption); trace_initcall_level(initcall_level_names[level]); for (fn = initcall_levels[level]; fn < initcall_levels[level+1]; fn++) @@ -1042,8 +1048,16 @@ static void __init do_pre_smp_initcalls(void) static int run_init_process(const char *init_filename) { + const char *const *p; + argv_init[0] = init_filename; pr_info("Run %s as init process\n", init_filename); + pr_debug(" with arguments:\n"); + for (p = argv_init; *p; p++) + pr_debug(" %s\n", *p); + pr_debug(" with environment:\n"); + for (p = envp_init; *p; p++) + pr_debug(" %s\n", *p); return do_execve(getname_kernel(init_filename), (const char __user *const __user *)argv_init, (const char __user *const __user *)envp_init); @@ -1090,6 +1104,11 @@ static void mark_readonly(void) } else pr_info("Kernel memory protection disabled.\n"); } +#elif defined(CONFIG_ARCH_HAS_STRICT_KERNEL_RWX) +static inline void mark_readonly(void) +{ + pr_warn("Kernel memory protection not selected by kernel config.\n"); +} #else static inline void mark_readonly(void) { @@ -1155,6 +1174,17 @@ static int __ref kernel_init(void *unused) "See Linux Documentation/admin-guide/init.rst for guidance."); } +void console_on_rootfs(void) +{ + /* Open the /dev/console as stdin, this should never fail */ + if (ksys_open((const char __user *) "/dev/console", O_RDWR, 0) < 0) + pr_err("Warning: unable to open an initial console.\n"); + + /* create stdout/stderr */ + (void) ksys_dup(0); + (void) ksys_dup(0); +} + static noinline void __init kernel_init_freeable(void) { /* @@ -1190,12 +1220,8 @@ static noinline void __init kernel_init_freeable(void) do_basic_setup(); - /* Open the /dev/console on the rootfs, this should never fail */ - if (ksys_open((const char __user *) "/dev/console", O_RDWR, 0) < 0) - pr_err("Warning: unable to open an initial console.\n"); + console_on_rootfs(); - (void) ksys_dup(0); - (void) ksys_dup(0); /* * check if there is an early userspace init. If yes, let it do all * the work |