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.