mirror of
https://github.com/FEX-Emu/FEX.git
synced 2026-10-09 19:00:20 +02:00
FEX doesn't support seccomp in userspace and allowing these through causes chromium secure sandbox to break. Disabling these with EINVAL allows FEX to behave as if seccomp isn't enabled in the kernel config Necessary to get the Civ6 launcher further
113 lines
4.0 KiB
C++
113 lines
4.0 KiB
C++
/*
|
|
$info$
|
|
tags: LinuxSyscalls|syscalls-shared
|
|
$end_info$
|
|
*/
|
|
|
|
#include "Tests/LinuxSyscalls/Syscalls.h"
|
|
#include "Tests/LinuxSyscalls/x64/Syscalls.h"
|
|
#include "Tests/LinuxSyscalls/x32/Syscalls.h"
|
|
|
|
#include <FEXCore/Utils/LogManager.h>
|
|
|
|
#include <cstring>
|
|
#include <linux/kcmp.h>
|
|
#include <linux/seccomp.h>
|
|
#include <stdarg.h>
|
|
#include <stddef.h>
|
|
#include <stdint.h>
|
|
#include <syslog.h>
|
|
#include <sys/random.h>
|
|
#include <sys/resource.h>
|
|
#include <sys/syscall.h>
|
|
#include <sys/utsname.h>
|
|
#include <sys/klog.h>
|
|
#include <unistd.h>
|
|
|
|
namespace FEX::HLE {
|
|
using cap_user_header_t = void*;
|
|
using cap_user_data_t = void*;
|
|
|
|
void RegisterInfo() {
|
|
REGISTER_SYSCALL_IMPL(uname, [](FEXCore::Core::CpuStateFrame *Frame, struct utsname *buf) -> uint64_t {
|
|
struct utsname Local{};
|
|
if (::uname(&Local) == 0) {
|
|
memcpy(buf->nodename, Local.nodename, sizeof(Local.nodename));
|
|
static_assert(sizeof(Local.nodename) <= sizeof(buf->nodename));
|
|
}
|
|
else {
|
|
strcpy(buf->nodename, "FEXCore");
|
|
LogMan::Msg::E("Couldn't determine host nodename. Defaulting to '%s'", buf->nodename);
|
|
}
|
|
strcpy(buf->sysname, "Linux");
|
|
strcpy(buf->release, "5.0.0");
|
|
const char version[] = "#" GIT_DESCRIBE_STRING " SMP " __DATE__ " " __TIME__;
|
|
strcpy(buf->version, version);
|
|
static_assert(sizeof(version) <= sizeof(buf->version), "uname version define became too large!");
|
|
// Tell the guest that we are a 64bit kernel
|
|
strcpy(buf->machine, "x86_64");
|
|
return 0;
|
|
});
|
|
|
|
REGISTER_SYSCALL_IMPL(getrlimit, [](FEXCore::Core::CpuStateFrame *Frame, int resource, struct rlimit *rlim) -> uint64_t {
|
|
uint64_t Result = ::getrlimit(resource, rlim);
|
|
SYSCALL_ERRNO();
|
|
});
|
|
|
|
REGISTER_SYSCALL_IMPL(setrlimit, [](FEXCore::Core::CpuStateFrame *Frame, int resource, const struct rlimit *rlim) -> uint64_t {
|
|
uint64_t Result = ::setrlimit(resource, rlim);
|
|
SYSCALL_ERRNO();
|
|
});
|
|
|
|
REGISTER_SYSCALL_IMPL(syslog, [](FEXCore::Core::CpuStateFrame *Frame, int type, char *bufp, int len) -> uint64_t {
|
|
uint64_t Result = ::klogctl(type, bufp, len);
|
|
SYSCALL_ERRNO();
|
|
});
|
|
|
|
REGISTER_SYSCALL_IMPL(getrandom, [](FEXCore::Core::CpuStateFrame *Frame, void *buf, size_t buflen, unsigned int flags) -> uint64_t {
|
|
uint64_t Result = ::getrandom(buf, buflen, flags);
|
|
SYSCALL_ERRNO();
|
|
});
|
|
|
|
REGISTER_SYSCALL_IMPL(capget, [](FEXCore::Core::CpuStateFrame *Frame, cap_user_header_t hdrp, cap_user_data_t datap) -> uint64_t {
|
|
uint64_t Result = ::syscall(SYS_capget, hdrp, datap);
|
|
SYSCALL_ERRNO();
|
|
});
|
|
|
|
REGISTER_SYSCALL_IMPL(capset, [](FEXCore::Core::CpuStateFrame *Frame, cap_user_header_t hdrp, const cap_user_data_t datap) -> uint64_t {
|
|
uint64_t Result = ::syscall(SYS_capset, hdrp, datap);
|
|
SYSCALL_ERRNO();
|
|
});
|
|
|
|
REGISTER_SYSCALL_IMPL(getcpu, [](FEXCore::Core::CpuStateFrame *Frame, unsigned *cpu, unsigned *node, struct getcpu_cache *tcache) -> uint64_t {
|
|
uint32_t LocalCPU{};
|
|
uint32_t LocalNode{};
|
|
// tcache is ignored
|
|
uint64_t Result = ::syscall(SYS_getcpu, cpu ? &LocalCPU : nullptr, node ? &LocalNode : nullptr, nullptr);
|
|
if (Result == 0) {
|
|
if (cpu) {
|
|
// Ensure we don't return a number over our number of emulated cores
|
|
*cpu = LocalCPU % FEX::HLE::_SyscallHandler->ThreadsConfig();
|
|
}
|
|
|
|
if (node) {
|
|
// Just claim we are part of node zero
|
|
*node = 0;
|
|
}
|
|
}
|
|
SYSCALL_ERRNO();
|
|
});
|
|
|
|
//compare two processes to determine if they share a kernel resource
|
|
REGISTER_SYSCALL_IMPL(kcmp, [](FEXCore::Core::CpuStateFrame *Frame, pid_t pid1, pid_t pid2, int type, unsigned long idx1, unsigned long idx2) -> uint64_t {
|
|
uint64_t Result = ::syscall(SYS_kcmp, pid1, pid2, type, idx1, idx2);
|
|
SYSCALL_ERRNO();
|
|
});
|
|
|
|
REGISTER_SYSCALL_IMPL(seccomp, [](FEXCore::Core::CpuStateFrame *Frame, unsigned int operation, unsigned int flags, void *args) -> uint64_t {
|
|
// FEX doesn't support seccomp
|
|
return -EINVAL;
|
|
});
|
|
}
|
|
}
|