tagger tag mp3tag mac kid3 editar easytag linux assembly x86-64 system-calls

mp3tag - tag editor linux



Error de acceso a memoria sys_rt_sigaction(controlador de seƱal) (1)

Siguiendo este artículo de Interfase de Señales de Linux , he estado tratando de usar sys_rt_sigaction en amd64 , pero siempre obtengo un error de acceso a la memoria cuando envío la señal. struct sigaction funciona cuando se usa la función C / C ++ sigaction .

¿Qué hay de malo en la llamada sys_rt_sigaction ?

C / C ++ con código ASM:

#include<signal.h> #include<stdio.h> #include<time.h> void handler(int){printf("handler/n");} void restorer(){asm volatile("mov $15,%%rax/nsyscall":::"rax");} struct sigaction act{handler}; timespec ts{10,0}; int main(){ act.sa_flags=0x04000000; act.sa_restorer=&restorer; //* asm volatile("/ mov $13,%%rax/n/ mov %0,%%rdi/n/ mov %1,%%rsi/n/ mov %2,%%rdx/n/ mov $8,%%r10/n/ syscall/n/ mov %%rax,%%rdi/n/ mov $60,%%rax/n/ #syscall/n/ "::"i"(7),"p"(&act),"p"(0):"rax","rdi","rsi","rdx","r10"); /**/ /* sigaction(7,&act,0); /**/ nanosleep(&ts,0); }

Compilar

g++ -o bin -std=c++11 g++ -o bin -std=c++11 -no-pie

Enviar señal

kill -7 `pidof bin`


En x86-64 linux, es obligatorio suministrar un sa_restorer y no lo ha hecho.

La parte relevante de la fuente del kernel :

/* x86-64 should always use SA_RESTORER. */ if (ksig->ka.sa.sa_flags & SA_RESTORER) { put_user_ex(ksig->ka.sa.sa_restorer, &frame->pretcode); } else { /* could use a vstub here */ err |= -EFAULT; }

El contenedor de la biblioteca C hace esto por usted:

kact.sa_flags = act->sa_flags | SA_RESTORER; kact.sa_restorer = &restore_rt;

Con el código actualizado, sí tiene un restaurador, pero tiene dos problemas: está roto y lo pasa mal. Si observa la fuente de la biblioteca C mencionada anteriormente, puede encontrar este comentario :

/* The difference here is that the sigaction structure used in the kernel is not the same as we use in the libc. Therefore we must translate it here. */

Además, no puede tener una función de C ++ como restaurador debido al prólogo de la función. Además, no se admite la invocación de printf desde un controlador de señal (pero funciona aquí). Finalmente, como señaló David Wohlferd, tus problemas están equivocados. Con todo, la siguiente podría ser una versión revisada:

#include<stdio.h> #include<unistd.h> #include<time.h> void handler(int){ const char msg[] = "handler/n"; write(0, msg, sizeof(msg)); } extern "C" void restorer(); asm volatile("restorer:mov $15,%rax/nsyscall"); struct kernel_sigaction { void (*k_sa_handler) (int); unsigned long sa_flags; void (*sa_restorer) (void); unsigned long sa_mask; }; struct kernel_sigaction act{handler}; timespec ts{10,0}; int main(){ act.sa_flags=0x04000000; act.sa_restorer=&restorer; asm volatile("/ mov $13,%%rax/n/ mov %0,%%rdi/n/ mov %1,%%rsi/n/ mov %2,%%rdx/n/ mov $8,%%r10/n/ syscall/n/ "::"i"(7),"p"(&act),"p"(0):"rax","rcx", "rdi","rsi","rdx","r8", "r9", "r10", "r11"); nanosleep(&ts,0); }

Sigue siendo hacky, y realmente no deberías estar haciéndolo de esta manera, obviamente.