从用户空间读取/dev/cpu/*/msr:操作不允许。

10

我正在尝试编写一个简单的应用程序,可以从用户空间读取msr寄存器。

我已经加载了msr模块,并为每个人赋予了对/dev/cpu/*/msr的读取权限。但是用户仍然无法访问这些文件,只有root可以访问。

权限看起来像这样:

crw-r--r-- 1 root root 202, 0 sep  6 17:55 /dev/cpu/0/msr

crw-r--r-- 1 root root 202, 1 sep  6 17:55 /dev/cpu/1/msr

crw-r--r-- 1 root root 202, 2 sep  6 17:55 /dev/cpu/2/msr

crw-r--r-- 1 root root 202, 3 sep  6 17:55 /dev/cpu/3/msr

当我尝试从用户空间读取这些文件时,一直收到“操作不允许”的错误消息,但当root尝试访问它们时,却可以正常工作。我做错了什么?我使用的是内核版本为3.11.0的Ubuntu 13.04。


你用sudo运行了你的程序吗? - OneOfOne
4个回答

12

自从大约3.7以来,Linux主线内核的更改现在需要一个可执行文件具有能力CAP_SYS_RAWIO才能打开MSR设备文件[2]。除了加载MSR内核模块并设置msr设备文件的适当文件权限外,还必须使用以下命令将CAP_SYS_RAWIO功能授予需要访问MSR驱动程序的任何用户可执行文件:

sudo setcap cap_sys_rawio=ep <user_executable>

1
谢谢您的建议,我尝试将CAP_SYS_RAWIO功能赋予可执行文件,但仍然遇到同样的问题! - futureishere
1
我尝试使用msr-tools设置rdmsr和wrmsr,但对我没有起作用。在我的情况下,它们是从bash脚本中调用的。这可能是个问题吗?我启用了安全启动,MSR模块已签名并加载。我的内核版本是4.18.0-16。 - Bim
1
谢谢,这对我很有用,无论是对于一个自定义程序(直接读取/dev/cpu文件)还是对于rdmsr实用程序,我通过以下方式授予了权限:sudo setcap cap_sys_rawio=ep \which rdmsr``。 - BeeOnRope

5

对我而言(在Debian上),在加载msr模块后设置设备权限是有帮助的。除了PaulUTK的回答之外,以root用户身份执行以下操作:

setcap cap_sys_rawio=ep <user_executable>

设备权限设置(在进行操作之前进行检查):

ls -l /dev/cpu/*/msr
crw------- ... /dev/cpu/0/msr

我添加了一个名为msr的组,并对其进行了分配。以root身份执行:
chgrp msr /dev/cpu/*/msr
chmod g+rw /dev/cpu/*/msr
ls -l /dev/cpu/*/msr
crw-rw---- ... /dev/cpu/0/msr

将用户分配到组中:

usermod -aG msr hardworkinguser

额外提示:

将群组应用于“hardworkinguser”而无需重新登录:

newgrp msr

我也听说安全启动必须被禁用。


0

回应用户Benjamin Peter的答案中提到的以下内容:

我也听说必须禁用安全启动。

使用AlmaLinux 8.7和4.18.0-425.3.1.el8.x86_64内核时,即使启用了安全启动,也能够读取MSR。

read_smi_count.c是测试程序的代码。成功运行它以读取MSR_SMI_COUNT(0x34)寄存器。在构建程序后,以下是输出,提示需要执行什么操作才能让用户程序访问读取MSR寄存器:

[mr_halfword@skylake-alma release]$ read_smi_count/read_smi_count 
Error: No permission to open /dev/cpu/0/msr. Try:
sudo chmod o+r /dev/cpu/0/msr
[mr_halfword@skylake-alma release]$ sudo chmod o+r /dev/cpu/0/msr
[sudo] password for mr_halfword: 
[mr_halfword@skylake-alma release]$ read_smi_count/read_smi_count 
Error: No permission to open /dev/cpu/0/msr. Try:
sudo setcap cap_sys_rawio=ep read_smi_count/read_smi_count
[mr_halfword@skylake-alma release]$ sudo setcap cap_sys_rawio=ep read_smi_count/read_smi_count
[mr_halfword@skylake-alma release]$ read_smi_count/read_smi_count 
SMI COUNT = 15240

dmesg 的输出确认了由于启用了 EFI 安全启动,内核已被锁定:

mr_halfword@skylake-alma release]$ dmesg|grep lockdown
[    0.000000] Kernel is locked down from EFI secure boot; see man kernel_lockdown.7
[    1.578247] Lockdown: swapper/0: Hibernation is restricted; see man kernel_lockdown.7
[   37.750117] Lockdown: x86_energy_perf: Direct MSR access is restricted; see man kernel_lockdown.7

锁定模式为完整性

[mr_halfword@skylake-alma release]$ cat /sys/kernel/security/lockdown 
none [integrity]

上述输出未显示机密锁定模式选项。尚未调查机密模式是否会防止读取MSR寄存器。

Linux内核锁定、完整性和机密性指出,机密模式应用了额外的限制,以防止从内核中读取秘密


-1

您可以看到vfs_read:

ssize_t vfs_read(struct file *file, char __user *buf, size_t count, loff_t *pos)
{
    ret = rw_verify_area(READ, file, pos, count);
    if (ret >= 0) {
        ...
        if (file->f_op->read)  // your driver read .
            ret = file->f_op->read(file, buf, count, pos);
        else
            ret = do_sync_read(file, buf, count, pos);
        ....

    }
    // here,  if the ret is  13.  your error will be occur.
    return ret;
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接