summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTobin C. Harding <me@tobin.cc>2017-11-22 18:59:45 -0500
committerTobin C. Harding <me@tobin.cc>2017-11-28 20:13:14 -0500
commit7b1924a1d930eb27fc79c4e4e2a6c1c970623e68 (patch)
treecdd958371ba49a69d64aae5df68ac0f181ba945d
parentad67b74d2469d9b82aaa572d76474c95bc484d57 (diff)
vsprintf: add printk specifier %px
printk specifier %p now hashes all addresses before printing. Sometimes we need to see the actual unmodified address. This can be achieved using %lx but then we face the risk that if in future we want to change the way the Kernel handles printing of pointers we will have to grep through the already existent 50 000 %lx call sites. Let's add specifier %px as a clear, opt-in, way to print a pointer and maintain some level of isolation from all the other hex integer output within the Kernel. Add printk specifier %px to print the actual unmodified address. Signed-off-by: Tobin C. Harding <me@tobin.cc>
-rw-r--r--Documentation/printk-formats.txt18
-rw-r--r--lib/vsprintf.c18
-rwxr-xr-xscripts/checkpatch.pl2
3 files changed, 36 insertions, 2 deletions
diff --git a/Documentation/printk-formats.txt b/Documentation/printk-formats.txt
index b4e668ac4fe3..aa0a776c817a 100644
--- a/Documentation/printk-formats.txt
+++ b/Documentation/printk-formats.txt
@@ -49,7 +49,8 @@ Pointer Types
49 49
50Pointers printed without a specifier extension (i.e unadorned %p) are 50Pointers printed without a specifier extension (i.e unadorned %p) are
51hashed to give a unique identifier without leaking kernel addresses to user 51hashed to give a unique identifier without leaking kernel addresses to user
52space. On 64 bit machines the first 32 bits are zeroed. 52space. On 64 bit machines the first 32 bits are zeroed. If you _really_
53want the address see %px below.
53 54
54:: 55::
55 56
@@ -106,6 +107,21 @@ For printing kernel pointers which should be hidden from unprivileged
106users. The behaviour of ``%pK`` depends on the ``kptr_restrict sysctl`` - see 107users. The behaviour of ``%pK`` depends on the ``kptr_restrict sysctl`` - see
107Documentation/sysctl/kernel.txt for more details. 108Documentation/sysctl/kernel.txt for more details.
108 109
110Unmodified Addresses
111====================
112
113::
114
115 %px 01234567 or 0123456789abcdef
116
117For printing pointers when you _really_ want to print the address. Please
118consider whether or not you are leaking sensitive information about the
119Kernel layout in memory before printing pointers with %px. %px is
120functionally equivalent to %lx. %px is preferred to %lx because it is more
121uniquely grep'able. If, in the future, we need to modify the way the Kernel
122handles printing pointers it will be nice to be able to find the call
123sites.
124
109Struct Resources 125Struct Resources
110================ 126================
111 127
diff --git a/lib/vsprintf.c b/lib/vsprintf.c
index d69452a0f2fa..d960aead0336 100644
--- a/lib/vsprintf.c
+++ b/lib/vsprintf.c
@@ -1646,6 +1646,20 @@ char *device_node_string(char *buf, char *end, struct device_node *dn,
1646 return widen_string(buf, buf - buf_start, end, spec); 1646 return widen_string(buf, buf - buf_start, end, spec);
1647} 1647}
1648 1648
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
1649static bool have_filled_random_ptr_key __read_mostly; 1663static bool have_filled_random_ptr_key __read_mostly;
1650static siphash_key_t ptr_key __read_mostly; 1664static siphash_key_t ptr_key __read_mostly;
1651 1665
@@ -1818,6 +1832,8 @@ static char *ptr_to_id(char *buf, char *end, void *ptr, struct printf_spec spec)
1818 * c major compatible string 1832 * c major compatible string
1819 * C full compatible string 1833 * C full compatible string
1820 * 1834 *
1835 * - 'x' For printing the address. Equivalent to "%lx".
1836 *
1821 * ** Please update also Documentation/printk-formats.txt when making changes ** 1837 * ** Please update also Documentation/printk-formats.txt when making changes **
1822 * 1838 *
1823 * 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
@@ -1940,6 +1956,8 @@ char *pointer(const char *fmt, char *buf, char *end, void *ptr,
1940 case 'F': 1956 case 'F':
1941 return device_node_string(buf, end, ptr, spec, fmt + 1); 1957 return device_node_string(buf, end, ptr, spec, fmt + 1);
1942 } 1958 }
1959 case 'x':
1960 return pointer_string(buf, end, ptr, spec);
1943 } 1961 }
1944 1962
1945 /* default is to _not_ leak addresses, hash before printing */ 1963 /* default is to _not_ leak addresses, hash before printing */
diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl
index 95cda3ecc66b..040aa79e1d9d 100755
--- a/scripts/checkpatch.pl
+++ b/scripts/checkpatch.pl
@@ -5753,7 +5753,7 @@ sub process {
5753 for (my $count = $linenr; $count <= $lc; $count++) { 5753 for (my $count = $linenr; $count <= $lc; $count++) {
5754 my $fmt = get_quoted_string($lines[$count - 1], raw_line($count, 0)); 5754 my $fmt = get_quoted_string($lines[$count - 1], raw_line($count, 0));
5755 $fmt =~ s/%%//g; 5755 $fmt =~ s/%%//g;
5756 if ($fmt =~ /(\%[\*\d\.]*p(?![\WFfSsBKRraEhMmIiUDdgVCbGNO]).)/) { 5756 if ($fmt =~ /(\%[\*\d\.]*p(?![\WFfSsBKRraEhMmIiUDdgVCbGNOx]).)/) {
5757 $bad_extension = $1; 5757 $bad_extension = $1;
5758 last; 5758 last;
5759 } 5759 }