Copying from nftnl_table_set_data(), validate input to
nftnl_set_elem_set() as well. Given that for some attributes the
function assumes passed data size, this seems necessary.

Since data size expected for NFTNL_SET_ELEM_VERDICT attribute is
sizeof(uint32_t), change type of 'verdict' field in union nftnl_data_reg
accordingly.

Signed-off-by: Phil Sutter <p...@nwl.cc>
---
Changes since v1:
- Change union nftnl_data_reg as outlined above.
---
 include/data_reg.h     |  2 +-
 include/libnftnl/set.h |  2 ++
 src/set_elem.c         | 10 ++++++++++
 3 files changed, 13 insertions(+), 1 deletion(-)

diff --git a/include/data_reg.h b/include/data_reg.h
index f2675f24918be..10517ba9b4ed0 100644
--- a/include/data_reg.h
+++ b/include/data_reg.h
@@ -19,7 +19,7 @@ union nftnl_data_reg {
                uint32_t        len;
        };
        struct {
-               int             verdict;
+               uint32_t        verdict;
                const char      *chain;
        };
 };
diff --git a/include/libnftnl/set.h b/include/libnftnl/set.h
index 6640ad929f346..2ea2e9a56ce4f 100644
--- a/include/libnftnl/set.h
+++ b/include/libnftnl/set.h
@@ -104,7 +104,9 @@ enum {
        NFTNL_SET_ELEM_USERDATA,
        NFTNL_SET_ELEM_EXPR,
        NFTNL_SET_ELEM_OBJREF,
+       __NFTNL_SET_ELEM_MAX
 };
+#define NFTNL_SET_ELEM_MAX (__NFTNL_SET_ELEM_MAX - 1)
 
 struct nftnl_set_elem;
 
diff --git a/src/set_elem.c b/src/set_elem.c
index 3794f12594079..d3ce807d838c8 100644
--- a/src/set_elem.c
+++ b/src/set_elem.c
@@ -96,10 +96,20 @@ void nftnl_set_elem_unset(struct nftnl_set_elem *s, 
uint16_t attr)
        s->flags &= ~(1 << attr);
 }
 
+static uint32_t nftnl_set_elem_validate[NFTNL_SET_ELEM_MAX + 1] = {
+       [NFTNL_SET_ELEM_FLAGS]          = sizeof(uint32_t),
+       [NFTNL_SET_ELEM_VERDICT]        = sizeof(uint32_t),
+       [NFTNL_SET_ELEM_TIMEOUT]        = sizeof(uint64_t),
+       [NFTNL_SET_ELEM_EXPIRATION]     = sizeof(uint64_t),
+};
+
 EXPORT_SYMBOL(nftnl_set_elem_set);
 int nftnl_set_elem_set(struct nftnl_set_elem *s, uint16_t attr,
                       const void *data, uint32_t data_len)
 {
+       nftnl_assert_attr_exists(attr, NFTNL_SET_ELEM_MAX);
+       nftnl_assert_validate(data, nftnl_set_elem_validate, attr, data_len);
+
        switch(attr) {
        case NFTNL_SET_ELEM_FLAGS:
                memcpy(&s->set_elem_flags, data, sizeof(s->set_elem_flags));
-- 
2.23.0

Reply via email to