From 5cd7785b0a042f48823dd0f38fac4d3b2e7b3d9c Mon Sep 17 00:00:00 2001 From: Pip Cet Date: Sun, 24 May 2026 08:06:46 +0000 Subject: [PATCH] Fix use-after-free in Ffuncall_with_delayed_message (bug#81108) * src/eval.c (with_delayed_message_display): (with_delayed_message_cancel): (Ffuncall_with_delayed_message): Use new temporary data structure. Cancel timer at most once. --- src/eval.c | 35 +++++++++++++++++++++++++++-------- 1 file changed, 27 insertions(+), 8 deletions(-) diff --git a/src/eval.c b/src/eval.c index b61bda4a024..bd3b119107b 100644 --- a/src/eval.c +++ b/src/eval.c @@ -1220,17 +1220,34 @@ usage: (while TEST BODY...) */) return Qnil; } +struct funcall_with_delayed_message_data +{ + Lisp_Object *message; + struct atimer *timer; +}; + static void with_delayed_message_display (struct atimer *timer) { - message3 (build_string (timer->client_data)); + struct funcall_with_delayed_message_data *data + = timer->client_data; + if (data->timer) + { + message3 (*data->message); + data->timer = NULL; + } } static void -with_delayed_message_cancel (void *timer) +with_delayed_message_cancel (void *datap) { - xfree (((struct atimer *) timer)->client_data); - cancel_atimer (timer); + struct funcall_with_delayed_message_data *data + = datap; + if (data->timer) + { + cancel_atimer (data->timer); + data->timer = NULL; + } } DEFUN ("funcall-with-delayed-message", @@ -1251,10 +1268,12 @@ is not displayed. */) /* Set up the atimer. */ struct timespec interval = dtotimespec (XFLOATINT (timeout)); - struct atimer *timer = start_atimer (ATIMER_RELATIVE, interval, - with_delayed_message_display, - xstrdup (SSDATA (message))); - record_unwind_protect_ptr (with_delayed_message_cancel, timer); + struct funcall_with_delayed_message_data data + = { .message = &message }; + data.timer = start_atimer (ATIMER_RELATIVE, interval, + with_delayed_message_display, + &data); + record_unwind_protect_ptr (with_delayed_message_cancel, &data); Lisp_Object result = calln (function);