Skip to content

Commit 5a31a46

Browse files
pzmarzlyqdeslandes
authored andcommitted
daemon: validate enum values coming from user
1 parent e99720f commit 5a31a46

File tree

8 files changed

+43
-19
lines changed

8 files changed

+43
-19
lines changed

src/bpfilter/cgen/cgen.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ int bf_cgen_new_from_pack(struct bf_cgen **cgen, bf_rpack_node_t node)
7979

8080
_cgen->program = NULL;
8181

82-
r = bf_rpack_kv_enum(node, "front", &_cgen->front);
82+
r = bf_rpack_kv_enum(node, "front", &_cgen->front, 0, _BF_FRONT_MAX);
8383
if (r)
8484
return bf_rpack_key_err(r, "bf_cgen.front");
8585

src/bpfilter/cgen/prog/map.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -103,11 +103,11 @@ int bf_map_new_from_pack(struct bf_map **map, int dir_fd, bf_rpack_node_t node)
103103
return bf_err_r(-EINVAL, "map name can't be empty");
104104
bf_strncpy(_map->name, BPF_OBJ_NAME_LEN, name);
105105

106-
r = bf_rpack_kv_enum(node, "type", &_map->type);
106+
r = bf_rpack_kv_enum(node, "type", &_map->type, 0, _BF_MAP_TYPE_MAX);
107107
if (r)
108108
return bf_rpack_key_err(r, "bf_map.type");
109109

110-
r = bf_rpack_kv_enum(node, "bpf_type", &_map->bpf_type);
110+
r = bf_rpack_kv_enum(node, "bpf_type", &_map->bpf_type, 0, __MAX_BPF_MAP_TYPE);
111111
if (r)
112112
return bf_rpack_key_err(r, "bf_map.bpf_type");
113113

src/libbpfilter/chain.c

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -73,8 +73,11 @@ int bf_chain_new(struct bf_chain **chain, const char *name, enum bf_hook hook,
7373
size_t ridx = 0;
7474
int r;
7575

76-
bf_assert(chain && name);
77-
bf_assert(policy < _BF_TERMINAL_VERDICT_MAX);
76+
assert(chain && name);
77+
if (hook >= _BF_HOOK_MAX)
78+
return bf_err_r(-EINVAL, "unknown hook type");
79+
if (policy >= _BF_TERMINAL_VERDICT_MAX)
80+
return bf_err_r(-EINVAL, "unknown policy type");
7881

7982
_chain = malloc(sizeof(*_chain));
8083
if (!_chain)
@@ -124,11 +127,11 @@ int bf_chain_new_from_pack(struct bf_chain **chain, bf_rpack_node_t node)
124127
if (r)
125128
return bf_rpack_key_err(r, "bf_chain.name");
126129

127-
r = bf_rpack_kv_enum(node, "hook", &hook);
130+
r = bf_rpack_kv_enum(node, "hook", &hook, 0, _BF_HOOK_MAX);
128131
if (r)
129132
return bf_rpack_key_err(r, "bf_chain.hook");
130133

131-
r = bf_rpack_kv_enum(node, "policy", &policy);
134+
r = bf_rpack_kv_enum(node, "policy", &policy, 0, _BF_TERMINAL_VERDICT_MAX);
132135
if (r)
133136
return bf_rpack_key_err(r, "bf_chain.policy");
134137

src/libbpfilter/include/bpfilter/pack.h

Lines changed: 26 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -304,19 +304,29 @@ typedef union
304304
* @brief Read an named enumerator value from a node.
305305
*
306306
* This macro will ensure the enumerator value is properly casted from the
307-
* corresponding integer stored in the pack.
307+
* corresponding integer stored in the pack, and validate that it falls within
308+
* the valid range [first, max).
308309
*
309310
* @param node Node to read from.
310311
* @param key Key of the node to read. Can't be NULL.
311312
* @param value Pointer to the enumerator value to read into.
313+
* @param first First valid enumerator value (inclusive).
314+
* @param max Maximum enumerator value (exclusive).
312315
* @return 0 on success, or a negative error value on failure.
313316
*/
314-
#define bf_rpack_kv_enum(node, key, value) \
317+
#define bf_rpack_kv_enum(node, key, value, first, max) \
315318
({ \
316319
int __value; \
317320
int __r = bf_rpack_kv_int(node, key, &__value); \
318-
if (!__r) \
319-
*(value) = __value; \
321+
if (!__r) { \
322+
if (__value < (first) || __value >= (max)) { \
323+
bf_err("invalid %s value %d (expected [%d, %d))", key, \
324+
__value, (int)(first), (int)(max)); \
325+
__r = -EINVAL; \
326+
} else { \
327+
*(value) = __value; \
328+
} \
329+
} \
320330
__r; \
321331
})
322332

@@ -327,14 +337,23 @@ typedef union
327337
*
328338
* @param node Node to read from.
329339
* @param value Pointer to the enumerator value to read into.
340+
* @param first First valid enumerator value (inclusive).
341+
* @param max Maximum enumerator value (exclusive).
330342
* @return 0 on success, or a negative error value on failure.
331343
*/
332-
#define bf_rpack_enum(node, value) \
344+
#define bf_rpack_enum(node, value, first, max) \
333345
({ \
334346
int __value; \
335347
int __r = bf_rpack_int(node, &__value); \
336-
if (!__r) \
337-
*(value) = __value; \
348+
if (!__r) { \
349+
if (__value < (first) || __value >= (max)) { \
350+
bf_err("invalid enum value %d (expected [%d, %d))", __value, \
351+
(int)(first), (int)(max)); \
352+
__r = -EINVAL; \
353+
} else { \
354+
*(value) = __value; \
355+
} \
356+
} \
338357
__r; \
339358
})
340359

src/libbpfilter/matcher.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1295,11 +1295,11 @@ int bf_matcher_new_from_pack(struct bf_matcher **matcher, bf_rpack_node_t node)
12951295

12961296
bf_assert(matcher);
12971297

1298-
r = bf_rpack_kv_enum(node, "type", &type);
1298+
r = bf_rpack_kv_enum(node, "type", &type, 0, _BF_MATCHER_TYPE_MAX);
12991299
if (r)
13001300
return bf_rpack_key_err(r, "bf_matcher.type");
13011301

1302-
r = bf_rpack_kv_enum(node, "op", &op);
1302+
r = bf_rpack_kv_enum(node, "op", &op, 0, _BF_MATCHER_OP_MAX);
13031303
if (r)
13041304
return bf_rpack_key_err(r, "bf_matcher.op");
13051305

src/libbpfilter/rule.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ int bf_rule_new_from_pack(struct bf_rule **rule, bf_rpack_node_t node)
9393
if (r)
9494
return bf_rpack_key_err(r, "bf_rule.mark");
9595

96-
r = bf_rpack_kv_enum(node, "verdict", &_rule->verdict);
96+
r = bf_rpack_kv_enum(node, "verdict", &_rule->verdict, 0, _BF_VERDICT_MAX);
9797
if (r)
9898
return bf_rpack_key_err(r, "bf_rule.verdict");
9999

src/libbpfilter/set.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -291,7 +291,7 @@ int bf_set_new_from_pack(struct bf_set **set, bf_rpack_node_t node)
291291
n_comps, BF_SET_MAX_N_COMPS);
292292
}
293293

294-
r = bf_rpack_enum(comp_node, &key[i]);
294+
r = bf_rpack_enum(comp_node, &key[i], 0, _BF_MATCHER_TYPE_MAX);
295295
if (r)
296296
return bf_rpack_key_err(r, "bf_set.key");
297297
}

tests/unit/libbpfilter/pack.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -399,7 +399,9 @@ static void wpack_enum(void **state)
399399
assert_ok(bf_rpack_new(&rpack, data, data_len));
400400
root = bf_rpack_root(rpack);
401401

402-
assert_ok(bf_rpack_kv_enum(root, "enum_val", &enum_val));
402+
assert_ok(bf_rpack_kv_enum(root, "enum_val", &enum_val, 0, 10));
403+
assert_err(bf_rpack_kv_enum(root, "enum_val", &enum_val, 0, 5));
404+
assert_err(bf_rpack_kv_enum(root, "enum_val", &enum_val, 6, 10));
403405
assert_int_equal(enum_val, 5);
404406
}
405407

0 commit comments

Comments
 (0)