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 | /* |
