|
@@ -1343,6 +1343,59 @@ char *uuid_string(char *buf, char *end, const u8 *addr,
|
|
|
return string(buf, end, uuid, spec);
|
|
|
}
|
|
|
|
|
|
+int kptr_restrict __read_mostly;
|
|
|
+
|
|
|
+static noinline_for_stack
|
|
|
+char *restricted_pointer(char *buf, char *end, const void *ptr,
|
|
|
+ struct printf_spec spec)
|
|
|
+{
|
|
|
+ spec.base = 16;
|
|
|
+ spec.flags |= SMALL;
|
|
|
+ if (spec.field_width == -1) {
|
|
|
+ spec.field_width = 2 * sizeof(ptr);
|
|
|
+ spec.flags |= ZEROPAD;
|
|
|
+ }
|
|
|
+
|
|
|
+ switch (kptr_restrict) {
|
|
|
+ case 0:
|
|
|
+ /* Always print %pK values */
|
|
|
+ break;
|
|
|
+ case 1: {
|
|
|
+ const struct cred *cred;
|
|
|
+
|
|
|
+ /*
|
|
|
+ * kptr_restrict==1 cannot be used in IRQ context
|
|
|
+ * because its test for CAP_SYSLOG would be meaningless.
|
|
|
+ */
|
|
|
+ if (in_irq() || in_serving_softirq() || in_nmi())
|
|
|
+ return string(buf, end, "pK-error", spec);
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Only print the real pointer value if the current
|
|
|
+ * process has CAP_SYSLOG and is running with the
|
|
|
+ * same credentials it started with. This is because
|
|
|
+ * access to files is checked at open() time, but %pK
|
|
|
+ * checks permission at read() time. We don't want to
|
|
|
+ * leak pointer values if a binary opens a file using
|
|
|
+ * %pK and then elevates privileges before reading it.
|
|
|
+ */
|
|
|
+ cred = current_cred();
|
|
|
+ if (!has_capability_noaudit(current, CAP_SYSLOG) ||
|
|
|
+ !uid_eq(cred->euid, cred->uid) ||
|
|
|
+ !gid_eq(cred->egid, cred->gid))
|
|
|
+ ptr = NULL;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ case 2:
|
|
|
+ default:
|
|
|
+ /* Always print 0's for %pK */
|
|
|
+ ptr = NULL;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ return number(buf, end, (unsigned long)ptr, spec);
|
|
|
+}
|
|
|
+
|
|
|
static noinline_for_stack
|
|
|
char *netdev_bits(char *buf, char *end, const void *addr, const char *fmt)
|
|
|
{
|
|
@@ -1591,8 +1644,6 @@ char *device_node_string(char *buf, char *end, struct device_node *dn,
|
|
|
return widen_string(buf, buf - buf_start, end, spec);
|
|
|
}
|
|
|
|
|
|
-int kptr_restrict __read_mostly;
|
|
|
-
|
|
|
/*
|
|
|
* Show a '%p' thing. A kernel extension is that the '%p' is followed
|
|
|
* by an extra set of alphanumeric characters that are extended format
|
|
@@ -1792,47 +1843,7 @@ char *pointer(const char *fmt, char *buf, char *end, void *ptr,
|
|
|
return buf;
|
|
|
}
|
|
|
case 'K':
|
|
|
- switch (kptr_restrict) {
|
|
|
- case 0:
|
|
|
- /* Always print %pK values */
|
|
|
- break;
|
|
|
- case 1: {
|
|
|
- const struct cred *cred;
|
|
|
-
|
|
|
- /*
|
|
|
- * kptr_restrict==1 cannot be used in IRQ context
|
|
|
- * because its test for CAP_SYSLOG would be meaningless.
|
|
|
- */
|
|
|
- if (in_irq() || in_serving_softirq() || in_nmi()) {
|
|
|
- if (spec.field_width == -1)
|
|
|
- spec.field_width = default_width;
|
|
|
- return string(buf, end, "pK-error", spec);
|
|
|
- }
|
|
|
-
|
|
|
- /*
|
|
|
- * Only print the real pointer value if the current
|
|
|
- * process has CAP_SYSLOG and is running with the
|
|
|
- * same credentials it started with. This is because
|
|
|
- * access to files is checked at open() time, but %pK
|
|
|
- * checks permission at read() time. We don't want to
|
|
|
- * leak pointer values if a binary opens a file using
|
|
|
- * %pK and then elevates privileges before reading it.
|
|
|
- */
|
|
|
- cred = current_cred();
|
|
|
- if (!has_capability_noaudit(current, CAP_SYSLOG) ||
|
|
|
- !uid_eq(cred->euid, cred->uid) ||
|
|
|
- !gid_eq(cred->egid, cred->gid))
|
|
|
- ptr = NULL;
|
|
|
- break;
|
|
|
- }
|
|
|
- case 2:
|
|
|
- default:
|
|
|
- /* Always print 0's for %pK */
|
|
|
- ptr = NULL;
|
|
|
- break;
|
|
|
- }
|
|
|
- break;
|
|
|
-
|
|
|
+ return restricted_pointer(buf, end, ptr, spec);
|
|
|
case 'N':
|
|
|
return netdev_bits(buf, end, ptr, fmt);
|
|
|
case 'a':
|