通过 kptr_restrict 来控制/proc/kallsyms 是否显示symbol的地址
例如这个值是1的时候就可以显示symbol
linux-7gzn:~ # cat /proc/sys/kernel/kptr_restrict
1
linux-7gzn:~ # cat /proc/kallsyms
ffff000008080000 t _head
ffff000008080000 T _text
ffff000008080040 t pe_header
ffff000008080044 t coff_header
ffff000008080058 t optional_header
如果把这个值写成2,就可以看到symbol的地址都是零
linux-7gzn:~ # echo 2 > /proc/sys/kernel/kptr_restrict
linux-7gzn:~ # cat /proc/sys/kernel/kptr_restrict
2
linux-7gzn:~ # cat /proc/kallsyms
0000000000000000 t _head
0000000000000000 T _text
0000000000000000 t pe_header
0000000000000000 t coff_header
0000000000000000 t optional_header
0000000000000000 t extra_header_fie
为什么会这样呢?还得从kallsyms.c的源代码中找线索
static int s_show(struct seq_file *m, void *p)
{
struct kallsym_iter *iter = m->private;
/* Some debugging symbols have no name. Ignore them. */
if (!iter->name[0])
return 0;
if (iter->module_name[0]) {
char type;
/*
* Label it "global" if it is exported,
* "local" if not exported.
*/
type = iter->exported ? toupper(iter->type) :
tolower(iter->type);
#关键一句,看起来应该是%pK 来控制是否显示地址
seq_printf(m, "%pK %c %s\t[%s]\n", (void *)iter->value,
type, iter->name, iter->module_name);
} else
seq_printf(m, "%pK %c %s\n", (void *)iter->value,
iter->type, iter->name);
return 0;
}
%pK的实现在 lib/vsprintf.c 中
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;
原来kptr_restrict 的取值范围为0,1,2.值是2的话,地址就是2,就如我们前面演示的那样,地址全部显示0.一般情况这个值是1,表示root和非root
用户都可以查看
kptr_restrict 来控制/proc/kallsyms 是否显示symbol的地址
最新推荐文章于 2023-04-05 09:05:07 发布