diff options
Diffstat (limited to 'lib/vsprintf.c')
-rw-r--r-- | lib/vsprintf.c | 35 |
1 files changed, 32 insertions, 3 deletions
diff --git a/lib/vsprintf.c b/lib/vsprintf.c index 26559bdb4c49..48586ac3a62e 100644 --- a/lib/vsprintf.c +++ b/lib/vsprintf.c | |||
@@ -27,6 +27,7 @@ | |||
27 | #include <linux/uaccess.h> | 27 | #include <linux/uaccess.h> |
28 | #include <linux/ioport.h> | 28 | #include <linux/ioport.h> |
29 | #include <linux/dcache.h> | 29 | #include <linux/dcache.h> |
30 | #include <linux/cred.h> | ||
30 | #include <net/addrconf.h> | 31 | #include <net/addrconf.h> |
31 | 32 | ||
32 | #include <asm/page.h> /* for PAGE_SIZE */ | 33 | #include <asm/page.h> /* for PAGE_SIZE */ |
@@ -1218,6 +1219,8 @@ int kptr_restrict __read_mostly; | |||
1218 | * The maximum supported length is 64 bytes of the input. Consider | 1219 | * The maximum supported length is 64 bytes of the input. Consider |
1219 | * to use print_hex_dump() for the larger input. | 1220 | * to use print_hex_dump() for the larger input. |
1220 | * - 'a' For a phys_addr_t type and its derivative types (passed by reference) | 1221 | * - 'a' For a phys_addr_t type and its derivative types (passed by reference) |
1222 | * - 'd[234]' For a dentry name (optionally 2-4 last components) | ||
1223 | * - 'D[234]' Same as 'd' but for a struct file | ||
1221 | * | 1224 | * |
1222 | * Note: The difference between 'S' and 'F' is that on ia64 and ppc64 | 1225 | * Note: The difference between 'S' and 'F' is that on ia64 and ppc64 |
1223 | * function pointers are really function descriptors, which contain a | 1226 | * function pointers are really function descriptors, which contain a |
@@ -1312,11 +1315,37 @@ char *pointer(const char *fmt, char *buf, char *end, void *ptr, | |||
1312 | spec.field_width = default_width; | 1315 | spec.field_width = default_width; |
1313 | return string(buf, end, "pK-error", spec); | 1316 | return string(buf, end, "pK-error", spec); |
1314 | } | 1317 | } |
1315 | if (!((kptr_restrict == 0) || | 1318 | |
1316 | (kptr_restrict == 1 && | 1319 | switch (kptr_restrict) { |
1317 | has_capability_noaudit(current, CAP_SYSLOG)))) | 1320 | case 0: |
1321 | /* Always print %pK values */ | ||
1322 | break; | ||
1323 | case 1: { | ||
1324 | /* | ||
1325 | * Only print the real pointer value if the current | ||
1326 | * process has CAP_SYSLOG and is running with the | ||
1327 | * same credentials it started with. This is because | ||
1328 | * access to files is checked at open() time, but %pK | ||
1329 | * checks permission at read() time. We don't want to | ||
1330 | * leak pointer values if a binary opens a file using | ||
1331 | * %pK and then elevates privileges before reading it. | ||
1332 | */ | ||
1333 | const struct cred *cred = current_cred(); | ||
1334 | |||
1335 | if (!has_capability_noaudit(current, CAP_SYSLOG) || | ||
1336 | !uid_eq(cred->euid, cred->uid) || | ||
1337 | !gid_eq(cred->egid, cred->gid)) | ||
1338 | ptr = NULL; | ||
1339 | break; | ||
1340 | } | ||
1341 | case 2: | ||
1342 | default: | ||
1343 | /* Always print 0's for %pK */ | ||
1318 | ptr = NULL; | 1344 | ptr = NULL; |
1345 | break; | ||
1346 | } | ||
1319 | break; | 1347 | break; |
1348 | |||
1320 | case 'N': | 1349 | case 'N': |
1321 | switch (fmt[1]) { | 1350 | switch (fmt[1]) { |
1322 | case 'F': | 1351 | case 'F': |