어떤 사용자가 종료 신호를 보냈는지 캡처

어떤 사용자가 종료 신호를 보냈는지 캡처

관리자 권한이 있는 다른 사용자가 해당 스크립트를 사용하려고 하는 동안 최대 절전 모드로 전환되는 스크립트를 실행하고 있다고 가정해 보겠습니다 pkill. 가능하다면 해당 신호를 내 프로세스에 보낸 사용자를 어떻게 캡처할 수 있습니까?

kill -9 <my_script>SIGKILL로는 아무 것도 캡처하거나 수행할 수 없기 때문에 이와 같은 기능으로는 아무것도 캡처할 수 없다는 것을 알고 있습니다 .

답변1

예, 가능합니다. 비록 스크립트에서는 아닐 수도 있습니다. 이렇게 하려면 다음을 사용하여 신호 처리기를 설정해야 합니다.sigaction플래그를 사용 SA_SIGINFO하고 동일한 서명된 핸들러를 제공합니다.

void handler(int sig, siginfo_t *info, void *ucontext)

신호를 처리하기 위해 호출될 때 두 번째 인수로 받는 포인터에는 siginfo_t송신 프로세스의 프로세스 식별자( ) 및 송신 프로세스의 읽기 사용자 식별자( )와 같은 정보가 포함됩니다. 전송된 신호를 사용하기 위해 채워집니다.info->si_pidinfo->si_uidkill또는sigqueue.

이것을 Python으로 구현하려면 많은 작업이 필요합니다.신호 모듈구조에 액세스하는 방법은 제공되지 않습니다 siginfo_t.

답변2

배쉬 + ctypes.sh

재미로 @StephenKitt의 솔루션을 사용하여 다음은 bash의 예입니다.배쉬 플러그인 ctypes.sh(이 예에서는 컴파일하고 설치해야 합니다 /usr/local.)

불행하게도 두 구성 모두 너무 복잡 sigaction하여 내장 명령이 작동할 수 없습니다. 따라서 이러한 구조는 수동으로 정의해야 합니다. 이는 매우 성가신 일이며 이식성이 없습니다(운영 체제나 아키텍처에). 이 예 에서는 x86_64 아키텍처에서 Linux >= 4.6(때문에)을 가정합니다.siginfo_tctypes.shstructinfo->si_pkey

#!/bin/bash

. /usr/local/bin/ctypes.sh || exit 2

handler () {
    local -a info=(int int int int uint32 uint32 int int64 int64 int64 int pointer int int pointer long int short pointer pointer int pointer int unsigned)
    unpack $3 info

    echo ''
    echo "handler($2, info={${info[@]}}, $4);"
    echo -- handling signal $2 --
    echo "info->si_pid=${info[4]}"
    echo "info->si_uid=${info[5]}"
    return
}
callback -n handler handler void int pointer pointer

SIGUSR2=12
SA_SIGINFO=4

act=(
    $handler
    long:0 long:0 long:0 long:0 long:0 long:0 long:0 long:0 long:0 long:0 long:0 long:0 long:0 long:0 long:0 long:0
    int:$SA_SIGINFO
    pointer:0
)
sizeof_act=$(( 8 + 16 * 8 + 4 + 8 ))

dlcall -n pact -r pointer malloc $sizeof_act
[ $pact != pointer:0 ] || exit 1
pack $pact act

dlcall -n ret -r int sigaction int:$SIGUSR2 $pact pointer:0
[ $ret = int:0 ] || exit 1

echo "sigaction(SIGUSR2, act={${act[@]}}, NULL) = $ret"

echo ''
echo run this: kill -$SIGUSR2 $$
sleep 99

구현하다:

1학기:

$ ./siginfo.bash 
sigaction(SIGUSR2, act={pointer:0x7ff26f0d3010 long:0 long:0 long:0 long:0 long:0 long:0 long:0 long:0 long:0 long:0 long:0 long:0 long:0 long:0 long:0 long:0 int:4 pointer:0}, NULL) = int:0

run this: kill -12 24250

2학기:

$ echo $$
21864
$ id -u
1000
$ kill -12 24250
$ 

항목 1에 대한 결과:

handler(int:12, info={int:12 int:0 int:0 int:0 uint32:21864 uint32:1000 int:0 int64:0 int64:0 int64:0 int:0 pointer:0 int:0 int:0 pointer:0 long:0 int:0 short:0 pointer:0 pointer:0 int:0 pointer:0 int:0 unsigned:0}, pointer:0x7fff4583a500);
-- handling signal int:12 --
info->si_pid=uint32:21864
info->si_uid=uint32:1000

관련 정보