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:46:59 +0200 |
| commit | e416d65ff456066d60d813c540ab2dd2a06d3d12 (patch) | |
| tree | bd377728193a18ec57602c662a0cf11980ae163c /net | |
| parent | 7935b636dd693dfe4483cfef4a1e91366c8103fa (diff) | |
| download | linux-e416d65ff456066d60d813c540ab2dd2a06d3d12.tar.gz linux-e416d65ff456066d60d813c540ab2dd2a06d3d12.tar.bz2 linux-e416d65ff456066d60d813c540ab2dd2a06d3d12.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')
| -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, }; |
