加入收藏 | 设为首页 | 会员中心 | 我要投稿 衡阳站长网 (https://www.0734zz.cn/)- 数据集成、设备管理、备份、数据加密、智能搜索!
当前位置: 首页 > 服务器 > 搭建环境 > Linux > 正文

linux – 为什么segfault而不是特权指令错误?

发布时间:2020-12-24 06:01:48 所属栏目:Linux 来源:网络整理
导读:我试图在用户模式下执行特权指令rdmsr,我希望得到某种特权错误,但我得到一个段错误.我已经检查了asm,我正在将0x186加载到ecx中,这应该是PERFEVTSEL0,基于 manual,第1171页. segfault的原因是什么,如何修改下面的代码来修复它? 我想在破解内核模块之前解决这

我试图在用户模式下执行特权指令rdmsr,我希望得到某种特权错误,但我得到一个段错误.我已经检查了asm,我正在将0x186加载到ecx中,这应该是PERFEVTSEL0,基于 manual,第1171页.

segfault的原因是什么,如何修改下面的代码来修复它?

我想在破解内核模块之前解决这个问题,因为我不希望这个段错误炸毁我的内核.

更新:我在Intel(R)Xeon(R)CPU X3470上运行.

#define _GNU_SOURCE

#include <stdio.h>
#include <stdlib.h>
#include <inttypes.h>

#include <sched.h>
#include <assert.h>

uint64_t
read_msr(int ecx)
{
    unsigned int a,d;
    __asm __volatile("rdmsr" : "=a"(a),"=d"(d) : "c"(ecx));
    return ((uint64_t)a) | (((uint64_t)d) << 32);
}

int main(int ac,char **av)
{
    uint64_t start,end;
    cpu_set_t cpuset;
    unsigned int c = 0x186;
    int i = 0;

    CPU_ZERO(&cpuset);
        CPU_SET(i,&cpuset);
        assert(sched_setaffinity(0,sizeof(cpuset),&cpuset) == 0);

    printf("%lun",read_msr(c));
    return 0;
}

解决方法

我将尝试回答的问题:为什么上面的代码导致SIGSEGV而不是SIGILL,虽然代码没有内存错误,但是非法指令(从非特权用户速度调用的特权指令)?

我希望得到一个带有si_code ILL_PRVOPC而不是段错误的SIGILL.你的问题目前是3岁,今天我偶然发现了同样的行为.我也很失望:-(

What is the cause of the segfault

原因似乎是Linux内核代码决定发送SIGSEGV.这是负责任的职能:
http://elixir.free-electrons.com/linux/v4.9/source/arch/x86/kernel/traps.c#L487
看看函数的最后一行.

在your follow up question中,您获得了其他汇编指令的列表,这些汇编指令作为SIGSEGV传播到用户空间,尽管它们实际上是一般性保护错误.我找到了你的问题,因为我用cli触发了这个行为.

and how can I modify the code below to fix it?

从Linux内核4.9开始,我不知道有任何可靠的方法可以区分内存错误(我希望是SIGSEGV)和来自用户空间的特权指令错误.

可能有非常黑客和不可移植的方式来解决这些案件.当特权指令导致SIGSEGV时,siginfo_t si_code被设置为一个值,该值不直接列在man 2 sigaction的SIGSEGV部分中.记录的值是SEGV_MAPERR,SEGV_ACCERR,SEGV_PKUERR,但我的系统上得到了SI_KERNEL(0x80).根据手册页,SI_KERNEL是一个代码“可以放在任何信号的si_code中”.在strace中,您会看到SIGSEGV {si_signo = SIGSEGV,si_code = SI_KERNEL,si_addr = 0}.负责的内核代码是here.

也可以为this字符串grep dmesg.

请永远不要使用这两种方法来区分生产系统上的GPF和内存错误.

代码的特定解决方案:只是不要从用户空间运行rdmsr.但是,如果您正在寻找一种通用的方法来弄清楚程序收到SIGSEGV的原因,那么这个答案实在令人不满意.

(编辑:衡阳站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    热点阅读