From 5c35e410fcea2cfee1b5841143a1a97ec4cb68f5 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Thu, 16 Jul 2026 20:05:28 +0200 Subject: [PATCH] ucode-mod-bpf: fix key/value aliasing in map argument conversion uc_bpf_map_arg converted integer arguments through a single static buffer. When map set was called with both an integer key and an integer value, the second conversion overwrote the first, so the element was written at the wrong key. Convert into a caller-provided buffer instead. Signed-off-by: Felix Fietkau --- package/utils/ucode-mod-bpf/src/bpf.c | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/package/utils/ucode-mod-bpf/src/bpf.c b/package/utils/ucode-mod-bpf/src/bpf.c index 0c896026dc1..1758510a54e 100644 --- a/package/utils/ucode-mod-bpf/src/bpf.c +++ b/package/utils/ucode-mod-bpf/src/bpf.c @@ -339,23 +339,19 @@ uc_bpf_module_get_program(uc_vm_t *vm, size_t nargs) } static void * -uc_bpf_map_arg(uc_value_t *val, const char *kind, unsigned int size) +uc_bpf_map_arg(uc_value_t *val, const char *kind, unsigned int size, + uint64_t *val_int) { - static union { - uint32_t u32; - uint64_t u64; - } val_int; - switch (ucv_type(val)) { case UC_INTEGER: if (size == 4) - val_int.u32 = ucv_int64_get(val); + *(uint32_t *)val_int = ucv_int64_get(val); else if (size == 8) - val_int.u64 = ucv_int64_get(val); + *val_int = ucv_int64_get(val); else break; - return &val_int; + return val_int; case UC_STRING: if (size != ucv_string_length(val)) break; @@ -373,12 +369,13 @@ uc_bpf_map_get(uc_vm_t *vm, size_t nargs) { struct uc_bpf_map *map = uc_fn_thisval("bpf.map"); uc_value_t *a_key = uc_fn_arg(0); + uint64_t key_int; void *key, *val; if (!map) err_return(EINVAL, NULL); - key = uc_bpf_map_arg(a_key, "key", map->key_size); + key = uc_bpf_map_arg(a_key, "key", map->key_size, &key_int); if (!key) return NULL; @@ -396,17 +393,18 @@ uc_bpf_map_set(uc_vm_t *vm, size_t nargs) uc_value_t *a_key = uc_fn_arg(0); uc_value_t *a_val = uc_fn_arg(1); uc_value_t *a_flags = uc_fn_arg(2); + uint64_t key_int, val_int; uint64_t flags; void *key, *val; if (!map) err_return(EINVAL, NULL); - key = uc_bpf_map_arg(a_key, "key", map->key_size); + key = uc_bpf_map_arg(a_key, "key", map->key_size, &key_int); if (!key) return NULL; - val = uc_bpf_map_arg(a_val, "value", map->val_size); + val = uc_bpf_map_arg(a_val, "value", map->val_size, &val_int); if (!val) return NULL; @@ -430,12 +428,13 @@ uc_bpf_map_delete(uc_vm_t *vm, size_t nargs) uc_value_t *a_key = uc_fn_arg(0); uc_value_t *a_return = uc_fn_arg(1); void *key, *val = NULL; + uint64_t key_int; int ret; if (!map) err_return(EINVAL, NULL); - key = uc_bpf_map_arg(a_key, "key", map->key_size); + key = uc_bpf_map_arg(a_key, "key", map->key_size, &key_int); if (!key) return NULL;