Bug 18678

Summary: Bug in libz
Product: Base System Reporter: Archie Cobbs <archie>
Component: binAssignee: freebsd-bugs (Nobody) <bugs>
Status: Closed FIXED    
Severity: Affects Only Me    
Priority: Normal    
Version: 3.4-RELEASE   
Hardware: Any   
OS: Any   

Description Archie Cobbs 2000-05-19 18:50:01 UTC
	[I rec'd this email on the ietf-ppp mailing list and copy it here]

> From owner-ietf-ppp-outgoing@merit.edu Fri May 19 07:25:39 2000
> Content-Type: text/plain; charset=us-ascii
> Content-Transfer-Encoding: 7bit
> Message-ID: <14629.20138.903736.299605@gargle.gargle.HOWL>
> Date: Fri, 19 May 2000 10:24:42 -0400 (EDT)
> From: James Carlson <james.d.carlson@east.sun.com>
> To: pppext <ietf-ppp@merit.edu>
> Subject: RFC 1979 Deflate / zlib warning
> X-Mailer: VM 6.75 under Emacs 20.6.1
> Sender: owner-ietf-ppp@merit.edu
> Precedence: bulk
> Errors-To: owner-ietf-ppp-outgoing@merit.edu
> Status: RO
> 
> I've found a potentially serious bug in all popular versions of zlib
> (0.99, 1.0.4, and the latest 1.1.3) by Jean-loup Gailly and Mark
> Adler.  This library is used to implement RFC 1979 Deflate
> compression.
> 
> The short version:
> 
> 	If the deflate window size is set to 8, zlib will corrupt
> 	memory and (depending on your implementation) cause a kernel
> 	panic.  The recommended fix is to reply with Configure-Nak if
> 	the peer the Window parameter set to 0000 (size 8) in its
> 	Configure-Request and ignore Configure-Nak with Window set to
> 	0000.
> 
> The long version:
> 
> 	The problem is that s->strstart gets set to a very large
> 	positive integer when wsize (local copy of s->w_size) is
> 	subtracted in deflate.c:fill_window().  This happens because
> 	MAX_DIST(s) resolves as a negative number when the window size
> 	is 8 -- MAX_DIST(s) is defined as s->w_size-MIN_LOOKAHEAD in
> 	deflate.h.  MIN_LOOKAHEAD is MAX_MATCH+MIN_MATCH+1, and that
> 	is 258+3+1 or 262.  Since a window size of 8 gives s->w_size
> 	256, MAX_DIST(s) is 256-262 or -6.
> 
> 	This results in read_buf() writing over memory outside of
> 	s->window, and a crash.
> 
> 	I tried experimenting with the definition of MAX_MATCH,
> 	MAX_LOOKAHEAD, and MAX_DIST(s) using cargo-cult techniques
> 	without much success.  I was able to get deflate() (the
> 	compression call) to avoid crashing, but I rewarded with
> 	either "invalid stored block lengths" or "oversubscribed
> 	dynamic bit lengths tree" on calling inflate() on the
> 	resulting compressed data, and I wasn't able to fix this.
> 
> Patches:
> 
> 	I've posted patches for ANU PPP and a short example program
> 	that crashes zlib to my Sun web site:
> 
> 		http://playground.sun.com/~carlsonj/
> 
> -- 
> James Carlson, Internet Engineering       <james.d.carlson@east.sun.com>
> SUN Microsystems / 1 Network Drive         71.234W   Vox +1 781 442 2084
> MS UBUR02-212 / Burlington MA 01803-2757   42.497N   Fax +1 781 442 1677
> "PPP Design and Debugging" --- http://people.ne.mediaone.net/carlson/ppp

Fix: 

See http://playground.sun.com/~carlsonj/
How-To-Repeat: 
	See http://playground.sun.com/~carlsonj/
Comment 1 Mike Barcroft freebsd_committer freebsd_triage 2001-07-22 03:37:37 UTC
State Changed
From-To: open->feedback


Does this problem still occur in newer versions of FreeBSD, 
such as 4.3-RELEASE?
Comment 2 Mike Barcroft freebsd_committer freebsd_triage 2001-07-23 05:48:37 UTC
On Sun, Jul 22, 2001 at 09:34:39PM -0500, Archie Cobbs wrote:
> mike@FreeBSD.org writes:
> > Synopsis: Bug in libz
> > 
> > State-Changed-From-To: open->feedback
> > State-Changed-By: mike
> > State-Changed-When: Sat Jul 21 19:37:37 PDT 2001
> > State-Changed-Why: 
> > 
> > Does this problem still occur in newer versions of FreeBSD,
> > such as 4.3-RELEASE?
> > 
> > http://www.FreeBSD.org/cgi/query-pr.cgi?pr=18678
> 
> Yes, because FreeBSD is using version 1.1.3. See the URL
> mentioned in the PR for more information:
> 
>     http://playground.sun.com/~carlsonj/

I see.  What was the response from the vendor?

Best regards,
Mike Barcroft
Comment 3 Mike Barcroft freebsd_committer freebsd_triage 2001-08-02 04:24:07 UTC
State Changed
From-To: feedback->analyzed


This is still a problem. 


Comment 4 Mike Barcroft freebsd_committer freebsd_triage 2001-08-02 04:24:07 UTC
Responsible Changed
From-To: freebsd-bugs->peter


Over to the maintainer of libz.
Comment 5 Mike Barcroft freebsd_committer freebsd_triage 2001-08-02 04:31:54 UTC
Adding to Audit-Trail.

----- Forwarded message from Archie Cobbs <archie@dellroad.org> -----

Delivered-To: mike@freebsd.org
From: Archie Cobbs <archie@dellroad.org>
Subject: Re: bin/18678: Bug in libz
In-Reply-To: <20010723004837.A70468@coffee.q9media.com> "from Mike Barcroft at
 Jul 23, 2001 00:48:37 am"
To: Mike Barcroft <mike@FreeBSD.org>
Date: Sat, 28 Jul 2001 21:49:26 -0500 (CDT)
X-Mailer: ELM [version 2.4ME+ PL82 (25)]

Mike Barcroft writes:
> On Sun, Jul 22, 2001 at 09:34:39PM -0500, Archie Cobbs wrote:
> > mike@FreeBSD.org writes:
> > > Synopsis: Bug in libz
> > > 
> > > State-Changed-From-To: open->feedback
> > > State-Changed-By: mike
> > > State-Changed-When: Sat Jul 21 19:37:37 PDT 2001
> > > State-Changed-Why: 
> > > 
> > > Does this problem still occur in newer versions of FreeBSD,
> > > such as 4.3-RELEASE?
> > > 
> > > http://www.FreeBSD.org/cgi/query-pr.cgi?pr=18678
> > 
> > Yes, because FreeBSD is using version 1.1.3. See the URL
> > mentioned in the PR for more information:
> > 
> >     http://playground.sun.com/~carlsonj/
> 
> I see.  What was the response from the vendor?

Never heard one (but I didn't pursue it myself very much).

-Archie

__________________________________________________________________________
Archie Cobbs     *     Packet Design     *     http://www.packetdesign.com

----- End forwarded message -----
Comment 6 Archie Cobbs 2002-05-30 21:14:41 UTC
Below is the test program copied here for your convenience.

  "You can demonstrate the problem for yourself with this test program.
   If TEST_WINDOW is set to 8, it crashes, but 9 to 15 works."

FYI, The bug still exists in FreeBSD 4.5-REL.

-Archie

___________________________________________________________________________
Archie Cobbs    *    Packet Design, Inc.   *    http://www.packetdesign.com

#include <stdio.h>
#include <stdlib.h>
#include "zconf.h"
#include "zlib.h"

/* cc -o zlib-bug -Wall zlib-bug.c -lz */

#define TEST_WINDOW	8

struct zchunk {
	unsigned	size;
	unsigned	guard;
};

#define	GUARD_MAGIC	0x77a6011a

static char quickbrown[] =
"The quick brown fox jumped over the lazy dog's back.";

static char tempbuf[1024],tempbuf2[1024];

static void *
z_alloc(void *notused, unsigned items, unsigned size)
{
	struct zchunk	*z;

	size = items * size + sizeof (struct zchunk);

	z = (struct zchunk *)malloc(size);

	z->size = size;
	z->guard = GUARD_MAGIC;

	return ((void *)(z + 1));
}

static void
z_free(void *notused, void *ptr)
{
	struct zchunk	*z = ((struct zchunk *)ptr) - 1;

	if (z->guard != GUARD_MAGIC) {
		fprintf(stderr,"z_free of corrupted chunk at 0x%p (%x, %x)\n",
		    (void *)z, z->size, z->guard);
		return;
	}
	free(z);
}

z_stream compr,decompr;

int
main(int argc, char **argv)
{
	int retv;

	compr.next_in = NULL;
	compr.zalloc = z_alloc;
	compr.zfree = z_free;
	if (deflateInit2(&compr, Z_DEFAULT_COMPRESSION, 8, TEST_WINDOW, 8,
	    Z_DEFAULT_STRATEGY) != Z_OK) {
		fprintf(stderr,"Compress set-up failed.\n");
		exit(1);
	}
	deflateReset(&compr);
	decompr.next_out = NULL;
	decompr.zalloc = z_alloc;
	decompr.zfree = z_free;
	if (inflateInit2(&decompr, TEST_WINDOW) != Z_OK) {
		fprintf(stderr,"Decompress set-up failed.\n");
		exit(1);
	}
	inflateReset(&decompr);

	for (;;) {
		fputc('.',stderr);
		compr.next_in = quickbrown;
		compr.avail_in = sizeof(quickbrown);
		compr.next_out = tempbuf;
		compr.avail_out = sizeof(tempbuf);
		retv = deflate(&compr,Z_NO_FLUSH);
		if (retv != Z_OK) {
			fprintf(stderr,"Compression failed %s\n",
			    compr.msg?compr.msg:"");
			exit(1);
		}
		if (compr.avail_out != sizeof(tempbuf)) {
			decompr.next_in = tempbuf;
			decompr.avail_in = sizeof(tempbuf)-compr.avail_out;
			decompr.next_out = tempbuf2;
			decompr.avail_out = sizeof(tempbuf2);
			retv = inflate(&decompr,Z_NO_FLUSH);
			if (retv != Z_OK) {
				fprintf(stderr,"Decompression failed %s\n",
				    decompr.msg?decompr.msg:"");
				exit(1);
			}
		}
	}
}
Comment 7 Peter Wemm freebsd_committer freebsd_triage 2004-03-29 20:17:14 UTC
Responsible Changed
From-To: peter->freebsd-bugs

Return neglected PR to the pool
Comment 8 Tim Robbins freebsd_committer freebsd_triage 2004-08-23 11:30:03 UTC
State Changed
From-To: analyzed->closed

This has been fixed (for some definition of the word) in zlib 1.1.4; 
all supported branches now use zlib 1.1.4 or newer.