10

I am trying to write a simple application that can read msr registers, and am running this application from userspace.

I have loaded the msr module and given read permissions for everyone to /dev/cpu/*/msr. But still the user is not able to access these files but the root can.

The permissions look like this:

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

I keep getting "Operation not permitted" error message when I try to read these files from userspace but works fine when root tries to access them. What am I doing wrong? I am on Ubuntu 13.04 with kernel version 3.11.0.

overloading
  • 1,173
  • 4
  • 23
  • 44
futureishere
  • 201
  • 2
  • 4

3 Answers3

11

Changes in the mainline Linux kernel since around 3.7 now require an executable to have capability CAP_SYS_RAWIO to open the MSR device file [2]. Besides loading the MSR kernel module and setting the appropriate file permissions on the msr device file, one must grant the CAP_SYS_RAWIO capability to any user executable that needs access to the MSR driver, using the command below:

sudo setcap cap_sys_rawio=ep <user_executable>
BeeOnRope
  • 56,602
  • 14
  • 172
  • 343
PaulUTK
  • 111
  • 3
  • 1
    Thanks, I tried giving the CAP_SYS_RAWIO capability to executable like you suggested and still face the same problem! – futureishere Jan 26 '14 at 16:11
  • 1
    I tried setting this for rdmsr and wrmsr from msr-tools, but it didn't work for me. In my case they are called from a bash script. Could that be a problem? I have Secure Boot on, the MSR module is signed and loaded. My kernel is 4.18.0-16. – Bim Mar 07 '19 at 10:18
  • 1
    Thanks, it worked for me, both for a custom program (which reads the `/dev/cpu` files directly) and for the rdmsr utility, which I gave the permissions via: `sudo setcap cap_sys_rawio=ep \`which rdmsr\``. – BeeOnRope Jan 11 '20 at 23:45
4

For me (on debian) it helped to set the device permissions after loading the msr module. In addition to the answer of PaulUTK, as root:

setcap cap_sys_rawio=ep <user_executable>

Setting device permission (check before):

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

I added a group msr and assigned it. As root:

chgrp msr /dev/cpu/*/msr
chmod g+rw /dev/cpu/*/msr
ls -l /dev/cpu/*/msr
crw-rw---- ... /dev/cpu/0/msr

Assign the group to the user:

usermod -aG msr hardworkinguser

Bonus hint:

Apply the group as the hardworkinguser without relogin:

newgrp msr

I also heard secure boot must be disabled.

Benjamin Peter
  • 3,914
  • 2
  • 19
  • 23
-1

You can see 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;
}
Pang
  • 9,073
  • 146
  • 84
  • 117
leesagacious
  • 143
  • 1
  • 7