From 6ca3ab626a04c3b05e6b3fde9a48457cf89c2889 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Thu, 5 Jun 2014 17:15:03 -0700 Subject: [PATCH] Don't try to read from invalid file descriptors in QProcess strace reveals that we do ioctl(-1, FIONREAD) and get EBADF. The only case where this could happen is inside _q_processDied, which calls the read functions without checking if the pipe is still open. Change-Id: I67637fc4267be73fc03d40c444fdfea89e1ef715 Reviewed-by: Oswald Buddenhagen --- src/corelib/io/qprocess.cpp | 3 +++ src/corelib/io/qprocess_unix.cpp | 2 ++ src/corelib/io/qprocess_win.cpp | 11 +++++------ 3 files changed, 10 insertions(+), 6 deletions(-) diff --git a/src/corelib/io/qprocess.cpp b/src/corelib/io/qprocess.cpp index 615e584f81..0436aa5428 100644 --- a/src/corelib/io/qprocess.cpp +++ b/src/corelib/io/qprocess.cpp @@ -903,6 +903,9 @@ void QProcessPrivate::cleanup() bool QProcessPrivate::tryReadFromChannel(Channel *channel) { Q_Q(QProcess); + if (channel->pipe[0] == INVALID_Q_PIPE) + return false; + qint64 available = bytesAvailableInChannel(channel); if (available == 0) { if (channel->notifier) diff --git a/src/corelib/io/qprocess_unix.cpp b/src/corelib/io/qprocess_unix.cpp index 430393d6f2..3c1eeb5f91 100644 --- a/src/corelib/io/qprocess_unix.cpp +++ b/src/corelib/io/qprocess_unix.cpp @@ -965,6 +965,7 @@ bool QProcessPrivate::processStarted() qint64 QProcessPrivate::bytesAvailableInChannel(const Channel *channel) const { + Q_ASSERT(channel->pipe[0] != INVALID_Q_PIPE); int nbytes = 0; qint64 available = 0; if (::ioctl(channel->pipe[0], FIONREAD, (char *) &nbytes) >= 0) @@ -977,6 +978,7 @@ qint64 QProcessPrivate::bytesAvailableInChannel(const Channel *channel) const qint64 QProcessPrivate::readFromChannel(const Channel *channel, char *data, qint64 maxlen) { + Q_ASSERT(channel->pipe[0] != INVALID_Q_PIPE); qint64 bytesRead = qt_safe_read(channel->pipe[0], data, maxlen); #if defined QPROCESS_DEBUG qDebug("QProcessPrivate::readFromChannel(%d, %p \"%s\", %lld) == %lld", diff --git a/src/corelib/io/qprocess_win.cpp b/src/corelib/io/qprocess_win.cpp index 2dd4c475d8..7b3f1f8f58 100644 --- a/src/corelib/io/qprocess_win.cpp +++ b/src/corelib/io/qprocess_win.cpp @@ -566,11 +566,8 @@ bool QProcessPrivate::processStarted() qint64 QProcessPrivate::bytesAvailableInChannel(const Channel *channel) const { - if (channel->pipe[0] == INVALID_Q_PIPE) - return 0; - - if (!channel->reader) - return 0; + Q_ASSERT(channel->pipe[0] != INVALID_Q_PIPE); + Q_ASSERT(channel->reader); DWORD bytesAvail = channel->reader->bytesAvailable(); #if defined QPROCESS_DEBUG @@ -581,7 +578,9 @@ qint64 QProcessPrivate::bytesAvailableInChannel(const Channel *channel) const qint64 QProcessPrivate::readFromChannel(const Channel *channel, char *data, qint64 maxlen) { - return channel->reader ? channel->reader->read(data, maxlen) : 0; + Q_ASSERT(channel->pipe[0] != INVALID_Q_PIPE); + Q_ASSERT(channel->reader); + return channel->reader->read(data, maxlen); } static BOOL QT_WIN_CALLBACK qt_terminateApp(HWND hwnd, LPARAM procId)