diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Kconfig.debug | 33 | ||||
-rw-r--r-- | lib/ashldi3.c | 2 | ||||
-rw-r--r-- | lib/ashrdi3.c | 2 | ||||
-rw-r--r-- | lib/asn1_decoder.c | 49 | ||||
-rw-r--r-- | lib/cmpdi2.c | 2 | ||||
-rw-r--r-- | lib/lshrdi3.c | 2 | ||||
-rw-r--r-- | lib/muldi3.c | 2 | ||||
-rw-r--r-- | lib/nlattr.c | 22 | ||||
-rw-r--r-- | lib/oid_registry.c | 16 | ||||
-rw-r--r-- | lib/rbtree.c | 10 | ||||
-rw-r--r-- | lib/test_bpf.c | 43 | ||||
-rw-r--r-- | lib/test_printf.c | 108 | ||||
-rw-r--r-- | lib/ucmpdi2.c | 2 | ||||
-rw-r--r-- | lib/vsprintf.c | 194 |
14 files changed, 329 insertions, 158 deletions
diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug index 947d3e2ed5c2..9d5b78aad4c5 100644 --- a/lib/Kconfig.debug +++ b/lib/Kconfig.debug | |||
@@ -1099,8 +1099,6 @@ config PROVE_LOCKING | |||
1099 | select DEBUG_MUTEXES | 1099 | select DEBUG_MUTEXES |
1100 | select DEBUG_RT_MUTEXES if RT_MUTEXES | 1100 | select DEBUG_RT_MUTEXES if RT_MUTEXES |
1101 | select DEBUG_LOCK_ALLOC | 1101 | select DEBUG_LOCK_ALLOC |
1102 | select LOCKDEP_CROSSRELEASE | ||
1103 | select LOCKDEP_COMPLETIONS | ||
1104 | select TRACE_IRQFLAGS | 1102 | select TRACE_IRQFLAGS |
1105 | default n | 1103 | default n |
1106 | help | 1104 | help |
@@ -1170,37 +1168,6 @@ config LOCK_STAT | |||
1170 | CONFIG_LOCK_STAT defines "contended" and "acquired" lock events. | 1168 | CONFIG_LOCK_STAT defines "contended" and "acquired" lock events. |
1171 | (CONFIG_LOCKDEP defines "acquire" and "release" events.) | 1169 | (CONFIG_LOCKDEP defines "acquire" and "release" events.) |
1172 | 1170 | ||
1173 | config LOCKDEP_CROSSRELEASE | ||
1174 | bool | ||
1175 | help | ||
1176 | This makes lockdep work for crosslock which is a lock allowed to | ||
1177 | be released in a different context from the acquisition context. | ||
1178 | Normally a lock must be released in the context acquiring the lock. | ||
1179 | However, relexing this constraint helps synchronization primitives | ||
1180 | such as page locks or completions can use the lock correctness | ||
1181 | detector, lockdep. | ||
1182 | |||
1183 | config LOCKDEP_COMPLETIONS | ||
1184 | bool | ||
1185 | help | ||
1186 | A deadlock caused by wait_for_completion() and complete() can be | ||
1187 | detected by lockdep using crossrelease feature. | ||
1188 | |||
1189 | config BOOTPARAM_LOCKDEP_CROSSRELEASE_FULLSTACK | ||
1190 | bool "Enable the boot parameter, crossrelease_fullstack" | ||
1191 | depends on LOCKDEP_CROSSRELEASE | ||
1192 | default n | ||
1193 | help | ||
1194 | The lockdep "cross-release" feature needs to record stack traces | ||
1195 | (of calling functions) for all acquisitions, for eventual later | ||
1196 | use during analysis. By default only a single caller is recorded, | ||
1197 | because the unwind operation can be very expensive with deeper | ||
1198 | stack chains. | ||
1199 | |||
1200 | However a boot parameter, crossrelease_fullstack, was | ||
1201 | introduced since sometimes deeper traces are required for full | ||
1202 | analysis. This option turns on the boot parameter. | ||
1203 | |||
1204 | config DEBUG_LOCKDEP | 1171 | config DEBUG_LOCKDEP |
1205 | bool "Lock dependency engine debugging" | 1172 | bool "Lock dependency engine debugging" |
1206 | depends on DEBUG_KERNEL && LOCKDEP | 1173 | depends on DEBUG_KERNEL && LOCKDEP |
diff --git a/lib/ashldi3.c b/lib/ashldi3.c index 1b6087db95a5..3ffc46e3bb6c 100644 --- a/lib/ashldi3.c +++ b/lib/ashldi3.c | |||
@@ -16,7 +16,7 @@ | |||
16 | 16 | ||
17 | #include <linux/export.h> | 17 | #include <linux/export.h> |
18 | 18 | ||
19 | #include <lib/libgcc.h> | 19 | #include <linux/libgcc.h> |
20 | 20 | ||
21 | long long notrace __ashldi3(long long u, word_type b) | 21 | long long notrace __ashldi3(long long u, word_type b) |
22 | { | 22 | { |
diff --git a/lib/ashrdi3.c b/lib/ashrdi3.c index 2e67c97ac65a..ea054550f0e8 100644 --- a/lib/ashrdi3.c +++ b/lib/ashrdi3.c | |||
@@ -16,7 +16,7 @@ | |||
16 | 16 | ||
17 | #include <linux/export.h> | 17 | #include <linux/export.h> |
18 | 18 | ||
19 | #include <lib/libgcc.h> | 19 | #include <linux/libgcc.h> |
20 | 20 | ||
21 | long long notrace __ashrdi3(long long u, word_type b) | 21 | long long notrace __ashrdi3(long long u, word_type b) |
22 | { | 22 | { |
diff --git a/lib/asn1_decoder.c b/lib/asn1_decoder.c index 1ef0cec38d78..dc14beae2c9a 100644 --- a/lib/asn1_decoder.c +++ b/lib/asn1_decoder.c | |||
@@ -313,42 +313,47 @@ next_op: | |||
313 | 313 | ||
314 | /* Decide how to handle the operation */ | 314 | /* Decide how to handle the operation */ |
315 | switch (op) { | 315 | switch (op) { |
316 | case ASN1_OP_MATCH_ANY_ACT: | ||
317 | case ASN1_OP_MATCH_ANY_ACT_OR_SKIP: | ||
318 | case ASN1_OP_COND_MATCH_ANY_ACT: | ||
319 | case ASN1_OP_COND_MATCH_ANY_ACT_OR_SKIP: | ||
320 | ret = actions[machine[pc + 1]](context, hdr, tag, data + dp, len); | ||
321 | if (ret < 0) | ||
322 | return ret; | ||
323 | goto skip_data; | ||
324 | |||
325 | case ASN1_OP_MATCH_ACT: | ||
326 | case ASN1_OP_MATCH_ACT_OR_SKIP: | ||
327 | case ASN1_OP_COND_MATCH_ACT_OR_SKIP: | ||
328 | ret = actions[machine[pc + 2]](context, hdr, tag, data + dp, len); | ||
329 | if (ret < 0) | ||
330 | return ret; | ||
331 | goto skip_data; | ||
332 | |||
333 | case ASN1_OP_MATCH: | 316 | case ASN1_OP_MATCH: |
334 | case ASN1_OP_MATCH_OR_SKIP: | 317 | case ASN1_OP_MATCH_OR_SKIP: |
318 | case ASN1_OP_MATCH_ACT: | ||
319 | case ASN1_OP_MATCH_ACT_OR_SKIP: | ||
335 | case ASN1_OP_MATCH_ANY: | 320 | case ASN1_OP_MATCH_ANY: |
336 | case ASN1_OP_MATCH_ANY_OR_SKIP: | 321 | case ASN1_OP_MATCH_ANY_OR_SKIP: |
322 | case ASN1_OP_MATCH_ANY_ACT: | ||
323 | case ASN1_OP_MATCH_ANY_ACT_OR_SKIP: | ||
337 | case ASN1_OP_COND_MATCH_OR_SKIP: | 324 | case ASN1_OP_COND_MATCH_OR_SKIP: |
325 | case ASN1_OP_COND_MATCH_ACT_OR_SKIP: | ||
338 | case ASN1_OP_COND_MATCH_ANY: | 326 | case ASN1_OP_COND_MATCH_ANY: |
339 | case ASN1_OP_COND_MATCH_ANY_OR_SKIP: | 327 | case ASN1_OP_COND_MATCH_ANY_OR_SKIP: |
340 | skip_data: | 328 | case ASN1_OP_COND_MATCH_ANY_ACT: |
329 | case ASN1_OP_COND_MATCH_ANY_ACT_OR_SKIP: | ||
330 | |||
341 | if (!(flags & FLAG_CONS)) { | 331 | if (!(flags & FLAG_CONS)) { |
342 | if (flags & FLAG_INDEFINITE_LENGTH) { | 332 | if (flags & FLAG_INDEFINITE_LENGTH) { |
333 | size_t tmp = dp; | ||
334 | |||
343 | ret = asn1_find_indefinite_length( | 335 | ret = asn1_find_indefinite_length( |
344 | data, datalen, &dp, &len, &errmsg); | 336 | data, datalen, &tmp, &len, &errmsg); |
345 | if (ret < 0) | 337 | if (ret < 0) |
346 | goto error; | 338 | goto error; |
347 | } else { | ||
348 | dp += len; | ||
349 | } | 339 | } |
350 | pr_debug("- LEAF: %zu\n", len); | 340 | pr_debug("- LEAF: %zu\n", len); |
351 | } | 341 | } |
342 | |||
343 | if (op & ASN1_OP_MATCH__ACT) { | ||
344 | unsigned char act; | ||
345 | |||
346 | if (op & ASN1_OP_MATCH__ANY) | ||
347 | act = machine[pc + 1]; | ||
348 | else | ||
349 | act = machine[pc + 2]; | ||
350 | ret = actions[act](context, hdr, tag, data + dp, len); | ||
351 | if (ret < 0) | ||
352 | return ret; | ||
353 | } | ||
354 | |||
355 | if (!(flags & FLAG_CONS)) | ||
356 | dp += len; | ||
352 | pc += asn1_op_lengths[op]; | 357 | pc += asn1_op_lengths[op]; |
353 | goto next_op; | 358 | goto next_op; |
354 | 359 | ||
@@ -434,6 +439,8 @@ next_op: | |||
434 | else | 439 | else |
435 | act = machine[pc + 1]; | 440 | act = machine[pc + 1]; |
436 | ret = actions[act](context, hdr, 0, data + tdp, len); | 441 | ret = actions[act](context, hdr, 0, data + tdp, len); |
442 | if (ret < 0) | ||
443 | return ret; | ||
437 | } | 444 | } |
438 | pc += asn1_op_lengths[op]; | 445 | pc += asn1_op_lengths[op]; |
439 | goto next_op; | 446 | goto next_op; |
diff --git a/lib/cmpdi2.c b/lib/cmpdi2.c index 6d7ebf6c2b86..2250da7e503e 100644 --- a/lib/cmpdi2.c +++ b/lib/cmpdi2.c | |||
@@ -16,7 +16,7 @@ | |||
16 | 16 | ||
17 | #include <linux/export.h> | 17 | #include <linux/export.h> |
18 | 18 | ||
19 | #include <lib/libgcc.h> | 19 | #include <linux/libgcc.h> |
20 | 20 | ||
21 | word_type notrace __cmpdi2(long long a, long long b) | 21 | word_type notrace __cmpdi2(long long a, long long b) |
22 | { | 22 | { |
diff --git a/lib/lshrdi3.c b/lib/lshrdi3.c index 8e845f4bb65f..99cfa5721f2d 100644 --- a/lib/lshrdi3.c +++ b/lib/lshrdi3.c | |||
@@ -17,7 +17,7 @@ | |||
17 | */ | 17 | */ |
18 | 18 | ||
19 | #include <linux/module.h> | 19 | #include <linux/module.h> |
20 | #include <lib/libgcc.h> | 20 | #include <linux/libgcc.h> |
21 | 21 | ||
22 | long long notrace __lshrdi3(long long u, word_type b) | 22 | long long notrace __lshrdi3(long long u, word_type b) |
23 | { | 23 | { |
diff --git a/lib/muldi3.c b/lib/muldi3.c index 88938543e10a..54c8b3123376 100644 --- a/lib/muldi3.c +++ b/lib/muldi3.c | |||
@@ -15,7 +15,7 @@ | |||
15 | */ | 15 | */ |
16 | 16 | ||
17 | #include <linux/export.h> | 17 | #include <linux/export.h> |
18 | #include <lib/libgcc.h> | 18 | #include <linux/libgcc.h> |
19 | 19 | ||
20 | #define W_TYPE_SIZE 32 | 20 | #define W_TYPE_SIZE 32 |
21 | 21 | ||
diff --git a/lib/nlattr.c b/lib/nlattr.c index 8bf78b4b78f0..dfa55c873c13 100644 --- a/lib/nlattr.c +++ b/lib/nlattr.c | |||
@@ -15,7 +15,11 @@ | |||
15 | #include <linux/types.h> | 15 | #include <linux/types.h> |
16 | #include <net/netlink.h> | 16 | #include <net/netlink.h> |
17 | 17 | ||
18 | /* for these data types attribute length must be exactly given size */ | 18 | /* For these data types, attribute length should be exactly the given |
19 | * size. However, to maintain compatibility with broken commands, if the | ||
20 | * attribute length does not match the expected size a warning is emitted | ||
21 | * to the user that the command is sending invalid data and needs to be fixed. | ||
22 | */ | ||
19 | static const u8 nla_attr_len[NLA_TYPE_MAX+1] = { | 23 | static const u8 nla_attr_len[NLA_TYPE_MAX+1] = { |
20 | [NLA_U8] = sizeof(u8), | 24 | [NLA_U8] = sizeof(u8), |
21 | [NLA_U16] = sizeof(u16), | 25 | [NLA_U16] = sizeof(u16), |
@@ -28,8 +32,16 @@ static const u8 nla_attr_len[NLA_TYPE_MAX+1] = { | |||
28 | }; | 32 | }; |
29 | 33 | ||
30 | static const u8 nla_attr_minlen[NLA_TYPE_MAX+1] = { | 34 | static const u8 nla_attr_minlen[NLA_TYPE_MAX+1] = { |
35 | [NLA_U8] = sizeof(u8), | ||
36 | [NLA_U16] = sizeof(u16), | ||
37 | [NLA_U32] = sizeof(u32), | ||
38 | [NLA_U64] = sizeof(u64), | ||
31 | [NLA_MSECS] = sizeof(u64), | 39 | [NLA_MSECS] = sizeof(u64), |
32 | [NLA_NESTED] = NLA_HDRLEN, | 40 | [NLA_NESTED] = NLA_HDRLEN, |
41 | [NLA_S8] = sizeof(s8), | ||
42 | [NLA_S16] = sizeof(s16), | ||
43 | [NLA_S32] = sizeof(s32), | ||
44 | [NLA_S64] = sizeof(s64), | ||
33 | }; | 45 | }; |
34 | 46 | ||
35 | static int validate_nla_bitfield32(const struct nlattr *nla, | 47 | static int validate_nla_bitfield32(const struct nlattr *nla, |
@@ -69,11 +81,9 @@ static int validate_nla(const struct nlattr *nla, int maxtype, | |||
69 | 81 | ||
70 | BUG_ON(pt->type > NLA_TYPE_MAX); | 82 | BUG_ON(pt->type > NLA_TYPE_MAX); |
71 | 83 | ||
72 | /* for data types NLA_U* and NLA_S* require exact length */ | 84 | if (nla_attr_len[pt->type] && attrlen != nla_attr_len[pt->type]) { |
73 | if (nla_attr_len[pt->type]) { | 85 | pr_warn_ratelimited("netlink: '%s': attribute type %d has an invalid length.\n", |
74 | if (attrlen != nla_attr_len[pt->type]) | 86 | current->comm, type); |
75 | return -ERANGE; | ||
76 | return 0; | ||
77 | } | 87 | } |
78 | 88 | ||
79 | switch (pt->type) { | 89 | switch (pt->type) { |
diff --git a/lib/oid_registry.c b/lib/oid_registry.c index 41b9e50711a7..0bcac6ccb1b2 100644 --- a/lib/oid_registry.c +++ b/lib/oid_registry.c | |||
@@ -116,14 +116,14 @@ int sprint_oid(const void *data, size_t datasize, char *buffer, size_t bufsize) | |||
116 | int count; | 116 | int count; |
117 | 117 | ||
118 | if (v >= end) | 118 | if (v >= end) |
119 | return -EBADMSG; | 119 | goto bad; |
120 | 120 | ||
121 | n = *v++; | 121 | n = *v++; |
122 | ret = count = snprintf(buffer, bufsize, "%u.%u", n / 40, n % 40); | 122 | ret = count = snprintf(buffer, bufsize, "%u.%u", n / 40, n % 40); |
123 | if (count >= bufsize) | ||
124 | return -ENOBUFS; | ||
123 | buffer += count; | 125 | buffer += count; |
124 | bufsize -= count; | 126 | bufsize -= count; |
125 | if (bufsize == 0) | ||
126 | return -ENOBUFS; | ||
127 | 127 | ||
128 | while (v < end) { | 128 | while (v < end) { |
129 | num = 0; | 129 | num = 0; |
@@ -134,20 +134,24 @@ int sprint_oid(const void *data, size_t datasize, char *buffer, size_t bufsize) | |||
134 | num = n & 0x7f; | 134 | num = n & 0x7f; |
135 | do { | 135 | do { |
136 | if (v >= end) | 136 | if (v >= end) |
137 | return -EBADMSG; | 137 | goto bad; |
138 | n = *v++; | 138 | n = *v++; |
139 | num <<= 7; | 139 | num <<= 7; |
140 | num |= n & 0x7f; | 140 | num |= n & 0x7f; |
141 | } while (n & 0x80); | 141 | } while (n & 0x80); |
142 | } | 142 | } |
143 | ret += count = snprintf(buffer, bufsize, ".%lu", num); | 143 | ret += count = snprintf(buffer, bufsize, ".%lu", num); |
144 | buffer += count; | 144 | if (count >= bufsize) |
145 | if (bufsize <= count) | ||
146 | return -ENOBUFS; | 145 | return -ENOBUFS; |
146 | buffer += count; | ||
147 | bufsize -= count; | 147 | bufsize -= count; |
148 | } | 148 | } |
149 | 149 | ||
150 | return ret; | 150 | return ret; |
151 | |||
152 | bad: | ||
153 | snprintf(buffer, bufsize, "(bad)"); | ||
154 | return -EBADMSG; | ||
151 | } | 155 | } |
152 | EXPORT_SYMBOL_GPL(sprint_oid); | 156 | EXPORT_SYMBOL_GPL(sprint_oid); |
153 | 157 | ||
diff --git a/lib/rbtree.c b/lib/rbtree.c index ba4a9d165f1b..d3ff682fd4b8 100644 --- a/lib/rbtree.c +++ b/lib/rbtree.c | |||
@@ -603,6 +603,16 @@ void rb_replace_node(struct rb_node *victim, struct rb_node *new, | |||
603 | } | 603 | } |
604 | EXPORT_SYMBOL(rb_replace_node); | 604 | EXPORT_SYMBOL(rb_replace_node); |
605 | 605 | ||
606 | void rb_replace_node_cached(struct rb_node *victim, struct rb_node *new, | ||
607 | struct rb_root_cached *root) | ||
608 | { | ||
609 | rb_replace_node(victim, new, &root->rb_root); | ||
610 | |||
611 | if (root->rb_leftmost == victim) | ||
612 | root->rb_leftmost = new; | ||
613 | } | ||
614 | EXPORT_SYMBOL(rb_replace_node_cached); | ||
615 | |||
606 | void rb_replace_node_rcu(struct rb_node *victim, struct rb_node *new, | 616 | void rb_replace_node_rcu(struct rb_node *victim, struct rb_node *new, |
607 | struct rb_root *root) | 617 | struct rb_root *root) |
608 | { | 618 | { |
diff --git a/lib/test_bpf.c b/lib/test_bpf.c index aa8812ae6776..9e9748089270 100644 --- a/lib/test_bpf.c +++ b/lib/test_bpf.c | |||
@@ -435,6 +435,41 @@ loop: | |||
435 | return 0; | 435 | return 0; |
436 | } | 436 | } |
437 | 437 | ||
438 | static int bpf_fill_ld_abs_vlan_push_pop2(struct bpf_test *self) | ||
439 | { | ||
440 | struct bpf_insn *insn; | ||
441 | |||
442 | insn = kmalloc_array(16, sizeof(*insn), GFP_KERNEL); | ||
443 | if (!insn) | ||
444 | return -ENOMEM; | ||
445 | |||
446 | /* Due to func address being non-const, we need to | ||
447 | * assemble this here. | ||
448 | */ | ||
449 | insn[0] = BPF_MOV64_REG(R6, R1); | ||
450 | insn[1] = BPF_LD_ABS(BPF_B, 0); | ||
451 | insn[2] = BPF_LD_ABS(BPF_H, 0); | ||
452 | insn[3] = BPF_LD_ABS(BPF_W, 0); | ||
453 | insn[4] = BPF_MOV64_REG(R7, R6); | ||
454 | insn[5] = BPF_MOV64_IMM(R6, 0); | ||
455 | insn[6] = BPF_MOV64_REG(R1, R7); | ||
456 | insn[7] = BPF_MOV64_IMM(R2, 1); | ||
457 | insn[8] = BPF_MOV64_IMM(R3, 2); | ||
458 | insn[9] = BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, | ||
459 | bpf_skb_vlan_push_proto.func - __bpf_call_base); | ||
460 | insn[10] = BPF_MOV64_REG(R6, R7); | ||
461 | insn[11] = BPF_LD_ABS(BPF_B, 0); | ||
462 | insn[12] = BPF_LD_ABS(BPF_H, 0); | ||
463 | insn[13] = BPF_LD_ABS(BPF_W, 0); | ||
464 | insn[14] = BPF_MOV64_IMM(R0, 42); | ||
465 | insn[15] = BPF_EXIT_INSN(); | ||
466 | |||
467 | self->u.ptr.insns = insn; | ||
468 | self->u.ptr.len = 16; | ||
469 | |||
470 | return 0; | ||
471 | } | ||
472 | |||
438 | static int bpf_fill_jump_around_ld_abs(struct bpf_test *self) | 473 | static int bpf_fill_jump_around_ld_abs(struct bpf_test *self) |
439 | { | 474 | { |
440 | unsigned int len = BPF_MAXINSNS; | 475 | unsigned int len = BPF_MAXINSNS; |
@@ -6066,6 +6101,14 @@ static struct bpf_test tests[] = { | |||
6066 | {}, | 6101 | {}, |
6067 | { {0x1, 0x42 } }, | 6102 | { {0x1, 0x42 } }, |
6068 | }, | 6103 | }, |
6104 | { | ||
6105 | "LD_ABS with helper changing skb data", | ||
6106 | { }, | ||
6107 | INTERNAL, | ||
6108 | { 0x34 }, | ||
6109 | { { ETH_HLEN, 42 } }, | ||
6110 | .fill_helper = bpf_fill_ld_abs_vlan_push_pop2, | ||
6111 | }, | ||
6069 | }; | 6112 | }; |
6070 | 6113 | ||
6071 | static struct net_device dev; | 6114 | static struct net_device dev; |
diff --git a/lib/test_printf.c b/lib/test_printf.c index 563f10e6876a..71ebfa43ad05 100644 --- a/lib/test_printf.c +++ b/lib/test_printf.c | |||
@@ -24,24 +24,6 @@ | |||
24 | #define PAD_SIZE 16 | 24 | #define PAD_SIZE 16 |
25 | #define FILL_CHAR '$' | 25 | #define FILL_CHAR '$' |
26 | 26 | ||
27 | #define PTR1 ((void*)0x01234567) | ||
28 | #define PTR2 ((void*)(long)(int)0xfedcba98) | ||
29 | |||
30 | #if BITS_PER_LONG == 64 | ||
31 | #define PTR1_ZEROES "000000000" | ||
32 | #define PTR1_SPACES " " | ||
33 | #define PTR1_STR "1234567" | ||
34 | #define PTR2_STR "fffffffffedcba98" | ||
35 | #define PTR_WIDTH 16 | ||
36 | #else | ||
37 | #define PTR1_ZEROES "0" | ||
38 | #define PTR1_SPACES " " | ||
39 | #define PTR1_STR "1234567" | ||
40 | #define PTR2_STR "fedcba98" | ||
41 | #define PTR_WIDTH 8 | ||
42 | #endif | ||
43 | #define PTR_WIDTH_STR stringify(PTR_WIDTH) | ||
44 | |||
45 | static unsigned total_tests __initdata; | 27 | static unsigned total_tests __initdata; |
46 | static unsigned failed_tests __initdata; | 28 | static unsigned failed_tests __initdata; |
47 | static char *test_buffer __initdata; | 29 | static char *test_buffer __initdata; |
@@ -217,30 +199,79 @@ test_string(void) | |||
217 | test("a | | ", "%-3.s|%-3.0s|%-3.*s", "a", "b", 0, "c"); | 199 | test("a | | ", "%-3.s|%-3.0s|%-3.*s", "a", "b", 0, "c"); |
218 | } | 200 | } |
219 | 201 | ||
202 | #define PLAIN_BUF_SIZE 64 /* leave some space so we don't oops */ | ||
203 | |||
204 | #if BITS_PER_LONG == 64 | ||
205 | |||
206 | #define PTR_WIDTH 16 | ||
207 | #define PTR ((void *)0xffff0123456789ab) | ||
208 | #define PTR_STR "ffff0123456789ab" | ||
209 | #define ZEROS "00000000" /* hex 32 zero bits */ | ||
210 | |||
211 | static int __init | ||
212 | plain_format(void) | ||
213 | { | ||
214 | char buf[PLAIN_BUF_SIZE]; | ||
215 | int nchars; | ||
216 | |||
217 | nchars = snprintf(buf, PLAIN_BUF_SIZE, "%p", PTR); | ||
218 | |||
219 | if (nchars != PTR_WIDTH || strncmp(buf, ZEROS, strlen(ZEROS)) != 0) | ||
220 | return -1; | ||
221 | |||
222 | return 0; | ||
223 | } | ||
224 | |||
225 | #else | ||
226 | |||
227 | #define PTR_WIDTH 8 | ||
228 | #define PTR ((void *)0x456789ab) | ||
229 | #define PTR_STR "456789ab" | ||
230 | |||
231 | static int __init | ||
232 | plain_format(void) | ||
233 | { | ||
234 | /* Format is implicitly tested for 32 bit machines by plain_hash() */ | ||
235 | return 0; | ||
236 | } | ||
237 | |||
238 | #endif /* BITS_PER_LONG == 64 */ | ||
239 | |||
240 | static int __init | ||
241 | plain_hash(void) | ||
242 | { | ||
243 | char buf[PLAIN_BUF_SIZE]; | ||
244 | int nchars; | ||
245 | |||
246 | nchars = snprintf(buf, PLAIN_BUF_SIZE, "%p", PTR); | ||
247 | |||
248 | if (nchars != PTR_WIDTH || strncmp(buf, PTR_STR, PTR_WIDTH) == 0) | ||
249 | return -1; | ||
250 | |||
251 | return 0; | ||
252 | } | ||
253 | |||
254 | /* | ||
255 | * We can't use test() to test %p because we don't know what output to expect | ||
256 | * after an address is hashed. | ||
257 | */ | ||
220 | static void __init | 258 | static void __init |
221 | plain(void) | 259 | plain(void) |
222 | { | 260 | { |
223 | test(PTR1_ZEROES PTR1_STR " " PTR2_STR, "%p %p", PTR1, PTR2); | 261 | int err; |
224 | /* | ||
225 | * The field width is overloaded for some %p extensions to | ||
226 | * pass another piece of information. For plain pointers, the | ||
227 | * behaviour is slightly odd: One cannot pass either the 0 | ||
228 | * flag nor a precision to %p without gcc complaining, and if | ||
229 | * one explicitly gives a field width, the number is no longer | ||
230 | * zero-padded. | ||
231 | */ | ||
232 | test("|" PTR1_STR PTR1_SPACES " | " PTR1_SPACES PTR1_STR "|", | ||
233 | "|%-*p|%*p|", PTR_WIDTH+2, PTR1, PTR_WIDTH+2, PTR1); | ||
234 | test("|" PTR2_STR " | " PTR2_STR "|", | ||
235 | "|%-*p|%*p|", PTR_WIDTH+2, PTR2, PTR_WIDTH+2, PTR2); | ||
236 | 262 | ||
237 | /* | 263 | err = plain_hash(); |
238 | * Unrecognized %p extensions are treated as plain %p, but the | 264 | if (err) { |
239 | * alphanumeric suffix is ignored (that is, does not occur in | 265 | pr_warn("plain 'p' does not appear to be hashed\n"); |
240 | * the output.) | 266 | failed_tests++; |
241 | */ | 267 | return; |
242 | test("|"PTR1_ZEROES PTR1_STR"|", "|%p0y|", PTR1); | 268 | } |
243 | test("|"PTR2_STR"|", "|%p0y|", PTR2); | 269 | |
270 | err = plain_format(); | ||
271 | if (err) { | ||
272 | pr_warn("hashing plain 'p' has unexpected format\n"); | ||
273 | failed_tests++; | ||
274 | } | ||
244 | } | 275 | } |
245 | 276 | ||
246 | static void __init | 277 | static void __init |
@@ -251,6 +282,7 @@ symbol_ptr(void) | |||
251 | static void __init | 282 | static void __init |
252 | kernel_ptr(void) | 283 | kernel_ptr(void) |
253 | { | 284 | { |
285 | /* We can't test this without access to kptr_restrict. */ | ||
254 | } | 286 | } |
255 | 287 | ||
256 | static void __init | 288 | static void __init |
diff --git a/lib/ucmpdi2.c b/lib/ucmpdi2.c index 49a53505c8e3..25ca2d4c1e19 100644 --- a/lib/ucmpdi2.c +++ b/lib/ucmpdi2.c | |||
@@ -15,7 +15,7 @@ | |||
15 | */ | 15 | */ |
16 | 16 | ||
17 | #include <linux/module.h> | 17 | #include <linux/module.h> |
18 | #include <lib/libgcc.h> | 18 | #include <linux/libgcc.h> |
19 | 19 | ||
20 | word_type __ucmpdi2(unsigned long long a, unsigned long long b) | 20 | word_type __ucmpdi2(unsigned long long a, unsigned long long b) |
21 | { | 21 | { |
diff --git a/lib/vsprintf.c b/lib/vsprintf.c index 1746bae94d41..01c3957b2de6 100644 --- a/lib/vsprintf.c +++ b/lib/vsprintf.c | |||
@@ -33,6 +33,8 @@ | |||
33 | #include <linux/uuid.h> | 33 | #include <linux/uuid.h> |
34 | #include <linux/of.h> | 34 | #include <linux/of.h> |
35 | #include <net/addrconf.h> | 35 | #include <net/addrconf.h> |
36 | #include <linux/siphash.h> | ||
37 | #include <linux/compiler.h> | ||
36 | #ifdef CONFIG_BLOCK | 38 | #ifdef CONFIG_BLOCK |
37 | #include <linux/blkdev.h> | 39 | #include <linux/blkdev.h> |
38 | #endif | 40 | #endif |
@@ -1343,6 +1345,59 @@ char *uuid_string(char *buf, char *end, const u8 *addr, | |||
1343 | return string(buf, end, uuid, spec); | 1345 | return string(buf, end, uuid, spec); |
1344 | } | 1346 | } |
1345 | 1347 | ||
1348 | int kptr_restrict __read_mostly; | ||
1349 | |||
1350 | static noinline_for_stack | ||
1351 | char *restricted_pointer(char *buf, char *end, const void *ptr, | ||
1352 | struct printf_spec spec) | ||
1353 | { | ||
1354 | spec.base = 16; | ||
1355 | spec.flags |= SMALL; | ||
1356 | if (spec.field_width == -1) { | ||
1357 | spec.field_width = 2 * sizeof(ptr); | ||
1358 | spec.flags |= ZEROPAD; | ||
1359 | } | ||
1360 | |||
1361 | switch (kptr_restrict) { | ||
1362 | case 0: | ||
1363 | /* Always print %pK values */ | ||
1364 | break; | ||
1365 | case 1: { | ||
1366 | const struct cred *cred; | ||
1367 | |||
1368 | /* | ||
1369 | * kptr_restrict==1 cannot be used in IRQ context | ||
1370 | * because its test for CAP_SYSLOG would be meaningless. | ||
1371 | */ | ||
1372 | if (in_irq() || in_serving_softirq() || in_nmi()) | ||
1373 | return string(buf, end, "pK-error", spec); | ||
1374 | |||
1375 | /* | ||
1376 | * Only print the real pointer value if the current | ||
1377 | * process has CAP_SYSLOG and is running with the | ||
1378 | * same credentials it started with. This is because | ||
1379 | * access to files is checked at open() time, but %pK | ||
1380 | * checks permission at read() time. We don't want to | ||
1381 | * leak pointer values if a binary opens a file using | ||
1382 | * %pK and then elevates privileges before reading it. | ||
1383 | */ | ||
1384 | cred = current_cred(); | ||
1385 | if (!has_capability_noaudit(current, CAP_SYSLOG) || | ||
1386 | !uid_eq(cred->euid, cred->uid) || | ||
1387 | !gid_eq(cred->egid, cred->gid)) | ||
1388 | ptr = NULL; | ||
1389 | break; | ||
1390 | } | ||
1391 | case 2: | ||
1392 | default: | ||
1393 | /* Always print 0's for %pK */ | ||
1394 | ptr = NULL; | ||
1395 | break; | ||
1396 | } | ||
1397 | |||
1398 | return number(buf, end, (unsigned long)ptr, spec); | ||
1399 | } | ||
1400 | |||
1346 | static noinline_for_stack | 1401 | static noinline_for_stack |
1347 | char *netdev_bits(char *buf, char *end, const void *addr, const char *fmt) | 1402 | char *netdev_bits(char *buf, char *end, const void *addr, const char *fmt) |
1348 | { | 1403 | { |
@@ -1591,7 +1646,86 @@ char *device_node_string(char *buf, char *end, struct device_node *dn, | |||
1591 | return widen_string(buf, buf - buf_start, end, spec); | 1646 | return widen_string(buf, buf - buf_start, end, spec); |
1592 | } | 1647 | } |
1593 | 1648 | ||
1594 | int kptr_restrict __read_mostly; | 1649 | static noinline_for_stack |
1650 | char *pointer_string(char *buf, char *end, const void *ptr, | ||
1651 | struct printf_spec spec) | ||
1652 | { | ||
1653 | spec.base = 16; | ||
1654 | spec.flags |= SMALL; | ||
1655 | if (spec.field_width == -1) { | ||
1656 | spec.field_width = 2 * sizeof(ptr); | ||
1657 | spec.flags |= ZEROPAD; | ||
1658 | } | ||
1659 | |||
1660 | return number(buf, end, (unsigned long int)ptr, spec); | ||
1661 | } | ||
1662 | |||
1663 | static bool have_filled_random_ptr_key __read_mostly; | ||
1664 | static siphash_key_t ptr_key __read_mostly; | ||
1665 | |||
1666 | static void fill_random_ptr_key(struct random_ready_callback *unused) | ||
1667 | { | ||
1668 | get_random_bytes(&ptr_key, sizeof(ptr_key)); | ||
1669 | /* | ||
1670 | * have_filled_random_ptr_key==true is dependent on get_random_bytes(). | ||
1671 | * ptr_to_id() needs to see have_filled_random_ptr_key==true | ||
1672 | * after get_random_bytes() returns. | ||
1673 | */ | ||
1674 | smp_mb(); | ||
1675 | WRITE_ONCE(have_filled_random_ptr_key, true); | ||
1676 | } | ||
1677 | |||
1678 | static struct random_ready_callback random_ready = { | ||
1679 | .func = fill_random_ptr_key | ||
1680 | }; | ||
1681 | |||
1682 | static int __init initialize_ptr_random(void) | ||
1683 | { | ||
1684 | int ret = add_random_ready_callback(&random_ready); | ||
1685 | |||
1686 | if (!ret) { | ||
1687 | return 0; | ||
1688 | } else if (ret == -EALREADY) { | ||
1689 | fill_random_ptr_key(&random_ready); | ||
1690 | return 0; | ||
1691 | } | ||
1692 | |||
1693 | return ret; | ||
1694 | } | ||
1695 | early_initcall(initialize_ptr_random); | ||
1696 | |||
1697 | /* Maps a pointer to a 32 bit unique identifier. */ | ||
1698 | static char *ptr_to_id(char *buf, char *end, void *ptr, struct printf_spec spec) | ||
1699 | { | ||
1700 | unsigned long hashval; | ||
1701 | const int default_width = 2 * sizeof(ptr); | ||
1702 | |||
1703 | if (unlikely(!have_filled_random_ptr_key)) { | ||
1704 | spec.field_width = default_width; | ||
1705 | /* string length must be less than default_width */ | ||
1706 | return string(buf, end, "(ptrval)", spec); | ||
1707 | } | ||
1708 | |||
1709 | #ifdef CONFIG_64BIT | ||
1710 | hashval = (unsigned long)siphash_1u64((u64)ptr, &ptr_key); | ||
1711 | /* | ||
1712 | * Mask off the first 32 bits, this makes explicit that we have | ||
1713 | * modified the address (and 32 bits is plenty for a unique ID). | ||
1714 | */ | ||
1715 | hashval = hashval & 0xffffffff; | ||
1716 | #else | ||
1717 | hashval = (unsigned long)siphash_1u32((u32)ptr, &ptr_key); | ||
1718 | #endif | ||
1719 | |||
1720 | spec.flags |= SMALL; | ||
1721 | if (spec.field_width == -1) { | ||
1722 | spec.field_width = default_width; | ||
1723 | spec.flags |= ZEROPAD; | ||
1724 | } | ||
1725 | spec.base = 16; | ||
1726 | |||
1727 | return number(buf, end, hashval, spec); | ||
1728 | } | ||
1595 | 1729 | ||
1596 | /* | 1730 | /* |
1597 | * Show a '%p' thing. A kernel extension is that the '%p' is followed | 1731 | * Show a '%p' thing. A kernel extension is that the '%p' is followed |
@@ -1698,11 +1832,16 @@ int kptr_restrict __read_mostly; | |||
1698 | * c major compatible string | 1832 | * c major compatible string |
1699 | * C full compatible string | 1833 | * C full compatible string |
1700 | * | 1834 | * |
1835 | * - 'x' For printing the address. Equivalent to "%lx". | ||
1836 | * | ||
1701 | * ** Please update also Documentation/printk-formats.txt when making changes ** | 1837 | * ** Please update also Documentation/printk-formats.txt when making changes ** |
1702 | * | 1838 | * |
1703 | * Note: The difference between 'S' and 'F' is that on ia64 and ppc64 | 1839 | * Note: The difference between 'S' and 'F' is that on ia64 and ppc64 |
1704 | * function pointers are really function descriptors, which contain a | 1840 | * function pointers are really function descriptors, which contain a |
1705 | * pointer to the real address. | 1841 | * pointer to the real address. |
1842 | * | ||
1843 | * Note: The default behaviour (unadorned %p) is to hash the address, | ||
1844 | * rendering it useful as a unique identifier. | ||
1706 | */ | 1845 | */ |
1707 | static noinline_for_stack | 1846 | static noinline_for_stack |
1708 | char *pointer(const char *fmt, char *buf, char *end, void *ptr, | 1847 | char *pointer(const char *fmt, char *buf, char *end, void *ptr, |
@@ -1792,47 +1931,9 @@ char *pointer(const char *fmt, char *buf, char *end, void *ptr, | |||
1792 | return buf; | 1931 | return buf; |
1793 | } | 1932 | } |
1794 | case 'K': | 1933 | case 'K': |
1795 | switch (kptr_restrict) { | 1934 | if (!kptr_restrict) |
1796 | case 0: | ||
1797 | /* Always print %pK values */ | ||
1798 | break; | ||
1799 | case 1: { | ||
1800 | const struct cred *cred; | ||
1801 | |||
1802 | /* | ||
1803 | * kptr_restrict==1 cannot be used in IRQ context | ||
1804 | * because its test for CAP_SYSLOG would be meaningless. | ||
1805 | */ | ||
1806 | if (in_irq() || in_serving_softirq() || in_nmi()) { | ||
1807 | if (spec.field_width == -1) | ||
1808 | spec.field_width = default_width; | ||
1809 | return string(buf, end, "pK-error", spec); | ||
1810 | } | ||
1811 | |||
1812 | /* | ||
1813 | * Only print the real pointer value if the current | ||
1814 | * process has CAP_SYSLOG and is running with the | ||
1815 | * same credentials it started with. This is because | ||
1816 | * access to files is checked at open() time, but %pK | ||
1817 | * checks permission at read() time. We don't want to | ||
1818 | * leak pointer values if a binary opens a file using | ||
1819 | * %pK and then elevates privileges before reading it. | ||
1820 | */ | ||
1821 | cred = current_cred(); | ||
1822 | if (!has_capability_noaudit(current, CAP_SYSLOG) || | ||
1823 | !uid_eq(cred->euid, cred->uid) || | ||
1824 | !gid_eq(cred->egid, cred->gid)) | ||
1825 | ptr = NULL; | ||
1826 | break; | ||
1827 | } | ||
1828 | case 2: | ||
1829 | default: | ||
1830 | /* Always print 0's for %pK */ | ||
1831 | ptr = NULL; | ||
1832 | break; | 1935 | break; |
1833 | } | 1936 | return restricted_pointer(buf, end, ptr, spec); |
1834 | break; | ||
1835 | |||
1836 | case 'N': | 1937 | case 'N': |
1837 | return netdev_bits(buf, end, ptr, fmt); | 1938 | return netdev_bits(buf, end, ptr, fmt); |
1838 | case 'a': | 1939 | case 'a': |
@@ -1857,15 +1958,12 @@ char *pointer(const char *fmt, char *buf, char *end, void *ptr, | |||
1857 | case 'F': | 1958 | case 'F': |
1858 | return device_node_string(buf, end, ptr, spec, fmt + 1); | 1959 | return device_node_string(buf, end, ptr, spec, fmt + 1); |
1859 | } | 1960 | } |
1961 | case 'x': | ||
1962 | return pointer_string(buf, end, ptr, spec); | ||
1860 | } | 1963 | } |
1861 | spec.flags |= SMALL; | ||
1862 | if (spec.field_width == -1) { | ||
1863 | spec.field_width = default_width; | ||
1864 | spec.flags |= ZEROPAD; | ||
1865 | } | ||
1866 | spec.base = 16; | ||
1867 | 1964 | ||
1868 | return number(buf, end, (unsigned long) ptr, spec); | 1965 | /* default is to _not_ leak addresses, hash before printing */ |
1966 | return ptr_to_id(buf, end, ptr, spec); | ||
1869 | } | 1967 | } |
1870 | 1968 | ||
1871 | /* | 1969 | /* |