]> git.ipfire.org Git - thirdparty/libnftnl.git/commitdiff
set: Do not leave free'd expr_list elements in place
authorPhil Sutter <phil@nwl.cc>
Wed, 31 May 2023 12:09:09 +0000 (14:09 +0200)
committerPablo Neira Ayuso <pablo@netfilter.org>
Thu, 13 Jul 2023 17:55:02 +0000 (19:55 +0200)
When freeing elements, remove them also to prevent a potential UAF.

Closes: https://bugzilla.netfilter.org/show_bug.cgi?id=1685
Fixes: 3469f09286cee ("src: add NFTNL_SET_EXPRESSIONS")
Signed-off-by: Phil Sutter <phil@nwl.cc>
src/set.c

index c46f8277ff6870234388a7d647ed50b8f0018cf6..719e59616e9747adc58be648e9771413c703cfe2 100644 (file)
--- a/src/set.c
+++ b/src/set.c
@@ -54,8 +54,10 @@ void nftnl_set_free(const struct nftnl_set *s)
        if (s->flags & (1 << NFTNL_SET_USERDATA))
                xfree(s->user.data);
 
-       list_for_each_entry_safe(expr, next, &s->expr_list, head)
+       list_for_each_entry_safe(expr, next, &s->expr_list, head) {
+               list_del(&expr->head);
                nftnl_expr_free(expr);
+       }
 
        list_for_each_entry_safe(elem, tmp, &s->element_list, head) {
                list_del(&elem->head);
@@ -105,8 +107,10 @@ void nftnl_set_unset(struct nftnl_set *s, uint16_t attr)
                break;
        case NFTNL_SET_EXPR:
        case NFTNL_SET_EXPRESSIONS:
-               list_for_each_entry_safe(expr, tmp, &s->expr_list, head)
+               list_for_each_entry_safe(expr, tmp, &s->expr_list, head) {
+                       list_del(&expr->head);
                        nftnl_expr_free(expr);
+               }
                break;
        default:
                return;
@@ -210,8 +214,10 @@ int nftnl_set_set_data(struct nftnl_set *s, uint16_t attr, const void *data,
                s->user.len = data_len;
                break;
        case NFTNL_SET_EXPR:
-               list_for_each_entry_safe(expr, tmp, &s->expr_list, head)
+               list_for_each_entry_safe(expr, tmp, &s->expr_list, head) {
+                       list_del(&expr->head);
                        nftnl_expr_free(expr);
+               }
 
                expr = (void *)data;
                list_add(&expr->head, &s->expr_list);
@@ -742,8 +748,10 @@ int nftnl_set_nlmsg_parse(const struct nlmsghdr *nlh, struct nftnl_set *s)
 
        return 0;
 out_set_expr:
-       list_for_each_entry_safe(expr, next, &s->expr_list, head)
+       list_for_each_entry_safe(expr, next, &s->expr_list, head) {
+               list_del(&expr->head);
                nftnl_expr_free(expr);
+       }
 
        return -1;
 }