netfilter: xt_u32: validate user space input
authorWander Lairson Costa <wander@redhat.com>
Mon, 28 Aug 2023 13:21:07 +0000 (10:21 -0300)
committerPablo Neira Ayuso <pablo@netfilter.org>
Wed, 30 Aug 2023 15:34:01 +0000 (17:34 +0200)
The xt_u32 module doesn't validate the fields in the xt_u32 structure.
An attacker may take advantage of this to trigger an OOB read by setting
the size fields with a value beyond the arrays boundaries.

Add a checkentry function to validate the structure.

This was originally reported by the ZDI project (ZDI-CAN-18408).

Fixes: 1b50b8a371e9 ("[NETFILTER]: Add u32 match")
Cc: stable@vger.kernel.org
Signed-off-by: Wander Lairson Costa <wander@redhat.com>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
net/netfilter/xt_u32.c

index 177b40d..117d461 100644 (file)
@@ -96,11 +96,32 @@ static bool u32_mt(const struct sk_buff *skb, struct xt_action_param *par)
        return ret ^ data->invert;
 }
 
+static int u32_mt_checkentry(const struct xt_mtchk_param *par)
+{
+       const struct xt_u32 *data = par->matchinfo;
+       const struct xt_u32_test *ct;
+       unsigned int i;
+
+       if (data->ntests > ARRAY_SIZE(data->tests))
+               return -EINVAL;
+
+       for (i = 0; i < data->ntests; ++i) {
+               ct = &data->tests[i];
+
+               if (ct->nnums > ARRAY_SIZE(ct->location) ||
+                   ct->nvalues > ARRAY_SIZE(ct->value))
+                       return -EINVAL;
+       }
+
+       return 0;
+}
+
 static struct xt_match xt_u32_mt_reg __read_mostly = {
        .name       = "u32",
        .revision   = 0,
        .family     = NFPROTO_UNSPEC,
        .match      = u32_mt,
+       .checkentry = u32_mt_checkentry,
        .matchsize  = sizeof(struct xt_u32),
        .me         = THIS_MODULE,
 };