Ensure Polyphemus-Mitigation and properly drop privileges - slock - simple X di… | |
git clone git://git.suckless.org/slock | |
Log | |
Files | |
Refs | |
README | |
LICENSE | |
--- | |
commit 22eba05f3683c12fa6a5f898d08c33704c9fbb73 | |
parent 04143fd68dbc656905714eff5c208fadb3464e25 | |
Author: FRIGN <[email protected]> | |
Date: Wed, 7 Sep 2016 13:32:29 +0200 | |
Ensure Polyphemus-Mitigation and properly drop privileges | |
Don't hide privilege drops inside readpw() and actually make it | |
configurable what you are dropping to in config.h. | |
The privilege drop comes after opening the Display because the | |
user "nobody" with "nogroup" can't do that. | |
So why do I call this strategy the Polyphemus-Mitigation? | |
""" | |
After the giant returns in the evening and eats two more of the men, | |
Odysseus offers Polyphemus some strong and undiluted wine given to him | |
earlier on his journey. Drunk and unwary, the giant asks Odysseus his | |
name, promising him a guest-gift if he answers. Odysseus tells him | |
"Οὖτις", which means "nobody" and Polyphemus promises to eat this | |
"Nobody" last of all. With that, he falls into a drunken sleep. Odysseus | |
had meanwhile hardened a wooden stake in the fire and now drives it into | |
Polyphemus' eye. When Polyphemus shouts for help from his fellow giants, | |
saying that "Nobody" has hurt him, they think Polyphemus is being | |
afflicted by divine power and recommend prayer as the answer. | |
""" | |
(source: https://en.wikipedia.org/wiki/Polyphemus) | |
Diffstat: | |
M config.def.h | 4 ++++ | |
M config.mk | 2 +- | |
M slock.c | 30 +++++++++++++++++++++++++----- | |
3 files changed, 30 insertions(+), 6 deletions(-) | |
--- | |
diff --git a/config.def.h b/config.def.h | |
@@ -1,3 +1,7 @@ | |
+/* user and group to drop privileges to */ | |
+static const char *user = "nobody"; | |
+static const char *group = "nogroup"; | |
+ | |
static const char *colorname[NUMCOLS] = { | |
"black", /* after initialization */ | |
"#005577", /* during input */ | |
diff --git a/config.mk b/config.mk | |
@@ -15,7 +15,7 @@ INCS = -I. -I/usr/include -I${X11INC} | |
LIBS = -L/usr/lib -lc -lcrypt -L${X11LIB} -lX11 -lXext -lXrandr | |
# flags | |
-CPPFLAGS = -DVERSION=\"${VERSION}\" -DHAVE_SHADOW_H | |
+CPPFLAGS = -DVERSION=\"${VERSION}\" -D_DEFAULT_SOURCE -DHAVE_SHADOW_H | |
CFLAGS = -std=c99 -pedantic -Wall -Os ${INCS} ${CPPFLAGS} | |
LDFLAGS = -s ${LIBS} | |
COMPATSRC = explicit_bzero.c | |
diff --git a/slock.c b/slock.c | |
@@ -6,6 +6,7 @@ | |
#include <ctype.h> | |
#include <errno.h> | |
+#include <grp.h> | |
#include <pwd.h> | |
#include <stdarg.h> | |
#include <stdlib.h> | |
@@ -83,7 +84,6 @@ dontkillme(void) | |
} | |
#endif | |
-/* only run as root */ | |
static const char * | |
getpw(void) | |
{ | |
@@ -119,10 +119,6 @@ getpw(void) | |
} | |
#endif /* HAVE_SHADOW_H */ | |
- /* drop privileges */ | |
- if (geteuid() == 0 && | |
- ((getegid() != pw->pw_gid && setgid(pw->pw_gid) < 0) || setuid(pw-… | |
- die("slock: cannot drop privileges\n"); | |
return rval; | |
} | |
@@ -316,6 +312,10 @@ usage(void) | |
int | |
main(int argc, char **argv) { | |
+ struct passwd *pwd; | |
+ struct group *grp; | |
+ uid_t duid; | |
+ gid_t dgid; | |
const char *pws; | |
Display *dpy; | |
int s, nlocks; | |
@@ -328,6 +328,18 @@ main(int argc, char **argv) { | |
usage(); | |
} ARGEND | |
+ /* validate drop-user and -group */ | |
+ errno = 0; | |
+ if (!(pwd = getpwnam(user))) | |
+ die("slock: getpwnam %s: %s\n", user, errno ? | |
+ strerror(errno) : "user entry not found"); | |
+ duid = pwd->pw_uid; | |
+ errno = 0; | |
+ if (!(grp = getgrnam(group))) | |
+ die("slock: getgrnam %s: %s\n", group, errno ? | |
+ strerror(errno) : "group entry not found"); | |
+ dgid = grp->gr_gid; | |
+ | |
#ifdef __linux__ | |
dontkillme(); | |
#endif | |
@@ -339,6 +351,14 @@ main(int argc, char **argv) { | |
if (!(dpy = XOpenDisplay(NULL))) | |
die("slock: cannot open display\n"); | |
+ /* drop privileges */ | |
+ if (setgroups(0, NULL) < 0) | |
+ die("slock: setgroups: %s\n", strerror(errno)); | |
+ if (setgid(dgid) < 0) | |
+ die("slock: setgid: %s\n", strerror(errno)); | |
+ if (setuid(duid) < 0) | |
+ die("slock: setuid: %s\n", strerror(errno)); | |
+ | |
/* check for Xrandr support */ | |
rr = XRRQueryExtension(dpy, &rrevbase, &rrerrbase); | |