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_printf.c | 108 | ||||
| -rw-r--r-- | lib/ucmpdi2.c | 2 | ||||
| -rw-r--r-- | lib/vsprintf.c | 194 |
13 files changed, 286 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_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 | /* |
