From: Felix Fietkau Date: Thu, 16 Jul 2026 18:05:28 +0000 (+0200) Subject: ucode-mod-bpf: fix key/value aliasing in map argument conversion X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=5c35e410fcea2cfee1b5841143a1a97ec4cb68f5;p=thirdparty%2Fopenwrt.git 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 --- 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;