summaryrefslogtreecommitdiff
path: root/init
diff options
context:
space:
mode:
Diffstat (limited to 'init')
-rw-r--r--init/Kconfig255
-rw-r--r--init/do_mounts_initrd.c22
-rw-r--r--init/initramfs.c76
-rw-r--r--init/main.c51
4 files changed, 148 insertions, 256 deletions
diff --git a/init/Kconfig b/init/Kconfig
index ddcbefe535e9..c984afc489de 100644
--- a/init/Kconfig
+++ b/init/Kconfig
@@ -77,6 +77,11 @@ config CC_HAS_ASM_GOTO_OUTPUT
depends on CC_HAS_ASM_GOTO
def_bool $(success,echo 'int foo(int x) { asm goto ("": "=r"(x) ::: bar); return x; bar: return 0; }' | $(CC) -x c - -c -o /dev/null)
+config CC_HAS_ASM_GOTO_TIED_OUTPUT
+ depends on CC_HAS_ASM_GOTO_OUTPUT
+ # Detect buggy gcc and clang, fixed in gcc-11 clang-14.
+ def_bool $(success,echo 'int foo(int *x) { asm goto (".long (%l[bar]) - .\n": "+m"(*x) ::: bar); return *x; bar: return 0; }' | $CC -x c - -c -o /dev/null)
+
config TOOLS_SUPPORT_RELR
def_bool $(success,env "CC=$(CC)" "LD=$(LD)" "NM=$(NM)" "OBJCOPY=$(OBJCOPY)" $(srctree)/scripts/tools-support-relr.sh)
@@ -352,23 +357,6 @@ config DEFAULT_HOSTNAME
but you may wish to use a different default here to make a minimal
system more usable with less configuration.
-#
-# For some reason microblaze and nios2 hard code SWAP=n. Hopefully we can
-# add proper SWAP support to them, in which case this can be remove.
-#
-config ARCH_NO_SWAP
- bool
-
-config SWAP
- bool "Support for paging of anonymous memory (swap)"
- depends on MMU && BLOCK && !ARCH_NO_SWAP
- default y
- help
- This option allows you to choose whether you want to have support
- for so called swap devices or swap files in your kernel that are
- used to provide more virtual memory than the actual RAM present
- in your computer. If unsure say Y.
-
config SYSVIPC
bool "System V IPC"
help
@@ -390,6 +378,10 @@ config SYSVIPC_SYSCTL
depends on SYSCTL
default y
+config SYSVIPC_COMPAT
+ def_bool y
+ depends on COMPAT && SYSVIPC
+
config POSIX_MQUEUE
bool "POSIX Message Queues"
depends on NET
@@ -435,8 +427,8 @@ config CROSS_MEMORY_ATTACH
See the man page for more details.
config USELIB
- bool "uselib syscall"
- def_bool ALPHA || M68K || SPARC || X86_32 || IA32_EMULATION
+ bool "uselib syscall (for libc5 and earlier)"
+ default ALPHA || M68K || SPARC
help
This option enables the uselib syscall, a system call used in the
dynamic linker from libc5 and earlier. glibc does not use this
@@ -715,8 +707,7 @@ config IKHEADERS
config LOG_BUF_SHIFT
int "Kernel log buffer size (16 => 64KB, 17 => 128KB)"
- range 12 25 if !H8300
- range 12 19 if H8300
+ range 12 25
default 17
depends on PRINTK
help
@@ -1351,7 +1342,7 @@ endif
config BOOT_CONFIG
bool "Boot config support"
- select BLK_DEV_INITRD
+ select BLK_DEV_INITRD if !BOOT_CONFIG_EMBED
help
Extra boot config allows system admin to pass a config file as
complemental extension of kernel cmdline when booting.
@@ -1361,6 +1352,35 @@ config BOOT_CONFIG
If unsure, say Y.
+config BOOT_CONFIG_EMBED
+ bool "Embed bootconfig file in the kernel"
+ depends on BOOT_CONFIG
+ help
+ Embed a bootconfig file given by BOOT_CONFIG_EMBED_FILE in the
+ kernel. Usually, the bootconfig file is loaded with the initrd
+ image. But if the system doesn't support initrd, this option will
+ help you by embedding a bootconfig file while building the kernel.
+
+ If unsure, say N.
+
+config BOOT_CONFIG_EMBED_FILE
+ string "Embedded bootconfig file path"
+ depends on BOOT_CONFIG_EMBED
+ help
+ Specify a bootconfig file which will be embedded to the kernel.
+ This bootconfig will be used if there is no initrd or no other
+ bootconfig in the initrd.
+
+config INITRAMFS_PRESERVE_MTIME
+ bool "Preserve cpio archive mtimes in initramfs"
+ default y
+ help
+ Each entry in an initramfs cpio archive carries an mtime value. When
+ enabled, extracted cpio items take this mtime, with directory mtime
+ setting deferred until after creation of any child entries.
+
+ If unsure, say Y.
+
choice
prompt "Compiler optimization level"
default CC_OPTIMIZE_FOR_PERFORMANCE
@@ -1667,16 +1687,6 @@ config ADVISE_SYSCALLS
applications use these syscalls, you can disable this option to save
space.
-config HAVE_ARCH_USERFAULTFD_WP
- bool
- help
- Arch has userfaultfd write protection support
-
-config HAVE_ARCH_USERFAULTFD_MINOR
- bool
- help
- Arch has userfaultfd minor fault support
-
config MEMBARRIER
bool "Enable membarrier() system call" if EXPERT
default y
@@ -1741,13 +1751,6 @@ config KALLSYMS_BASE_RELATIVE
# syscall, maps, verifier
-config USERFAULTFD
- bool "Enable userfaultfd() system call"
- depends on MMU
- help
- Enable the userfaultfd() system call that allows to intercept and
- handle page faults in userland.
-
config ARCH_HAS_MEMBARRIER_CALLBACKS
bool
@@ -1862,165 +1865,6 @@ config DEBUG_PERF_USE_VMALLOC
endmenu
-config VM_EVENT_COUNTERS
- default y
- bool "Enable VM event counters for /proc/vmstat" if EXPERT
- help
- VM event counters are needed for event counts to be shown.
- This option allows the disabling of the VM event counters
- on EXPERT systems. /proc/vmstat will only show page counts
- if VM event counters are disabled.
-
-config SLUB_DEBUG
- default y
- bool "Enable SLUB debugging support" if EXPERT
- depends on SLUB && SYSFS
- help
- SLUB has extensive debug support features. Disabling these can
- result in significant savings in code size. This also disables
- SLUB sysfs support. /sys/slab will not exist and there will be
- no support for cache validation etc.
-
-config COMPAT_BRK
- bool "Disable heap randomization"
- default y
- help
- Randomizing heap placement makes heap exploits harder, but it
- also breaks ancient binaries (including anything libc5 based).
- This option changes the bootup default to heap randomization
- disabled, and can be overridden at runtime by setting
- /proc/sys/kernel/randomize_va_space to 2.
-
- On non-ancient distros (post-2000 ones) N is usually a safe choice.
-
-choice
- prompt "Choose SLAB allocator"
- default SLUB
- help
- This option allows to select a slab allocator.
-
-config SLAB
- bool "SLAB"
- depends on !PREEMPT_RT
- select HAVE_HARDENED_USERCOPY_ALLOCATOR
- help
- The regular slab allocator that is established and known to work
- well in all environments. It organizes cache hot objects in
- per cpu and per node queues.
-
-config SLUB
- bool "SLUB (Unqueued Allocator)"
- select HAVE_HARDENED_USERCOPY_ALLOCATOR
- help
- SLUB is a slab allocator that minimizes cache line usage
- instead of managing queues of cached objects (SLAB approach).
- Per cpu caching is realized using slabs of objects instead
- of queues of objects. SLUB can use memory efficiently
- and has enhanced diagnostics. SLUB is the default choice for
- a slab allocator.
-
-config SLOB
- depends on EXPERT
- bool "SLOB (Simple Allocator)"
- depends on !PREEMPT_RT
- help
- SLOB replaces the stock allocator with a drastically simpler
- allocator. SLOB is generally more space efficient but
- does not perform as well on large systems.
-
-endchoice
-
-config SLAB_MERGE_DEFAULT
- bool "Allow slab caches to be merged"
- default y
- depends on SLAB || SLUB
- help
- For reduced kernel memory fragmentation, slab caches can be
- merged when they share the same size and other characteristics.
- This carries a risk of kernel heap overflows being able to
- overwrite objects from merged caches (and more easily control
- cache layout), which makes such heap attacks easier to exploit
- by attackers. By keeping caches unmerged, these kinds of exploits
- can usually only damage objects in the same cache. To disable
- merging at runtime, "slab_nomerge" can be passed on the kernel
- command line.
-
-config SLAB_FREELIST_RANDOM
- bool "Randomize slab freelist"
- depends on SLAB || SLUB
- help
- Randomizes the freelist order used on creating new pages. This
- security feature reduces the predictability of the kernel slab
- allocator against heap overflows.
-
-config SLAB_FREELIST_HARDENED
- bool "Harden slab freelist metadata"
- depends on SLAB || SLUB
- help
- Many kernel heap attacks try to target slab cache metadata and
- other infrastructure. This options makes minor performance
- sacrifices to harden the kernel slab allocator against common
- freelist exploit methods. Some slab implementations have more
- sanity-checking than others. This option is most effective with
- CONFIG_SLUB.
-
-config SHUFFLE_PAGE_ALLOCATOR
- bool "Page allocator randomization"
- default SLAB_FREELIST_RANDOM && ACPI_NUMA
- help
- Randomization of the page allocator improves the average
- utilization of a direct-mapped memory-side-cache. See section
- 5.2.27 Heterogeneous Memory Attribute Table (HMAT) in the ACPI
- 6.2a specification for an example of how a platform advertises
- the presence of a memory-side-cache. There are also incidental
- security benefits as it reduces the predictability of page
- allocations to compliment SLAB_FREELIST_RANDOM, but the
- default granularity of shuffling on the "MAX_ORDER - 1" i.e,
- 10th order of pages is selected based on cache utilization
- benefits on x86.
-
- While the randomization improves cache utilization it may
- negatively impact workloads on platforms without a cache. For
- this reason, by default, the randomization is enabled only
- after runtime detection of a direct-mapped memory-side-cache.
- Otherwise, the randomization may be force enabled with the
- 'page_alloc.shuffle' kernel command line parameter.
-
- Say Y if unsure.
-
-config SLUB_CPU_PARTIAL
- default y
- depends on SLUB && SMP
- bool "SLUB per cpu partial cache"
- help
- Per cpu partial caches accelerate objects allocation and freeing
- that is local to a processor at the price of more indeterminism
- in the latency of the free. On overflow these caches will be cleared
- which requires the taking of locks that may cause latency spikes.
- Typically one would choose no for a realtime system.
-
-config MMAP_ALLOW_UNINITIALIZED
- bool "Allow mmapped anonymous memory to be uninitialized"
- depends on EXPERT && !MMU
- default n
- help
- Normally, and according to the Linux spec, anonymous memory obtained
- from mmap() has its contents cleared before it is passed to
- userspace. Enabling this config option allows you to request that
- mmap() skip that if it is given an MAP_UNINITIALIZED flag, thus
- providing a huge performance boost. If this option is not enabled,
- then the flag will be ignored.
-
- This is taken advantage of by uClibc's malloc(), and also by
- ELF-FDPIC binfmt's brk and stack allocator.
-
- Because of the obvious security issues, this option should only be
- enabled on embedded devices where you control what is run in
- userspace. Since that isn't generally a problem on no-MMU systems,
- it is normally safe to say Y here.
-
- See Documentation/admin-guide/mm/nommu-mmap.rst for more information.
-
config SYSTEM_DATA_VERIFICATION
def_bool n
select SYSTEM_TRUSTED_KEYRING
@@ -2118,6 +1962,17 @@ config MODULE_FORCE_UNLOAD
rmmod). This is mainly for kernel developers and desperate users.
If unsure, say N.
+config MODULE_UNLOAD_TAINT_TRACKING
+ bool "Tainted module unload tracking"
+ depends on MODULE_UNLOAD
+ default n
+ help
+ This option allows you to maintain a record of each unloaded
+ module that tainted the kernel. In addition to displaying a
+ list of linked (or loaded) modules e.g. on detection of a bad
+ page (see bad_page()), the aforementioned details are also
+ shown. If unsure, say N.
+
config MODVERSIONS
bool "Module versioning support"
help
@@ -2136,10 +1991,6 @@ config ASM_MODVERSIONS
assembly. This can be enabled only when the target architecture
supports it.
-config MODULE_REL_CRCS
- bool
- depends on MODVERSIONS
-
config MODULE_SRCVERSION_ALL
bool "Source checksum for all modules"
help
diff --git a/init/do_mounts_initrd.c b/init/do_mounts_initrd.c
index 533d81ed74d4..327962ea354c 100644
--- a/init/do_mounts_initrd.c
+++ b/init/do_mounts_initrd.c
@@ -14,12 +14,32 @@
unsigned long initrd_start, initrd_end;
int initrd_below_start_ok;
-unsigned int real_root_dev; /* do_proc_dointvec cannot handle kdev_t */
+static unsigned int real_root_dev; /* do_proc_dointvec cannot handle kdev_t */
static int __initdata mount_initrd = 1;
phys_addr_t phys_initrd_start __initdata;
unsigned long phys_initrd_size __initdata;
+#ifdef CONFIG_SYSCTL
+static struct ctl_table kern_do_mounts_initrd_table[] = {
+ {
+ .procname = "real-root-dev",
+ .data = &real_root_dev,
+ .maxlen = sizeof(int),
+ .mode = 0644,
+ .proc_handler = proc_dointvec,
+ },
+ { }
+};
+
+static __init int kernel_do_mounts_initrd_sysctls_init(void)
+{
+ register_sysctl_init("kernel", kern_do_mounts_initrd_table);
+ return 0;
+}
+late_initcall(kernel_do_mounts_initrd_sysctls_init);
+#endif /* CONFIG_SYSCTL */
+
static int __init no_initrd(char *str)
{
mount_initrd = 0;
diff --git a/init/initramfs.c b/init/initramfs.c
index 41e7857d510d..18229cfe8906 100644
--- a/init/initramfs.c
+++ b/init/initramfs.c
@@ -18,8 +18,11 @@
#include <linux/task_work.h>
#include <linux/umh.h>
-static ssize_t __init xwrite(struct file *file, const char *p, size_t count,
- loff_t *pos)
+static __initdata bool csum_present;
+static __initdata u32 io_csum;
+
+static ssize_t __init xwrite(struct file *file, const unsigned char *p,
+ size_t count, loff_t *pos)
{
ssize_t out = 0;
@@ -34,6 +37,13 @@ static ssize_t __init xwrite(struct file *file, const char *p, size_t count,
} else if (rv == 0)
break;
+ if (csum_present) {
+ ssize_t i;
+
+ for (i = 0; i < rv; i++)
+ io_csum += p[i];
+ }
+
p += rv;
out += rv;
count -= rv;
@@ -117,31 +127,36 @@ static void __init free_hash(void)
}
}
-static long __init do_utime(char *filename, time64_t mtime)
+#ifdef CONFIG_INITRAMFS_PRESERVE_MTIME
+static void __init do_utime(char *filename, time64_t mtime)
{
- struct timespec64 t[2];
+ struct timespec64 t[2] = { { .tv_sec = mtime }, { .tv_sec = mtime } };
+ init_utimes(filename, t);
+}
- t[0].tv_sec = mtime;
- t[0].tv_nsec = 0;
- t[1].tv_sec = mtime;
- t[1].tv_nsec = 0;
- return init_utimes(filename, t);
+static void __init do_utime_path(const struct path *path, time64_t mtime)
+{
+ struct timespec64 t[2] = { { .tv_sec = mtime }, { .tv_sec = mtime } };
+ vfs_utimes(path, t);
}
static __initdata LIST_HEAD(dir_list);
struct dir_entry {
struct list_head list;
- char *name;
time64_t mtime;
+ char name[];
};
static void __init dir_add(const char *name, time64_t mtime)
{
- struct dir_entry *de = kmalloc(sizeof(struct dir_entry), GFP_KERNEL);
+ size_t nlen = strlen(name) + 1;
+ struct dir_entry *de;
+
+ de = kmalloc(sizeof(struct dir_entry) + nlen, GFP_KERNEL);
if (!de)
panic_show_mem("can't allocate dir_entry buffer");
INIT_LIST_HEAD(&de->list);
- de->name = kstrdup(name, GFP_KERNEL);
+ strscpy(de->name, name, nlen);
de->mtime = mtime;
list_add(&de->list, &dir_list);
}
@@ -152,10 +167,15 @@ static void __init dir_utime(void)
list_for_each_entry_safe(de, tmp, &dir_list, list) {
list_del(&de->list);
do_utime(de->name, de->mtime);
- kfree(de->name);
kfree(de);
}
}
+#else
+static void __init do_utime(char *filename, time64_t mtime) {}
+static void __init do_utime_path(const struct path *path, time64_t mtime) {}
+static void __init dir_add(const char *name, time64_t mtime) {}
+static void __init dir_utime(void) {}
+#endif
static __initdata time64_t mtime;
@@ -167,15 +187,16 @@ static __initdata unsigned long body_len, name_len;
static __initdata uid_t uid;
static __initdata gid_t gid;
static __initdata unsigned rdev;
+static __initdata u32 hdr_csum;
static void __init parse_header(char *s)
{
- unsigned long parsed[12];
+ unsigned long parsed[13];
char buf[9];
int i;
buf[8] = '\0';
- for (i = 0, s += 6; i < 12; i++, s += 8) {
+ for (i = 0, s += 6; i < 13; i++, s += 8) {
memcpy(buf, s, 8);
parsed[i] = simple_strtoul(buf, NULL, 16);
}
@@ -190,6 +211,7 @@ static void __init parse_header(char *s)
minor = parsed[8];
rdev = new_encode_dev(MKDEV(parsed[9], parsed[10]));
name_len = parsed[11];
+ hdr_csum = parsed[12];
}
/* FSM */
@@ -258,12 +280,15 @@ static int __init do_collect(void)
static int __init do_header(void)
{
- if (memcmp(collected, "070707", 6)==0) {
- error("incorrect cpio method used: use -H newc option");
- return 1;
- }
- if (memcmp(collected, "070701", 6)) {
- error("no cpio magic");
+ if (!memcmp(collected, "070701", 6)) {
+ csum_present = false;
+ } else if (!memcmp(collected, "070702", 6)) {
+ csum_present = true;
+ } else {
+ if (memcmp(collected, "070707", 6) == 0)
+ error("incorrect cpio method used: use -H newc option");
+ else
+ error("no cpio magic");
return 1;
}
parse_header(collected);
@@ -354,6 +379,7 @@ static int __init do_name(void)
if (IS_ERR(wfile))
return 0;
wfile_pos = 0;
+ io_csum = 0;
vfs_fchown(wfile, uid, gid);
vfs_fchmod(wfile, mode);
@@ -381,15 +407,13 @@ static int __init do_name(void)
static int __init do_copy(void)
{
if (byte_count >= body_len) {
- struct timespec64 t[2] = { };
if (xwrite(wfile, victim, body_len, &wfile_pos) != body_len)
error("write error");
- t[0].tv_sec = mtime;
- t[1].tv_sec = mtime;
- vfs_utimes(&wfile->f_path, t);
-
+ do_utime_path(&wfile->f_path, mtime);
fput(wfile);
+ if (csum_present && io_csum != hdr_csum)
+ error("bad data checksum");
eat(body_len);
state = SkipIt;
return 0;
diff --git a/init/main.c b/init/main.c
index 39baac0211c6..0ee39cdcfcac 100644
--- a/init/main.c
+++ b/init/main.c
@@ -266,7 +266,7 @@ static int __init loglevel(char *str)
early_param("loglevel", loglevel);
#ifdef CONFIG_BLK_DEV_INITRD
-static void * __init get_boot_config_from_initrd(u32 *_size, u32 *_csum)
+static void * __init get_boot_config_from_initrd(size_t *_size)
{
u32 size, csum;
char *data;
@@ -300,17 +300,20 @@ found:
return NULL;
}
+ if (xbc_calc_checksum(data, size) != csum) {
+ pr_err("bootconfig checksum failed\n");
+ return NULL;
+ }
+
/* Remove bootconfig from initramfs/initrd */
initrd_end = (unsigned long)data;
if (_size)
*_size = size;
- if (_csum)
- *_csum = csum;
return data;
}
#else
-static void * __init get_boot_config_from_initrd(u32 *_size, u32 *_csum)
+static void * __init get_boot_config_from_initrd(size_t *_size)
{
return NULL;
}
@@ -407,14 +410,16 @@ static int __init warn_bootconfig(char *str)
static void __init setup_boot_config(void)
{
static char tmp_cmdline[COMMAND_LINE_SIZE] __initdata;
- const char *msg;
- int pos;
- u32 size, csum;
- char *data, *err;
- int ret;
+ const char *msg, *data;
+ int pos, ret;
+ size_t size;
+ char *err;
/* Cut out the bootconfig data even if we have no bootconfig option */
- data = get_boot_config_from_initrd(&size, &csum);
+ data = get_boot_config_from_initrd(&size);
+ /* If there is no bootconfig in initrd, try embedded one. */
+ if (!data)
+ data = xbc_get_embedded_bootconfig(&size);
strlcpy(tmp_cmdline, boot_command_line, COMMAND_LINE_SIZE);
err = parse_args("bootconfig", tmp_cmdline, NULL, 0, 0, 0, NULL,
@@ -433,13 +438,8 @@ static void __init setup_boot_config(void)
}
if (size >= XBC_DATA_MAX) {
- pr_err("bootconfig size %d greater than max size %d\n",
- size, XBC_DATA_MAX);
- return;
- }
-
- if (xbc_calc_checksum(data, size) != csum) {
- pr_err("bootconfig checksum failed\n");
+ pr_err("bootconfig size %ld greater than max size %d\n",
+ (long)size, XBC_DATA_MAX);
return;
}
@@ -452,7 +452,7 @@ static void __init setup_boot_config(void)
msg, pos);
} else {
xbc_get_info(&ret, NULL);
- pr_info("Load bootconfig: %d bytes %d nodes\n", size, ret);
+ pr_info("Load bootconfig: %ld bytes %d nodes\n", (long)size, ret);
/* keys starting with "kernel." are passed via cmdline */
extra_command_line = xbc_make_cmdline("kernel");
/* Also, "init." keys are init arguments */
@@ -471,7 +471,7 @@ static void __init exit_boot_config(void)
static void __init setup_boot_config(void)
{
/* Remove bootconfig data from initrd */
- get_boot_config_from_initrd(NULL, NULL);
+ get_boot_config_from_initrd(NULL);
}
static int __init warn_bootconfig(char *str)
@@ -1035,21 +1035,18 @@ asmlinkage __visible void __init __no_sanitize_address start_kernel(void)
softirq_init();
timekeeping_init();
kfence_init();
+ time_init();
/*
* For best initial stack canary entropy, prepare it after:
* - setup_arch() for any UEFI RNG entropy and boot cmdline access
- * - timekeeping_init() for ktime entropy used in rand_initialize()
- * - rand_initialize() to get any arch-specific entropy like RDRAND
- * - add_latent_entropy() to get any latent entropy
- * - adding command line entropy
+ * - timekeeping_init() for ktime entropy used in random_init()
+ * - time_init() for making random_get_entropy() work on some platforms
+ * - random_init() to initialize the RNG from from early entropy sources
*/
- rand_initialize();
- add_latent_entropy();
- add_device_randomness(command_line, strlen(command_line));
+ random_init(command_line);
boot_init_stack_canary();
- time_init();
perf_event_init();
profile_init();
call_function_init();