diff options
author | Wander Lairson Costa <wander@redhat.com> | 2023-08-28 10:21:07 -0300 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2023-09-23 10:48:09 +0200 |
commit | ddf190be80ef0677629416a128f9da91e5800d21 (patch) | |
tree | 154b21097918c8e4b9dd4f8186c370669403d640 /net/netfilter/xt_u32.c | |
parent | e632d09dffc68b9602d6893a99bfe3001d36cefc (diff) | |
download | linux-stable-ddf190be80ef0677629416a128f9da91e5800d21.tar.gz linux-stable-ddf190be80ef0677629416a128f9da91e5800d21.tar.bz2 linux-stable-ddf190be80ef0677629416a128f9da91e5800d21.zip |
netfilter: xt_u32: validate user space input
commit 69c5d284f67089b4750d28ff6ac6f52ec224b330 upstream.
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>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'net/netfilter/xt_u32.c')
-rw-r--r-- | net/netfilter/xt_u32.c | 21 |
1 files changed, 21 insertions, 0 deletions
diff --git a/net/netfilter/xt_u32.c b/net/netfilter/xt_u32.c index a95b50342dbb..58ba402bc0b0 100644 --- a/net/netfilter/xt_u32.c +++ b/net/netfilter/xt_u32.c @@ -95,11 +95,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, }; |