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: