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/kobject_uevent.c | 16 | ||||
| -rw-r--r-- | lib/lshrdi3.c | 2 | ||||
| -rw-r--r-- | lib/mpi/longlong.h | 18 | ||||
| -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 | 54 | ||||
| -rw-r--r-- | lib/test_printf.c | 108 | ||||
| -rw-r--r-- | lib/timerqueue.c | 8 | ||||
| -rw-r--r-- | lib/ucmpdi2.c | 2 | ||||
| -rw-r--r-- | lib/vsprintf.c | 194 |
17 files changed, 370 insertions, 170 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/kobject_uevent.c b/lib/kobject_uevent.c index c3e84edc47c9..2615074d3de5 100644 --- a/lib/kobject_uevent.c +++ b/lib/kobject_uevent.c | |||
| @@ -346,7 +346,8 @@ static int kobject_uevent_net_broadcast(struct kobject *kobj, | |||
| 346 | static void zap_modalias_env(struct kobj_uevent_env *env) | 346 | static void zap_modalias_env(struct kobj_uevent_env *env) |
| 347 | { | 347 | { |
| 348 | static const char modalias_prefix[] = "MODALIAS="; | 348 | static const char modalias_prefix[] = "MODALIAS="; |
| 349 | int i; | 349 | size_t len; |
| 350 | int i, j; | ||
| 350 | 351 | ||
| 351 | for (i = 0; i < env->envp_idx;) { | 352 | for (i = 0; i < env->envp_idx;) { |
| 352 | if (strncmp(env->envp[i], modalias_prefix, | 353 | if (strncmp(env->envp[i], modalias_prefix, |
| @@ -355,11 +356,18 @@ static void zap_modalias_env(struct kobj_uevent_env *env) | |||
| 355 | continue; | 356 | continue; |
| 356 | } | 357 | } |
| 357 | 358 | ||
| 358 | if (i != env->envp_idx - 1) | 359 | len = strlen(env->envp[i]) + 1; |
| 359 | memmove(&env->envp[i], &env->envp[i + 1], | 360 | |
| 360 | sizeof(env->envp[i]) * env->envp_idx - 1); | 361 | if (i != env->envp_idx - 1) { |
| 362 | memmove(env->envp[i], env->envp[i + 1], | ||
| 363 | env->buflen - len); | ||
| 364 | |||
| 365 | for (j = i; j < env->envp_idx - 1; j++) | ||
| 366 | env->envp[j] = env->envp[j + 1] - len; | ||
| 367 | } | ||
| 361 | 368 | ||
| 362 | env->envp_idx--; | 369 | env->envp_idx--; |
| 370 | env->buflen -= len; | ||
| 363 | } | 371 | } |
| 364 | } | 372 | } |
| 365 | 373 | ||
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/mpi/longlong.h b/lib/mpi/longlong.h index 57fd45ab7af1..08c60d10747f 100644 --- a/lib/mpi/longlong.h +++ b/lib/mpi/longlong.h | |||
| @@ -671,7 +671,23 @@ do { \ | |||
| 671 | ************** MIPS/64 ************** | 671 | ************** MIPS/64 ************** |
| 672 | ***************************************/ | 672 | ***************************************/ |
| 673 | #if (defined(__mips) && __mips >= 3) && W_TYPE_SIZE == 64 | 673 | #if (defined(__mips) && __mips >= 3) && W_TYPE_SIZE == 64 |
| 674 | #if (__GNUC__ >= 5) || (__GNUC__ >= 4 && __GNUC_MINOR__ >= 4) | 674 | #if defined(__mips_isa_rev) && __mips_isa_rev >= 6 |
| 675 | /* | ||
| 676 | * GCC ends up emitting a __multi3 intrinsic call for MIPS64r6 with the plain C | ||
| 677 | * code below, so we special case MIPS64r6 until the compiler can do better. | ||
| 678 | */ | ||
| 679 | #define umul_ppmm(w1, w0, u, v) \ | ||
| 680 | do { \ | ||
| 681 | __asm__ ("dmulu %0,%1,%2" \ | ||
| 682 | : "=d" ((UDItype)(w0)) \ | ||
| 683 | : "d" ((UDItype)(u)), \ | ||
| 684 | "d" ((UDItype)(v))); \ | ||
| 685 | __asm__ ("dmuhu %0,%1,%2" \ | ||
| 686 | : "=d" ((UDItype)(w1)) \ | ||
| 687 | : "d" ((UDItype)(u)), \ | ||
| 688 | "d" ((UDItype)(v))); \ | ||
| 689 | } while (0) | ||
| 690 | #elif (__GNUC__ >= 5) || (__GNUC__ >= 4 && __GNUC_MINOR__ >= 4) | ||
| 675 | #define umul_ppmm(w1, w0, u, v) \ | 691 | #define umul_ppmm(w1, w0, u, v) \ |
| 676 | do { \ | 692 | do { \ |
| 677 | typedef unsigned int __ll_UTItype __attribute__((mode(TI))); \ | 693 | typedef unsigned int __ll_UTItype __attribute__((mode(TI))); \ |
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..f369889e521d 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; |
| @@ -6207,9 +6250,8 @@ static struct bpf_prog *generate_filter(int which, int *err) | |||
| 6207 | return NULL; | 6250 | return NULL; |
| 6208 | } | 6251 | } |
| 6209 | } | 6252 | } |
| 6210 | /* We don't expect to fail. */ | ||
| 6211 | if (*err) { | 6253 | if (*err) { |
| 6212 | pr_cont("FAIL to attach err=%d len=%d\n", | 6254 | pr_cont("FAIL to prog_create err=%d len=%d\n", |
| 6213 | *err, fprog.len); | 6255 | *err, fprog.len); |
| 6214 | return NULL; | 6256 | return NULL; |
| 6215 | } | 6257 | } |
| @@ -6233,6 +6275,10 @@ static struct bpf_prog *generate_filter(int which, int *err) | |||
| 6233 | * checks. | 6275 | * checks. |
| 6234 | */ | 6276 | */ |
| 6235 | fp = bpf_prog_select_runtime(fp, err); | 6277 | fp = bpf_prog_select_runtime(fp, err); |
| 6278 | if (*err) { | ||
| 6279 | pr_cont("FAIL to select_runtime err=%d\n", *err); | ||
| 6280 | return NULL; | ||
| 6281 | } | ||
| 6236 | break; | 6282 | break; |
| 6237 | } | 6283 | } |
| 6238 | 6284 | ||
| @@ -6418,8 +6464,8 @@ static __init int test_bpf(void) | |||
| 6418 | pass_cnt++; | 6464 | pass_cnt++; |
| 6419 | continue; | 6465 | continue; |
| 6420 | } | 6466 | } |
| 6421 | 6467 | err_cnt++; | |
| 6422 | return err; | 6468 | continue; |
| 6423 | } | 6469 | } |
| 6424 | 6470 | ||
| 6425 | pr_cont("jited:%u ", fp->jited); | 6471 | pr_cont("jited:%u ", fp->jited); |
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/timerqueue.c b/lib/timerqueue.c index 4a720ed4fdaf..0d54bcbc8170 100644 --- a/lib/timerqueue.c +++ b/lib/timerqueue.c | |||
| @@ -33,8 +33,9 @@ | |||
| 33 | * @head: head of timerqueue | 33 | * @head: head of timerqueue |
| 34 | * @node: timer node to be added | 34 | * @node: timer node to be added |
| 35 | * | 35 | * |
| 36 | * Adds the timer node to the timerqueue, sorted by the | 36 | * Adds the timer node to the timerqueue, sorted by the node's expires |
| 37 | * node's expires value. | 37 | * value. Returns true if the newly added timer is the first expiring timer in |
| 38 | * the queue. | ||
| 38 | */ | 39 | */ |
| 39 | bool timerqueue_add(struct timerqueue_head *head, struct timerqueue_node *node) | 40 | bool timerqueue_add(struct timerqueue_head *head, struct timerqueue_node *node) |
| 40 | { | 41 | { |
| @@ -70,7 +71,8 @@ EXPORT_SYMBOL_GPL(timerqueue_add); | |||
| 70 | * @head: head of timerqueue | 71 | * @head: head of timerqueue |
| 71 | * @node: timer node to be removed | 72 | * @node: timer node to be removed |
| 72 | * | 73 | * |
| 73 | * Removes the timer node from the timerqueue. | 74 | * Removes the timer node from the timerqueue. Returns true if the queue is |
| 75 | * not empty after the remove. | ||
| 74 | */ | 76 | */ |
| 75 | bool timerqueue_del(struct timerqueue_head *head, struct timerqueue_node *node) | 77 | bool timerqueue_del(struct timerqueue_head *head, struct timerqueue_node *node) |
| 76 | { | 78 | { |
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 | /* |
