From fffd4c20aa785af1c3841bf11136eeface6f158f Mon Sep 17 00:00:00 2001 From: Tobias Waldekranz Date: Mon, 22 Aug 2022 14:38:16 +0200 Subject: [PATCH 1/2] Fix use-after-free on machines with unsigned-by-default chars With C being the bastion of user freedom, a compiler is of course free to choose the signedness of a naked `char`. This means that for some compiler/architecture combinations (notably GCC5/aarch64), `char` is equivalent to `unsigned char`. However, since an `active` value of -1 is used to signify a timer queued for destruction, it is important that `active` is always of the signed persuasion. Otherwise, `pev_check` will incorrectly determine that the timer is still active, firing the callback once more. When the timer callback was `delete_group_cb`, the callback context would no longer be valid, leading to a SEGV. Signed-off-by: Tobias Waldekranz --- src/pev.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pev.c b/src/pev.c index 17cbf15..1aaa28a 100644 --- a/src/pev.c +++ b/src/pev.c @@ -22,7 +22,7 @@ struct pev { int id; char type; - char active; + signed char active; union { int sd; From d328befda020a2a33676df2ea60e12b642ad46db Mon Sep 17 00:00:00 2001 From: Tobias Waldekranz Date: Wed, 31 Aug 2022 14:59:45 +0200 Subject: [PATCH 2/2] Fix incorrect VID parsing of MDB entries Previous parser assumed that every entry had exactly one flag between the group and the VID, which is not always true. Move to a parser that is order independent and that ignores unknown fields. --- src/bridge.c | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/src/bridge.c b/src/bridge.c index bd4d123..2ca0ae8 100644 --- a/src/bridge.c +++ b/src/bridge.c @@ -98,10 +98,28 @@ static int populate(void) return -1; while (fgets(buf, sizeof(buf), fp)) { - char br[5], port[16], group[64], opt[10]; - int vid, n; + char br[5], port[16], group[64]; + char *tok, *dst; + int vid = 0; + + for (tok = strtok(buf, " \t"); tok; tok = strtok(NULL, " \t")) { + if (!strcmp(tok, "dev")) { + dst = br; + } else if (!strcmp(tok, "port")) { + dst = port; + } else if (!strcmp(tok, "grp")) { + dst = group; + } else if (!strcmp(tok, "vid")) { + tok = strtok(NULL, " \t"); + vid = strtol(tok, NULL, 10); + continue; + } else { + continue; + } - n = sscanf(buf, "dev %s port %s grp %s %s vid %d", br, port, group, opt, &vid); + tok = strtok(NULL, " \t"); + strcpy(dst, tok); + } /* XXX: Filter out IPv6 and MAC for now ... */ if (strchr(group, ':'))