Skip to content

Commit 213377a

Browse files
committed
fix: IPC security review fixes
1 parent f03d419 commit 213377a

4 files changed

Lines changed: 20 additions & 69 deletions

File tree

ipc/ipc.h

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -61,8 +61,6 @@ inline QStringList sanitizeArguments(PermittedProcess proc, const QStringList &a
6161

6262
switch (proc) {
6363
case OpenVPN: {
64-
// Whitelist only args actually used by the client:
65-
// --config <path>, --management <host> <port>, --management-client
6664
namedArgs["--config"] = [](const QString& v) { return !v.isEmpty(); };
6765
namedArgs["--management"] = [](const QString& v) { return !v.isEmpty(); };
6866
namedArgs["--management-client"] = nullptr;
@@ -73,17 +71,6 @@ inline QStringList sanitizeArguments(PermittedProcess proc, const QStringList &a
7371
});
7472
break;
7573
}
76-
case Wireguard: {
77-
// Whitelist only subcommand + config file path (wg-quick up/down <conf>)
78-
if (args.size() == 2) {
79-
const QString &sub = args[0];
80-
if (sub == QStringLiteral("up") || sub == QStringLiteral("down")) {
81-
return args;
82-
}
83-
}
84-
qWarning() << "IPC: blocked unexpected WireGuard arguments";
85-
return {};
86-
}
8774
case Tun2Socks:
8875
namedArgs["-device"] = [](const QString& v) { return v.startsWith("tun://"); };
8976
namedArgs["-proxy"] = [](const QString& v) { return v.startsWith("socks5://"); };

ipc/ipcserver.cpp

Lines changed: 0 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -22,27 +22,6 @@
2222
#include "tapcontroller_win.h"
2323
#endif
2424

25-
#ifdef Q_OS_LINUX
26-
#include <sys/socket.h>
27-
#include <sys/types.h>
28-
29-
extern uid_t g_allowedUid;
30-
extern bool g_allowedUidSet;
31-
32-
static bool checkPrivPeerCredentials(QLocalSocket *socket) {
33-
struct ucred cred{};
34-
socklen_t len = sizeof(cred);
35-
if (getsockopt(socket->socketDescriptor(), SOL_SOCKET, SO_PEERCRED, &cred, &len) != 0) {
36-
qWarning() << "IpcServer: SO_PEERCRED failed, rejecting privileged process connection";
37-
return false;
38-
}
39-
if (cred.uid == 0) return true;
40-
if (g_allowedUidSet && cred.uid == g_allowedUid) return true;
41-
qWarning() << "IpcServer: rejected privileged process connection from unauthorized UID" << cred.uid;
42-
return false;
43-
}
44-
#endif
45-
4625

4726
IpcServer::IpcServer(QObject *parent) : IpcInterfaceSource(parent)
4827
{
@@ -70,13 +49,6 @@ int IpcServer::createPrivilegedProcess()
7049
QObject::connect(pd.localServer.data(), &QLocalServer::newConnection, this, [pd]() {
7150
qDebug() << "IpcServer new connection";
7251
QLocalSocket *conn = pd.localServer->nextPendingConnection();
73-
#ifdef Q_OS_LINUX
74-
if (!checkPrivPeerCredentials(conn)) {
75-
conn->close();
76-
conn->deleteLater();
77-
return;
78-
}
79-
#endif
8052
if (pd.serverNode) {
8153
pd.serverNode->addHostSideConnection(conn);
8254
pd.serverNode->enableRemoting(pd.ipcProcess.data());

service/server/killswitch.cpp

Lines changed: 19 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -189,7 +189,7 @@ bool KillSwitch::disableAllTraffic() {
189189

190190
bool KillSwitch::resetAllowedRange(const QStringList &ranges) {
191191

192-
#ifdef Q_OS_LINUX
192+
#if defined(Q_OS_LINUX) || defined(Q_OS_MACOS)
193193
if (!std::all_of(ranges.cbegin(), ranges.cend(), isValidIpOrCidr)) {
194194
qCritical() << "IPC: invalid IP/CIDR in ranges, rejecting resetAllowedRange";
195195
return false;
@@ -220,7 +220,7 @@ bool KillSwitch::resetAllowedRange(const QStringList &ranges) {
220220
}
221221

222222
bool KillSwitch::addAllowedRange(const QStringList &ranges) {
223-
#ifdef Q_OS_LINUX
223+
#if defined(Q_OS_LINUX) || defined(Q_OS_MACOS)
224224
if (!std::all_of(ranges.cbegin(), ranges.cend(), isValidIpOrCidr)) {
225225
qCritical() << "IPC: invalid IP/CIDR in ranges, rejecting addAllowedRange";
226226
return false;
@@ -323,6 +323,15 @@ bool KillSwitch::enableKillSwitch(const QJsonObject &configStr, int vpnAdapterIn
323323
bool allowMarkedXray = 0;
324324
QStringList allownets;
325325
QStringList blocknets;
326+
QStringList allowedDnsServers;
327+
for (const QJsonValue &dns : configStr.value(amnezia::configKey::allowedDnsServers).toArray()) {
328+
if (!dns.isString()) break;
329+
const QString dnsStr = dns.toString();
330+
if (isValidIpOrCidr(dnsStr))
331+
allowedDnsServers.append(dnsStr);
332+
else if (!dnsStr.isEmpty())
333+
qWarning() << "IPC: rejected invalid allowedDnsServer:" << dnsStr;
334+
}
326335

327336
if (splitTunnelType == 0) {
328337
blockAll = true;
@@ -387,18 +396,7 @@ bool KillSwitch::enableKillSwitch(const QJsonObject &configStr, int vpnAdapterIn
387396

388397
dnsServers.append("127.0.0.1");
389398
dnsServers.append("127.0.0.53");
390-
391-
392-
for (auto dns : configStr.value(amnezia::configKey::allowedDnsServers).toArray()) {
393-
if (!dns.isString()) {
394-
break;
395-
}
396-
const QString dnsStr = dns.toString();
397-
if (isValidIpOrCidr(dnsStr))
398-
dnsServers.append(dnsStr);
399-
else if (!dnsStr.isEmpty())
400-
qWarning() << "IPC: rejected invalid allowedDnsServer:" << dnsStr;
401-
}
399+
dnsServers.append(allowedDnsServers);
402400

403401
LinuxFirewall::updateDNSServers(dnsServers);
404402
LinuxFirewall::setAnchorEnabled(LinuxFirewall::IPv4, QStringLiteral("320.allowDNS"), true);
@@ -412,6 +410,11 @@ bool KillSwitch::enableKillSwitch(const QJsonObject &configStr, int vpnAdapterIn
412410
MacOSFirewall::install();
413411

414412
MacOSFirewall::ensureRootAnchorPriority();
413+
if (!std::all_of(allownets.cbegin(), allownets.cend(), isValidIpOrCidr) ||
414+
!std::all_of(blocknets.cbegin(), blocknets.cend(), isValidIpOrCidr)) {
415+
qCritical() << "IPC: invalid IP/CIDR in allownets/blocknets, rejecting enableKillSwitch";
416+
return false;
417+
}
415418
MacOSFirewall::setAnchorEnabled(QStringLiteral("000.allowLoopback"), true);
416419
MacOSFirewall::setAnchorEnabled(QStringLiteral("100.blockAll"), blockAll);
417420
MacOSFirewall::setAnchorEnabled(QStringLiteral("110.allowNets"), allowNets);
@@ -440,17 +443,8 @@ bool KillSwitch::enableKillSwitch(const QJsonObject &configStr, int vpnAdapterIn
440443
qWarning() << "IPC: rejected invalid dns2:" << dns2;
441444
}
442445

443-
for (auto dns : configStr.value(amnezia::configKey::allowedDnsServers).toArray()) {
444-
if (!dns.isString()) {
445-
break;
446-
}
447-
const QString dnsStr = dns.toString();
448-
if (isValidIpOrCidr(dnsStr))
449-
dnsServers.append(dnsStr);
450-
else if (!dnsStr.isEmpty())
451-
qWarning() << "IPC: rejected invalid allowedDnsServer:" << dnsStr;
452-
}
453-
446+
dnsServers.append(allowedDnsServers);
447+
454448
MacOSFirewall::setAnchorEnabled(QStringLiteral("310.blockDNS"), true);
455449
MacOSFirewall::setAnchorTable(QStringLiteral("310.blockDNS"), true, QStringLiteral("dnsaddr"), dnsServers);
456450
MacOSFirewall::setAnchorEnabled(QStringLiteral("400.allowPIA"), true);

service/server/localserver.cpp

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
#include "tapcontroller_win.h"
1818
#endif
1919

20-
2120
namespace {
2221
Logger logger("WgDaemonServer");
2322
}
@@ -36,8 +35,7 @@ LocalServer::LocalServer(QObject *parent) : QObject(parent),
3635

3736
QObject::connect(m_server.data(), &QLocalServer::newConnection, this, [this]() {
3837
qDebug() << "LocalServer new connection";
39-
QLocalSocket *conn = m_server->nextPendingConnection();
40-
m_serverNode.addHostSideConnection(conn);
38+
m_serverNode.addHostSideConnection(m_server->nextPendingConnection());
4139

4240
if (!m_isRemotingEnabled) {
4341
m_isRemotingEnabled = true;

0 commit comments

Comments
 (0)