diff options
| -rw-r--r-- | include/linux/printk.h | 5 | ||||
| -rw-r--r-- | kernel/printk/printk_ringbuffer.c | 27 | ||||
| -rw-r--r-- | kernel/printk/printk_ringbuffer.h | 4 | ||||
| -rw-r--r-- | lib/tests/Makefile | 2 | ||||
| -rw-r--r-- | lib/tests/printf_kunit.c | 22 | ||||
| -rw-r--r-- | lib/vsprintf.c | 4 |
6 files changed, 46 insertions, 18 deletions
diff --git a/include/linux/printk.h b/include/linux/printk.h index 54e3c621fec3..f594c1266bfd 100644 --- a/include/linux/printk.h +++ b/include/linux/printk.h @@ -815,7 +815,8 @@ static inline void print_hex_dump_devel(const char *prefix_str, int prefix_type, #endif /** - * print_hex_dump_bytes - shorthand form of print_hex_dump() with default params + * print_hex_dump_bytes - shorthand form of print_hex_dump_debug() with default + * params * @prefix_str: string to prefix each line with; * caller supplies trailing spaces for alignment if desired * @prefix_type: controls whether prefix of an offset, address, or none @@ -823,7 +824,7 @@ static inline void print_hex_dump_devel(const char *prefix_str, int prefix_type, * @buf: data blob to dump * @len: number of bytes in the @buf * - * Calls print_hex_dump(), with log level of KERN_DEBUG, + * Calls print_hex_dump_debug(), with log level of KERN_DEBUG, * rowsize of 16, groupsize of 1, and ASCII output included. */ #define print_hex_dump_bytes(prefix_str, prefix_type, buf, len) \ diff --git a/kernel/printk/printk_ringbuffer.c b/kernel/printk/printk_ringbuffer.c index 56c8e3d031f4..85c0c854b3ce 100644 --- a/kernel/printk/printk_ringbuffer.c +++ b/kernel/printk/printk_ringbuffer.c @@ -14,7 +14,7 @@ * * Data Structure * -------------- - * The printk_ringbuffer is made up of 3 internal ringbuffers: + * The printk_ringbuffer is made up of 2 internal ringbuffers: * * desc_ring * A ring of descriptors and their meta data (such as sequence number, @@ -224,7 +224,7 @@ * * prb_rec_init_rd(&r, &info, &text_buf[0], sizeof(text_buf)); * - * prb_for_each_record(0, &test_rb, &seq, &r) { + * prb_for_each_record(0, &test_rb, seq, &r) { * if (info.seq != seq) * pr_warn("lost %llu records\n", info.seq - seq); * @@ -1302,23 +1302,26 @@ static const char *get_data(struct prb_data_ring *data_ring, return NULL; } - /* Sanity check. Data-less blocks were handled earlier. */ - if (WARN_ON_ONCE(!data_check_size(data_ring, *data_size) || !*data_size)) - return NULL; - /* A valid data block will always be aligned to the ID size. */ if (WARN_ON_ONCE(blk_lpos->begin != ALIGN(blk_lpos->begin, sizeof(db->id))) || WARN_ON_ONCE(blk_lpos->next != ALIGN(blk_lpos->next, sizeof(db->id)))) { return NULL; } - /* A valid data block will always have at least an ID. */ - if (WARN_ON_ONCE(*data_size < sizeof(db->id))) + /* + * A regular data block will always have an ID and at least + * 1 byte of data. Data-less blocks were handled earlier. + */ + if (WARN_ON_ONCE(*data_size <= sizeof(db->id))) return NULL; /* Subtract block ID space from size to reflect data size. */ *data_size -= sizeof(db->id); + /* Sanity check the max size of the regular data block. */ + if (WARN_ON_ONCE(!data_check_size(data_ring, *data_size))) + return NULL; + return &db->data[0]; } @@ -1365,7 +1368,7 @@ static struct prb_desc *desc_reopen_last(struct prb_desc_ring *desc_ring, * * WMB from _prb_commit:A to _prb_commit:B * matching - * MB If desc_reopen_last:A to prb_reserve_in_last:A + * MB from desc_reopen_last:A to prb_reserve_in_last:A */ if (!atomic_long_try_cmpxchg(&d->state_var, &prev_state_val, DESC_SV(id, desc_reserved))) { /* LMM(desc_reopen_last:A) */ @@ -1770,9 +1773,9 @@ static void _prb_commit(struct prb_reserved_entry *e, unsigned long state_val) * * Relies on: * - * MB _prb_commit:B to prb_commit:A + * MB from _prb_commit:B to prb_commit:A * matching - * MB desc_reserve:D to desc_make_final:A + * MB from desc_reserve:D to desc_make_final:A */ if (!atomic_long_try_cmpxchg(&d->state_var, &prev_state_val, DESC_SV(e->id, state_val))) { /* LMM(_prb_commit:B) */ @@ -2035,7 +2038,7 @@ u64 prb_first_seq(struct printk_ringbuffer *rb) * * MB from desc_push_tail:B to desc_reserve:F * matching - * RMB prb_first_seq:B to prb_first_seq:A + * RMB from prb_first_seq:B to prb_first_seq:A */ smp_rmb(); /* LMM(prb_first_seq:C) */ } diff --git a/kernel/printk/printk_ringbuffer.h b/kernel/printk/printk_ringbuffer.h index 1651b53ece34..2648da0a68b2 100644 --- a/kernel/printk/printk_ringbuffer.h +++ b/kernel/printk/printk_ringbuffer.h @@ -127,7 +127,7 @@ enum desc_state { }; #define _DATA_SIZE(sz_bits) (1UL << (sz_bits)) -#define _DESCS_COUNT(ct_bits) (1U << (ct_bits)) +#define _DESCS_COUNT(ct_bits) (1UL << (ct_bits)) #define DESC_SV_BITS BITS_PER_LONG #define DESC_FLAGS_SHIFT (DESC_SV_BITS - 2) #define DESC_FLAGS_MASK (3UL << DESC_FLAGS_SHIFT) @@ -388,7 +388,7 @@ for ((s) = from; prb_read_valid(rb, s, r); (s) = (r)->info->seq + 1) * * This is a macro for conveniently iterating over a ringbuffer. * Note that @s may not be the sequence number of the record on each - * iteration. For the sequence number, @r->info->seq should be checked. + * iteration. For the sequence number, @i->seq should be checked. * * Context: Any context. */ diff --git a/lib/tests/Makefile b/lib/tests/Makefile index 05f74edbc62b..7e9c2fa52e35 100644 --- a/lib/tests/Makefile +++ b/lib/tests/Makefile @@ -40,6 +40,8 @@ obj-$(CONFIG_MEMCPY_KUNIT_TEST) += memcpy_kunit.o obj-$(CONFIG_MIN_HEAP_KUNIT_TEST) += min_heap_kunit.o CFLAGS_overflow_kunit.o = $(call cc-disable-warning, tautological-constant-out-of-range-compare) obj-$(CONFIG_OVERFLOW_KUNIT_TEST) += overflow_kunit.o +# GCC < 12.1 can miscompile errptr() test when branch profiling is enabled. +CFLAGS_printf_kunit.o += -DDISABLE_BRANCH_PROFILING obj-$(CONFIG_PRINTF_KUNIT_TEST) += printf_kunit.o obj-$(CONFIG_RANDSTRUCT_KUNIT_TEST) += randstruct_kunit.o obj-$(CONFIG_SCANF_KUNIT_TEST) += scanf_kunit.o diff --git a/lib/tests/printf_kunit.c b/lib/tests/printf_kunit.c index f6f21b445ece..bb70b9cddadd 100644 --- a/lib/tests/printf_kunit.c +++ b/lib/tests/printf_kunit.c @@ -17,6 +17,7 @@ #include <linux/dcache.h> #include <linux/socket.h> #include <linux/in.h> +#include <linux/in6.h> #include <linux/gfp.h> #include <linux/mm.h> @@ -437,6 +438,27 @@ ip4(struct kunit *kunittest) static void ip6(struct kunit *kunittest) { + const struct in6_addr addr = { + .s6_addr = { 0x00, 0x01, 0x00, 0x02, 0x00, 0x03, 0x00, 0x04, + 0x00, 0x05, 0x00, 0x06, 0x00, 0x07, 0x00, 0x08 } + }; + const struct in6_addr single_zero = { + .s6_addr = { 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x04, + 0x00, 0x05, 0x00, 0x06, 0x00, 0x07, 0x00, 0x08 } + }; + struct sockaddr_in6 sa = { + .sin6_family = AF_INET6, + .sin6_port = cpu_to_be16(12345), + .sin6_addr = addr, + }; + + test("00010002000300040005000600070008|0001:0002:0003:0004:0005:0006:0007:0008", + "%pi6|%pI6", &addr, &addr); + test("00010002000300040005000600070008|0001:0002:0003:0004:0005:0006:0007:0008", + "%piS|%pIS", &sa, &sa); + test("1:2:3:4:5:6:7:8", "%pI6c", &addr); + test("1:0:3:4:5:6:7:8", "%pI6c", &single_zero); + test("[1:2:3:4:5:6:7:8]:12345", "%pISpc", &sa); } static void diff --git a/lib/vsprintf.c b/lib/vsprintf.c index 800b8ac49f53..9f359b31c8d1 100644 --- a/lib/vsprintf.c +++ b/lib/vsprintf.c @@ -1107,7 +1107,7 @@ char *resource_string(char *buf, char *end, struct resource *res, 2*RSRC_BUF_SIZE + FLAG_BUF_SIZE + RAW_BUF_SIZE)]; char *p = sym, *pend = sym + sizeof(sym); - int decode = (fmt[0] == 'R') ? 1 : 0; + bool decode = fmt[0] == 'R'; const struct printf_spec *specp; if (check_pointer(&buf, end, res, spec)) @@ -1132,7 +1132,7 @@ char *resource_string(char *buf, char *end, struct resource *res, } else { p = string_nocheck(p, pend, "??? ", str_spec); specp = &mem_spec; - decode = 0; + decode = false; } if (decode && res->flags & IORESOURCE_UNSET) { p = string_nocheck(p, pend, "size ", str_spec); |
