diff --git a/cmake/Modules/EttercapLibCheck.cmake b/cmake/Modules/EttercapLibCheck.cmake index 5a64b543b..bbb28299c 100644 --- a/cmake/Modules/EttercapLibCheck.cmake +++ b/cmake/Modules/EttercapLibCheck.cmake @@ -233,6 +233,7 @@ check_function_exists(memmem HAVE_MEMMEM) check_function_exists(memrchr HAVE_MEMRCHR) check_function_exists(basename HAVE_BASENAME) check_function_exists(strndup HAVE_STRNDUP) +check_function_exists(setresuid HAVE_SETRESUID) find_library(HAVE_PCAP pcap) if(HAVE_PCAP) diff --git a/include/config.h.cmake b/include/config.h.cmake index 69d4eded8..265404a84 100644 --- a/include/config.h.cmake +++ b/include/config.h.cmake @@ -43,6 +43,7 @@ #cmakedefine HAVE_MEMMEM #cmakedefine HAVE_MEMRCHR #cmakedefine HAVE_BASENAME +#cmakedefine HAVE_SETRESUID #cmakedefine HAVE_NCURSES #cmakedefine HAVE_GTK diff --git a/include/ec.h b/include/ec.h index d69de613b..553698250 100644 --- a/include/ec.h +++ b/include/ec.h @@ -28,6 +28,7 @@ #define _REENTRANT /* for strtok_r() */ #endif #include +#include /* for setresuid() and setresgid() */ #if defined (__USE_GNU) #undef __USE_GNU #endif @@ -35,7 +36,6 @@ #undef _GNU_SOURCE #endif #include -#include #include /* diff --git a/src/ec_utils.c b/src/ec_utils.c index ab8bbb4b6..2d25d1dc8 100644 --- a/src/ec_utils.c +++ b/src/ec_utils.c @@ -184,8 +184,17 @@ void regain_privs(void) #ifdef OS_WINDOWS return; #endif +#ifdef HAVE_SETRESUID + /* the saved set-user-ID is still 0, see drop_privs() */ + if (setresuid(0, 0, 0) < 0) + ERROR_MSG("setresuid()"); + + if (setresgid(0, 0, 0) < 0) + ERROR_MSG("setresgid()"); +#else if(seteuid(0) < 0) ERROR_MSG("seteuid()"); +#endif USER_MSG("Regained root privileges: %d %d", getuid(), geteuid()); } @@ -227,6 +236,22 @@ void drop_privs(void) reset_logfile_owners(geteuid(), getegid(), uid, gid); +#ifdef HAVE_SETRESUID + /* + * set both the real and the effective IDs, keeping only the saved + * set-user-ID as root so regain_privs() still works. + * a process with real UID 0 and a non-root effective UID looks like a + * setuid binary to its children, and e.g. bubblewrap (used by the + * glycin image loaders behind GTK) refuses to run in that state. + */ + DEBUG_MSG("drop_privs: setresuid(%d) setresgid(%d)", uid, gid); + + if ( setresgid(gid, gid, 0) < 0 ) + ERROR_MSG("setresgid()"); + + if ( setresuid(uid, uid, 0) < 0 ) + ERROR_MSG("setresuid()"); +#else DEBUG_MSG("drop_privs: seteuid(%d) setegid(%d)", uid, gid); /* drop to a good uid/gid ;) */ @@ -235,6 +260,7 @@ void drop_privs(void) if ( seteuid(uid) < 0 ) ERROR_MSG("seteuid()"); +#endif DEBUG_MSG("privs: UID: %d %d GID: %d %d", (int)getuid(), (int)geteuid(), (int)getgid(), (int)getegid() ); USER_MSG("Privileges dropped to EUID %d EGID %d...\n\n", (int)geteuid(), (int)getegid() );