Subject: kern/36864: opencrypto - deflate failed to decompress large packets
To: None <kern-bug-people@netbsd.org, gnats-admin@netbsd.org,>
From: Wolfgang Stukenbrock <Wolfgang.Stukenbrock@nagler-company.com>
List: netbsd-bugs
Date: 08/30/2007 10:05:01
>Number:         36864
>Category:       kern
>Synopsis:       opencrypto - deflate failed to decompress large packets
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    kern-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Thu Aug 30 10:05:00 +0000 2007
>Originator:     Wolfgang Stukenbrock
>Release:        NetBSD 3.1
>Organization:
Dr. Nagler & Company GmbH
	
>Environment:
	
	
System: NetBSD test-s0 3.1 NetBSD 3.1 (test-s0) #0: Tue Apr 3 11:33:43 CEST 2007 root@test-s0:/usr/src/sys/arch/i386/compile/test-s0 i386
Architecture: i386
Machine: i386
>Description:
	When packets with e.g. all 0 in it gets compressed the compression 
	will have a verygood result, but the current implemntation failed
	to decompress it again.
	This may happen, if you use NFS though an ipsec-tunnel with compression.
	The main problem is that the decompression stuff uses the current
	size as an estimation for the resulting size with a limit of 8 additional
	malloc() expansion.
	The result of this bug is, that you cannot use ipcomp for tunnels if
	you are tunneling NFS connections trough it.
	The buggy code is located in /usr/src/sys/opencrypto/deflate.c.
>How-To-Repeat:
	setup an ipcomp-connection and try to send the first 10k of /dev/zero
	through it ...
>Fix:
	This fix is not very best one, but it solves the problem.
	The idea is to increase the allocated size to a minimum, even if
	there is a very small packet. I've decided to use 512 bytes as the min.
	in order to get all normal packets decompressed in one block in order
	to speed up the whole thing.

*** deflate.c   2007/08/30 09:51:30     1.1
--- deflate.c   2007/08/30 09:54:40
***************
*** 104,109 ****
--- 104,117 ----
                i++;
        } else {
                /*
+                * workaround a problem with very goo compression
+                * e.g. a NFS packet with all 0 in it gets compressed to something
+                * around 65 bytes, but it will expand to 1448 bytes.
+                * We usse this code only for ipsec processing - so speedup everything
+                * by increasing size to at 512 bytes.
+                */
+               if (size < 512) size = 512;
+               /*
                 * Choose a buffer with 4x the size of the input buffer
                 * for the size of the output buffer in the case of
                 * decompression. If it's not sufficient, it will need to be


>Unformatted: