From 7283c8c0ac9db8b38bb280576668256023d82fb4 Mon Sep 17 00:00:00 2001 From: Hiltjo Posthuma Date: Tue, 13 Oct 2026 14:28:33 +0200 Subject: check and restrict size hint values Could not reproduce a crash, but may mess up window geometry, etc. Test program below to give an idea: cc repro.c -o repro -lX11; ./repro int main(void) { Display *d; int screen; Window root; Window win; d = XOpenDisplay(NULL); if (!d) { fprintf(stderr, "XOpenDisplay failed\n"); return 1; } screen = DefaultScreen(d); root = RootWindow(d, screen); win = XCreateSimpleWindow(d, root, 0, 0, 100, 100, 0, 0, 0); if (!win) { fprintf(stderr, "XCreateSimpleWindow failed\n"); XCloseDisplay(d); return 1; } //XMapWindow(d, win); XMapRaised(d, win); XSizeHints h = {0}; h.flags = PResizeInc | PBaseSize | PMinSize; h.width_inc = -1; h.height_inc = -1; h.base_width = INT_MIN + 500; /* window is 500px wide */ h.base_height = 0; h.min_width = ~0L; h.min_height = ~0L; XSetWMNormalHints(d, win, &h); sleep(3); //XDestroyWindow(d, win); XCloseDisplay(d); return 0; } --- dwm.c | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) (limited to 'dwm.c') diff --git a/dwm.c b/dwm.c index ab3a84c..5ff6fd4 100644 --- a/dwm.c +++ b/dwm.c @@ -1968,32 +1968,32 @@ updatesizehints(Client *c) /* size is uninitialized, ensure that size.flags aren't used */ size.flags = PSize; if (size.flags & PBaseSize) { - c->basew = size.base_width; - c->baseh = size.base_height; + c->basew = MAX(0, size.base_width); + c->baseh = MAX(0, size.base_height); } else if (size.flags & PMinSize) { - c->basew = size.min_width; - c->baseh = size.min_height; + c->basew = MAX(0, size.min_width); + c->baseh = MAX(0, size.min_height); } else c->basew = c->baseh = 0; if (size.flags & PResizeInc) { - c->incw = size.width_inc; - c->inch = size.height_inc; + c->incw = MAX(0, size.width_inc); + c->inch = MAX(0, size.height_inc); } else c->incw = c->inch = 0; if (size.flags & PMaxSize) { - c->maxw = size.max_width; - c->maxh = size.max_height; + c->maxw = MAX(0, size.max_width); + c->maxh = MAX(0, size.max_height); } else c->maxw = c->maxh = 0; if (size.flags & PMinSize) { - c->minw = size.min_width; - c->minh = size.min_height; + c->minw = MAX(0, size.min_width); + c->minh = MAX(0, size.min_height); } else if (size.flags & PBaseSize) { - c->minw = size.base_width; - c->minh = size.base_height; + c->minw = MAX(0, size.base_width); + c->minh = MAX(0, size.base_height); } else c->minw = c->minh = 0; - if (size.flags & PAspect) { + if ((size.flags & PAspect) && size.min_aspect.x > 0 && size.max_aspect.y > 0) { c->mina = (float)size.min_aspect.y / size.min_aspect.x; c->maxa = (float)size.max_aspect.x / size.max_aspect.y; } else -- cgit v1.3.1 From 3fdf0241fcd1b7677a034c0c8f213587e5e706e7 Mon Sep 17 00:00:00 2001 From: Hiltjo Posthuma Date: Tue, 13 Oct 2026 14:30:47 +0200 Subject: ignore malformed ConfigureNotify with width or height <= 0 This could crash dwm. cc repro.c -o repro -lX11; ./repro int main(void) { Display *d; int screen; Window root; d = XOpenDisplay(NULL); if (!d) { fprintf(stderr, "XOpenDisplay failed\n"); return 1; } screen = DefaultScreen(d); root = RootWindow(d, screen); XConfigureEvent ce = {0}; ce.type = ConfigureNotify; ce.display = d; ce.event = root; ce.window = root; ce.width = 0; ce.height = 0; XSendEvent(d, root, False, StructureNotifyMask, (XEvent *)&ce); XFlush(d); XCloseDisplay(d); return 0; } --- dwm.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'dwm.c') diff --git a/dwm.c b/dwm.c index 5ff6fd4..1249997 100644 --- a/dwm.c +++ b/dwm.c @@ -559,6 +559,9 @@ configurenotify(XEvent *e) /* TODO: updategeom handling sucks, needs to be simplified */ if (ev->window == root) { + if (ev->width <= 0 || ev->height <= 0) + return; + dirty = (sw != ev->width || sh != ev->height); sw = ev->width; sh = ev->height; -- cgit v1.3.1 From ce41d3479103fe818466cde9394cce9ac314f519 Mon Sep 17 00:00:00 2001 From: Hiltjo Posthuma Date: Tue, 13 Oct 2026 14:34:59 +0200 Subject: properly NUL terminate ltsymbol Although this is config error in config.h if the symbol is too long. Make sure it is correct. Note that the symbol would then get truncated. --- dwm.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'dwm.c') diff --git a/dwm.c b/dwm.c index 1249997..515e4e4 100644 --- a/dwm.c +++ b/dwm.c @@ -395,7 +395,8 @@ arrange(Monitor *m) void arrangemon(Monitor *m) { - strncpy(m->ltsymbol, m->lt[m->sellt]->symbol, sizeof m->ltsymbol); + strncpy(m->ltsymbol, m->lt[m->sellt]->symbol, sizeof(m->ltsymbol) - 1); + m->ltsymbol[sizeof(m->ltsymbol) - 1] = '\0'; if (m->lt[m->sellt]->arrange) m->lt[m->sellt]->arrange(m); } @@ -645,7 +646,8 @@ createmon(void) m->topbar = topbar; m->lt[0] = &layouts[0]; m->lt[1] = &layouts[1 % LENGTH(layouts)]; - strncpy(m->ltsymbol, layouts[0].symbol, sizeof m->ltsymbol); + strncpy(m->ltsymbol, layouts[0].symbol, sizeof(m->ltsymbol) - 1); + m->ltsymbol[sizeof(m->ltsymbol) - 1] = '\0'; return m; } -- cgit v1.3.1 From d587dd65a4d55c810438336170301b67e69dcade Mon Sep 17 00:00:00 2001 From: Hiltjo Posthuma Date: Tue, 13 Oct 2026 14:37:57 +0200 Subject: fix a possible memory leak if a list is empty for XmbTextPropertyToTextList --- dwm.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'dwm.c') diff --git a/dwm.c b/dwm.c index 515e4e4..f26a943 100644 --- a/dwm.c +++ b/dwm.c @@ -924,8 +924,9 @@ gettextprop(Window w, Atom atom, char *text, unsigned int size) return 0; if (name.encoding == XA_STRING) { strncpy(text, (char *)name.value, size - 1); - } else if (XmbTextPropertyToTextList(dpy, &name, &list, &n) >= Success && n > 0 && *list) { - strncpy(text, *list, size - 1); + } else if (XmbTextPropertyToTextList(dpy, &name, &list, &n) >= Success) { + if (n > 0 && *list) + strncpy(text, *list, size - 1); XFreeStringList(list); } text[size - 1] = '\0'; -- cgit v1.3.1 From ebfe6719885e1b567d59828be3dc27cb5a0d4adf Mon Sep 17 00:00:00 2001 From: Hiltjo Posthuma Date: Tue, 13 Oct 2026 14:39:44 +0200 Subject: check return value of XGetModifierMapping --- dwm.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'dwm.c') diff --git a/dwm.c b/dwm.c index f26a943..212c6ba 100644 --- a/dwm.c +++ b/dwm.c @@ -1955,7 +1955,8 @@ updatenumlockmask(void) XModifierKeymap *modmap; numlockmask = 0; - modmap = XGetModifierMapping(dpy); + if (!(modmap = XGetModifierMapping(dpy))) + return; for (i = 0; i < 8; i++) for (j = 0; j < modmap->max_keypermod; j++) if (modmap->modifiermap[i * modmap->max_keypermod + j] -- cgit v1.3.1 From 1d07715ebdf41f293b8de0c027932e71d8360a36 Mon Sep 17 00:00:00 2001 From: Hiltjo Posthuma Date: Tue, 13 Oct 2026 14:42:56 +0200 Subject: print an error if fork failed (resource / process limits) --- dwm.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'dwm.c') diff --git a/dwm.c b/dwm.c index 212c6ba..3f45aab 100644 --- a/dwm.c +++ b/dwm.c @@ -1654,10 +1654,16 @@ void spawn(const Arg *arg) { struct sigaction sa; + pid_t pid; if (arg->v == dmenucmd) dmenumon[0] = '0' + selmon->num; - if (fork() == 0) { + + if ((pid = fork()) == -1) { + fprintf(stderr, "dwm: fork failed: %s\n", strerror(errno)); + return; + } + if (pid == 0) { if (dpy) close(ConnectionNumber(dpy)); setsid(); -- cgit v1.3.1 From bca7cf2bd91760855408326411a659ff72895860 Mon Sep 17 00:00:00 2001 From: Hiltjo Posthuma Date: Tue, 13 Oct 2026 15:00:21 +0200 Subject: support spawning dmenu with more than 10 monitors --- config.def.h | 2 +- dwm.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'dwm.c') diff --git a/config.def.h b/config.def.h index 81c3fc0..cb4cf6b 100644 --- a/config.def.h +++ b/config.def.h @@ -57,7 +57,7 @@ static const Layout layouts[] = { #define SHCMD(cmd) { .v = (const char*[]){ "/bin/sh", "-c", cmd, NULL } } /* commands */ -static char dmenumon[2] = "0"; /* component of dmenucmd, manipulated in spawn() */ +static char dmenumon[8]; /* component of dmenucmd, manipulated in spawn() */ static const char *dmenucmd[] = { "dmenu_run", "-m", dmenumon, "-fn", dmenufont, "-nb", col_gray1, "-nf", col_gray3, "-sb", col_cyan, "-sf", col_gray4, NULL }; static const char *termcmd[] = { "st", NULL }; diff --git a/dwm.c b/dwm.c index 3f45aab..421704c 100644 --- a/dwm.c +++ b/dwm.c @@ -1657,7 +1657,7 @@ spawn(const Arg *arg) pid_t pid; if (arg->v == dmenucmd) - dmenumon[0] = '0' + selmon->num; + snprintf(dmenumon, sizeof(dmenumon), "%d", selmon->num); if ((pid = fork()) == -1) { fprintf(stderr, "dwm: fork failed: %s\n", strerror(errno)); -- cgit v1.3.1 From f08763b74e32d83dd5d706ce2090b235ed518a89 Mon Sep 17 00:00:00 2001 From: Hiltjo Posthuma Date: Wed, 28 Oct 2026 19:05:10 +0100 Subject: setlayout: NUL terminate ltsymbol --- dwm.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'dwm.c') diff --git a/dwm.c b/dwm.c index 421704c..35cce9a 100644 --- a/dwm.c +++ b/dwm.c @@ -1520,7 +1520,8 @@ setlayout(const Arg *arg) selmon->sellt ^= 1; if (arg && arg->v) selmon->lt[selmon->sellt] = (Layout *)arg->v; - strncpy(selmon->ltsymbol, selmon->lt[selmon->sellt]->symbol, sizeof selmon->ltsymbol); + strncpy(selmon->ltsymbol, selmon->lt[selmon->sellt]->symbol, sizeof(selmon->ltsymbol) - 1); + selmon->ltsymbol[sizeof(selmon->ltsymbol) - 1] = '\0'; if (selmon->sel) arrange(selmon); else -- cgit v1.3.1