diff --git a/CMakeLists.txt b/CMakeLists.txt index fa01e3a50e1..6f76d70d2e5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -23,6 +23,7 @@ if (NOT WIN32) set(USE_EDITLINE ON CACHE BOOL "Whether or not to enable the CLI-mode debugger") endif() set(USE_GDB_STUB ON CACHE BOOL "Whether or not to enable the GDB stub ARM debugger") +set(USE_PLEDGE_UNVEIL OFF CACHE BOOL "Whether or not to drop privileges with pledge and unveil") set(USE_FFMPEG ON CACHE BOOL "Whether or not to enable FFmpeg support") set(USE_ZLIB ON CACHE BOOL "Whether or not to enable zlib support") set(USE_MINIZIP ON CACHE BOOL "Whether or not to enable external minizip support") @@ -475,6 +476,10 @@ find_feature(USE_SQLITE3 "sqlite3") find_feature(USE_ELF "libelf") find_feature(ENABLE_PYTHON "PythonLibs") +if(USE_PLEDGE_UNVEIL) + set(USE_EPOXY OFF) +endif() + if(USE_FFMPEG) set(USE_LIBAVRESAMPLE ON) set(USE_LIBSWRESAMPLE ON) @@ -515,6 +520,10 @@ if(USE_GDB_STUB) endif() source_group("Debugger" FILES ${DEBUGGER_SRC}) +if(USE_PLEDGE_UNVEIL) + list(APPEND FEATURES PLEDGE_UNVEIL) +endif() + if(USE_FFMPEG) list(APPEND FEATURES FFMPEG) if(USE_LIBSWRESAMPLE) @@ -1229,6 +1238,7 @@ if(NOT QUIET) message(STATUS " CLI debugger: ${USE_EDITLINE}") endif() message(STATUS " GDB stub: ${USE_GDB_STUB}") + message(STATUS " pledge/unveil: ${USE_PLEDGE_UNVEIL}") message(STATUS " Video recording: ${USE_FFMPEG}") message(STATUS " GIF recording: ${USE_MAGICK}") message(STATUS " Screenshot/advanced savestate support: ${USE_PNG}") diff --git a/src/platform/sdl/main.c b/src/platform/sdl/main.c index dd20b0397fe..14fab2f98c9 100644 --- a/src/platform/sdl/main.c +++ b/src/platform/sdl/main.c @@ -44,6 +44,12 @@ static void mSDLDeinit(struct mSDLRenderer* renderer); static int mSDLRun(struct mSDLRenderer* renderer, struct mArguments* args); +#ifdef USE_PLEDGE_UNVEIL +static bool mUnveil(struct mCore* core); +static bool mPledgeBroad(struct mArguments* args); +static bool mPledgeNarrow(struct mArguments* args); +#endif + static struct VFile* _state = NULL; static void _loadState(struct mCoreThread* thread) { @@ -150,6 +156,15 @@ int main(int argc, char** argv) { renderer.player.bindings = &renderer.core->inputMap; mSDLInitBindingsGBA(&renderer.core->inputMap); mSDLInitEvents(&renderer.events); + +#ifdef USE_PLEDGE_UNVEIL + if (!mPledgeBroad(&args)) { + freeArguments(&args); + fprintf(stderr, "pledge\n"); + return 1; + } +#endif + mSDLEventsLoadConfig(&renderer.events, mCoreConfigGetInput(&renderer.core->config)); mSDLAttachPlayer(&renderer.events, &renderer.player); mSDLPlayerLoadConfig(&renderer.player, mCoreConfigGetInput(&renderer.core->config)); @@ -247,6 +262,17 @@ int mSDLRun(struct mSDLRenderer* renderer, struct mArguments* args) { state->close(state); } } +#ifdef USE_PLEDGE_UNVEIL + if (!mUnveil(renderer->core)) { + didFail = true; + fprintf(stderr, "unveil\n"); + } + + if (!mPledgeNarrow(args)) { + didFail = true; + fprintf(stderr, "pledge\n"); + } +#endif renderer->runloop(renderer, &thread); mSDLPauseAudio(&renderer->audio); if (mCoreThreadHasCrashed(&thread)) { @@ -295,3 +321,58 @@ static void mSDLDeinit(struct mSDLRenderer* renderer) { SDL_Quit(); } + +#ifdef USE_PLEDGE_UNVEIL +static bool mUnveil(struct mCore* core) { + int slot, snret; + char name[PATH_MAX]; + for (slot = 1; slot < 10; slot++) { + snret = snprintf(name, sizeof(name), "%s.ss%i", core->dirs.baseName, slot); + if (snret < 0 || snret >= sizeof(name)) { + return false; + } + if (unveil(name, "rwc") == -1) { + return false; + } + } + return true; +} + +static bool mPledgeBroad(struct mArguments *args) { + if (args->debuggerType == DEBUGGER_CLI) { + if (pledge("stdio rpath wpath cpath inet fattr unix dns tty drm audio unveil", NULL) == -1) { + return false; + } +#ifdef USE_GDB_STUB + } else if (args->debuggerType == DEBUGGER_GDB) { + if (pledge("stdio rpath wpath cpath inet fattr unix dns drm audio unveil", NULL) == -1) { + return false; + } +#endif + } else { + if (pledge("stdio rpath wpath cpath inet fattr unix dns drm audio unveil", NULL) == -1) { + return false; + } + } + return true; +} + +static bool mPledgeNarrow(struct mArguments *args) { + if (args->debuggerType == DEBUGGER_CLI) { + if (pledge("stdio rpath wpath cpath fattr tty drm audio", NULL) == -1) { + return false; + } +#ifdef USE_GDB_STUB + } else if (args->debuggerType == DEBUGGER_GDB) { + if (pledge("stdio rpath wpath cpath inet fattr drm audio", NULL) == -1) { + return false; + } +#endif + } else { + if (pledge("stdio rpath wpath cpath fattr drm audio", NULL) == -1) { + return false; + } + } + return true; +} +#endif