Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

netfilter: xt_u32: validate user space input

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>

authored by

Wander Lairson Costa and committed by
Pablo Neira Ayuso
69c5d284 e9947649

+21
+21
net/netfilter/xt_u32.c
··· 96 96 return ret ^ data->invert; 97 97 } 98 98 99 + static int u32_mt_checkentry(const struct xt_mtchk_param *par) 100 + { 101 + const struct xt_u32 *data = par->matchinfo; 102 + const struct xt_u32_test *ct; 103 + unsigned int i; 104 + 105 + if (data->ntests > ARRAY_SIZE(data->tests)) 106 + return -EINVAL; 107 + 108 + for (i = 0; i < data->ntests; ++i) { 109 + ct = &data->tests[i]; 110 + 111 + if (ct->nnums > ARRAY_SIZE(ct->location) || 112 + ct->nvalues > ARRAY_SIZE(ct->value)) 113 + return -EINVAL; 114 + } 115 + 116 + return 0; 117 + } 118 + 99 119 static struct xt_match xt_u32_mt_reg __read_mostly = { 100 120 .name = "u32", 101 121 .revision = 0, 102 122 .family = NFPROTO_UNSPEC, 103 123 .match = u32_mt, 124 + .checkentry = u32_mt_checkentry, 104 125 .matchsize = sizeof(struct xt_u32), 105 126 .me = THIS_MODULE, 106 127 };