당신은 또한 인용는 POSIX 페이지의 섹션은 무엇 si-code
수단을 나열하고 여기에 의미가 있다는 :
신호에 의해 생성되지 않은 경우 : 섹션 말에 들어가
SI_QUEUE
The signal was sent by the sigqueue() function.
위의 , si_code
은 XBD에 설명 된 또는에 설명 된 신호 특정 값 중 하나에 중 하나를 설정해야합니다구현 정의 값 은 위의 값 중 하나와 같지 않습니다.
sigqueue()
함수 만 SI_QUEUE
을 사용하면 아무 것도 위반되지 않습니다. 당신의 시나리오는 을 사용하는 sigqueue()
함수가 아닌 코드를 포함합니다. 문제는 POSIX가 시스템 호출을하도록 허용 된 특정 라이브러리 함수 (POSIX 정의 라이브러리 함수가 아닌 일부 함수와 반대)를 실행하는 운영 체제를 계획하는지 여부입니다. 어떤 특징이 있습니다. 나는 대답이 "아니오"라고 생각한다. 2011-03-26의 같은
이
편집, 태평양 표준시 14시 : 페이지를하지 것이기 때문에
이 편집 8 시간 전부터 R ..의 코멘트에 대한 응답입니다 나는 적절하게 볼륨있는 코멘트를 남긴다 :
나는 당신이 기본적으로 옳다고 생각한다. 그러나 시스템이 POSIX 호환이거나 그렇지 않습니다. 비 라이브러리 함수가 uid, pid 및 'si_code'의 비 호환 조합을 초래하는 syscall을 수행하는 경우, 인용 한 두 번째 명령문은 호출 자체가 호환되지 않음을 분명히합니다. 하나는 이것을 두 가지 방식으로 해석 할 수 있습니다. 한 가지 방법은 다음과 같습니다. "사용자가이 규칙을 위반하면 시스템이 정책을 준수하지 않게됩니다." 하지만 당신 말이 맞아, 나는 바보 같아. 비 권유 사용자가 비 호환 사용자가 될 수있는 시스템이 무슨 소용입니까?필자가 보았 듯이이 수정은 시스템 호출을하는 라이브러리의 sigqueue()가 아니라는 것을 시스템에 알리기 위해 커널 자체가 'si_code'를 'SI_QUEUE'가 아닌 다른 것으로 설정해야합니다. uid와 pid를 설정합니다. 제 견해로, 여러분은 커널 사람들과 함께 이것을 제기해야합니다. 그러나 그들은 어려움을 겪을 수 있습니다. 특정 라이브러리 기능에 의해 시스템 호출이 생성되었는지 여부를 감지하여 라이브러리가 작동하는 방식을 확인하는 보안 방법을 모르겠습니다. 거의 정의상, 단지 syscall을 둘러싼 편의성 래퍼 일 뿐이다. 그리고 그것은 그들이 취하는 입장 일 수도 있습니다. 나는 실망 할 것입니다. 2011-03-26 18:00 PST 비 등
는
(부피) 편집 : 코멘트 길이
다시 때문에 제한.
이 게시물에 대한 답변은 R .. 님의 댓글 1 시간 전에 작성되었습니다.
저는 시스코 대상에게 조금 새로운 것이므로 제발 참아주십시오.
"커널 sysqueue
syscall"이란 말은`__NR_rt_sigqueueinfo '호출을 의미합니까? 즉, 단지 내가 이런 짓을 할 때 내가 찾은 하나 : 그런 경우
grep -Ri 'NR.*queue' /usr/include
, 내가 원래 점을 이해하지 못하는 것 같아요. 커널은 (루트가 아닌) SI-QUEUE
을 위조 된 pid와 uid로 오류없이 사용하게합니다.
#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() */
과 수신 측 따라서 코딩 : 나는 송신 측 따라서 코딩 한 경우
#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() */
나는 그 (루트가 아닌) 따라서 수신 측 실행할 수 있습니다
:
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$
을
그리고 전송 끝에서 다음을 참조하십시오 (루트가 아님) :
wally:~/tmp/20110326$ send 9023
wally:~/tmp/20110326$
보시다시피, 세 번째 이벤트는 pid 및 uid를 스푸핑했습니다. 당신이 원래 반대 한 것이 아닌가요? 시야에 EINVAL
또는 EPERM
이 없습니다. 나는 혼란 스러울 것 같아.
당신은 그 것처럼 보입니다. 아마도 리눅스 커널 메일 링리스트를 시도해야 할 것이다 : http://www.kernel.org/pub/linux/docs/lkml/ –