Fix oops on bad entry list
PATCH 1/1 Fix oops on bad entry list
[Note: I am not subscribed to netfilter-devel; please CC me on any replies]
The patch below fixes an oops that occurs in Linux kernels
<= 2.4.19-pre10 if an entry list passed to IPT_SO_SET_REPLACE contains an entry with a jump to an invalid position (into the middle of another entry or outside the list).
--Andrew Church
[email protected] http://achurch.org/
ipv4/netfilter/ip_tables.c renamed from ipv4/netfilter/ip_tables.c.old +30 -0
@@ -739,6 +739,7 @@ unsigned int *i) {unsigned int h; +struct ipt_standard_target *t;if ((unsigned long )e % __alignof__(struct ipt_entry ) !=0 || (unsigned char *)e +sizeof (struct ipt_entry ) >= limit) {
@@ -751,6 +752,35 @@duprintf ("checking: element %p size %u\n" , e, e->next_offset);return -EINVAL ; + } + +if (e->target_offset +sizeof (struct ipt_entry_target ) + >= e->next_offset) { +duprintf ("checking: element %p size %u target %u\n" , + e, e->next_offset, e->target_offset); +return -EINVAL ; + } + +/* If the target is another chain, make sure the pointer is valid */ + t = (void *)ipt_get_target (e); +if (strcmp (t->target.u.user.name,IPT_STANDARD_TARGET ) ==0 + && t->verdict >=0 ) { +int checkpos =0 ; +if (t->verdict >= newinfo->size) { +duprintf ("checking: element %p: jump target %u" +" out of range" , e, t->verdict); +return -EINVAL ; + } +while (checkpos < t->verdict) { +struct ipt_entry *e2; + e2 = (void *)newinfo->entries + checkpos; + checkpos += e2->next_offset; + } +if (checkpos > t->verdict) { +duprintf ("checking: element %p: jump target %u" +" invalid" , e, t->verdict); +return -EINVAL ; + } }/* Check hooks & underflows */