Esa sección de la página POSIX se cita también enumera lo si-code
medios, y aquí es el significado:
SI_QUEUE
The signal was sent by the sigqueue() function.
Esa sección pasa a decir:
Si la señal no fue generada por uno de las funciones o eventos enumerados anteriormente , si_code
se debe establecer a uno de los valores específicos de la señal descritos en XBD, oa valor definido en la implementación que es no igual a ninguno de los valores definidos arriba.
No se infringe nada si solo la función sigqueue()
usa SI_QUEUE
. Su escenario involucra código que no sea la función sigqueue()
usando SI_QUEUE
La pregunta es si POSIX visualiza un sistema operativo que impone que solo una función de biblioteca especificada (a diferencia de alguna función que no es una función de biblioteca definida POSIX) tenga permiso para realizar una llamada al sistema con ciertas características Creo que la respuesta es no".
EDITAR partir de 2011-03-26, 14:00 PST:
Esta edición es en respuesta a comentario de hace ocho horas R .. 's, ya que la página no dejaría me deja un comentario suficientemente voluminoso:
Creo que básicamente tienes razón. Pero o bien un sistema cumple con POSIX o no lo está. Si una función que no es de la biblioteca realiza un syscall que da como resultado una combinación no compatible de uid, pid y 'si_code', entonces la segunda declaración que cité deja en claro que la llamada en sí misma no es compatible. Uno puede interpretar esto de dos maneras. Una forma es: "Si un usuario rompe esta regla, entonces hace que el sistema no cumpla". Pero tienes razón, creo que es una tontería. ¿De qué sirve un sistema cuando cualquier usuario no privilegiado puede hacerlo no conforme?La solución, como yo lo veo, es de alguna manera hacer que el sistema sepa que no es la biblioteca 'sigqueue()' que hace la llamada al sistema, entonces el núcleo mismo debe establecer 'si_code' en algo que no sea 'SI_QUEUE', y dejar el uid y pid como los configuraste. En mi opinión, deberías plantear esto a la gente del kernel. Sin embargo, pueden tener dificultades; No conozco ninguna forma segura para que ellos detecten si un syscall está hecho por una función de biblioteca particular, viendo cómo funciona la biblioteca. casi por definición, son simplemente envoltorios de conveniencia alrededor de los syscalls. Y esa puede ser la posición que toman, y sé que será una desilusión.
(voluminoso) EDITAR como de 2011-03-26, 18:00 PST:
de nuevo debido a las limitaciones en longitud comentario.
Esto es en respuesta a R .. del comentario de hace una hora aproximadamente.
Soy un poco nuevo en el tema de syscall, así que por favor tengan paciencia conmigo.
Por "kernel sysqueue
syscall", ¿te refieres a la llamada `__NR_rt_sigqueueinfo '? Esa es la única que he encontrado cuando hice esto:
grep -Ri 'NR.*queue' /usr/include
Si ese es el caso, creo que no soy la comprensión de su punto original. El kernel permitirá que (no root) use SI-QUEUE
con un pid y un uid falsificados sin error. Si tengo el lado emisor codificado así:
#include <sys/syscall.h>
#include <sys/types.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main(int argc,
char **argv
)
{
long john_silver;
siginfo_t my_siginfo;
if(argc!=2)
{
fprintf(stderr,"missing pid argument\n");
exit(1);
}
john_silver=strtol(argv[1],NULL,0);
if(kill(john_silver,SIGUSR1))
{
fprintf(stderr,"kill() fail\n");
exit(1);
}
sleep(1);
my_siginfo.si_signo=SIGUSR1;
my_siginfo.si_code=SI_QUEUE;
my_siginfo.si_pid=getpid();
my_siginfo.si_uid=getuid();
my_siginfo.si_value.sival_int=41;
if(syscall(__NR_rt_sigqueueinfo,john_silver,SIGUSR1,&my_siginfo))
{
perror("syscall()");
exit(1);
}
sleep(1);
my_siginfo.si_signo=SIGUSR2;
my_siginfo.si_code=SI_QUEUE;
my_siginfo.si_pid=getpid()+1;
my_siginfo.si_uid=getuid()+1;
my_siginfo.si_value.sival_int=42;
if(syscall(__NR_rt_sigqueueinfo,john_silver,SIGUSR2,&my_siginfo))
{
perror("syscall()");
exit(1);
}
return 0;
} /* main() */
y el lado receptor codificado así:
#include <sys/types.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
int signaled_flag=0;
siginfo_t received_information;
void
my_handler(int signal_number,
siginfo_t *signal_information,
void *we_ignore_this
)
{
memmove(&received_information,
signal_information,
sizeof(received_information)
);
signaled_flag=1;
} /* my_handler() */
/*--------------------------------------------------------------------------*/
int
main(void)
{
pid_t myself;
struct sigaction the_action;
myself=getpid();
printf("signal receiver is process %d\n",myself);
the_action.sa_sigaction=my_handler;
sigemptyset(&the_action.sa_mask);
the_action.sa_flags=SA_SIGINFO;
if(sigaction(SIGUSR1,&the_action,NULL))
{
fprintf(stderr,"sigaction(SIGUSR1) fail\n");
exit(1);
}
if(sigaction(SIGUSR2,&the_action,NULL))
{
fprintf(stderr,"sigaction(SIGUSR2) fail\n");
exit(1);
}
for(;;)
{
while(!signaled_flag)
{
sleep(1);
}
printf("si_signo: %d\n",received_information.si_signo);
printf("si_pid : %d\n",received_information.si_pid );
printf("si_uid : %d\n",received_information.si_uid );
if(received_information.si_signo==SIGUSR2)
{
break;
}
signaled_flag=0;
}
return 0;
} /* main() */
A continuación, puedo correr (no root) el lado de recepción de este modo:
wally:~/tmp/20110326$ receive
signal receiver is process 9023
si_signo: 10
si_pid : 9055
si_uid : 4000
si_signo: 10
si_pid : 9055
si_uid : 4000
si_signo: 12
si_pid : 9056
si_uid : 4001
wally:~/tmp/20110326$
Y vea esto (no raíz) en el envío:
wally:~/tmp/20110326$ send 9023
wally:~/tmp/20110326$
Como puede ver, el tercer evento ha falsificado pid y uid. ¿No es eso a lo que originalmente te opusiste? No hay EINVAL
o EPERM
a la vista. Creo que estoy confundido
Parece que no le gustó SO. Tal vez deberías probar la lista de distribución del kernel de Linux: http://www.kernel.org/pub/linux/docs/lkml/ –