Skip to content

Commit b66cb4f

Browse files
committed
Merge tag 'printk-for-7.1' of git://git.kernel.org/pub/scm/linux/kernel/git/printk/linux
Pull printk updates from Petr Mladek: - Fix printk ring buffer initialization and sanity checks - Workaround printf kunit test compilation with gcc < 12.1 - Add IPv6 address printf format tests - Misc code and documentation cleanup * tag 'printk-for-7.1' of git://git.kernel.org/pub/scm/linux/kernel/git/printk/linux: printf: Compile the kunit test with DISABLE_BRANCH_PROFILING DISABLE_BRANCH_PROFILING lib/vsprintf: use bool for local decode variable lib/hexdump: print_hex_dump_bytes() calls print_hex_dump_debug() printk: ringbuffer: fix errors in comments printk_ringbuffer: Add sanity check for 0-size data printk_ringbuffer: Fix get_data() size sanity check printf: add IPv6 address format tests printk: Fix _DESCS_COUNT type for 64-bit systems
2 parents ccbc9fd + add9d91 commit b66cb4f

6 files changed

Lines changed: 46 additions & 18 deletions

File tree

include/linux/printk.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -815,15 +815,16 @@ static inline void print_hex_dump_devel(const char *prefix_str, int prefix_type,
815815
#endif
816816

817817
/**
818-
* print_hex_dump_bytes - shorthand form of print_hex_dump() with default params
818+
* print_hex_dump_bytes - shorthand form of print_hex_dump_debug() with default
819+
* params
819820
* @prefix_str: string to prefix each line with;
820821
* caller supplies trailing spaces for alignment if desired
821822
* @prefix_type: controls whether prefix of an offset, address, or none
822823
* is printed (%DUMP_PREFIX_OFFSET, %DUMP_PREFIX_ADDRESS, %DUMP_PREFIX_NONE)
823824
* @buf: data blob to dump
824825
* @len: number of bytes in the @buf
825826
*
826-
* Calls print_hex_dump(), with log level of KERN_DEBUG,
827+
* Calls print_hex_dump_debug(), with log level of KERN_DEBUG,
827828
* rowsize of 16, groupsize of 1, and ASCII output included.
828829
*/
829830
#define print_hex_dump_bytes(prefix_str, prefix_type, buf, len) \

kernel/printk/printk_ringbuffer.c

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
*
1515
* Data Structure
1616
* --------------
17-
* The printk_ringbuffer is made up of 3 internal ringbuffers:
17+
* The printk_ringbuffer is made up of 2 internal ringbuffers:
1818
*
1919
* desc_ring
2020
* A ring of descriptors and their meta data (such as sequence number,
@@ -224,7 +224,7 @@
224224
*
225225
* prb_rec_init_rd(&r, &info, &text_buf[0], sizeof(text_buf));
226226
*
227-
* prb_for_each_record(0, &test_rb, &seq, &r) {
227+
* prb_for_each_record(0, &test_rb, seq, &r) {
228228
* if (info.seq != seq)
229229
* pr_warn("lost %llu records\n", info.seq - seq);
230230
*
@@ -1302,23 +1302,26 @@ static const char *get_data(struct prb_data_ring *data_ring,
13021302
return NULL;
13031303
}
13041304

1305-
/* Sanity check. Data-less blocks were handled earlier. */
1306-
if (WARN_ON_ONCE(!data_check_size(data_ring, *data_size) || !*data_size))
1307-
return NULL;
1308-
13091305
/* A valid data block will always be aligned to the ID size. */
13101306
if (WARN_ON_ONCE(blk_lpos->begin != ALIGN(blk_lpos->begin, sizeof(db->id))) ||
13111307
WARN_ON_ONCE(blk_lpos->next != ALIGN(blk_lpos->next, sizeof(db->id)))) {
13121308
return NULL;
13131309
}
13141310

1315-
/* A valid data block will always have at least an ID. */
1316-
if (WARN_ON_ONCE(*data_size < sizeof(db->id)))
1311+
/*
1312+
* A regular data block will always have an ID and at least
1313+
* 1 byte of data. Data-less blocks were handled earlier.
1314+
*/
1315+
if (WARN_ON_ONCE(*data_size <= sizeof(db->id)))
13171316
return NULL;
13181317

13191318
/* Subtract block ID space from size to reflect data size. */
13201319
*data_size -= sizeof(db->id);
13211320

1321+
/* Sanity check the max size of the regular data block. */
1322+
if (WARN_ON_ONCE(!data_check_size(data_ring, *data_size)))
1323+
return NULL;
1324+
13221325
return &db->data[0];
13231326
}
13241327

@@ -1365,7 +1368,7 @@ static struct prb_desc *desc_reopen_last(struct prb_desc_ring *desc_ring,
13651368
*
13661369
* WMB from _prb_commit:A to _prb_commit:B
13671370
* matching
1368-
* MB If desc_reopen_last:A to prb_reserve_in_last:A
1371+
* MB from desc_reopen_last:A to prb_reserve_in_last:A
13691372
*/
13701373
if (!atomic_long_try_cmpxchg(&d->state_var, &prev_state_val,
13711374
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)
17701773
*
17711774
* Relies on:
17721775
*
1773-
* MB _prb_commit:B to prb_commit:A
1776+
* MB from _prb_commit:B to prb_commit:A
17741777
* matching
1775-
* MB desc_reserve:D to desc_make_final:A
1778+
* MB from desc_reserve:D to desc_make_final:A
17761779
*/
17771780
if (!atomic_long_try_cmpxchg(&d->state_var, &prev_state_val,
17781781
DESC_SV(e->id, state_val))) { /* LMM(_prb_commit:B) */
@@ -2035,7 +2038,7 @@ u64 prb_first_seq(struct printk_ringbuffer *rb)
20352038
*
20362039
* MB from desc_push_tail:B to desc_reserve:F
20372040
* matching
2038-
* RMB prb_first_seq:B to prb_first_seq:A
2041+
* RMB from prb_first_seq:B to prb_first_seq:A
20392042
*/
20402043
smp_rmb(); /* LMM(prb_first_seq:C) */
20412044
}

kernel/printk/printk_ringbuffer.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,7 @@ enum desc_state {
127127
};
128128

129129
#define _DATA_SIZE(sz_bits) (1UL << (sz_bits))
130-
#define _DESCS_COUNT(ct_bits) (1U << (ct_bits))
130+
#define _DESCS_COUNT(ct_bits) (1UL << (ct_bits))
131131
#define DESC_SV_BITS BITS_PER_LONG
132132
#define DESC_FLAGS_SHIFT (DESC_SV_BITS - 2)
133133
#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)
388388
*
389389
* This is a macro for conveniently iterating over a ringbuffer.
390390
* Note that @s may not be the sequence number of the record on each
391-
* iteration. For the sequence number, @r->info->seq should be checked.
391+
* iteration. For the sequence number, @i->seq should be checked.
392392
*
393393
* Context: Any context.
394394
*/

lib/tests/Makefile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@ obj-$(CONFIG_MEMCPY_KUNIT_TEST) += memcpy_kunit.o
4040
obj-$(CONFIG_MIN_HEAP_KUNIT_TEST) += min_heap_kunit.o
4141
CFLAGS_overflow_kunit.o = $(call cc-disable-warning, tautological-constant-out-of-range-compare)
4242
obj-$(CONFIG_OVERFLOW_KUNIT_TEST) += overflow_kunit.o
43+
# GCC < 12.1 can miscompile errptr() test when branch profiling is enabled.
44+
CFLAGS_printf_kunit.o += -DDISABLE_BRANCH_PROFILING
4345
obj-$(CONFIG_PRINTF_KUNIT_TEST) += printf_kunit.o
4446
obj-$(CONFIG_RANDSTRUCT_KUNIT_TEST) += randstruct_kunit.o
4547
obj-$(CONFIG_SCANF_KUNIT_TEST) += scanf_kunit.o

lib/tests/printf_kunit.c

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#include <linux/dcache.h>
1818
#include <linux/socket.h>
1919
#include <linux/in.h>
20+
#include <linux/in6.h>
2021

2122
#include <linux/gfp.h>
2223
#include <linux/mm.h>
@@ -437,6 +438,27 @@ ip4(struct kunit *kunittest)
437438
static void
438439
ip6(struct kunit *kunittest)
439440
{
441+
const struct in6_addr addr = {
442+
.s6_addr = { 0x00, 0x01, 0x00, 0x02, 0x00, 0x03, 0x00, 0x04,
443+
0x00, 0x05, 0x00, 0x06, 0x00, 0x07, 0x00, 0x08 }
444+
};
445+
const struct in6_addr single_zero = {
446+
.s6_addr = { 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x04,
447+
0x00, 0x05, 0x00, 0x06, 0x00, 0x07, 0x00, 0x08 }
448+
};
449+
struct sockaddr_in6 sa = {
450+
.sin6_family = AF_INET6,
451+
.sin6_port = cpu_to_be16(12345),
452+
.sin6_addr = addr,
453+
};
454+
455+
test("00010002000300040005000600070008|0001:0002:0003:0004:0005:0006:0007:0008",
456+
"%pi6|%pI6", &addr, &addr);
457+
test("00010002000300040005000600070008|0001:0002:0003:0004:0005:0006:0007:0008",
458+
"%piS|%pIS", &sa, &sa);
459+
test("1:2:3:4:5:6:7:8", "%pI6c", &addr);
460+
test("1:0:3:4:5:6:7:8", "%pI6c", &single_zero);
461+
test("[1:2:3:4:5:6:7:8]:12345", "%pISpc", &sa);
440462
}
441463

442464
static void

lib/vsprintf.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1107,7 +1107,7 @@ char *resource_string(char *buf, char *end, struct resource *res,
11071107
2*RSRC_BUF_SIZE + FLAG_BUF_SIZE + RAW_BUF_SIZE)];
11081108

11091109
char *p = sym, *pend = sym + sizeof(sym);
1110-
int decode = (fmt[0] == 'R') ? 1 : 0;
1110+
bool decode = fmt[0] == 'R';
11111111
const struct printf_spec *specp;
11121112

11131113
if (check_pointer(&buf, end, res, spec))
@@ -1132,7 +1132,7 @@ char *resource_string(char *buf, char *end, struct resource *res,
11321132
} else {
11331133
p = string_nocheck(p, pend, "??? ", str_spec);
11341134
specp = &mem_spec;
1135-
decode = 0;
1135+
decode = false;
11361136
}
11371137
if (decode && res->flags & IORESOURCE_UNSET) {
11381138
p = string_nocheck(p, pend, "size ", str_spec);

0 commit comments

Comments
 (0)