From: Todd C. Miller Date: Fri, 12 May 2017 16:02:17 +0000 (-0600) Subject: Handle the possibility of the siginfo parameter in sa_sigaction X-Git-Tag: SUDO_1_8_21^2~89 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=9d4a92b9b49ab9129596ce4cd29c79fafa790b99;p=sudo Handle the possibility of the siginfo parameter in sa_sigaction handler being NULL. --- diff --git a/include/sudo_event.h b/include/sudo_event.h index ac368dd6e..2e8542a42 100644 --- a/include/sudo_event.h +++ b/include/sudo_event.h @@ -54,7 +54,8 @@ typedef void (*sudo_ev_callback_t)(int fd, int what, void *closure); */ struct sudo_ev_siginfo_container { void *closure; - siginfo_t siginfo; + siginfo_t *siginfo; + char si_buf[1]; }; /* Member of struct sudo_event_base. */ diff --git a/lib/util/event.c b/lib/util/event.c index b95a70ab8..aa89d6f68 100644 --- a/lib/util/event.c +++ b/lib/util/event.c @@ -114,7 +114,13 @@ sudo_ev_activate_sigevents(struct sudo_event_base *base) TAILQ_FOREACH(ev, &base->signals[i], entries) { if (ISSET(ev->events, SUDO_EV_SIGINFO)) { struct sudo_ev_siginfo_container *sc = ev->closure; - memcpy(&sc->siginfo, base->siginfo[i], sizeof(sc->siginfo)); + if (base->siginfo[i]->si_signo == 0) { + /* No siginfo available. */ + sc->siginfo = NULL; + } else { + sc->siginfo = (siginfo_t *)sc->si_buf; + memcpy(sc->siginfo, base->siginfo[i], sizeof(siginfo_t)); + } } /* Make event active. */ ev->revents = ev->events & (SUDO_EV_SIGNAL|SUDO_EV_SIGINFO); @@ -248,7 +254,7 @@ sudo_ev_alloc_v1(int fd, short events, sudo_ev_callback_t callback, void *closur /* For SUDO_EV_SIGINFO we use a container to store closure + siginfo_t */ if (ISSET(events, SUDO_EV_SIGINFO)) { struct sudo_ev_siginfo_container *container = - malloc(sizeof(*container)); + malloc(sizeof(*container) + sizeof(siginfo_t) - 1); if (container == NULL) { sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO, "%s: unable to allocate siginfo container", __func__); @@ -290,8 +296,12 @@ sudo_ev_handler(int signo, siginfo_t *info, void *context) /* * Update signals_pending[] and siginfo[]. * All signals must be blocked any time siginfo[] is accessed. + * If no siginfo available, zero out the struct in base. */ - memcpy(signal_base->siginfo[signo], info, sizeof(*info)); + if (info == NULL) + memset(signal_base->siginfo[signo], 0, sizeof(*info)); + else + memcpy(signal_base->siginfo[signo], info, sizeof(*info)); signal_base->signal_pending[signo] = 1; signal_base->signal_caught = 1;