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 <nbd@nbd.name>
This commit is contained in:
parent
b9685dcf3d
commit
d07c48fa09
1 changed files with 15 additions and 15 deletions
|
@ -306,15 +306,16 @@ cb_prepare(struct uc_uline_state *us, const char *name)
|
||||||
static uc_value_t *
|
static uc_value_t *
|
||||||
cb_call_ret(struct uc_uline_state *us, size_t args, ...)
|
cb_call_ret(struct uc_uline_state *us, size_t args, ...)
|
||||||
{
|
{
|
||||||
|
uc_vm_t *vm = us->vm;
|
||||||
va_list ap;
|
va_list ap;
|
||||||
|
|
||||||
va_start(ap, args);
|
va_start(ap, args);
|
||||||
for (size_t i = 0; i < args; i++)
|
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);
|
va_end(ap);
|
||||||
|
|
||||||
if (uc_vm_call(us->vm, true, args) == EXCEPTION_NONE)
|
if (uc_vm_call(vm, true, args) == EXCEPTION_NONE)
|
||||||
return uc_vm_stack_pop(us->vm);
|
return uc_vm_stack_pop(vm);
|
||||||
|
|
||||||
return NULL;
|
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);
|
struct uc_uline_state *us = container_of(fd, struct uc_uline_state, fd);
|
||||||
uc_value_t *val;
|
uc_value_t *val;
|
||||||
|
|
||||||
while (!uloop_cancelled && us->poll_cb) {
|
uline_poll(&us->s);
|
||||||
uline_poll(&us->s);
|
|
||||||
|
|
||||||
val = us->line;
|
val = us->line;
|
||||||
if (!val)
|
if (!val)
|
||||||
break;
|
return;
|
||||||
|
|
||||||
us->line = NULL;
|
us->line = NULL;
|
||||||
if (!ucv_is_callable(us->poll_cb))
|
if (!ucv_is_callable(us->poll_cb))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
uc_vm_stack_push(us->vm, ucv_get(us->res));
|
uc_vm_stack_push(us->vm, ucv_get(us->res));
|
||||||
uc_vm_stack_push(us->vm, ucv_get(us->poll_cb));
|
uc_vm_stack_push(us->vm, ucv_get(us->poll_cb));
|
||||||
cb_call(us, 1, val);
|
cb_call(us, 1, val);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
|
@ -543,6 +542,7 @@ static void free_state(void *ptr)
|
||||||
if (!us)
|
if (!us)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
uloop_fd_delete(&us->fd);
|
||||||
registry = uc_vm_registry_get(us->vm, "uline.registry");
|
registry = uc_vm_registry_get(us->vm, "uline.registry");
|
||||||
ucv_array_set(registry, us->registry_index, NULL);
|
ucv_array_set(registry, us->registry_index, NULL);
|
||||||
uline_free(&us->s);
|
uline_free(&us->s);
|
||||||
|
|
Loading…
Reference in a new issue