summaryrefslogtreecommitdiffstats
path: root/src/rule.c
diff options
context:
space:
mode:
authorPablo Neira Ayuso <pablo@netfilter.org>2014-02-25 22:30:12 +0100
committerPablo Neira Ayuso <pablo@netfilter.org>2014-02-27 10:35:07 +0100
commit53c0ff324598ce2926236c32b2b4c858a0b3831a (patch)
tree1f8d2ce3804d0abf4fdc253bf3d78abc34b3fcd4 /src/rule.c
parent7756d31990cd47673a21cacf6fd6d33227d6270e (diff)
src: add nft_*_attr_{set|get}_data interface
This patch adds two functions that allows you to validate the size of the attribute. This new functions provide a replacement for nft_rule_attr_set and nft_rule_attr_get. The data_len parameter was already passed to the {_set|_get} funcion in expressions. For consistency, add nft_rule_expr_{set|get}_data alias. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Diffstat (limited to 'src/rule.c')
-rw-r--r--src/rule.c58
1 files changed, 50 insertions, 8 deletions
diff --git a/src/rule.c b/src/rule.c
index 5e149c7..ca4235b 100644
--- a/src/rule.c
+++ b/src/rule.c
@@ -113,11 +113,22 @@ void nft_rule_attr_unset(struct nft_rule *r, uint16_t attr)
}
EXPORT_SYMBOL(nft_rule_attr_unset);
-void nft_rule_attr_set(struct nft_rule *r, uint16_t attr, const void *data)
+static uint32_t nft_rule_attr_validate[NFT_RULE_ATTR_MAX + 1] = {
+ [NFT_RULE_ATTR_HANDLE] = sizeof(uint64_t),
+ [NFT_RULE_ATTR_COMPAT_PROTO] = sizeof(uint32_t),
+ [NFT_RULE_ATTR_COMPAT_FLAGS] = sizeof(uint32_t),
+ [NFT_RULE_ATTR_FAMILY] = sizeof(uint8_t),
+ [NFT_RULE_ATTR_POSITION] = sizeof(uint64_t),
+};
+
+void nft_rule_attr_set_data(struct nft_rule *r, uint16_t attr,
+ const void *data, uint32_t data_len)
{
if (attr > NFT_RULE_ATTR_MAX)
return;
+ nft_assert_validate(nft_rule_attr_validate, attr, data_len);
+
switch(attr) {
case NFT_RULE_ATTR_TABLE:
if (r->table)
@@ -149,49 +160,68 @@ void nft_rule_attr_set(struct nft_rule *r, uint16_t attr, const void *data)
}
r->flags |= (1 << attr);
}
+EXPORT_SYMBOL(nft_rule_attr_set_data);
+
+void nft_rule_attr_set(struct nft_rule *r, uint16_t attr, const void *data)
+{
+ nft_rule_attr_set_data(r, attr, data, nft_rule_attr_validate[attr]);
+}
EXPORT_SYMBOL(nft_rule_attr_set);
void nft_rule_attr_set_u32(struct nft_rule *r, uint16_t attr, uint32_t val)
{
- nft_rule_attr_set(r, attr, &val);
+ nft_rule_attr_set_data(r, attr, &val, sizeof(uint32_t));
}
EXPORT_SYMBOL(nft_rule_attr_set_u32);
void nft_rule_attr_set_u64(struct nft_rule *r, uint16_t attr, uint64_t val)
{
- nft_rule_attr_set(r, attr, &val);
+ nft_rule_attr_set_data(r, attr, &val, sizeof(uint64_t));
}
EXPORT_SYMBOL(nft_rule_attr_set_u64);
void nft_rule_attr_set_str(struct nft_rule *r, uint16_t attr, const char *str)
{
- nft_rule_attr_set(r, attr, str);
+ nft_rule_attr_set_data(r, attr, str, strlen(str));
}
EXPORT_SYMBOL(nft_rule_attr_set_str);
-const void *nft_rule_attr_get(const struct nft_rule *r, uint16_t attr)
+const void *nft_rule_attr_get_data(const struct nft_rule *r, uint16_t attr,
+ uint32_t *data_len)
{
if (!(r->flags & (1 << attr)))
return NULL;
switch(attr) {
case NFT_RULE_ATTR_FAMILY:
+ *data_len = sizeof(uint8_t);
return &r->family;
case NFT_RULE_ATTR_TABLE:
return r->table;
case NFT_RULE_ATTR_CHAIN:
return r->chain;
case NFT_RULE_ATTR_HANDLE:
+ *data_len = sizeof(uint64_t);
return &r->handle;
case NFT_RULE_ATTR_COMPAT_PROTO:
+ *data_len = sizeof(uint32_t);
return &r->compat.proto;
case NFT_RULE_ATTR_COMPAT_FLAGS:
+ *data_len = sizeof(uint32_t);
return &r->compat.flags;
case NFT_RULE_ATTR_POSITION:
+ *data_len = sizeof(uint64_t);
return &r->position;
}
return NULL;
}
+EXPORT_SYMBOL(nft_rule_attr_get_data);
+
+const void *nft_rule_attr_get(const struct nft_rule *r, uint16_t attr)
+{
+ uint32_t data_len;
+ return nft_rule_attr_get_data(r, attr, &data_len);
+}
EXPORT_SYMBOL(nft_rule_attr_get);
const char *nft_rule_attr_get_str(const struct nft_rule *r, uint16_t attr)
@@ -202,21 +232,33 @@ EXPORT_SYMBOL(nft_rule_attr_get_str);
uint32_t nft_rule_attr_get_u32(const struct nft_rule *r, uint16_t attr)
{
- const uint32_t *val = nft_rule_attr_get(r, attr);
+ uint32_t data_len;
+ const uint32_t *val = nft_rule_attr_get_data(r, attr, &data_len);
+
+ nft_assert(attr, data_len == sizeof(uint32_t));
+
return val ? *val : 0;
}
EXPORT_SYMBOL(nft_rule_attr_get_u32);
uint64_t nft_rule_attr_get_u64(const struct nft_rule *r, uint16_t attr)
{
- const uint64_t *val = nft_rule_attr_get(r, attr);
+ uint32_t data_len;
+ const uint64_t *val = nft_rule_attr_get_data(r, attr, &data_len);
+
+ nft_assert(attr, data_len == sizeof(uint64_t));
+
return val ? *val : 0;
}
EXPORT_SYMBOL(nft_rule_attr_get_u64);
uint8_t nft_rule_attr_get_u8(const struct nft_rule *r, uint16_t attr)
{
- const uint8_t *val = nft_rule_attr_get(r, attr);
+ uint32_t data_len;
+ const uint8_t *val = nft_rule_attr_get_data(r, attr, &data_len);
+
+ nft_assert(attr, data_len == sizeof(uint8_t));
+
return val ? *val : 0;
}
EXPORT_SYMBOL(nft_rule_attr_get_u8);