summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/.gitignore2
-rw-r--r--lib/Kconfig.debug48
-rw-r--r--lib/Kconfig.ubsan4
-rw-r--r--lib/Makefile41
-rw-r--r--lib/bcd.c4
-rw-r--r--lib/btree.c1
-rw-r--r--lib/buildid.c397
-rw-r--r--lib/checksum_kunit.c9
-rw-r--r--lib/closure.c2
-rw-r--r--lib/codetag.c17
-rw-r--r--lib/crypto/mpi/Makefile2
-rw-r--r--lib/crypto/mpi/ec.c1507
-rw-r--r--lib/crypto/mpi/mpi-add.c89
-rw-r--r--lib/crypto/mpi/mpi-bit.c168
-rw-r--r--lib/crypto/mpi/mpi-cmp.c46
-rw-r--r--lib/crypto/mpi/mpi-div.c82
-rw-r--r--lib/crypto/mpi/mpi-internal.h21
-rw-r--r--lib/crypto/mpi/mpi-inv.c143
-rw-r--r--lib/crypto/mpi/mpi-mod.c148
-rw-r--r--lib/crypto/mpi/mpi-mul.c29
-rw-r--r--lib/crypto/mpi/mpicoder.c336
-rw-r--r--lib/crypto/mpi/mpih-mul.c25
-rw-r--r--lib/crypto/mpi/mpiutil.c184
-rw-r--r--lib/debugobjects.c27
-rw-r--r--lib/decompress_unlzma.c2
-rw-r--r--lib/decompress_unxz.c40
-rw-r--r--lib/dim/Makefile2
-rw-r--r--lib/dump_stack.c1
-rw-r--r--lib/dynamic_debug.c4
-rw-r--r--lib/fault-inject.c1
-rw-r--r--lib/fortify_kunit.c3
-rw-r--r--lib/generic-radix-tree.c82
-rw-r--r--lib/glob.c2
-rw-r--r--lib/iov_iter.c240
-rw-r--r--lib/irq_poll.c2
-rw-r--r--lib/kunit/device.c7
-rw-r--r--lib/kunit/test.c19
-rw-r--r--lib/kunit_iov_iter.c259
-rw-r--r--lib/list-test.c10
-rw-r--r--lib/lru_cache.c10
-rw-r--r--lib/lz4/lz4hc_compress.c1
-rw-r--r--lib/maple_tree.c812
-rw-r--r--lib/math/Makefile2
-rw-r--r--lib/math/div64.c115
-rw-r--r--lib/math/test_mul_u64_u64_div_u64.c99
-rw-r--r--lib/math/tests/Makefile3
-rw-r--r--lib/math/tests/int_pow_kunit.c52
-rw-r--r--lib/overflow_kunit.c3
-rw-r--r--lib/percpu_counter.c2
-rw-r--r--lib/rhashtable.c2
-rw-r--r--lib/scatterlist.c69
-rw-r--r--lib/slub_kunit.c31
-rw-r--r--lib/string_helpers.c3
-rw-r--r--lib/strncpy_from_user.c9
-rw-r--r--lib/strnlen_user.c9
-rw-r--r--lib/test_bpf.c3
-rw-r--r--lib/test_fortify/.gitignore2
-rw-r--r--lib/test_fortify/Makefile28
-rw-r--r--lib/test_fortify/test_fortify.sh66
-rw-r--r--lib/test_fpu_glue.c2
-rw-r--r--lib/test_hmm.c5
-rw-r--r--lib/test_objpool.c3
-rw-r--r--lib/test_printf.c26
-rw-r--r--lib/union_find.c49
-rw-r--r--lib/vdso/Makefile1
-rw-r--r--lib/vdso/getrandom.c31
-rw-r--r--lib/vsprintf.c23
-rw-r--r--lib/xz/Kconfig13
-rw-r--r--lib/xz/xz_crc32.c11
-rw-r--r--lib/xz/xz_dec_bcj.c191
-rw-r--r--lib/xz/xz_dec_lzma2.c15
-rw-r--r--lib/xz/xz_dec_stream.c13
-rw-r--r--lib/xz/xz_dec_syms.c14
-rw-r--r--lib/xz/xz_dec_test.c12
-rw-r--r--lib/xz/xz_lzma2.h5
-rw-r--r--lib/xz/xz_private.h40
-rw-r--r--lib/xz/xz_stream.h5
-rw-r--r--lib/zstd/compress/zstd_compress.c2
-rw-r--r--lib/zstd/zstd_compress_module.c49
-rw-r--r--lib/zstd/zstd_decompress_module.c36
80 files changed, 2350 insertions, 3523 deletions
diff --git a/lib/.gitignore b/lib/.gitignore
index 54596b634ecb..101a4aa92fb5 100644
--- a/lib/.gitignore
+++ b/lib/.gitignore
@@ -5,5 +5,3 @@
/gen_crc32table
/gen_crc64table
/oid_registry_data.c
-/test_fortify.log
-/test_fortify/*.log
diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
index a30c03a66172..bc8faa4509e1 100644
--- a/lib/Kconfig.debug
+++ b/lib/Kconfig.debug
@@ -97,7 +97,7 @@ config BOOT_PRINTK_DELAY
using "boot_delay=N".
It is likely that you would also need to use "lpj=M" to preset
- the "loops per jiffie" value.
+ the "loops per jiffy" value.
See a previous boot log for the "lpj" value to use for your
system, and then set "lpj=M" before setting "boot_delay=N".
NOTE: Using this option may adversely affect SMP systems.
@@ -379,13 +379,15 @@ config DEBUG_INFO_BTF
depends on !DEBUG_INFO_SPLIT && !DEBUG_INFO_REDUCED
depends on !GCC_PLUGIN_RANDSTRUCT || COMPILE_TEST
depends on BPF_SYSCALL
- depends on !DEBUG_INFO_DWARF5 || PAHOLE_VERSION >= 121
+ depends on PAHOLE_VERSION >= 116
+ depends on DEBUG_INFO_DWARF4 || PAHOLE_VERSION >= 121
# pahole uses elfutils, which does not have support for Hexagon relocations
depends on !HEXAGON
help
Generate deduplicated BTF type information from DWARF debug info.
- Turning this on expects presence of pahole tool, which will convert
- DWARF type info into equivalent deduplicated BTF type info.
+ Turning this on requires pahole v1.16 or later (v1.21 or later to
+ support DWARF 5), which will convert DWARF type info into equivalent
+ deduplicated BTF type info.
config PAHOLE_HAS_SPLIT_BTF
def_bool PAHOLE_VERSION >= 119
@@ -1515,7 +1517,7 @@ config LOCKDEP_BITS
config LOCKDEP_CHAINS_BITS
int "Bitsize for MAX_LOCKDEP_CHAINS"
depends on LOCKDEP && !LOCKDEP_SMALL
- range 10 30
+ range 10 21
default 16
help
Try increasing this value if you hit "BUG: MAX_LOCKDEP_CHAINS too low!" message.
@@ -1614,6 +1616,7 @@ config SCF_TORTURE_TEST
config CSD_LOCK_WAIT_DEBUG
bool "Debugging for csd_lock_wait(), called from smp_call_function*()"
depends on DEBUG_KERNEL
+ depends on SMP
depends on 64BIT
default n
help
@@ -2173,6 +2176,14 @@ config KCOV_IRQ_AREA_SIZE
soft interrupts. This specifies the size of those areas in the
number of unsigned long words.
+config KCOV_SELFTEST
+ bool "Perform short selftests on boot"
+ depends on KCOV
+ help
+ Run short KCOV coverage collection selftests on boot.
+ On test failure, causes the kernel to panic. Recommended to be
+ enabled, ensuring critical functionality works as intended.
+
menuconfig RUNTIME_TESTING_MENU
bool "Runtime Testing"
default y
@@ -2280,6 +2291,16 @@ config TEST_DIV64
If unsure, say N.
+config TEST_MULDIV64
+ tristate "mul_u64_u64_div_u64() test"
+ depends on DEBUG_KERNEL || m
+ help
+ Enable this to turn on 'mul_u64_u64_div_u64()' function test.
+ This test is executed only once during system boot (so affects
+ only boot time), or at module load time.
+
+ If unsure, say N.
+
config TEST_IOV_ITER
tristate "Test iov_iter operation" if !KUNIT_ALL_TESTS
depends on KUNIT
@@ -2616,6 +2637,7 @@ config RESOURCE_KUNIT_TEST
tristate "KUnit test for resource API" if !KUNIT_ALL_TESTS
depends on KUNIT
default KUNIT_ALL_TESTS
+ select GET_FREE_REGION
help
This builds the resource API unit test.
Tests the logic of API provided by resource.c and ioport.h.
@@ -3051,3 +3073,19 @@ config RUST_KERNEL_DOCTESTS
endmenu # "Rust"
endmenu # Kernel hacking
+
+config INT_POW_TEST
+ tristate "Integer exponentiation (int_pow) test" if !KUNIT_ALL_TESTS
+ depends on KUNIT
+ default KUNIT_ALL_TESTS
+ help
+ This option enables the KUnit test suite for the int_pow function,
+ which performs integer exponentiation. The test suite is designed to
+ verify that the implementation of int_pow correctly computes the power
+ of a given base raised to a given exponent.
+
+ Enabling this option will include tests that check various scenarios
+ and edge cases to ensure the accuracy and reliability of the exponentiation
+ function.
+
+ If unsure, say N
diff --git a/lib/Kconfig.ubsan b/lib/Kconfig.ubsan
index bdda600f8dfb..1d4aa7a83b3a 100644
--- a/lib/Kconfig.ubsan
+++ b/lib/Kconfig.ubsan
@@ -29,8 +29,8 @@ config UBSAN_TRAP
Also note that selecting Y will cause your kernel to Oops
with an "illegal instruction" error with no further details
- when a UBSAN violation occurs. (Except on arm64, which will
- report which Sanitizer failed.) This may make it hard to
+ when a UBSAN violation occurs. (Except on arm64 and x86, which
+ will report which Sanitizer failed.) This may make it hard to
determine whether an Oops was caused by UBSAN or to figure
out the details of a UBSAN violation. It makes the kernel log
output less useful for bug reports.
diff --git a/lib/Makefile b/lib/Makefile
index 322bb127b4dc..773adf88af41 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -14,6 +14,7 @@ KCOV_INSTRUMENT_list_debug.o := n
KCOV_INSTRUMENT_debugobjects.o := n
KCOV_INSTRUMENT_dynamic_debug.o := n
KCOV_INSTRUMENT_fault-inject.o := n
+KCOV_INSTRUMENT_find_bit.o := n
# string.o implements standard library functions like memset/memcpy etc.
# Use -ffreestanding to ensure that the compiler does not try to "optimize"
@@ -34,7 +35,7 @@ lib-y := ctype.o string.o vsprintf.o cmdline.o \
is_single_threaded.o plist.o decompress.o kobject_uevent.o \
earlycpio.o seq_buf.o siphash.o dec_and_lock.o \
nmi_backtrace.o win_minmax.o memcat_p.o \
- buildid.o objpool.o
+ buildid.o objpool.o union_find.o
lib-$(CONFIG_PRINTK) += dump_stack.o
lib-$(CONFIG_SMP) += cpumask.o
@@ -393,40 +394,4 @@ obj-$(CONFIG_GENERIC_LIB_DEVMEM_IS_ALLOWED) += devmem_is_allowed.o
obj-$(CONFIG_FIRMWARE_TABLE) += fw_table.o
-# FORTIFY_SOURCE compile-time behavior tests
-TEST_FORTIFY_SRCS = $(wildcard $(src)/test_fortify/*-*.c)
-TEST_FORTIFY_LOGS = $(patsubst $(src)/%.c, %.log, $(TEST_FORTIFY_SRCS))
-TEST_FORTIFY_LOG = test_fortify.log
-
-quiet_cmd_test_fortify = TEST $@
- cmd_test_fortify = $(CONFIG_SHELL) $(srctree)/scripts/test_fortify.sh \
- $< $@ "$(NM)" $(CC) $(c_flags) \
- $(call cc-disable-warning,fortify-source) \
- -DKBUILD_EXTRA_WARN1
-
-targets += $(TEST_FORTIFY_LOGS)
-clean-files += $(TEST_FORTIFY_LOGS)
-clean-files += $(addsuffix .o, $(TEST_FORTIFY_LOGS))
-$(obj)/test_fortify/%.log: $(src)/test_fortify/%.c \
- $(src)/test_fortify/test_fortify.h \
- $(srctree)/include/linux/fortify-string.h \
- $(srctree)/scripts/test_fortify.sh \
- FORCE
- $(call if_changed,test_fortify)
-
-quiet_cmd_gen_fortify_log = GEN $@
- cmd_gen_fortify_log = cat </dev/null $(filter-out FORCE,$^) 2>/dev/null > $@ || true
-
-targets += $(TEST_FORTIFY_LOG)
-clean-files += $(TEST_FORTIFY_LOG)
-$(obj)/$(TEST_FORTIFY_LOG): $(addprefix $(obj)/, $(TEST_FORTIFY_LOGS)) FORCE
- $(call if_changed,gen_fortify_log)
-
-# Fake dependency to trigger the fortify tests.
-ifeq ($(CONFIG_FORTIFY_SOURCE),y)
-$(obj)/string.o: $(obj)/$(TEST_FORTIFY_LOG)
-endif
-
-# Some architectures define __NO_FORTIFY if __SANITIZE_ADDRESS__ is undefined.
-# Pass CFLAGS_KASAN to avoid warnings.
-$(foreach x, $(patsubst %.log,%.o,$(TEST_FORTIFY_LOGS)), $(eval KASAN_SANITIZE_$(x) := y))
+subdir-$(CONFIG_FORTIFY_SOURCE) += test_fortify
diff --git a/lib/bcd.c b/lib/bcd.c
index 7e4750b6e801..c5e79ba9cd7b 100644
--- a/lib/bcd.c
+++ b/lib/bcd.c
@@ -10,6 +10,8 @@ EXPORT_SYMBOL(_bcd2bin);
unsigned char _bin2bcd(unsigned val)
{
- return ((val / 10) << 4) + val % 10;
+ const unsigned int t = (val * 103) >> 10;
+
+ return (t << 4) | (val - t * 10);
}
EXPORT_SYMBOL(_bin2bcd);
diff --git a/lib/btree.c b/lib/btree.c
index 49420cae3a83..bb81d3393ac5 100644
--- a/lib/btree.c
+++ b/lib/btree.c
@@ -43,7 +43,6 @@
#include <linux/slab.h>
#include <linux/module.h>
-#define MAX(a, b) ((a) > (b) ? (a) : (b))
#define NODESIZE MAX(L1_CACHE_BYTES, 128)
struct btree_geo {
diff --git a/lib/buildid.c b/lib/buildid.c
index e02b5507418b..290641d92ac1 100644
--- a/lib/buildid.c
+++ b/lib/buildid.c
@@ -8,154 +8,302 @@
#define BUILD_ID 3
+#define MAX_PHDR_CNT 256
+
+struct freader {
+ void *buf;
+ u32 buf_sz;
+ int err;
+ union {
+ struct {
+ struct file *file;
+ struct folio *folio;
+ void *addr;
+ loff_t folio_off;
+ bool may_fault;
+ };
+ struct {
+ const char *data;
+ u64 data_sz;
+ };
+ };
+};
+
+static void freader_init_from_file(struct freader *r, void *buf, u32 buf_sz,
+ struct file *file, bool may_fault)
+{
+ memset(r, 0, sizeof(*r));
+ r->buf = buf;
+ r->buf_sz = buf_sz;
+ r->file = file;
+ r->may_fault = may_fault;
+}
+
+static void freader_init_from_mem(struct freader *r, const char *data, u64 data_sz)
+{
+ memset(r, 0, sizeof(*r));
+ r->data = data;
+ r->data_sz = data_sz;
+}
+
+static void freader_put_folio(struct freader *r)
+{
+ if (!r->folio)
+ return;
+ kunmap_local(r->addr);
+ folio_put(r->folio);
+ r->folio = NULL;
+}
+
+static int freader_get_folio(struct freader *r, loff_t file_off)
+{
+ /* check if we can just reuse current folio */
+ if (r->folio && file_off >= r->folio_off &&
+ file_off < r->folio_off + folio_size(r->folio))
+ return 0;
+
+ freader_put_folio(r);
+
+ r->folio = filemap_get_folio(r->file->f_mapping, file_off >> PAGE_SHIFT);
+
+ /* if sleeping is allowed, wait for the page, if necessary */
+ if (r->may_fault && (IS_ERR(r->folio) || !folio_test_uptodate(r->folio))) {
+ filemap_invalidate_lock_shared(r->file->f_mapping);
+ r->folio = read_cache_folio(r->file->f_mapping, file_off >> PAGE_SHIFT,
+ NULL, r->file);
+ filemap_invalidate_unlock_shared(r->file->f_mapping);
+ }
+
+ if (IS_ERR(r->folio) || !folio_test_uptodate(r->folio)) {
+ if (!IS_ERR(r->folio))
+ folio_put(r->folio);
+ r->folio = NULL;
+ return -EFAULT;
+ }
+
+ r->folio_off = folio_pos(r->folio);
+ r->addr = kmap_local_folio(r->folio, 0);
+
+ return 0;
+}
+
+static const void *freader_fetch(struct freader *r, loff_t file_off, size_t sz)
+{
+ size_t folio_sz;
+
+ /* provided internal temporary buffer should be sized correctly */
+ if (WARN_ON(r->buf && sz > r->buf_sz)) {
+ r->err = -E2BIG;
+ return NULL;
+ }
+
+ if (unlikely(file_off + sz < file_off)) {
+ r->err = -EOVERFLOW;
+ return NULL;
+ }
+
+ /* working with memory buffer is much more straightforward */
+ if (!r->buf) {
+ if (file_off + sz > r->data_sz) {
+ r->err = -ERANGE;
+ return NULL;
+ }
+ return r->data + file_off;
+ }
+
+ /* fetch or reuse folio for given file offset */
+ r->err = freader_get_folio(r, file_off);
+ if (r->err)
+ return NULL;
+
+ /* if requested data is crossing folio boundaries, we have to copy
+ * everything into our local buffer to keep a simple linear memory
+ * access interface
+ */
+ folio_sz = folio_size(r->folio);
+ if (file_off + sz > r->folio_off + folio_sz) {
+ int part_sz = r->folio_off + folio_sz - file_off;
+
+ /* copy the part that resides in the current folio */
+ memcpy(r->buf, r->addr + (file_off - r->folio_off), part_sz);
+
+ /* fetch next folio */
+ r->err = freader_get_folio(r, r->folio_off + folio_sz);
+ if (r->err)
+ return NULL;
+
+ /* copy the rest of requested data */
+ memcpy(r->buf + part_sz, r->addr, sz - part_sz);
+
+ return r->buf;
+ }
+
+ /* if data fits in a single folio, just return direct pointer */
+ return r->addr + (file_off - r->folio_off);
+}
+
+static void freader_cleanup(struct freader *r)
+{
+ if (!r->buf)
+ return; /* non-file-backed mode */
+
+ freader_put_folio(r);
+}
+
/*
* Parse build id from the note segment. This logic can be shared between
* 32-bit and 64-bit system, because Elf32_Nhdr and Elf64_Nhdr are
* identical.
*/
-static int parse_build_id_buf(unsigned char *build_id,
- __u32 *size,
- const void *note_start,
- Elf32_Word note_size)
+static int parse_build_id(struct freader *r, unsigned char *build_id, __u32 *size,
+ loff_t note_off, Elf32_Word note_size)
{
- Elf32_Word note_offs = 0, new_offs;
+ const char note_name[] = "GNU";
+ const size_t note_name_sz = sizeof(note_name);
+ u32 build_id_off, new_off, note_end, name_sz, desc_sz;
+ const Elf32_Nhdr *nhdr;
+ const char *data;
+
+ if (check_add_overflow(note_off, note_size, &note_end))
+ return -EINVAL;
- while (note_offs + sizeof(Elf32_Nhdr) < note_size) {
- Elf32_Nhdr *nhdr = (Elf32_Nhdr *)(note_start + note_offs);
+ while (note_end - note_off > sizeof(Elf32_Nhdr) + note_name_sz) {
+ nhdr = freader_fetch(r, note_off, sizeof(Elf32_Nhdr) + note_name_sz);
+ if (!nhdr)
+ return r->err;
+
+ name_sz = READ_ONCE(nhdr->n_namesz);
+ desc_sz = READ_ONCE(nhdr->n_descsz);
+
+ new_off = note_off + sizeof(Elf32_Nhdr);
+ if (check_add_overflow(new_off, ALIGN(name_sz, 4), &new_off) ||
+ check_add_overflow(new_off, ALIGN(desc_sz, 4), &new_off) ||
+ new_off > note_end)
+ break;
if (nhdr->n_type == BUILD_ID &&
- nhdr->n_namesz == sizeof("GNU") &&