5

I have two places in a kernel module (Linux 3.13):

  1. One is module_init
  2. The other is code I hook with running an invalid opcode (by hacking interrupt description table).

My code is to enable hardware performance counter. When I put it in module_init, the code works fine. But when I put it to second place (triggered by running an instruction with an invalid opcode), the code gets a permission denied error (i.e. errno:-13).

Since both places are in a single kernel module, is it true that "even in kernel space, there are different privileges?"

Updates: something that is worth to mention is that when I run the invalid opcode as root in user space, the -13 errno is gone; otherwise, it stays...

I speculate that "the privilege of an instruction execution decides that of its interrupt handler's execution."

Richard
  • 14,642
  • 18
  • 56
  • 77
  • You always have [OS privelleges](http://en.wikipedia.org/wiki/Privilege_level) on a processor. Even in *kernel mode*; not everything is allowed. Otherwise you could easily take over control. – Willem Van Onsem Jun 08 '15 at 02:28
  • @CommuSoft: Does this explain the difference between his kernel code in `module_init` vs. his kernel code for the opcode trap? – Nemo Jun 08 '15 at 02:29
  • 2
    A [SSCCE](http://www.sscce.org/) would help a lot here, I think. – Nemo Jun 08 '15 at 02:30
  • @CommuSoft are you saying that the handler code (case 2 in OP) are running in kernel but with privilege other than ring 0? – Richard Jun 08 '15 at 02:30
  • 2
    Some kernel functions intentionaly check priveleges of the current user. For more detailed answer, update your post with a function `enable hardware counter` and a way of `hacking interrupt description table`. – Tsyvarev Jun 08 '15 at 09:25

1 Answers1

2

Because module_init and your hook code running in different process. And there are different privileges between different process.

Generally, code must running in a process.

module_init always running in the period of insmoding module(See the sys_init_module function). When you insmod a kernel module, you must be a root. And the process is root too. So it running well.

But when you put the code in the IDT, it may running in a user process since a user process trigger a interrupt. So it got a -EPERM.

You can check the euid, uid, pid and comm in your code. Like this:

int hook_func()
{
    printk(KERN_INFO"Code Called in hook_func. My pid: %d, comm: %s, uid: %d, euid: %d\n",
            current->tgid, current->comm, current->cred->uid, current->cred->euid);
    ...
}

int my_init()
{
    printk(KERN_INFO"Code Called in my_init. My pid: %d, comm: %s, uid: %d, euid: %d\n",
            current->tgid, current->comm, current->cred->uid, current->cred->euid);
    ...
}

module_init(my_init);
shuofei
  • 133
  • 7