diff --git a/src/libbpfilter/cgen/printer.c b/src/libbpfilter/cgen/printer.c index 7c1a730a..f1b302d1 100644 --- a/src/libbpfilter/cgen/printer.c +++ b/src/libbpfilter/cgen/printer.c @@ -90,11 +90,11 @@ static int _bf_printer_msg_new_from_pack(struct bf_printer_msg **msg, if (r) return bf_err_r(r, "failed to create bf_printer_msg from pack"); - r = bf_rpack_kv_u64(node, "offset", &_msg->offset); + r = bf_rpack_kv_size(node, "offset", &_msg->offset); if (r) return bf_rpack_key_err(r, "bf_printer_msg.offset"); - r = bf_rpack_kv_u64(node, "len", &_msg->len); + r = bf_rpack_kv_size(node, "len", &_msg->len); if (r) return bf_rpack_key_err(r, "bf_printer_msg.len"); diff --git a/src/libbpfilter/cgen/prog/map.c b/src/libbpfilter/cgen/prog/map.c index f723ebe1..54c494ff 100644 --- a/src/libbpfilter/cgen/prog/map.c +++ b/src/libbpfilter/cgen/prog/map.c @@ -271,15 +271,15 @@ int bf_map_new_from_pack(struct bf_map **map, int dir_fd, bf_rpack_node_t node) if (r) return bf_rpack_key_err(r, "bf_map.bpf_type"); - r = bf_rpack_kv_u64(node, "key_size", &_map->key_size); + r = bf_rpack_kv_size(node, "key_size", &_map->key_size); if (r) return bf_rpack_key_err(r, "bf_map.key_size"); - r = bf_rpack_kv_u64(node, "value_size", &_map->value_size); + r = bf_rpack_kv_size(node, "value_size", &_map->value_size); if (r) return bf_rpack_key_err(r, "bf_map.value_size"); - r = bf_rpack_kv_u64(node, "n_elems", &_map->n_elems); + r = bf_rpack_kv_size(node, "n_elems", &_map->n_elems); if (r) return bf_rpack_key_err(r, "bf_map.n_elems"); if (_map->n_elems == 0) diff --git a/src/libbpfilter/include/bpfilter/pack.h b/src/libbpfilter/include/bpfilter/pack.h index 39262d99..45338533 100644 --- a/src/libbpfilter/include/bpfilter/pack.h +++ b/src/libbpfilter/include/bpfilter/pack.h @@ -451,6 +451,7 @@ int bf_rpack_u8(bf_rpack_node_t node, uint8_t *value); int bf_rpack_u16(bf_rpack_node_t node, uint16_t *value); int bf_rpack_u32(bf_rpack_node_t node, uint32_t *value); int bf_rpack_u64(bf_rpack_node_t node, uint64_t *value); +int bf_rpack_size(bf_rpack_node_t node, size_t *value); int bf_rpack_str(bf_rpack_node_t node, char **value); int bf_rpack_bool(bf_rpack_node_t node, bool *value); int bf_rpack_bin(bf_rpack_node_t node, const void **data, size_t *data_len); @@ -464,6 +465,7 @@ int bf_rpack_kv_u8(bf_rpack_node_t node, const char *key, uint8_t *value); int bf_rpack_kv_u16(bf_rpack_node_t node, const char *key, uint16_t *value); int bf_rpack_kv_u32(bf_rpack_node_t node, const char *key, uint32_t *value); int bf_rpack_kv_u64(bf_rpack_node_t node, const char *key, uint64_t *value); +int bf_rpack_kv_size(bf_rpack_node_t node, const char *key, size_t *value); int bf_rpack_kv_str(bf_rpack_node_t node, const char *key, char **value); int bf_rpack_kv_bool(bf_rpack_node_t node, const char *key, bool *value); int bf_rpack_kv_bin(bf_rpack_node_t node, const char *key, const void **data, diff --git a/src/libbpfilter/pack.c b/src/libbpfilter/pack.c index c088c9a0..27f96105 100644 --- a/src/libbpfilter/pack.c +++ b/src/libbpfilter/pack.c @@ -5,6 +5,8 @@ #include "bpfilter/pack.h" +#include + #include "bpfilter/core/list.h" #include "bpfilter/helper.h" #include "bpfilter/logger.h" @@ -532,6 +534,25 @@ int bf_rpack_u64(bf_rpack_node_t node, uint64_t *value) return 0; } +int bf_rpack_size(bf_rpack_node_t node, size_t *value) +{ + uint64_t _value; + int r; + + r = bf_rpack_u64(node, &_value); + if (r) + return r; + +#if SIZE_MAX < UINT64_MAX + if (_value > SIZE_MAX) + return -EOVERFLOW; +#endif + + *value = _value; + + return 0; +} + int bf_rpack_kv_u64(bf_rpack_node_t node, const char *key, uint64_t *value) { bf_rpack_node_t child; @@ -544,6 +565,18 @@ int bf_rpack_kv_u64(bf_rpack_node_t node, const char *key, uint64_t *value) return bf_rpack_u64(child, value); } +int bf_rpack_kv_size(bf_rpack_node_t node, const char *key, size_t *value) +{ + bf_rpack_node_t child; + int r; + + r = bf_rpack_kv_node(node, key, &child); + if (r) + return r; + + return bf_rpack_size(child, value); +} + int bf_rpack_str(bf_rpack_node_t node, char **value) { mpack_node_t _node = MP_NODE(node); diff --git a/tests/unit/libbpfilter/core/list.c b/tests/unit/libbpfilter/core/list.c index 34404351..dbfb8fcc 100644 --- a/tests/unit/libbpfilter/core/list.c +++ b/tests/unit/libbpfilter/core/list.c @@ -88,7 +88,7 @@ static void pack_and_unpack(void **state) _cleanup_free_ size_t *value = NULL; assert_non_null(value = malloc(sizeof(*value))); - assert_ok(bf_rpack_kv_u64(list_elem_node, "size_t", value)); + assert_ok(bf_rpack_kv_size(list_elem_node, "size_t", value)); assert_ok(bf_list_push(&destination, (void **)&value)); } diff --git a/tests/unit/libbpfilter/pack.c b/tests/unit/libbpfilter/pack.c index 4cf604f2..bacb6fbe 100644 --- a/tests/unit/libbpfilter/pack.c +++ b/tests/unit/libbpfilter/pack.c @@ -194,6 +194,51 @@ static void rpack_primitives(void **state) assert_true(bf_rpack_is_nil(nil_node)); } +static void rpack_size_t(void **state) +{ + _free_bf_wpack_ bf_wpack_t *wpack = NULL; + _free_bf_rpack_ bf_rpack_t *rpack = NULL; + const void *data; + size_t data_len; + bf_rpack_node_t root; + size_t size_val; + + (void)state; + + assert_ok(bf_wpack_new(&wpack)); + bf_wpack_kv_u64(wpack, "size_val", 42); + assert_ok(bf_wpack_get_data(wpack, &data, &data_len)); + + assert_ok(bf_rpack_new(&rpack, data, data_len)); + root = bf_rpack_root(rpack); + + assert_ok(bf_rpack_kv_size(root, "size_val", &size_val)); + assert_int_equal(size_val, 42); +} + +static void rpack_size_t_overflow(void **state) +{ + (void)state; + +#if SIZE_MAX < UINT64_MAX + _free_bf_wpack_ bf_wpack_t *wpack = NULL; + _free_bf_rpack_ bf_rpack_t *rpack = NULL; + const void *data; + size_t data_len; + bf_rpack_node_t root; + size_t size_val = 0; + + assert_ok(bf_wpack_new(&wpack)); + bf_wpack_kv_u64(wpack, "size_val", (uint64_t)SIZE_MAX + 1); + assert_ok(bf_wpack_get_data(wpack, &data, &data_len)); + + assert_ok(bf_rpack_new(&rpack, data, data_len)); + root = bf_rpack_root(rpack); + + assert_err(bf_rpack_kv_size(root, "size_val", &size_val)); +#endif +} + static void rpack_binary(void **state) { _free_bf_wpack_ bf_wpack_t *wpack = NULL; @@ -442,6 +487,8 @@ int main(void) cmocka_unit_test(wpack_enum), cmocka_unit_test(rpack_new_free), cmocka_unit_test(rpack_primitives), + cmocka_unit_test(rpack_size_t), + cmocka_unit_test(rpack_size_t_overflow), cmocka_unit_test(rpack_binary), cmocka_unit_test(rpack_nested_objects), cmocka_unit_test(rpack_arrays),