Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SDL: Add option to drop privileges with unveil()/pledge() #1271

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
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
15 changes: 15 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@ if(NOT LIBMGBA_ONLY)
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")
if (CMAKE_SYSTEM_NAME STREQUAL OpenBSD)
set(USE_PLEDGE ON CACHE BOOL "Whether or not to drop privileges with pledge")
endif()
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")
Expand Down Expand Up @@ -465,6 +468,10 @@ if(DISABLE_DEPS)
set(USE_ZLIB OFF)
endif()

if(USE_PLEDGE)
set(USE_EPOXY OFF)
endif()

set(WANT_ZLIB ${USE_ZLIB})
set(WANT_PNG ${USE_PNG})
set(WANT_SQLITE3 ${USE_SQLITE3})
Expand All @@ -489,6 +496,10 @@ find_feature(USE_SQLITE3 "sqlite3")
find_feature(USE_ELF "libelf")
find_feature(ENABLE_PYTHON "PythonLibs")

if(USE_PLEDGE)
bentley marked this conversation as resolved.
Show resolved Hide resolved
Copy link
Member

Choose a reason for hiding this comment

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

You forgot to delete it here.

set(USE_EPOXY OFF)
endif()

if(USE_FFMPEG AND NOT DEFINED VCPKG_TARGET_TRIPLET)
set(USE_LIBAVRESAMPLE ON)
set(USE_LIBSWRESAMPLE ON)
Expand Down Expand Up @@ -520,6 +531,10 @@ if(USE_GDB_STUB)
endif()
source_group("Debugger" FILES ${DEBUGGER_SRC})

if(USE_PLEDGE)
list(APPEND FEATURES PLEDGE)
endif()

if(USE_FFMPEG)
list(APPEND FEATURES FFMPEG)
if(USE_LIBSWRESAMPLE)
Expand Down
65 changes: 65 additions & 0 deletions src/platform/sdl/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,11 @@ static void mSDLDeinit(struct mSDLRenderer* renderer);

static int mSDLRun(struct mSDLRenderer* renderer, struct mArguments* args);

#ifdef USE_PLEDGE
static bool mPledgeBroad(struct mArguments* args);
static bool mPledgeNarrow(struct mArguments* args);
#endif

static struct VFile* _state = NULL;

static void _loadState(struct mCoreThread* thread) {
Expand Down Expand Up @@ -149,6 +154,20 @@ int main(int argc, char** argv) {
renderer.player.bindings = &renderer.core->inputMap;
mSDLInitBindingsGBA(&renderer.core->inputMap);
mSDLInitEvents(&renderer.events);

#ifdef USE_PLEDGE
if (!mPledgeBroad(&args)) {
Copy link
Member

Choose a reason for hiding this comment

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

Is there any reason this isn't done immediately after generating the args struct? There's a lot of stuff you're not freeing or deiniting here.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Joystick initialization calls some USB ioctls that are not allowed by any pledge, so this is as early as the pledge call can go.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I gave this another try.

freeArguments(&args);
mCoreConfigDeinit(&renderer.core->config);
mInputMapDeinit(&renderer.core->inputMap);
renderer.core->deinit(renderer.core);
mSDLDeinitEvents(&renderer.events);
Copy link
Member

Choose a reason for hiding this comment

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

mSDLDeinitEvents is called by mSDLDeinit, you don't need to call it yourself. mCoreConfigFreeOpts should be called though.

mSDLDeinit(&renderer);
fputs("Broad pledge() failed\n", stderr);
Copy link
Member

Choose a reason for hiding this comment

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

fputs already appends the \n.

return 1;
}
#endif

mSDLEventsLoadConfig(&renderer.events, mCoreConfigGetInput(&renderer.core->config));
mSDLAttachPlayer(&renderer.events, &renderer.player);
mSDLPlayerLoadConfig(&renderer.player, mCoreConfigGetInput(&renderer.core->config));
Expand Down Expand Up @@ -264,6 +283,12 @@ int mSDLRun(struct mSDLRenderer* renderer, struct mArguments* args) {
state->close(state);
}
}
#ifdef USE_PLEDGE
if (!mPledgeNarrow(args)) {
didFail = true;
fputs("Narrow pledge() failed\n", stderr);
Copy link
Member

Choose a reason for hiding this comment

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

Ditto about the \n.

}
#endif
renderer->runloop(renderer, &thread);
mSDLPauseAudio(&renderer->audio);
if (mCoreThreadHasCrashed(&thread)) {
Expand Down Expand Up @@ -312,3 +337,43 @@ static void mSDLDeinit(struct mSDLRenderer* renderer) {

SDL_Quit();
}

#ifdef USE_PLEDGE
static bool mPledgeBroad(struct mArguments *args) {
if (args->debuggerType == DEBUGGER_CLI) {
if (pledge("stdio rpath wpath cpath inet fattr unix dns sendfd prot_exec 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 unix dns sendfd prot_exec drm audio", NULL) == -1) {
return false;
}
#endif
} else {
if (pledge("stdio rpath wpath cpath inet fattr unix dns sendfd prot_exec drm audio", NULL) == -1) {
return false;
}
}
return true;
}

static bool mPledgeNarrow(struct mArguments *args) {
if (args->debuggerType == DEBUGGER_CLI) {
if (pledge("stdio rpath wpath cpath fattr sendfd tty prot_exec drm audio", NULL) == -1) {
return false;
}
#ifdef USE_GDB_STUB
} else if (args->debuggerType == DEBUGGER_GDB) {
if (pledge("stdio rpath wpath cpath inet fattr sendfd prot_exec drm audio", NULL) == -1) {
return false;
}
#endif
} else {
if (pledge("stdio rpath wpath cpath fattr sendfd prot_exec drm audio", NULL) == -1) {
return false;
}
}
return true;
}
#endif