From 9f1afe23fe0b79936dbcf3be0bb629d16aea10d2 Mon Sep 17 00:00:00 2001 From: "Todd C. Miller" Date: Thu, 20 Apr 2017 16:13:14 -0600 Subject: [PATCH] Use the standard idiom for popping all entries from a tail queue. The llvm checker gets confused by TAILQ_REMOVE and generate use-after-free false positives. --- src/exec_pty.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/exec_pty.c b/src/exec_pty.c index a983dbb15..7e12acbbf 100644 --- a/src/exec_pty.c +++ b/src/exec_pty.c @@ -1061,8 +1061,7 @@ sigfwd_cb(int sock, int what, void *v) ssize_t nsent; debug_decl(sigfwd_cb, SUDO_DEBUG_EXEC) - while (!TAILQ_EMPTY(&ec->sigfwd_list)) { - sigfwd = TAILQ_FIRST(&ec->sigfwd_list); + while ((sigfwd = TAILQ_FIRST(&ec->sigfwd_list)) != NULL) { if (sigfwd->signo == SIGCONT_FG) strlcpy(signame, "CONT_FG", sizeof(signame)); else if (sigfwd->signo == SIGCONT_BG) @@ -1080,14 +1079,13 @@ sigfwd_cb(int sock, int what, void *v) free(sigfwd); if (nsent != sizeof(cstat)) { if (errno == EPIPE) { - struct sigforward *sigfwd_next; sudo_debug_printf(SUDO_DEBUG_ERROR, "broken pipe writing to child over backchannel"); /* Other end of socket gone, empty out sigfwd_list. */ - TAILQ_FOREACH_SAFE(sigfwd, &ec->sigfwd_list, entries, sigfwd_next) { + while ((sigfwd = TAILQ_FIRST(&ec->sigfwd_list)) != NULL) { + TAILQ_REMOVE(&ec->sigfwd_list, sigfwd, entries); free(sigfwd); } - TAILQ_INIT(&ec->sigfwd_list); /* XXX - child (monitor) is dead, we should exit too? */ } break; -- 2.40.0