linux - Why a segfault instead of privilege instruction error? -


i trying execute privileged instruction rdmsr in user mode, , expect kind of privilege error, segfault instead. have checked asm , loading 0x186 ecx, supposed perfevtsel0, based on manual, page 1171.

what cause of segfault, , how can modify code below fix it?

i want resolve before hacking kernel module, because don't want segfault blow kernel.

update: running on 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 = 0;      cpu_zero(&cpuset);         cpu_set(i, &cpuset);         assert(sched_setaffinity(0, sizeof(cpuset), &cpuset) == 0);      printf("%lu\n", read_msr(c));     return 0; } 

the question try answer: why above code cause sigsegv instead of sigill, though code has no memory error, illegal instruction (a privileged instruction called non-privileged user pace)?


i expect sigill si_code ill_prvopc instead of segfault, too. question 3 years old , today, stumbled upon same behavior. disappointed :-(


what cause of segfault

the cause seems linux kernel code decides send sigsegv. here responsible function: http://elixir.free-electrons.com/linux/v4.9/source/arch/x86/kernel/traps.c#l487 have @ last line of function.

in your follow question, got list of other assembly instructions propagated sigsegv userspace though general protection faults. found question because triggered behavior cli.

and how can modify code below fix it?

as of linux kernel 4.9, i'm not aware of reliable way distinguish between memory error (what expect sigsegv) , privileged instruction error userspace.

there may hacky , unportable way distibguish these cases. when privileged instruction causes sigsegv, siginfo_t si_code set value illegal according man 2 sigaction. documented values segv_maperr, segv_accerr, segv_pkuerr, si_kernel (0x80) on system. in strace, see sigsegv {si_signo=sigsegv, si_code=si_kernel, si_addr=0}. responsible kernel code here.

it possible grep dmesg this string.

please, never ever use 2 methods distinguish between gpf , memory error on production system.

specific solution code: don't run rdmsr user space. answer unsatisfying if looking generic way figure out why program received sigsegv.


Comments

Popular posts from this blog

Android layout hidden on keyboard show -

google app engine - 403 Forbidden POST - Flask WTForms -

c - Why would PK11_GenerateRandom() return an error -8023? -