0

As far as I understand, a SEGV signal is sent by the OS to inform a process that it has attempted an illegal memory access. But I noticed that it is also possible to send a SEGV signal to a process from another process (e.g. kill -s SEGV pid).

Therefore I was wondering, what is the use of being able to send a SEGV signal to another process?

Futhermore, is there anyway for a process to know whether the SEGV signal was sent by the OS or by another process?

1

2 Answers 2

3

Therefore I was wondering, what is the use of being able to send a SEGV signal to another process?

I suppose someone could send it manually for testing. But even if no use for it was thought of originally, we never know if someone might come up with a use, and then arbitrary restrictions would just get in the way.

Futhermore, is there anyway for a process to know whether the SEGV signal was sent by the OS or by another process?

Yes, as mentioned in Catch which user sends kill signal, signal handlers set with sigaction() with the SA_SIGINFO flag can read a number of details from the siginfo_t structure. Those contain the reason the signal was sent (si_code), and if it applies, the sending user and PID (si_uid, si_pid).

See the man page: https://man7.org/linux/man-pages/man2/sigaction.2.html

Here's a simple program to test that, it sets up a handler for SIGSEGV and sends it to itself, first with kill() and then by triggering an invalid memory access:

#include <sys/types.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

void action(int sig, siginfo_t *si, void *p)
{
    printf("sig: %d\n", sig);
    printf("si_signo: %d\n", si->si_signo);
    char *reason = "?";
    switch (si->si_code) {
        case SI_USER: reason = "Signal sent by user"; break;
        case SI_TKILL: reason = "Signal sent by user (tkill)"; break;
        case SI_KERNEL: reason = "Signal sent by kernel"; break;
        case SEGV_MAPERR:
            reason = "SIGSEGV - Address not mapped to object"; break;
        case SEGV_ACCERR: 
            reason = "SIGSEGV - Invalid permissions for mapped object"; break;
    }
    printf("si_code: %d (%s)\n", si->si_code, reason);
    printf("si_pid: %d\n", (int) si->si_pid);
    printf("si_uid: %d\n", (int) si->si_uid);
    printf("si_addr: 0x%016lx\n", (unsigned long) si->si_addr);
    if (si->si_code != SI_USER && si->si_code != SI_TKILL) {
        // if it's an actual error, exit instead of
        // returning to repeat the error 
        _exit(1);
    }
}   

int main(void)
{
    struct sigaction sa = {0}; 
    sa.sa_sigaction = action;
    sa.sa_flags = SA_SIGINFO;
    int ret = sigaction(SIGSEGV, &sa, NULL);
    if (ret == -1) {
        perror("sigaction");
        exit(1);
    }
    printf("raising SIGSEGV manually\n");
    kill(getpid(), SIGSEGV);
    printf("\n");
    printf("trying to trigger SIGSEGV\n");
    volatile int *p = (int *) 0xdeadbeef;
    (void) *p;
}

The output on my system is:

raising SIGSEGV manually
sig: 11
si_signo: 11
si_code: 0 (Signal sent by user)
si_pid: 13868
si_uid: 1000
si_addr: 0x000003e80000362c

trying to trigger SIGSEGV
sig: 11
si_signo: 11
si_code: 1 (SIGSEGV - Address not mapped to object)
si_pid: -559038737
si_uid: 0
si_addr: 0x00000000deadbeef

(Note that some fields that don't apply to the case in question contain garbage.)

1

Unix puts no restrictions on what signals can be sent to a process. It only restricts signals based on process ownership.

In general, there is no way to determine the source of a signal.

3
  • 2
    "In general, there is no way to determine the source of a signal" - that is not true. You can know the source of a signal from within the process that received it. See the following answer (that was already commented to the question by @A.B): unix.stackexchange.com/a/489720/273579
    – aviro
    Commented Nov 22, 2021 at 7:30
  • That's why I said "in general" ... that method doesn't work in many cases, like python and shell scripts. And that comment wasn't there when I wrote this answer.
    – user10489
    Commented Nov 22, 2021 at 12:27
  • @user10489, but in general there is a way to determine the source! the system calls allow for it just fine. It might be that with some script languages in particular it's hard to impossible. But then again the question didn't ask about Python or the shell. And based on the timestamps, the comment was there about 4 h before this answer.
    – ilkkachu
    Commented Nov 22, 2021 at 13:48

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .