From: Felix Fietkau Date: Wed, 30 Apr 2025 08:40:38 +0000 (+0200) Subject: ucode-mod-uline: fix crash on cleanup X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=d07c48fa091d09f3bf5247799e08ef722b932f3c;p=thirdparty%2Fopenwrt.git ucode-mod-uline: fix crash on cleanup - only run a single poll in the uloop_fd cb to avoid use-after-free on close - delete the uloop_fd on close - when calling into ucode, fetch the vm pointer before the call in order to avoid accessing the stale uline context Signed-off-by: Felix Fietkau --- diff --git a/package/utils/ucode-mod-uline/src/ucode.c b/package/utils/ucode-mod-uline/src/ucode.c index 353d6bba548..7d7753a6d85 100644 --- a/package/utils/ucode-mod-uline/src/ucode.c +++ b/package/utils/ucode-mod-uline/src/ucode.c @@ -306,15 +306,16 @@ cb_prepare(struct uc_uline_state *us, const char *name) static uc_value_t * cb_call_ret(struct uc_uline_state *us, size_t args, ...) { + uc_vm_t *vm = us->vm; va_list ap; va_start(ap, args); for (size_t i = 0; i < args; i++) - uc_vm_stack_push(us->vm, ucv_get(va_arg(ap, void *))); + uc_vm_stack_push(vm, ucv_get(va_arg(ap, void *))); va_end(ap); - if (uc_vm_call(us->vm, true, args) == EXCEPTION_NONE) - return uc_vm_stack_pop(us->vm); + if (uc_vm_call(vm, true, args) == EXCEPTION_NONE) + return uc_vm_stack_pop(vm); return NULL; } @@ -369,21 +370,19 @@ static void uc_uline_poll_cb(struct uloop_fd *fd, unsigned int events) struct uc_uline_state *us = container_of(fd, struct uc_uline_state, fd); uc_value_t *val; - while (!uloop_cancelled && us->poll_cb) { - uline_poll(&us->s); + uline_poll(&us->s); - val = us->line; - if (!val) - break; + val = us->line; + if (!val) + return; - us->line = NULL; - if (!ucv_is_callable(us->poll_cb)) - return; + us->line = NULL; + if (!ucv_is_callable(us->poll_cb)) + return; - uc_vm_stack_push(us->vm, ucv_get(us->res)); - uc_vm_stack_push(us->vm, ucv_get(us->poll_cb)); - cb_call(us, 1, val); - } + uc_vm_stack_push(us->vm, ucv_get(us->res)); + uc_vm_stack_push(us->vm, ucv_get(us->poll_cb)); + cb_call(us, 1, val); } static bool @@ -543,6 +542,7 @@ static void free_state(void *ptr) if (!us) return; + uloop_fd_delete(&us->fd); registry = uc_vm_registry_get(us->vm, "uline.registry"); ucv_array_set(registry, us->registry_index, NULL); uline_free(&us->s);