From: martijn Date: Wed, 11 Aug 2021 15:13:46 +0000 (+0000) Subject: Only enter the sig_no switch if we actually return from read(2) with X-Git-Url: http://artulab.com/gitweb/?a=commitdiff_plain;h=0a47089c9bda281e4eb96db8abe24c2b3ed7b380;p=openbsd Only enter the sig_no switch if we actually return from read(2) with errno == EINTR. There was a race here where read(2) can return with a different errno, but the signal handler enters between the read return and the switch, which could result in handling a signal, while we should be handling the error. This fix assumes that signal handlers don't clobber our errno, but doing that would open a whole other can of worms. OK schwarze@, millert@ --- diff --git a/lib/libedit/read.c b/lib/libedit/read.c index 754d898a222..7900193aecc 100644 --- a/lib/libedit/read.c +++ b/lib/libedit/read.c @@ -1,4 +1,4 @@ -/* $OpenBSD: read.c,v 1.46 2021/08/10 14:28:10 schwarze Exp $ */ +/* $OpenBSD: read.c,v 1.47 2021/08/11 15:13:46 martijn Exp $ */ /* $NetBSD: read.c,v 1.100 2016/05/24 19:31:27 christos Exp $ */ /*- @@ -240,15 +240,17 @@ read_char(EditLine *el, wchar_t *cp) el->el_signal->sig_no = 0; while ((num_read = read(el->el_infd, cbuf + cbp, 1)) == -1) { int e = errno; - switch (el->el_signal->sig_no) { - case SIGCONT: - el_set(el, EL_REFRESH); - /*FALLTHROUGH*/ - case SIGWINCH: - sig_set(el); - goto again; - default: - break; + if (errno == EINTR) { + switch (el->el_signal->sig_no) { + case SIGCONT: + el_set(el, EL_REFRESH); + /*FALLTHROUGH*/ + case SIGWINCH: + sig_set(el); + goto again; + default: + break; + } } if (!tried && read__fixio(el->el_infd, e) == 0) { errno = save_errno;