aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--kernel/kallsyms.c49
1 files changed, 47 insertions, 2 deletions
diff --git a/kernel/kallsyms.c b/kernel/kallsyms.c
index 127e7cfafa55..51b49ed452e4 100644
--- a/kernel/kallsyms.c
+++ b/kernel/kallsyms.c
@@ -480,6 +480,7 @@ struct kallsym_iter {
480 char name[KSYM_NAME_LEN]; 480 char name[KSYM_NAME_LEN];
481 char module_name[MODULE_NAME_LEN]; 481 char module_name[MODULE_NAME_LEN];
482 int exported; 482 int exported;
483 int show_value;
483}; 484};
484 485
485static int get_ksymbol_mod(struct kallsym_iter *iter) 486static int get_ksymbol_mod(struct kallsym_iter *iter)
@@ -580,14 +581,23 @@ static void s_stop(struct seq_file *m, void *p)
580{ 581{
581} 582}
582 583
584#ifndef CONFIG_64BIT
585# define KALLSYM_FMT "%08lx"
586#else
587# define KALLSYM_FMT "%016lx"
588#endif
589
583static int s_show(struct seq_file *m, void *p) 590static int s_show(struct seq_file *m, void *p)
584{ 591{
592 unsigned long value;
585 struct kallsym_iter *iter = m->private; 593 struct kallsym_iter *iter = m->private;
586 594
587 /* Some debugging symbols have no name. Ignore them. */ 595 /* Some debugging symbols have no name. Ignore them. */
588 if (!iter->name[0]) 596 if (!iter->name[0])
589 return 0; 597 return 0;
590 598
599 value = iter->show_value ? iter->value : 0;
600
591 if (iter->module_name[0]) { 601 if (iter->module_name[0]) {
592 char type; 602 char type;
593 603
@@ -597,10 +607,10 @@ static int s_show(struct seq_file *m, void *p)
597 */ 607 */
598 type = iter->exported ? toupper(iter->type) : 608 type = iter->exported ? toupper(iter->type) :
599 tolower(iter->type); 609 tolower(iter->type);
600 seq_printf(m, "%pK %c %s\t[%s]\n", (void *)iter->value, 610 seq_printf(m, KALLSYM_FMT " %c %s\t[%s]\n", value,
601 type, iter->name, iter->module_name); 611 type, iter->name, iter->module_name);
602 } else 612 } else
603 seq_printf(m, "%pK %c %s\n", (void *)iter->value, 613 seq_printf(m, KALLSYM_FMT " %c %s\n", value,
604 iter->type, iter->name); 614 iter->type, iter->name);
605 return 0; 615 return 0;
606} 616}
@@ -612,6 +622,40 @@ static const struct seq_operations kallsyms_op = {
612 .show = s_show 622 .show = s_show
613}; 623};
614 624
625static inline int kallsyms_for_perf(void)
626{
627#ifdef CONFIG_PERF_EVENTS
628 extern int sysctl_perf_event_paranoid;
629 if (sysctl_perf_event_paranoid <= 1)
630 return 1;
631#endif
632 return 0;
633}
634
635/*
636 * We show kallsyms information even to normal users if we've enabled
637 * kernel profiling and are explicitly not paranoid (so kptr_restrict
638 * is clear, and sysctl_perf_event_paranoid isn't set).
639 *
640 * Otherwise, require CAP_SYSLOG (assuming kptr_restrict isn't set to
641 * block even that).
642 */
643static int kallsyms_show_value(void)
644{
645 switch (kptr_restrict) {
646 case 0:
647 if (kallsyms_for_perf())
648 return 1;
649 /* fallthrough */
650 case 1:
651 if (has_capability_noaudit(current, CAP_SYSLOG))
652 return 1;
653 /* fallthrough */
654 default:
655 return 0;
656 }
657}
658
615static int kallsyms_open(struct inode *inode, struct file *file) 659static int kallsyms_open(struct inode *inode, struct file *file)
616{ 660{
617 /* 661 /*
@@ -625,6 +669,7 @@ static int kallsyms_open(struct inode *inode, struct file *file)
625 return -ENOMEM; 669 return -ENOMEM;
626 reset_iter(iter, 0); 670 reset_iter(iter, 0);
627 671
672 iter->show_value = kallsyms_show_value();
628 return 0; 673 return 0;
629} 674}
630 675