Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge tag 'printk-hash-pointer-4.15-rc2' of git://github.com/tcharding/linux

Pull printk pointer hashing update from Tobin Harding:
"Here is the patch set that implements hashing of printk specifier %p.

First we have two clean up patches then we do the hashing. Hashing is
done via the SipHash algorithm. The next patch adds printk specifier
%px for printing pointers when we _really_ want to see the address i.e
%px is functionally equivalent to %lx. Final patch in the set fixes
KASAN since we break it by hashing %p.

For the record here is the justification for the series:

Currently there exist approximately 14 000 places in the Kernel
where addresses are being printed using an unadorned %p. This
potentially leaks sensitive information about the Kernel layout in
memory. Many of these calls are stale, instead of fixing every call
we hash the address by default before printing. We then add %px to
provide a way to print the actual address. Although this is
achievable using %lx, using %px will assist us if we ever want to
change pointer printing behaviour. %px is more uniquely grep'able
(there are already >50 000 uses of %lx).

The added advantage of hashing %p is that security is now opt-out,
if you _really_ want the address you have to work a little harder
and use %px.

This will of course break some users, forcing code printing needed
addresses to be updated"

[ I do expect this to be an annoyance, and a number of %px users to be
added for debuggability. But nobody is willing to audit existing %p
users for information leaks, and a number of places really only use
the pointer as an object identifier rather than really 'I need the
address'.

IOW - sorry for the inconvenience, but it's the least inconvenient of
the options. - Linus ]

* tag 'printk-hash-pointer-4.15-rc2' of git://github.com/tcharding/linux:
kasan: use %px to print addresses instead of %p
vsprintf: add printk specifier %px
printk: hash addresses printed with %p
vsprintf: refactor %pK code out of pointer()
docs: correct documentation for %pK

+248 -95
+28 -3
Documentation/printk-formats.txt
··· 5 5 :Author: Randy Dunlap <rdunlap@infradead.org> 6 6 :Author: Andrew Murray <amurray@mpc-data.co.uk> 7 7 8 - 9 8 Integer types 10 9 ============= 11 10 ··· 43 44 44 45 Raw pointer value SHOULD be printed with %p. The kernel supports 45 46 the following extended format specifiers for pointer types: 47 + 48 + Pointer Types 49 + ============= 50 + 51 + Pointers printed without a specifier extension (i.e unadorned %p) are 52 + hashed to give a unique identifier without leaking kernel addresses to user 53 + space. On 64 bit machines the first 32 bits are zeroed. If you _really_ 54 + want the address see %px below. 55 + 56 + :: 57 + 58 + %p abcdef12 or 00000000abcdef12 46 59 47 60 Symbols/Function Pointers 48 61 ========================= ··· 96 85 printk("Faulted at %pS\n", (void *)regs->ip); 97 86 printk(" %s%pB\n", (reliable ? "" : "? "), (void *)*stack); 98 87 99 - 100 88 Kernel Pointers 101 89 =============== 102 90 103 91 :: 104 92 105 - %pK 0x01234567 or 0x0123456789abcdef 93 + %pK 01234567 or 0123456789abcdef 106 94 107 95 For printing kernel pointers which should be hidden from unprivileged 108 96 users. The behaviour of ``%pK`` depends on the ``kptr_restrict sysctl`` - see 109 97 Documentation/sysctl/kernel.txt for more details. 98 + 99 + Unmodified Addresses 100 + ==================== 101 + 102 + :: 103 + 104 + %px 01234567 or 0123456789abcdef 105 + 106 + For printing pointers when you _really_ want to print the address. Please 107 + consider whether or not you are leaking sensitive information about the 108 + Kernel layout in memory before printing pointers with %px. %px is 109 + functionally equivalent to %lx. %px is preferred to %lx because it is more 110 + uniquely grep'able. If, in the future, we need to modify the way the Kernel 111 + handles printing pointers it will be nice to be able to find the call 112 + sites. 110 113 111 114 Struct Resources 112 115 ================
+70 -38
lib/test_printf.c
··· 24 24 #define PAD_SIZE 16 25 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 27 static unsigned total_tests __initdata; 46 28 static unsigned failed_tests __initdata; 47 29 static char *test_buffer __initdata; ··· 199 217 test("a | | ", "%-3.s|%-3.0s|%-3.*s", "a", "b", 0, "c"); 200 218 } 201 219 220 + #define PLAIN_BUF_SIZE 64 /* leave some space so we don't oops */ 221 + 222 + #if BITS_PER_LONG == 64 223 + 224 + #define PTR_WIDTH 16 225 + #define PTR ((void *)0xffff0123456789ab) 226 + #define PTR_STR "ffff0123456789ab" 227 + #define ZEROS "00000000" /* hex 32 zero bits */ 228 + 229 + static int __init 230 + plain_format(void) 231 + { 232 + char buf[PLAIN_BUF_SIZE]; 233 + int nchars; 234 + 235 + nchars = snprintf(buf, PLAIN_BUF_SIZE, "%p", PTR); 236 + 237 + if (nchars != PTR_WIDTH || strncmp(buf, ZEROS, strlen(ZEROS)) != 0) 238 + return -1; 239 + 240 + return 0; 241 + } 242 + 243 + #else 244 + 245 + #define PTR_WIDTH 8 246 + #define PTR ((void *)0x456789ab) 247 + #define PTR_STR "456789ab" 248 + 249 + static int __init 250 + plain_format(void) 251 + { 252 + /* Format is implicitly tested for 32 bit machines by plain_hash() */ 253 + return 0; 254 + } 255 + 256 + #endif /* BITS_PER_LONG == 64 */ 257 + 258 + static int __init 259 + plain_hash(void) 260 + { 261 + char buf[PLAIN_BUF_SIZE]; 262 + int nchars; 263 + 264 + nchars = snprintf(buf, PLAIN_BUF_SIZE, "%p", PTR); 265 + 266 + if (nchars != PTR_WIDTH || strncmp(buf, PTR_STR, PTR_WIDTH) == 0) 267 + return -1; 268 + 269 + return 0; 270 + } 271 + 272 + /* 273 + * We can't use test() to test %p because we don't know what output to expect 274 + * after an address is hashed. 275 + */ 202 276 static void __init 203 277 plain(void) 204 278 { 205 - test(PTR1_ZEROES PTR1_STR " " PTR2_STR, "%p %p", PTR1, PTR2); 206 - /* 207 - * The field width is overloaded for some %p extensions to 208 - * pass another piece of information. For plain pointers, the 209 - * behaviour is slightly odd: One cannot pass either the 0 210 - * flag nor a precision to %p without gcc complaining, and if 211 - * one explicitly gives a field width, the number is no longer 212 - * zero-padded. 213 - */ 214 - test("|" PTR1_STR PTR1_SPACES " | " PTR1_SPACES PTR1_STR "|", 215 - "|%-*p|%*p|", PTR_WIDTH+2, PTR1, PTR_WIDTH+2, PTR1); 216 - test("|" PTR2_STR " | " PTR2_STR "|", 217 - "|%-*p|%*p|", PTR_WIDTH+2, PTR2, PTR_WIDTH+2, PTR2); 279 + int err; 218 280 219 - /* 220 - * Unrecognized %p extensions are treated as plain %p, but the 221 - * alphanumeric suffix is ignored (that is, does not occur in 222 - * the output.) 223 - */ 224 - test("|"PTR1_ZEROES PTR1_STR"|", "|%p0y|", PTR1); 225 - test("|"PTR2_STR"|", "|%p0y|", PTR2); 281 + err = plain_hash(); 282 + if (err) { 283 + pr_warn("plain 'p' does not appear to be hashed\n"); 284 + failed_tests++; 285 + return; 286 + } 287 + 288 + err = plain_format(); 289 + if (err) { 290 + pr_warn("hashing plain 'p' has unexpected format\n"); 291 + failed_tests++; 292 + } 226 293 } 227 294 228 295 static void __init ··· 282 251 static void __init 283 252 kernel_ptr(void) 284 253 { 254 + /* We can't test this without access to kptr_restrict. */ 285 255 } 286 256 287 257 static void __init
+145 -49
lib/vsprintf.c
··· 33 33 #include <linux/uuid.h> 34 34 #include <linux/of.h> 35 35 #include <net/addrconf.h> 36 + #include <linux/siphash.h> 37 + #include <linux/compiler.h> 36 38 #ifdef CONFIG_BLOCK 37 39 #include <linux/blkdev.h> 38 40 #endif ··· 1345 1343 return string(buf, end, uuid, spec); 1346 1344 } 1347 1345 1346 + int kptr_restrict __read_mostly; 1347 + 1348 + static noinline_for_stack 1349 + char *restricted_pointer(char *buf, char *end, const void *ptr, 1350 + struct printf_spec spec) 1351 + { 1352 + spec.base = 16; 1353 + spec.flags |= SMALL; 1354 + if (spec.field_width == -1) { 1355 + spec.field_width = 2 * sizeof(ptr); 1356 + spec.flags |= ZEROPAD; 1357 + } 1358 + 1359 + switch (kptr_restrict) { 1360 + case 0: 1361 + /* Always print %pK values */ 1362 + break; 1363 + case 1: { 1364 + const struct cred *cred; 1365 + 1366 + /* 1367 + * kptr_restrict==1 cannot be used in IRQ context 1368 + * because its test for CAP_SYSLOG would be meaningless. 1369 + */ 1370 + if (in_irq() || in_serving_softirq() || in_nmi()) 1371 + return string(buf, end, "pK-error", spec); 1372 + 1373 + /* 1374 + * Only print the real pointer value if the current 1375 + * process has CAP_SYSLOG and is running with the 1376 + * same credentials it started with. This is because 1377 + * access to files is checked at open() time, but %pK 1378 + * checks permission at read() time. We don't want to 1379 + * leak pointer values if a binary opens a file using 1380 + * %pK and then elevates privileges before reading it. 1381 + */ 1382 + cred = current_cred(); 1383 + if (!has_capability_noaudit(current, CAP_SYSLOG) || 1384 + !uid_eq(cred->euid, cred->uid) || 1385 + !gid_eq(cred->egid, cred->gid)) 1386 + ptr = NULL; 1387 + break; 1388 + } 1389 + case 2: 1390 + default: 1391 + /* Always print 0's for %pK */ 1392 + ptr = NULL; 1393 + break; 1394 + } 1395 + 1396 + return number(buf, end, (unsigned long)ptr, spec); 1397 + } 1398 + 1348 1399 static noinline_for_stack 1349 1400 char *netdev_bits(char *buf, char *end, const void *addr, const char *fmt) 1350 1401 { ··· 1646 1591 return widen_string(buf, buf - buf_start, end, spec); 1647 1592 } 1648 1593 1649 - int kptr_restrict __read_mostly; 1594 + static noinline_for_stack 1595 + char *pointer_string(char *buf, char *end, const void *ptr, 1596 + struct printf_spec spec) 1597 + { 1598 + spec.base = 16; 1599 + spec.flags |= SMALL; 1600 + if (spec.field_width == -1) { 1601 + spec.field_width = 2 * sizeof(ptr); 1602 + spec.flags |= ZEROPAD; 1603 + } 1604 + 1605 + return number(buf, end, (unsigned long int)ptr, spec); 1606 + } 1607 + 1608 + static bool have_filled_random_ptr_key __read_mostly; 1609 + static siphash_key_t ptr_key __read_mostly; 1610 + 1611 + static void fill_random_ptr_key(struct random_ready_callback *unused) 1612 + { 1613 + get_random_bytes(&ptr_key, sizeof(ptr_key)); 1614 + /* 1615 + * have_filled_random_ptr_key==true is dependent on get_random_bytes(). 1616 + * ptr_to_id() needs to see have_filled_random_ptr_key==true 1617 + * after get_random_bytes() returns. 1618 + */ 1619 + smp_mb(); 1620 + WRITE_ONCE(have_filled_random_ptr_key, true); 1621 + } 1622 + 1623 + static struct random_ready_callback random_ready = { 1624 + .func = fill_random_ptr_key 1625 + }; 1626 + 1627 + static int __init initialize_ptr_random(void) 1628 + { 1629 + int ret = add_random_ready_callback(&random_ready); 1630 + 1631 + if (!ret) { 1632 + return 0; 1633 + } else if (ret == -EALREADY) { 1634 + fill_random_ptr_key(&random_ready); 1635 + return 0; 1636 + } 1637 + 1638 + return ret; 1639 + } 1640 + early_initcall(initialize_ptr_random); 1641 + 1642 + /* Maps a pointer to a 32 bit unique identifier. */ 1643 + static char *ptr_to_id(char *buf, char *end, void *ptr, struct printf_spec spec) 1644 + { 1645 + unsigned long hashval; 1646 + const int default_width = 2 * sizeof(ptr); 1647 + 1648 + if (unlikely(!have_filled_random_ptr_key)) { 1649 + spec.field_width = default_width; 1650 + /* string length must be less than default_width */ 1651 + return string(buf, end, "(ptrval)", spec); 1652 + } 1653 + 1654 + #ifdef CONFIG_64BIT 1655 + hashval = (unsigned long)siphash_1u64((u64)ptr, &ptr_key); 1656 + /* 1657 + * Mask off the first 32 bits, this makes explicit that we have 1658 + * modified the address (and 32 bits is plenty for a unique ID). 1659 + */ 1660 + hashval = hashval & 0xffffffff; 1661 + #else 1662 + hashval = (unsigned long)siphash_1u32((u32)ptr, &ptr_key); 1663 + #endif 1664 + 1665 + spec.flags |= SMALL; 1666 + if (spec.field_width == -1) { 1667 + spec.field_width = default_width; 1668 + spec.flags |= ZEROPAD; 1669 + } 1670 + spec.base = 16; 1671 + 1672 + return number(buf, end, hashval, spec); 1673 + } 1650 1674 1651 1675 /* 1652 1676 * Show a '%p' thing. A kernel extension is that the '%p' is followed ··· 1832 1698 * c major compatible string 1833 1699 * C full compatible string 1834 1700 * 1701 + * - 'x' For printing the address. Equivalent to "%lx". 1702 + * 1835 1703 * ** Please update also Documentation/printk-formats.txt when making changes ** 1836 1704 * 1837 1705 * Note: The difference between 'S' and 'F' is that on ia64 and ppc64 1838 1706 * function pointers are really function descriptors, which contain a 1839 1707 * pointer to the real address. 1708 + * 1709 + * Note: The default behaviour (unadorned %p) is to hash the address, 1710 + * rendering it useful as a unique identifier. 1840 1711 */ 1841 1712 static noinline_for_stack 1842 1713 char *pointer(const char *fmt, char *buf, char *end, void *ptr, ··· 1931 1792 return buf; 1932 1793 } 1933 1794 case 'K': 1934 - switch (kptr_restrict) { 1935 - case 0: 1936 - /* Always print %pK values */ 1937 - break; 1938 - case 1: { 1939 - const struct cred *cred; 1940 - 1941 - /* 1942 - * kptr_restrict==1 cannot be used in IRQ context 1943 - * because its test for CAP_SYSLOG would be meaningless. 1944 - */ 1945 - if (in_irq() || in_serving_softirq() || in_nmi()) { 1946 - if (spec.field_width == -1) 1947 - spec.field_width = default_width; 1948 - return string(buf, end, "pK-error", spec); 1949 - } 1950 - 1951 - /* 1952 - * Only print the real pointer value if the current 1953 - * process has CAP_SYSLOG and is running with the 1954 - * same credentials it started with. This is because 1955 - * access to files is checked at open() time, but %pK 1956 - * checks permission at read() time. We don't want to 1957 - * leak pointer values if a binary opens a file using 1958 - * %pK and then elevates privileges before reading it. 1959 - */ 1960 - cred = current_cred(); 1961 - if (!has_capability_noaudit(current, CAP_SYSLOG) || 1962 - !uid_eq(cred->euid, cred->uid) || 1963 - !gid_eq(cred->egid, cred->gid)) 1964 - ptr = NULL; 1965 - break; 1966 - } 1967 - case 2: 1968 - default: 1969 - /* Always print 0's for %pK */ 1970 - ptr = NULL; 1971 - break; 1972 - } 1973 - break; 1974 - 1795 + return restricted_pointer(buf, end, ptr, spec); 1975 1796 case 'N': 1976 1797 return netdev_bits(buf, end, ptr, fmt); 1977 1798 case 'a': ··· 1956 1857 case 'F': 1957 1858 return device_node_string(buf, end, ptr, spec, fmt + 1); 1958 1859 } 1860 + case 'x': 1861 + return pointer_string(buf, end, ptr, spec); 1959 1862 } 1960 - spec.flags |= SMALL; 1961 - if (spec.field_width == -1) { 1962 - spec.field_width = default_width; 1963 - spec.flags |= ZEROPAD; 1964 - } 1965 - spec.base = 16; 1966 1863 1967 - return number(buf, end, (unsigned long) ptr, spec); 1864 + /* default is to _not_ leak addresses, hash before printing */ 1865 + return ptr_to_id(buf, end, ptr, spec); 1968 1866 } 1969 1867 1970 1868 /*
+4 -4
mm/kasan/report.c
··· 134 134 135 135 pr_err("BUG: KASAN: %s in %pS\n", 136 136 bug_type, (void *)info->ip); 137 - pr_err("%s of size %zu at addr %p by task %s/%d\n", 137 + pr_err("%s of size %zu at addr %px by task %s/%d\n", 138 138 info->is_write ? "Write" : "Read", info->access_size, 139 139 info->access_addr, current->comm, task_pid_nr(current)); 140 140 } ··· 206 206 const char *rel_type; 207 207 int rel_bytes; 208 208 209 - pr_err("The buggy address belongs to the object at %p\n" 209 + pr_err("The buggy address belongs to the object at %px\n" 210 210 " which belongs to the cache %s of size %d\n", 211 211 object, cache->name, cache->object_size); 212 212 ··· 225 225 } 226 226 227 227 pr_err("The buggy address is located %d bytes %s of\n" 228 - " %d-byte region [%p, %p)\n", 228 + " %d-byte region [%px, %px)\n", 229 229 rel_bytes, rel_type, cache->object_size, (void *)object_addr, 230 230 (void *)(object_addr + cache->object_size)); 231 231 } ··· 302 302 char shadow_buf[SHADOW_BYTES_PER_ROW]; 303 303 304 304 snprintf(buffer, sizeof(buffer), 305 - (i == 0) ? ">%p: " : " %p: ", kaddr); 305 + (i == 0) ? ">%px: " : " %px: ", kaddr); 306 306 /* 307 307 * We should not pass a shadow pointer to generic 308 308 * function, because generic functions may try to
+1 -1
scripts/checkpatch.pl
··· 5753 5753 for (my $count = $linenr; $count <= $lc; $count++) { 5754 5754 my $fmt = get_quoted_string($lines[$count - 1], raw_line($count, 0)); 5755 5755 $fmt =~ s/%%//g; 5756 - if ($fmt =~ /(\%[\*\d\.]*p(?![\WFfSsBKRraEhMmIiUDdgVCbGNO]).)/) { 5756 + if ($fmt =~ /(\%[\*\d\.]*p(?![\WFfSsBKRraEhMmIiUDdgVCbGNOx]).)/) { 5757 5757 $bad_extension = $1; 5758 5758 last; 5759 5759 }