|
@@ -480,6 +480,7 @@ struct kallsym_iter {
|
|
|
char name[KSYM_NAME_LEN];
|
|
|
char module_name[MODULE_NAME_LEN];
|
|
|
int exported;
|
|
|
+ int show_value;
|
|
|
};
|
|
|
|
|
|
static int get_ksymbol_mod(struct kallsym_iter *iter)
|
|
@@ -580,14 +581,23 @@ static void s_stop(struct seq_file *m, void *p)
|
|
|
{
|
|
|
}
|
|
|
|
|
|
+#ifndef CONFIG_64BIT
|
|
|
+# define KALLSYM_FMT "%08lx"
|
|
|
+#else
|
|
|
+# define KALLSYM_FMT "%016lx"
|
|
|
+#endif
|
|
|
+
|
|
|
static int s_show(struct seq_file *m, void *p)
|
|
|
{
|
|
|
+ unsigned long value;
|
|
|
struct kallsym_iter *iter = m->private;
|
|
|
|
|
|
/* Some debugging symbols have no name. Ignore them. */
|
|
|
if (!iter->name[0])
|
|
|
return 0;
|
|
|
|
|
|
+ value = iter->show_value ? iter->value : 0;
|
|
|
+
|
|
|
if (iter->module_name[0]) {
|
|
|
char type;
|
|
|
|
|
@@ -597,10 +607,10 @@ static int s_show(struct seq_file *m, void *p)
|
|
|
*/
|
|
|
type = iter->exported ? toupper(iter->type) :
|
|
|
tolower(iter->type);
|
|
|
- seq_printf(m, "%pK %c %s\t[%s]\n", (void *)iter->value,
|
|
|
+ seq_printf(m, KALLSYM_FMT " %c %s\t[%s]\n", value,
|
|
|
type, iter->name, iter->module_name);
|
|
|
} else
|
|
|
- seq_printf(m, "%pK %c %s\n", (void *)iter->value,
|
|
|
+ seq_printf(m, KALLSYM_FMT " %c %s\n", value,
|
|
|
iter->type, iter->name);
|
|
|
return 0;
|
|
|
}
|
|
@@ -612,6 +622,40 @@ static const struct seq_operations kallsyms_op = {
|
|
|
.show = s_show
|
|
|
};
|
|
|
|
|
|
+static inline int kallsyms_for_perf(void)
|
|
|
+{
|
|
|
+#ifdef CONFIG_PERF_EVENTS
|
|
|
+ extern int sysctl_perf_event_paranoid;
|
|
|
+ if (sysctl_perf_event_paranoid <= 1)
|
|
|
+ return 1;
|
|
|
+#endif
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+/*
|
|
|
+ * We show kallsyms information even to normal users if we've enabled
|
|
|
+ * kernel profiling and are explicitly not paranoid (so kptr_restrict
|
|
|
+ * is clear, and sysctl_perf_event_paranoid isn't set).
|
|
|
+ *
|
|
|
+ * Otherwise, require CAP_SYSLOG (assuming kptr_restrict isn't set to
|
|
|
+ * block even that).
|
|
|
+ */
|
|
|
+static int kallsyms_show_value(void)
|
|
|
+{
|
|
|
+ switch (kptr_restrict) {
|
|
|
+ case 0:
|
|
|
+ if (kallsyms_for_perf())
|
|
|
+ return 1;
|
|
|
+ /* fallthrough */
|
|
|
+ case 1:
|
|
|
+ if (has_capability_noaudit(current, CAP_SYSLOG))
|
|
|
+ return 1;
|
|
|
+ /* fallthrough */
|
|
|
+ default:
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
static int kallsyms_open(struct inode *inode, struct file *file)
|
|
|
{
|
|
|
/*
|
|
@@ -625,6 +669,7 @@ static int kallsyms_open(struct inode *inode, struct file *file)
|
|
|
return -ENOMEM;
|
|
|
reset_iter(iter, 0);
|
|
|
|
|
|
+ iter->show_value = kallsyms_show_value();
|
|
|
return 0;
|
|
|
}
|
|
|
|