[hackers] [slock] Ensure Polyphemus-Mitigation and properly drop privileges || FRIGN

From: <git_AT_suckless.org>
Date: Thu, 8 Sep 2016 23:34:49 +0200 (CEST)

commit 22eba05f3683c12fa6a5f898d08c33704c9fbb73
Author: FRIGN <dev_AT_frign.de>
AuthorDate: Wed Sep 7 13:32:29 2016 +0200
Commit: Markus Teich <markus.teich_AT_stusta.mhn.de>
CommitDate: Thu Sep 8 00:36:45 2016 +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)

diff --git a/config.def.h b/config.def.h
index eae2d9a..6fba2b6 100644
--- a/config.def.h
+++ b/config.def.h
_AT_@ -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
index 049305c..11357a7 100644
--- a/config.mk
+++ b/config.mk
_AT_@ -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
index da4b099..7127ebe 100644
--- a/slock.c
+++ b/slock.c
_AT_@ -6,6 +6,7 @@
 
 #include <ctype.h>
 #include <errno.h>
+#include <grp.h>
 #include <pwd.h>
 #include <stdarg.h>
 #include <stdlib.h>
_AT_@ -83,7 +84,6 @@ dontkillme(void)
 }
 #endif
 
-/* only run as root */
 static const char *
 getpw(void)
 {
_AT_@ -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->pw_uid) < 0))
- die("slock: cannot drop privileges\n");
         return rval;
 }
 
_AT_@ -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;
_AT_@ -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
_AT_@ -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);
 
Received on Thu Sep 08 2016 - 23:34:49 CEST

This archive was generated by hypermail 2.3.0 : Thu Sep 08 2016 - 23:36:14 CEST