mirror of
https://codeberg.org/dnkl/foot.git
synced 2026-06-30 13:14:56 -04:00
notify: fix crash in notify_done() when terminal has been closed before notification
In server mode, if a terminal instance triggered a tracked notification (e.g. a bell notification, or a kitty notification), then the foot server crashed if the terminal instance was closed before the notification. This happened because the notify_done() callback's user supplied argument was the terminal instance, and this pointer was not verified before it was de-referenced. Fix by searching the wayland global's list of terminal instances, and ignore the callback if the wanted terminal instance is gone. Closes #2397
This commit is contained in:
parent
73e6d21000
commit
ebaa878dce
2 changed files with 35 additions and 5 deletions
|
|
@ -114,6 +114,9 @@
|
||||||
([#2364][2364]).
|
([#2364][2364]).
|
||||||
* Escape quotes in file names being DnD:ed on the command line
|
* Escape quotes in file names being DnD:ed on the command line
|
||||||
([#2363][2363]).
|
([#2363][2363]).
|
||||||
|
* Crash in `--server` mode, when a tracked notification is closed
|
||||||
|
after the associated terminal instance has been closed
|
||||||
|
([#2397][2397]).
|
||||||
|
|
||||||
[2353]: https://codeberg.org/dnkl/foot/issues/2353
|
[2353]: https://codeberg.org/dnkl/foot/issues/2353
|
||||||
[2352]: https://codeberg.org/dnkl/foot/issues/2352
|
[2352]: https://codeberg.org/dnkl/foot/issues/2352
|
||||||
|
|
@ -122,6 +125,7 @@
|
||||||
[2360]: https://codeberg.org/dnkl/foot/issues/2360
|
[2360]: https://codeberg.org/dnkl/foot/issues/2360
|
||||||
[2370]: https://codeberg.org/dnkl/foot/issues/2370
|
[2370]: https://codeberg.org/dnkl/foot/issues/2370
|
||||||
[2364]: https://codeberg.org/dnkl/foot/issues/2364
|
[2364]: https://codeberg.org/dnkl/foot/issues/2364
|
||||||
|
[2397]: https://codeberg.org/dnkl/foot/issues/2397
|
||||||
|
|
||||||
|
|
||||||
### Security
|
### Security
|
||||||
|
|
|
||||||
36
notify.c
36
notify.c
|
|
@ -233,10 +233,31 @@ fdm_notify_stdout(struct fdm *fdm, int fd, int events, void *data)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct done_context {
|
||||||
|
struct wayland *wayl;
|
||||||
|
struct terminal *term;
|
||||||
|
};
|
||||||
|
|
||||||
static void
|
static void
|
||||||
notif_done(struct reaper *reaper, pid_t pid, int status, void *data)
|
notif_done(struct reaper *reaper, pid_t pid, int status, void *data)
|
||||||
{
|
{
|
||||||
struct terminal *term = data;
|
struct done_context *ctx = data;
|
||||||
|
const struct wayland *wayl = ctx->wayl;
|
||||||
|
const struct terminal *wanted_term = ctx->term;
|
||||||
|
free(ctx);
|
||||||
|
|
||||||
|
struct terminal *term = NULL;
|
||||||
|
tll_foreach(wayl->terms, it) {
|
||||||
|
if (it->item == wanted_term) {
|
||||||
|
term = it->item;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (term == NULL) {
|
||||||
|
LOG_WARN("notification closed, but the associated terminal instance is already gone");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
tll_foreach(term->active_notifications, it) {
|
tll_foreach(term->active_notifications, it) {
|
||||||
struct notification *notif = &it->item;
|
struct notification *notif = &it->item;
|
||||||
|
|
@ -567,11 +588,18 @@ notify_notify(struct terminal *term, struct notification *notif)
|
||||||
&fdm_notify_stdout, (void *)term);
|
&fdm_notify_stdout, (void *)term);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct done_context *ctx = NULL;
|
||||||
|
if (track_notification) {
|
||||||
|
ctx = xmalloc(sizeof(*ctx));
|
||||||
|
ctx->wayl = term->wl;
|
||||||
|
ctx->term = term;
|
||||||
|
}
|
||||||
|
|
||||||
/* Redirect stdin to /dev/null, but ignore failure to open */
|
/* Redirect stdin to /dev/null, but ignore failure to open */
|
||||||
int devnull = open("/dev/null", O_RDONLY);
|
int devnull = open("/dev/null", O_RDONLY);
|
||||||
pid_t pid = spawn(
|
pid_t pid = spawn(
|
||||||
term->reaper, NULL, argv, devnull, stdout_fds[1], -1,
|
term->reaper, NULL, argv, devnull, stdout_fds[1], -1,
|
||||||
track_notification ? ¬if_done : NULL, (void *)term, NULL);
|
track_notification ? ¬if_done : NULL, ctx, NULL);
|
||||||
|
|
||||||
if (stdout_fds[1] >= 0) {
|
if (stdout_fds[1] >= 0) {
|
||||||
/* Close write-end of stdout pipe */
|
/* Close write-end of stdout pipe */
|
||||||
|
|
@ -649,9 +677,7 @@ notify_close(struct terminal *term, const char *id)
|
||||||
}
|
}
|
||||||
|
|
||||||
int devnull = open("/dev/null", O_RDONLY);
|
int devnull = open("/dev/null", O_RDONLY);
|
||||||
spawn(
|
spawn(term->reaper, NULL, argv, devnull, -1, -1, NULL, NULL, NULL);
|
||||||
term->reaper, NULL, argv, devnull, -1, -1,
|
|
||||||
NULL, (void *)term, NULL);
|
|
||||||
|
|
||||||
if (devnull >= 0)
|
if (devnull >= 0)
|
||||||
close(devnull);
|
close(devnull);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue