aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/ashldi3.c2
-rw-r--r--lib/ashrdi3.c2
-rw-r--r--lib/asn1_decoder.c49
-rw-r--r--lib/cmpdi2.c2
-rw-r--r--lib/lshrdi3.c2
-rw-r--r--lib/muldi3.c2
-rw-r--r--lib/nlattr.c22
-rw-r--r--lib/oid_registry.c16
-rw-r--r--lib/test_printf.c108
-rw-r--r--lib/ucmpdi2.c2
-rw-r--r--lib/vsprintf.c194
11 files changed, 276 insertions, 125 deletions
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
21long long notrace __ashldi3(long long u, word_type b) 21long 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
21long long notrace __ashrdi3(long long u, word_type b) 21long 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
21word_type notrace __cmpdi2(long long a, long long b) 21word_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
22long long notrace __lshrdi3(long long u, word_type b) 22long 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 */
19static const u8 nla_attr_len[NLA_TYPE_MAX+1] = { 23static 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
30static const u8 nla_attr_minlen[NLA_TYPE_MAX+1] = { 34static 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
35static int validate_nla_bitfield32(const struct nlattr *nla, 47static 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
152bad:
153 snprintf(buffer, bufsize, "(bad)");
154 return -EBADMSG;
151} 155}
152EXPORT_SYMBOL_GPL(sprint_oid); 156EXPORT_SYMBOL_GPL(sprint_oid);
153 157
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
45static unsigned total_tests __initdata; 27static unsigned total_tests __initdata;
46static unsigned failed_tests __initdata; 28static unsigned failed_tests __initdata;
47static char *test_buffer __initdata; 29static 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
211static int __init
212plain_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
231static int __init
232plain_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
240static int __init
241plain_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 */
220static void __init 258static void __init
221plain(void) 259plain(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
246static void __init 277static void __init
@@ -251,6 +282,7 @@ symbol_ptr(void)
251static void __init 282static void __init
252kernel_ptr(void) 283kernel_ptr(void)
253{ 284{
285 /* We can't test this without access to kptr_restrict. */
254} 286}
255 287
256static void __init 288static 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
20word_type __ucmpdi2(unsigned long long a, unsigned long long b) 20word_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
1348int kptr_restrict __read_mostly;
1349
1350static noinline_for_stack
1351char *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
1346static noinline_for_stack 1401static noinline_for_stack
1347char *netdev_bits(char *buf, char *end, const void *addr, const char *fmt) 1402char *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
1594int kptr_restrict __read_mostly; 1649static noinline_for_stack
1650char *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
1663static bool have_filled_random_ptr_key __read_mostly;
1664static siphash_key_t ptr_key __read_mostly;
1665
1666static 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
1678static struct random_ready_callback random_ready = {
1679 .func = fill_random_ptr_key
1680};
1681
1682static 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}
1695early_initcall(initialize_ptr_random);
1696
1697/* Maps a pointer to a 32 bit unique identifier. */
1698static 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 */
1707static noinline_for_stack 1846static noinline_for_stack
1708char *pointer(const char *fmt, char *buf, char *end, void *ptr, 1847char *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/*