mirror of
https://git.eden-emu.dev/eden-emu/eden.git
synced 2026-08-17 13:56:06 +00:00
bsd:s and bsd:u enforce socket() distinctions
This commit is contained in:
@@ -1,3 +1,6 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
|
||||
@@ -173,8 +173,26 @@ void BSD::Socket(HLERequestContext& ctx) {
|
||||
|
||||
LOG_DEBUG(Service, "called. domain={} type={} protocol={}", domain, type, protocol);
|
||||
|
||||
const auto [fd, bsd_errno] = SocketImpl(static_cast<Domain>(domain), static_cast<Type>(type),
|
||||
static_cast<Protocol>(protocol));
|
||||
const auto [fd, bsd_errno] = SocketImpl(Domain(domain), Type(type), Protocol(protocol));
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 4};
|
||||
rb.Push(ResultSuccess);
|
||||
rb.Push<s32>(fd);
|
||||
rb.PushEnum(bsd_errno);
|
||||
}
|
||||
|
||||
void BSD::SocketExempt(HLERequestContext& ctx) {
|
||||
IPC::RequestParser rp{ctx};
|
||||
const u32 domain = rp.Pop<u32>();
|
||||
const u32 type = rp.Pop<u32>();
|
||||
const u32 protocol = rp.Pop<u32>();
|
||||
|
||||
LOG_DEBUG(Service, "called. domain={} type={} protocol={}", domain, type, protocol);
|
||||
|
||||
auto [fd, bsd_errno] = SocketImpl(Domain(domain), Type(type), Protocol(protocol));
|
||||
if (bsd_errno == Errno::SUCCESS) {
|
||||
bsd_errno = ShutdownImpl(fd, 0);
|
||||
}
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 4};
|
||||
rb.Push(ResultSuccess);
|
||||
@@ -445,6 +463,7 @@ void BSD::Close(HLERequestContext& ctx) {
|
||||
BuildErrnoResponse(ctx, CloseImpl(fd));
|
||||
}
|
||||
|
||||
/// @brief Only bsd:s is able to dup()
|
||||
void BSD::DuplicateSocket(HLERequestContext& ctx) {
|
||||
struct InputParameters {
|
||||
s32 fd;
|
||||
@@ -463,6 +482,13 @@ void BSD::DuplicateSocket(HLERequestContext& ctx) {
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 4};
|
||||
rb.Push(ResultSuccess);
|
||||
if (is_user) {
|
||||
rb.PushRaw(OutputParameters{
|
||||
.ret = 0,
|
||||
.bsd_errno = Errno::INVAL,
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
auto const res_v = DuplicateSocketImpl(input.fd);
|
||||
if (auto* res = std::get_if<s32>(&res_v)) {
|
||||
@@ -496,11 +522,13 @@ void BSD::ExecuteWork(HLERequestContext& ctx, Work work) {
|
||||
}
|
||||
|
||||
std::pair<s32, Errno> BSD::SocketImpl(Domain domain, Type type, Protocol protocol) {
|
||||
|
||||
if (type == Type::SEQPACKET) {
|
||||
UNIMPLEMENTED_MSG("SOCK_SEQPACKET errno management");
|
||||
} else if (type == Type::RAW && (domain != Domain::INET || protocol != Protocol::ICMP)) {
|
||||
UNIMPLEMENTED_MSG("SOCK_RAW errno management");
|
||||
// user bsd:u has restrictions on SOCK_SEQPACKET and SOCK_RAW
|
||||
if (is_user && (type == Type::SEQPACKET || type == Type::RAW)) {
|
||||
if (type == Type::RAW && domain == Domain::INET && protocol == Protocol::ICMP) {
|
||||
// fine, can use on bsd:s and bsd:u
|
||||
} else {
|
||||
return {-1, Errno::INVAL};
|
||||
}
|
||||
}
|
||||
|
||||
[[maybe_unused]] const bool unk_flag = (static_cast<u32>(type) & 0x20000000) != 0;
|
||||
@@ -1052,14 +1080,15 @@ void BSD::OnProxyPacketReceived(const Network::ProxyPacket& packet) {
|
||||
}
|
||||
}
|
||||
|
||||
BSD::BSD(Core::System& system_, const char* name)
|
||||
: ServiceFramework{system_, name} {
|
||||
BSD::BSD(Core::System& system_, const char* name, bool is_user_)
|
||||
: ServiceFramework{system_, name}
|
||||
, is_user{is_user_} {
|
||||
// clang-format off
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, &BSD::RegisterClient, "RegisterClient"},
|
||||
{1, &BSD::StartMonitoring, "StartMonitoring"},
|
||||
{2, &BSD::Socket, "Socket"},
|
||||
{3, nullptr, "SocketExempt"},
|
||||
{3, &BSD::SocketExempt, "SocketExempt"},
|
||||
{4, nullptr, "Open"},
|
||||
{5, &BSD::Select, "Select"},
|
||||
{6, &BSD::Poll, "Poll"},
|
||||
@@ -1125,7 +1154,8 @@ std::unique_lock<std::mutex> BSD::LockService() noexcept {
|
||||
return {};
|
||||
}
|
||||
|
||||
BSDCFG::BSDCFG(Core::System& system_) : ServiceFramework{system_, "bsdcfg"} {
|
||||
BSDCFG::BSDCFG(Core::System& system_, const char *name)
|
||||
: ServiceFramework{system_, name} {
|
||||
// clang-format off
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, nullptr, "SetIfUp"},
|
||||
@@ -1152,4 +1182,16 @@ BSDCFG::BSDCFG(Core::System& system_) : ServiceFramework{system_, "bsdcfg"} {
|
||||
|
||||
BSDCFG::~BSDCFG() = default;
|
||||
|
||||
BSD_NU::BSD_NU(Core::System& system_)
|
||||
: ServiceFramework{system_, "bsd:nu"} {
|
||||
// clang-format off
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, nullptr, "CreateUserService"},
|
||||
};
|
||||
// clang-format on
|
||||
RegisterHandlers(functions);
|
||||
}
|
||||
|
||||
BSD_NU::~BSD_NU() = default;
|
||||
|
||||
} // namespace Service::Sockets
|
||||
|
||||
@@ -29,7 +29,7 @@ namespace Service::Sockets {
|
||||
|
||||
class BSD final : public ServiceFramework<BSD> {
|
||||
public:
|
||||
explicit BSD(Core::System& system_, const char* name);
|
||||
explicit BSD(Core::System& system_, const char* name, bool is_user);
|
||||
~BSD() override;
|
||||
|
||||
// These methods are called from SSL; the first two are also called from
|
||||
@@ -129,6 +129,7 @@ private:
|
||||
void RegisterClient(HLERequestContext& ctx);
|
||||
void StartMonitoring(HLERequestContext& ctx);
|
||||
void Socket(HLERequestContext& ctx);
|
||||
void SocketExempt(HLERequestContext& ctx);
|
||||
void Select(HLERequestContext& ctx);
|
||||
void Poll(HLERequestContext& ctx);
|
||||
void Accept(HLERequestContext& ctx);
|
||||
@@ -155,8 +156,7 @@ private:
|
||||
void ExecuteWork(HLERequestContext& ctx, Work work);
|
||||
|
||||
std::pair<s32, Errno> SocketImpl(Domain domain, Type type, Protocol protocol);
|
||||
std::pair<s32, Errno> PollImpl(std::vector<u8>& write_buffer, std::span<const u8> read_buffer,
|
||||
s32 nfds, s32 timeout);
|
||||
std::pair<s32, Errno> PollImpl(std::vector<u8>& write_buffer, std::span<const u8> read_buffer, s32 nfds, s32 timeout);
|
||||
std::pair<s32, Errno> AcceptImpl(s32 fd, std::vector<u8>& write_buffer);
|
||||
Errno BindImpl(s32 fd, std::span<const u8> addr);
|
||||
Errno ConnectImpl(s32 fd, std::span<const u8> addr);
|
||||
@@ -189,12 +189,19 @@ private:
|
||||
|
||||
protected:
|
||||
std::unique_lock<std::mutex> LockService() noexcept override;
|
||||
bool is_user = false;
|
||||
};
|
||||
|
||||
class BSDCFG final : public ServiceFramework<BSDCFG> {
|
||||
public:
|
||||
explicit BSDCFG(Core::System& system_);
|
||||
explicit BSDCFG(Core::System& system_, const char *name);
|
||||
~BSDCFG() override;
|
||||
};
|
||||
|
||||
class BSD_NU final : public ServiceFramework<BSD_NU> {
|
||||
public:
|
||||
explicit BSD_NU(Core::System& system_);
|
||||
~BSD_NU() override;
|
||||
};
|
||||
|
||||
} // namespace Service::Sockets
|
||||
|
||||
@@ -406,4 +406,21 @@ void SFDNSRES::ResolverSetOptionRequest(HLERequestContext& ctx) {
|
||||
rb.Push(ResultSuccess);
|
||||
rb.Push<s32>(0); // bsd errno
|
||||
}
|
||||
|
||||
|
||||
DNS_PRIV::DNS_PRIV(Core::System& system_)
|
||||
: ServiceFramework{system_, "dns:priv"} {
|
||||
// clang-format off
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, nullptr, "Cmd0"},
|
||||
{1, nullptr, "Cmd1"},
|
||||
{2, nullptr, "Cmd2"},
|
||||
};
|
||||
// clang-format on
|
||||
RegisterHandlers(functions);
|
||||
}
|
||||
|
||||
DNS_PRIV::~DNS_PRIV() = default;
|
||||
|
||||
|
||||
} // namespace Service::Sockets
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
@@ -25,4 +28,10 @@ private:
|
||||
void ResolverSetOptionRequest(HLERequestContext& ctx);
|
||||
};
|
||||
|
||||
class DNS_PRIV final : public ServiceFramework<DNS_PRIV> {
|
||||
public:
|
||||
explicit DNS_PRIV(Core::System& system_);
|
||||
~DNS_PRIV() override;
|
||||
};
|
||||
|
||||
} // namespace Service::Sockets
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
@@ -12,12 +15,16 @@ namespace Service::Sockets {
|
||||
void LoopProcess(Core::System& system) {
|
||||
auto server_manager = std::make_unique<ServerManager>(system);
|
||||
|
||||
server_manager->RegisterNamedService("bsd:s", std::make_shared<BSD>(system, "bsd:s"));
|
||||
server_manager->RegisterNamedService("bsd:u", std::make_shared<BSD>(system, "bsd:u"));
|
||||
server_manager->RegisterNamedService("bsdcfg", std::make_shared<BSDCFG>(system));
|
||||
server_manager->RegisterNamedService("bsd:s", std::make_shared<BSD>(system, "bsd:s", false));
|
||||
server_manager->RegisterNamedService("bsd:u", std::make_shared<BSD>(system, "bsd:u", true));
|
||||
server_manager->RegisterNamedService("bsd:a", std::make_shared<BSD>(system, "bsd:a", true));
|
||||
server_manager->RegisterNamedService("bsd:nu", std::make_shared<BSD_NU>(system));
|
||||
server_manager->RegisterNamedService("bsdcfg", std::make_shared<BSDCFG>(system, "bsdcfg"));
|
||||
server_manager->RegisterNamedService("ifcfg", std::make_shared<BSDCFG>(system, "ifcfg"));
|
||||
server_manager->RegisterNamedService("nsd:a", std::make_shared<NSD>(system, "nsd:a"));
|
||||
server_manager->RegisterNamedService("nsd:u", std::make_shared<NSD>(system, "nsd:u"));
|
||||
server_manager->RegisterNamedService("sfdnsres", std::make_shared<SFDNSRES>(system));
|
||||
server_manager->RegisterNamedService("dns:priv", std::make_shared<DNS_PRIV>(system));
|
||||
server_manager->StartAdditionalHostThreads("bsdsocket", 2);
|
||||
ServerManager::RunServer(std::move(server_manager));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user