linux kptr_restrict使用

     在内核Documentation/sysctl/kernel.txt中对其使用有介绍,如下所示:

kptr_restrict:

This toggle indicates whether restrictions are placed on
exposing kernel addresses via /proc and other interfaces.

When kptr_restrict is set to 0 (the default) the address is hashed before
printing. (This is the equivalent to %p.)

When kptr_restrict is set to (1), kernel pointers printed using the %pK
format specifier will be replaced with 0's unless the user has CAP_SYSLOG
and effective user and group ids are equal to the real ids. This is
because %pK checks are done at read() time rather than open() time, so
if permissions are elevated between the open() and the read() (e.g via
a setuid binary) then %pK will not leak kernel pointers to unprivileged
users. Note, this is a temporary solution only. The correct long-term
solution is to do the permission checks at open() time. Consider removing
world read permissions from files that use %pK, and using dmesg_restrict
to protect against uses of %pK in dmesg(8) if leaking kernel pointer
values to unprivileged users is a concern.

When kptr_restrict is set to (2), kernel pointers printed using
%pK will be replaced with 0's regardless of privileges.

       简单来讲,变量kptr_restrict是可以用来限制内核地址的打印,当kptr_restrict=0时,会直接打印内核地址(%p和%pK效果一样);当kptr_restrict=1时,若在中断上下文或软中断时,%pK打印“pK-error”,否则内核地址打印全0;当kptr_restrict=2时,%pK打印内核地址为全0;而内核地址以%p打印时无论在什么情况下都会以HASH地址方式打印,而%pK可以通过 变量kptr_restrict隐藏内核地址,防止内核地址泄漏。

可以通过代码简单看出:

char *restricted_pointer(char *buf, char *end, const void *ptr,
             struct printf_spec spec)
{
    switch (kptr_restrict) {
    case 0:
        /* Handle as %p, hash and do _not_ leak addresses. */
        return ptr_to_id(buf, end, ptr, spec);   //直接打印内核地址HASH值
    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 = 2 * sizeof(ptr);
            return error_string(buf, end, "pK-error", spec);  //在中断上下文或软中断等处,打印“pK-error”
        }

        /*
         * 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;  //直接打印全0
        break;
    }
    case 2:
    default:
        /* Always print 0's for %pK */
        ptr = NULL;
        break;
    }

以下为以%pK打印内核地址:

在未修改时或kptr_restrict=0时,内核地址打印如下所示:

Euler:/home # ./test.sh                                                                                                             
disable begin 0                                                                                                                     
[  128.153235] hisi_sas_v3_hw 0000:74:02.0: erroneous completion iptt=4030 task=0000000021ed4560 dev id=1 CQ hdr: 0x1103 0x10fbe 0x0
 0x20000 Error info: 0x0 0x4000000 0x0 0x0                                                                                          
[  128.168481] sas: smp_execute_task_sg: task to dev 500e004aaaaaaa1f response: 0x0 status 0x2                                      
[  128.177189] sas: broadcast received: 0                                                                                           
[  128.180938] sas: REVALIDATING DOMAIN on port 0, pid:3519      

修改kptr_restrict=1时,内核地址打印如下所示:

  Euler:/home # ./test.sh                                                                                                             
disable begin 0                                                                                                                     
[  226.287150] hisi_sas_v3_hw 0000:74:02.0: erroneous completion iptt=4064 task=        pK-error dev id=1 CQ hdr: 0x1103 0x10fe0 0x0
 0x20000 Error info: 0x0 0x4000000 0x0 0x0                                                                                          
[  226.302395] sas: smp_execute_task_sg: task to dev 500e004aaaaaaa1f response: 0x0 status 0x2                                      
[  226.311106] sas: broadcast received: 0                                                                                           
[  226.314852] sas: REVALIDATING DOMAIN on port 0, pid:3519    

修改kptr_restrict=2时,内核地址打印如下所示:

Euler:/home # ./test.sh                                                                                                             
disable begin 0                                                                                                                     
[  506.507222] hisi_sas_v3_hw 0000:74:02.0: erroneous completion iptt=4041 task=0000000000000000 dev id=1 CQ hdr: 0x1103 0x10fc9 0x0
 0x20000 Error info: 0x0 0x4000000 0x0 0x0                                                                                          
[  506.522471] sas: smp_execute_task_sg: task to dev 500e004aaaaaaa1f response: 0x0 status 0x2                                      
[  506.531174] sas: broadcast received: 0                                                                                           
[  506.534918] sas: REVALIDATING DOMAIN on port 0, pid:3519  

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值