On Sun, Mar 15, 2020 at 10:09:53AM -0400, Okan Demirmen wrote:
> On Sat 2020.03.14 at 18:33 +0100, Tim van der Molen wrote:
> > Stefan Sperling (2020-03-14 18:12 +0100):
> > > On Sat, Mar 14, 2020 at 05:36:46PM +0100, Otto Moerbeek wrote:
> > > > Looking a the diff, I do see a use-after-free.
> > >
> > > The problem is the use of TAILQ_FOREACH(wn, ...) instead of
> > > TAILQ_FOREACH_SAFE(wn, ...) in combination with free(wn), correct?
> >
> > Most likely, yes.
>
> Revised diff using TAILQ_FOREACH_SAFE.
Doesn't seem right.
>
> Index: client.c
> ===================================================================
> RCS file: /home/open/cvs/xenocara/app/cwm/client.c,v
> retrieving revision 1.260
> diff -u -p -r1.260 client.c
> --- client.c 14 Mar 2020 16:11:09 -0000 1.260
> +++ client.c 14 Mar 2020 18:36:49 -0000
> @@ -667,22 +667,24 @@ client_close(struct client_ctx *cc)
> void
> client_set_name(struct client_ctx *cc)
> {
> - struct winname *wn;
> - char *newname;
> + struct winname *wn, *wmnxt;
> int i = 0;
>
> - if (!xu_get_strprop(cc->win, ewmh[_NET_WM_NAME], &newname))
> - if (!xu_get_strprop(cc->win, XA_WM_NAME, &newname))
> - newname = xstrdup("");
> + free(cc->name);
cc->name is freed
> + if (!xu_get_strprop(cc->win, ewmh[_NET_WM_NAME], &cc->name))
> + if (!xu_get_strprop(cc->win, XA_WM_NAME, &cc->name))
> + cc->name = xstrdup("");
And only re-assigned on certain conditions
>
> - TAILQ_FOREACH(wn, &cc->nameq, entry) {
> - if (strcmp(wn->name, newname) == 0)
> + TAILQ_FOREACH_SAFE(wn, &cc->nameq, entry, wmnxt) {
> + if (strcmp(wn->name, cc->name) == 0) {
> TAILQ_REMOVE(&cc->nameq, wn, entry);
> + free(wn->name);
> + free(wn);
> + }
> i++;
> }
> - cc->name = newname;
> wn = xmalloc(sizeof(*wn));
> - wn->name = xstrdup(newname);
> + wn->name = xstrdup(cc->name);
and then used unconditioanlly
> TAILQ_INSERT_TAIL(&cc->nameq, wn, entry);
>
> /* Garbage collection. */