diff --git a/src/dde-update/main.cpp b/src/dde-update/main.cpp index e6ff7306..ea366292 100644 --- a/src/dde-update/main.cpp +++ b/src/dde-update/main.cpp @@ -24,6 +24,7 @@ #include #include #include +#include Q_LOGGING_CATEGORY(logUpdateModal, "dde.update.modalupdate") @@ -86,12 +87,20 @@ class FifoNotifier if (m_path.isEmpty()) { return; } - // Write our PID so the wrapper can track this exact process via kill -0. + // Open first, then verify it's a FIFO via fstat(). + // This avoids the TOCTOU race of stat() before open(). int fd = open(m_path.toUtf8().constData(), O_WRONLY | O_NONBLOCK); if (fd < 0) { qCWarning(logUpdateModal) << "FifoNotifier: cannot report PID, open failed:" << strerror(errno); return; } + struct stat st; + if (fstat(fd, &st) != 0 || !S_ISFIFO(st.st_mode)) { + qCWarning(logUpdateModal) << "FifoNotifier: path is not a FIFO, cannot report PID"; + close(fd); + return; + } + // Write our PID so the wrapper can track this exact process via kill -0. QByteArray msg = "PID:" + QByteArray::number(getpid()) + "\n"; bool ok = writeAllFifo(fd, msg, 5000); close(fd); @@ -108,6 +117,8 @@ class FifoNotifier return; } qCInfo(logUpdateModal) << "FifoNotifier: notifying FIFO" << m_path; + // Open first, then verify it's a FIFO via fstat(). + // This avoids the TOCTOU race of stat() before open(). // O_NONBLOCK so we don't hang if the reader already closed; // the script opens fd 3<> before launching us so a reader exists. int fd = open(m_path.toUtf8().constData(), O_WRONLY | O_NONBLOCK); @@ -115,6 +126,12 @@ class FifoNotifier qCWarning(logUpdateModal) << "FifoNotifier: cannot open" << m_path << ":" << strerror(errno); return; } + struct stat st; + if (fstat(fd, &st) != 0 || !S_ISFIFO(st.st_mode)) { + qCWarning(logUpdateModal) << "FifoNotifier: path is not a FIFO, cannot notify"; + close(fd); + return; + } // Write "EXIT\n" to signal exit to the wrapper. QByteArray msg("EXIT\n"); bool ok = writeAllFifo(fd, msg, 2000); diff --git a/src/dde-update/securityloaderhelper.cpp b/src/dde-update/securityloaderhelper.cpp index 0ba00e86..8b9ff90d 100644 --- a/src/dde-update/securityloaderhelper.cpp +++ b/src/dde-update/securityloaderhelper.cpp @@ -18,6 +18,7 @@ #include #include #include +#include static const QString DEFAULT_AUTH_RESOURCE = ":/misc/org.deepin.dde-update.json"; // Upper bound for the authorization response to guard against a misbehaving @@ -65,6 +66,14 @@ LoaderHandshakeInfo SecurityLoaderHelper::parseLoaderArgs(int argc, char *argv[] continue; } info.fd1 = static_cast(fd); + // Verify the fd is actually a FIFO to prevent writing + // authorization data to arbitrary open files. + struct stat st; + if (fstat(info.fd1, &st) != 0 || !S_ISFIFO(st.st_mode)) { + qWarning() << "fd1 is not a FIFO, ignoring"; + info.fd1 = -1; + continue; + } info.isLoadedByLoader = true; } else if (strcmp(argv[i], "--fd2") == 0 && i + 1 < argc) { const char *val = argv[++i]; @@ -77,6 +86,14 @@ LoaderHandshakeInfo SecurityLoaderHelper::parseLoaderArgs(int argc, char *argv[] continue; } info.fd2 = static_cast(fd); + // Verify the fd is actually a FIFO to prevent writing + // authorization data to arbitrary open files. + struct stat st; + if (fstat(info.fd2, &st) != 0 || !S_ISFIFO(st.st_mode)) { + qWarning() << "fd2 is not a FIFO, ignoring"; + info.fd2 = -1; + continue; + } } }