Skip to contentSkip to conversation

Fix oops on bad entry list

PATCH New Andrew Church 1 participant 1 message Jun 19, 2002 netfilter

lore
Share & tools
lore
#0 lore raw

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 */