Good evening fellow hackers,
I sat down this evening to write down some patches that have been
floating around in my head for a while.
See attached. Most important is the patch which removes the abomination
of user $USER which actually poses quite a risk and only is done on
part of the systems. The largest one is the one removing global state
of the program to make code audits simpler.
Cheers
FRIGN
--
FRIGN
>From 86c4a4edc72958461c9142d218ac0a285751e708 Mon Sep 17 00:00:00 2001
From: FRIGN
Date: Sun, 11 Sep 2016 23:08:19 +0200
Subject: [PATCH 1/3] Localize and rework data structures
For a project like slock there is no need to carry around global state.
By moving the three structures to main() it is now clear which functions
modify which state, greatly improving the readability of the code,
especially given slock is a suid program.
---
slock.c | 62 ++
1 file changed, 34 insertions(+), 28 deletions(-)
diff --git a/slock.c b/slock.c
index 7127ebe..83f6810 100644
--- a/slock.c
+++ b/slock.c
@@ -33,18 +33,18 @@ enum {
#include "config.h"
-typedef struct {
+struct lock {
int screen;
Window root, win;
Pixmap pmap;
unsigned long colors[NUMCOLS];
-} Lock;
+};
-static Lock **locks;
-static int nscreens;
-static Bool rr;
-static int rrevbase;
-static int rrerrbase;
+struct xrandr {
+ int active;
+ int evbase;
+ int errbase;
+};
static void
die(const char *errstr, ...)
@@ -123,7 +123,8 @@ getpw(void)
}
static void
-readpw(Display *dpy, const char *pws)
+readpw(Display *dpy, struct xrandr *rr, struct lock **locks, int nscreens,
+ const char *pws)
{
char buf[32], passwd[256], *encrypted;
int num, screen, running, failure;
@@ -194,7 +195,7 @@ readpw(Display *dpy, const char *pws)
}
oldc = color;
}
- } else if (rr && ev.type == rrevbase + RRScreenChangeNotify) {
+ } else if (rr->active && ev.type == rr->evbase + RRScreenChangeNotify) {
XRRScreenChangeNotifyEvent *rre = (XRRScreenChangeNotifyEvent*)
for (screen = 0; screen < nscreens; screen++) {
if (locks[screen]->win == rre->window) {
@@ -208,7 +209,7 @@ readpw(Display *dpy, const char *pws)
}
static void
-unlockscreen(Display *dpy, Lock *lock)
+unlockscreen(Display *dpy, struct lock *lock)
{
if(dpy == NULL || lock == NULL)
return;
@@ -223,28 +224,31 @@ unlockscreen(Display *dpy, Lock *lock)
}
static void
-cleanup(Display *dpy)
+cleanup(Display **dpy, struct lock ***locks, int *nscreens)
{
int s;
- for (s = 0; s < nscreens; ++s)
- unlockscreen(dpy, locks[s]);
+ for (s = 0; s < *nscreens; ++s)
+ unlockscreen(*dpy, (*locks)[s]);
+ *nscreens = 0;
- free(locks);
- XCloseDisplay(dpy);
+ free(*locks);
+ *locks = NULL;
+ XCloseDisplay(*dpy);
+ *dpy = NULL;
}
-static Lock *
-lockscreen(Display *dpy, int screen)
+static struct lock *
+lockscreen(Display *dpy, struct xrandr *rr, int screen)
{
char curs[] = {0, 0, 0, 0, 0, 0, 0, 0};
int i, ptgrab, kbgrab;
- Lock *lock;
+ struct lock *lock;
XColor color, dummy;
XSetWindowAttributes wa;
Cursor invisible;
- if (dpy == NULL || screen < 0 || !(lock = malloc(sizeof(Lock
+ if (dpy == NULL || screen < 0 || !(lock = malloc(sizeof(struct lock
return NULL;
lock->screen = screen;
@@ -281,7 +285,7 @@ lockscreen(Display *dpy, int screen)
/* input is grabbed: we can lock the screen */
if (ptgrab == GrabSuccess && kbgrab == GrabSuccess) {
XMapRaised(dpy, lock->win);
- if (rr)
+ if (rr->active)
XRRSelectInput(dpy, lock->win, RRScreenChangeNotifyMask);
XSelectInput(dpy, lock->root, SubstructureNotifyMask);
@@ -312,13 +316,15 @@ usage(void)
int
main(int argc, char **argv) {
+ struct xrandr rr;
+ struct lock **locks;
struct passwd *pwd;
struct group *grp;
uid_t duid;
gid_t dgid;
const char *pws;
Display *dpy;
- int s, nlocks;
+ int s, nlocks, nscreens;
ARGBEGIN {
case 'v':
@@ -360,16 +366,16 @@ main(int argc, char **argv) {
die("slock: setuid: %s\n", strerror(errno));
/* check for Xrandr support */
- rr = XRRQueryExtension(dpy, , );
+ rr.active = XRRQueryExtension(dpy, , );
/* get number of screens in display "dpy" and blank them */
nscreens = ScreenCount(dpy);
- if (!(locks = calloc(nscreens, sizeof(Lock * {
+ if (!(locks = calloc(nscreens, sizeof(struct lock * {
XCloseDisplay(dpy);
die("slock: out of memory\n");
}
for (nlocks = 0, s = 0; s < nscreens; s++) {
- if ((locks[s] = lockscreen(dpy, s)) != NULL)
+ if ((locks[s] = lockscreen(dpy, , s)) != NULL)
nlocks++;
else
break;
@@ -378,7 +384,7 @@ main(int argc, char **argv) {
/* did we manage to lock everything? */
if (nlocks != nscreens) {
- cleanup(dpy);
+ cleanup(, , );
return 1;
}
@@ -386,7 +392,7 @@ main(int argc, char **argv) {
if (argc > 0) {
switch (fork()) {
case -1:
- cleanup(dpy);
+ cleanup(, , );
die("slock: fork failed: %s\n", strerror(errno));
case