From: Karel Zak Date: Fri, 22 Nov 2019 10:56:04 +0000 (+0100) Subject: lib/pty: make sure we not use closed FD X-Git-Tag: v2.35-rc1~51 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=f896aef36bb0d26c5a7a816ce163a481c41a6485;p=thirdparty%2Futil-linux.git lib/pty: make sure we not use closed FD Signed-off-by: Karel Zak --- diff --git a/lib/pty-session.c b/lib/pty-session.c index a7fb7d40b5..87d8e58b5e 100644 --- a/lib/pty-session.c +++ b/lib/pty-session.c @@ -312,11 +312,16 @@ static void write_eof_to_child(struct ul_pty *pty) static int mainloop_callback(struct ul_pty *pty) { + int rc; + if (!pty->callbacks.mainloop) return 0; DBG(IO, ul_debugobj(pty, "calling mainloop callback")); - return pty->callbacks.mainloop(pty->callback_data); + rc = pty->callbacks.mainloop(pty->callback_data); + + DBG(IO, ul_debugobj(pty, " callback done [rc=%d]", rc)); + return rc; } static int handle_io(struct ul_pty *pty, int fd, int *eof) @@ -565,14 +570,16 @@ int ul_pty_proxy_master(struct ul_pty *pty) if (pfd[i].revents == 0) continue; - DBG(IO, ul_debugobj(pty, " active pfd[%s].fd=%d %s %s %s", + DBG(IO, ul_debugobj(pty, " active pfd[%s].fd=%d %s %s %s %s", i == POLLFD_STDIN ? "stdin" : i == POLLFD_MASTER ? "master" : i == POLLFD_SIGNAL ? "signal" : "???", pfd[i].fd, pfd[i].revents & POLLIN ? "POLLIN" : "", pfd[i].revents & POLLHUP ? "POLLHUP" : "", - pfd[i].revents & POLLERR ? "POLLERR" : "")); + pfd[i].revents & POLLERR ? "POLLERR" : "", + pfd[i].revents & POLLNVAL ? "POLLNVAL" : "")); + switch (i) { case POLLFD_STDIN: case POLLFD_MASTER: @@ -581,8 +588,11 @@ int ul_pty_proxy_master(struct ul_pty *pty) rc = handle_io(pty, pfd[i].fd, &eof); /* EOF maybe detected by two ways: * A) poll() return POLLHUP event after close() - * B) read() returns 0 (no data) */ - if ((pfd[i].revents & POLLHUP) || eof) { + * B) read() returns 0 (no data) + * + * POLLNVAL means that fd is closed. + */ + if ((pfd[i].revents & POLLHUP) || (pfd[i].revents & POLLNVAL) || eof) { DBG(IO, ul_debugobj(pty, " ignore FD")); pfd[i].fd = -1; if (i == POLLFD_STDIN) {