Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion REUSE.toml
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ SPDX-FileCopyrightText = "None"
SPDX-License-Identifier = "GPL-2.0-or-later"

[[annotations]]
path = ["releng/prepare-relnotes", "src/daemon/Auth.cpp", "src/daemon/Auth.h", "src/common/ConfigReader.cpp", "src/common/ConfigReader.h", "src/common/Configuration.cpp", "src/common/Configuration.h", "src/common/MessageHandler.h", "src/common/Messages.h", "src/common/Session.cpp", "src/common/Session.h", "src/common/SignalHandler.cpp", "src/common/SignalHandler.h", "src/common/SocketWriter.cpp", "src/common/SocketWriter.h", "src/common/XAuth.cpp", "src/common/XAuth.h", "src/daemon/DaemonApp.cpp", "src/daemon/DaemonApp.h", "src/daemon/Display.cpp", "src/daemon/Display.h", "src/daemon/DisplayManager.cpp", "src/daemon/DisplayManager.h", "src/daemon/PowerManager.cpp", "src/daemon/PowerManager.h", "src/daemon/SeatManager.cpp", "src/daemon/SeatManager.h", "src/daemon/SocketServer.cpp", "src/daemon/SocketServer.h", "src/daemon/TreelandConnector.cpp", "src/daemon/TreelandConnector.h", "src/daemon/VirtualTerminal.cpp", "src/daemon/VirtualTerminal.h", "src/daemon/Utils.h", "src/daemon/XorgDisplayServer.cpp", "src/daemon/XorgDisplayServer.h", "src/daemon/UserSession.cpp", "src/daemon/UserSession.h", "src/common/LogindDBusTypes.cpp", "src/common/LogindDBusTypes.h"]
path = ["releng/prepare-relnotes", "src/daemon/Auth.cpp", "src/daemon/Auth.h", "src/common/ConfigReader.cpp", "src/common/ConfigReader.h", "src/common/Configuration.cpp", "src/common/Configuration.h", "src/common/MessageHandler.h", "src/common/Messages.h", "src/common/Session.cpp", "src/common/Session.h", "src/common/SignalHandler.cpp", "src/common/SignalHandler.h", "src/common/SocketWriter.cpp", "src/common/SocketWriter.h", "src/common/XAuth.cpp", "src/common/XAuth.h", "src/daemon/DaemonApp.cpp", "src/daemon/DaemonApp.h", "src/daemon/Display.cpp", "src/daemon/Display.h", "src/daemon/DisplayManager.cpp", "src/daemon/DisplayManager.h", "src/daemon/PowerManager.cpp", "src/daemon/PowerManager.h", "src/daemon/SeatManager.cpp", "src/daemon/SeatManager.h", "src/daemon/TreelandConnector.cpp", "src/daemon/TreelandConnector.h", "src/daemon/VirtualTerminal.cpp", "src/daemon/VirtualTerminal.h", "src/daemon/Utils.h", "src/daemon/XorgDisplayServer.cpp", "src/daemon/XorgDisplayServer.h", "src/daemon/UserSession.cpp", "src/daemon/UserSession.h", "src/common/LogindDBusTypes.cpp", "src/common/LogindDBusTypes.h"]
precedence = "aggregate"
SPDX-FileCopyrightText = "None"
SPDX-License-Identifier = "GPL-2.0-or-later"
50 changes: 26 additions & 24 deletions src/daemon/Auth.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -218,17 +218,19 @@ namespace DDM {
return true;
}

int Auth::openSession(const QString &command,
QProcessEnvironment env,
const QByteArray &cookie) {
QString Auth::openSession(const QString &command,
QProcessEnvironment env,
const QByteArray &cookie) {
Q_ASSERT(authenticated);

int pipefd[2];
if (pipe(pipefd) == -1) {
qWarning() << "[Auth] pipe failed:" << strerror(errno);
return -1;
return {};
}

char xdgSessionId[128] = {};

// Here is most safe place to jump VT
VirtualTerminal::jumpToVt(tty, false, false);

Expand All @@ -239,7 +241,7 @@ namespace DDM {
qWarning() << "[Auth] fork failed:" << strerror(errno);
close(pipefd[0]);
close(pipefd[1]);
return -1;
return {};
}
case 0: {
// Child (session leader) process
Expand Down Expand Up @@ -275,57 +277,57 @@ namespace DDM {
env = *sessionEnv;

// Retrieve XDG_SESSION_ID
xdgSessionId = env.value(QStringLiteral("XDG_SESSION_ID")).toInt();
if (xdgSessionId <= 0) {
qCritical() << "[SessionLeader] Invalid XDG_SESSION_ID from pam_open_session()";
exit(1);
}
if (write(pipefd[1], &xdgSessionId, sizeof(int)) != sizeof(int)) {
session = env.value(QStringLiteral("XDG_SESSION_ID"));
QByteArray sessionBa = session.toLocal8Bit();
strcpy(xdgSessionId, sessionBa.constData());
if (write(pipefd[1], &xdgSessionId, sizeof(char) * 128) != sizeof(char) * 128) {
qCritical() << "[SessionLeader] Failed to write XDG_SESSION_ID to parent process!";
exit(1);
Comment on lines 279 to 285
Copy link

Copilot AI Feb 28, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

strcpy(xdgSessionId, sessionBa.constData()) can overflow the fixed 128-byte buffer if the session ID is longer than expected, leading to memory corruption. Use a bounded copy (e.g. qstrncpy/strncpy) and also treat an empty XDG_SESSION_ID as a hard error (exit) to avoid starting a session that the parent will consider failed.

strcpy(xdgSessionId, sessionBa.constData()) 在会话 ID 超出 128 字节时会溢出固定缓冲区,造成内存破坏。请使用有界拷贝(如 qstrncpy/strncpy),并且当 XDG_SESSION_ID 为空时应直接视为致命错误并退出,避免子进程继续启动而父进程判定失败。

Copilot uses AI. Check for mistakes.
}

// RUN!!!
UserSession session(this);
session.setProcessEnvironment(env);
session.start(command, type, cookie);
if (!session.waitForStarted()) {
UserSession desktop(this);
desktop.setProcessEnvironment(env);
desktop.start(command, type, cookie);
if (!desktop.waitForStarted()) {
qCritical() << "[SessionLeader] Failed to start session process. Exit now.";
exit(1);
}

// Send session PID to parent
sessionPid = session.processId();
sessionPid = desktop.processId();
if (write(pipefd[1], &sessionPid, sizeof(qint64)) != sizeof(qint64)) {
qCritical() << "[SessionLeader] Failed to write session PID to parent process!";
exit(1);
}
qInfo() << "[SessionLeader] Session started with PID" << sessionPid;

session.waitForFinished(-1);
desktop.waitForFinished(-1);

// Handle session end
if (session.exitStatus() == QProcess::CrashExit) {
if (desktop.exitStatus() == QProcess::CrashExit) {
qCritical() << "[SessionLeader] Session process crashed. Exit now.";
exit(1);
}
qInfo() << "[SessionLeader] Session process finished with exit code"
<< session.exitCode() << ". Exiting.";
exit(session.exitCode());
<< desktop.exitCode() << ". Exiting.";
exit(desktop.exitCode());
}
default: {
// Parent process
close(pipefd[1]);

if (read(pipefd[0], &xdgSessionId, sizeof(int)) < 0) {
if (read(pipefd[0], &xdgSessionId, sizeof(char) * 128) != sizeof(char) * 128) {
qWarning() << "[Auth] Failed to read XDG_SESSION_ID from child process:" << strerror(errno);
close(pipefd[0]);
return -1;
return {};
}
session = QString::fromLocal8Bit(xdgSessionId);

if (read(pipefd[0], &sessionPid, sizeof(qint64)) < 0) {
qWarning() << "[Auth] Failed to read session PID from child process:" << strerror(errno);
close(pipefd[0]);
return -1;
return {};
}
utmpLogin(true);

Expand All @@ -339,7 +341,7 @@ namespace DDM {
});

sessionOpened = true;
return xdgSessionId;
return session;
}
}
}
Expand Down
12 changes: 6 additions & 6 deletions src/daemon/Auth.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,8 @@ namespace DDM {
/** Virtual terminal number (e.g. 7 for tty7) */
int tty{ 0 };

/** Logind session ID (the XDG_SESSION_ID env var). Positive values are valid */
int xdgSessionId{ 0 };
/** Logind session ID (the XDG_SESSION_ID env var) */
QString session{};

/** PID of the session leader. Positive values are valid */
pid_t sessionLeaderPid{ 0 };
Expand All @@ -67,11 +67,11 @@ namespace DDM {
* @param command Command to execute as user process
* @param env Environment variables to set for the session
* @param cookie XAuth cookie, must be provided if type=X11
* @return A valid XDG_SESSION_ID on success, zero or negative on failure
* @return A valid XDG_SESSION_ID on success, empty string on failure
*/
int openSession(const QString &command,
QProcessEnvironment env,
const QByteArray &cookie = QByteArray());
QString openSession(const QString &command,
QProcessEnvironment env,
const QByteArray &cookie = QByteArray());

/**
* Close PAM session
Expand Down
17 changes: 8 additions & 9 deletions src/daemon/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
# Generate treeland-ddm protocol files
set(TREELAND_DDM_HEADER ${CMAKE_CURRENT_BINARY_DIR}/treeland-ddm-v1.h)
set(TREELAND_DDM_SOURCE ${CMAKE_CURRENT_BINARY_DIR}/treeland-ddm-v1.c)
set(TREELAND_DDM_HEADER ${CMAKE_CURRENT_BINARY_DIR}/treeland-ddm-v2.h)
set(TREELAND_DDM_SOURCE ${CMAKE_CURRENT_BINARY_DIR}/treeland-ddm-v2.c)

add_custom_command(
OUTPUT ${TREELAND_DDM_HEADER}
COMMAND wayland-scanner client-header < ${TREELAND_PROTOCOLS_DATA_DIR}/treeland-ddm-v1.xml > ${TREELAND_DDM_HEADER}
DEPENDS ${TREELAND_PROTOCOLS_DATA_DIR}/treeland-ddm-v1.xml
COMMENT "Generating treeland-ddm-v1.h"
COMMAND wayland-scanner client-header < ${TREELAND_PROTOCOLS_DATA_DIR}/treeland-ddm-v2.xml > ${TREELAND_DDM_HEADER}
DEPENDS ${TREELAND_PROTOCOLS_DATA_DIR}/treeland-ddm-v2.xml
COMMENT "Generating treeland-ddm-v2.h"
)

add_custom_command(
OUTPUT ${TREELAND_DDM_SOURCE}
COMMAND wayland-scanner private-code < ${TREELAND_PROTOCOLS_DATA_DIR}/treeland-ddm-v1.xml > ${TREELAND_DDM_SOURCE}
DEPENDS ${TREELAND_PROTOCOLS_DATA_DIR}/treeland-ddm-v1.xml
COMMENT "Generating treeland-ddm-v1.c"
COMMAND wayland-scanner private-code < ${TREELAND_PROTOCOLS_DATA_DIR}/treeland-ddm-v2.xml > ${TREELAND_DDM_SOURCE}
DEPENDS ${TREELAND_PROTOCOLS_DATA_DIR}/treeland-ddm-v2.xml
COMMENT "Generating treeland-ddm-v2.c"
)

configure_file(config.h.in config.h IMMEDIATE @ONLY)
Expand All @@ -24,7 +24,6 @@ set(DAEMON_SOURCES
DisplayManager.cpp
PowerManager.cpp
SeatManager.cpp
SocketServer.cpp
TreelandConnector.cpp
UserSession.cpp
VirtualTerminal.cpp
Expand Down
1 change: 0 additions & 1 deletion src/daemon/DaemonApp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,6 @@ namespace DDM {
connect(m_signalHandler, &SignalHandler::sigintReceived, this, &DaemonApp::quit);
connect(m_signalHandler, &SignalHandler::sigtermReceived, this, &DaemonApp::quit);

m_treelandConnector = new TreelandConnector();
// log message
qDebug() << "Starting...";

Expand Down
3 changes: 0 additions & 3 deletions src/daemon/DaemonApp.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ namespace DDM {
class PowerManager;
class SeatManager;
class SignalHandler;
class TreelandConnector;

class DaemonApp : public QCoreApplication {
Q_OBJECT
Expand All @@ -45,7 +44,6 @@ namespace DDM {
inline PowerManager *powerManager() const { return m_powerManager; };
inline SeatManager *seatManager() const { return m_seatManager; };
inline SignalHandler *signalHandler() const { return m_signalHandler; };
inline TreelandConnector *treelandConnector() const { return m_treelandConnector; };

void backToNormal();

Expand All @@ -61,7 +59,6 @@ namespace DDM {
PowerManager *m_powerManager { nullptr };
SeatManager *m_seatManager { nullptr };
SignalHandler *m_signalHandler { nullptr };
TreelandConnector *m_treelandConnector { nullptr };
};
}

Expand Down
Loading
Loading