From 028011a8169b7b447c6a91b4a32c302ac4199db4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Tue, 4 Oct 2022 21:09:43 +0200 Subject: [PATCH] =?UTF-8?q?module/sway-xkb:=20don=E2=80=99t=20add=20the=20?= =?UTF-8?q?=E2=80=9Csame=E2=80=9D=20device=20multiple=20times?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Not sure if Sway bug or not, but we’ve seen Sway presenting multiple input devices with the exact same ID (and nothing else differentiating them). This caused a crash in the sway-xkb module, since we didn’t check if we were already tracking the device, and thus bumped the “num_existing_inputs” variable multiple times for the same input object. This lead to a content() returning an array with uninitialized elements, and thus a crash. Closes #229 --- CHANGELOG.md | 3 +++ modules/sway-xkb.c | 10 +++++++++- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 532530a..ade384d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -115,6 +115,8 @@ * network: missing SSID (recent kernels, or possibly wireless drivers, no longer provide the SSID in the `NL80211_CMD_NEW_STATION` response) ([#226][226]). +* sway-xkb: crash when compositor presents multiple inputs with + identical IDs ([#229][229]). [169]: https://codeberg.org/dnkl/yambar/issues/169 [172]: https://codeberg.org/dnkl/yambar/issues/172 @@ -123,6 +125,7 @@ [198]: https://codeberg.org/dnkl/yambar/issues/198 [221]: https://codeberg.org/dnkl/yambar/issues/221 [226]: https://codeberg.org/dnkl/yambar/issues/226 +[229]: https://codeberg.org/dnkl/yambar/issues/229 ### Security diff --git a/modules/sway-xkb.c b/modules/sway-xkb.c index 6ee3e3a..3f2e965 100644 --- a/modules/sway-xkb.c +++ b/modules/sway-xkb.c @@ -67,6 +67,7 @@ content(struct module *mod) mtx_lock(&mod->lock); + assert(m->num_existing_inputs <= m->num_inputs); struct exposable *particles[max(m->num_existing_inputs, 1)]; for (size_t i = 0, j = 0; i < m->num_inputs; i++) { @@ -120,9 +121,12 @@ handle_input_reply(int type, const struct json_object *json, void *_mod) struct input *input = NULL; for (size_t i = 0; i < m->num_inputs; i++) { struct input *maybe_input = &m->inputs[i]; - if (strcmp(maybe_input->identifier, id) == 0) { + if (strcmp(maybe_input->identifier, id) == 0 && !maybe_input->exists) + { input = maybe_input; + LOG_DBG("adding: %s", id); + mtx_lock(&mod->lock); input->exists = true; m->num_existing_inputs++; @@ -209,6 +213,8 @@ handle_input_event(int type, const struct json_object *json, void *_mod) if (is_removed) { if (input->exists) { + LOG_DBG("removing: %s", id); + mtx_lock(&mod->lock); input->exists = false; m->num_existing_inputs--; @@ -220,6 +226,8 @@ handle_input_event(int type, const struct json_object *json, void *_mod) if (is_added) { if (!input->exists) { + LOG_DBG("adding: %s", id); + mtx_lock(&mod->lock); input->exists = true; m->num_existing_inputs++;