diff options
Diffstat (limited to 'lib/vsprintf.c')
-rw-r--r-- | lib/vsprintf.c | 194 |
1 files changed, 146 insertions, 48 deletions
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 | /* |