UNCLEAN match broken in 2.4.6?

James Morris jmorris@intercode.com.au
Thu, 5 Jul 2001 19:26:31 +1000 (EST)


On Thu, 5 Jul 2001, Joseph Fannin jhf@rivenstone.net wrote:

> I too am seeing the problems with UNCLEAN match support in kernel
> 2.4.6 that Luigi Genoni reported yesterday.


Please try the patch below.


- James
-- 
James Morris                          http://www.intercode.com.au/jmorris/
<jmorris@intercode.com.au>

diff -urN linux-2.4.6/net/ipv4/netfilter/ipt_unclean.c linux-2.4.6-f1/net/ipv4/netfilter/ipt_unclean.c
--- linux-2.4.6/net/ipv4/netfilter/ipt_unclean.c	Wed Jul  4 21:27:32 2001
+++ linux-2.4.6-f1/net/ipv4/netfilter/ipt_unclean.c	Thu Jul  5 19:16:00 2001
@@ -268,6 +268,7 @@
 	  int embedded)
 {
 	u_int8_t *opt = (u_int8_t *)tcph;
+	u_int8_t *endhdr = (u_int8_t *)tcph + tcph->doff * 4;
 	u_int8_t tcpflags;
 	int end_of_options = 0;
 	size_t i;
@@ -373,7 +374,7 @@
 				return 0;
 			}
 			/* CHECK: oversize options. */
-			else if (opt[i+1] + i >= tcph->doff * 4) {
+			else if (&opt[i] + opt[i+1] > endhdr) {
 				limpk("TCP option %u at %Zu too long\n",
 				      (unsigned int) opt[i], i);
 				return 0;
@@ -392,6 +393,7 @@
 check_ip(struct iphdr *iph, size_t length, int embedded)
 {
 	u_int8_t *opt = (u_int8_t *)iph;
+	u_int8_t *endhdr = (u_int8_t *)iph + iph->ihl * 4;
 	int end_of_options = 0;
 	void *protoh;
 	size_t datalen;
@@ -444,7 +446,7 @@
 				return 0;
 			}
 			/* CHECK: oversize options. */
-			else if (opt[i+1] + i > iph->ihl * 4) {
+			else if (&opt[i] + opt[i+1] > endhdr) {
 				limpk("IP option %u at %u too long\n",
 				      opt[i], i);
 				return 0;