Synopsis: Format string vulnerability in zlib gzprintf()
NetBSD versions: NetBSD-1.5.3 (older 1-5 zlib should be upgraded completely)
Thanks to: Bill Squier
Reported in NetBSD Security Advisory: NetBSD-SA2003-004

Index: src/lib/libz/gzio.c
===================================================================
RCS file: /cvsroot/src/lib/libz/gzio.c,v
retrieving revision 1.9.8.1
retrieving revision 1.9.8.2
diff -c -p -r1.9.8.1 -r1.9.8.2
*** src/lib/libz/gzio.c	2002/03/20 23:18:16	1.9.8.1
--- src/lib/libz/gzio.c	2003/03/05 19:56:46	1.9.8.2
*************** int ZEXPORTVA gzprintf (gzFile file, con
*** 531,544 ****
      int len;
  
      va_start(va, format);
! #ifdef HAS_vsnprintf
!     (void)vsnprintf(buf, sizeof(buf), format, va);
! #else
!     (void)vsprintf(buf, format, va);
! #endif
      va_end(va);
!     len = strlen(buf); /* some *sprintf don't return the nb of bytes written */
!     if (len <= 0) return 0;
  
      return gzwrite(file, buf, (unsigned)len);
  }
--- 531,539 ----
      int len;
  
      va_start(va, format);
!     len = vsnprintf(buf, sizeof(buf), format, va);
      va_end(va);
!     if (len <= 0 || len >= sizeof(buf)) return 0;
  
      return gzwrite(file, buf, (unsigned)len);
  }
*************** int ZEXPORTVA gzprintf (file, format, a1
*** 554,568 ****
      char buf[Z_PRINTF_BUFSIZE];
      int len;
  
! #ifdef HAS_snprintf
!     snprintf(buf, sizeof(buf), format, a1, a2, a3, a4, a5, a6, a7, a8,
  	     a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
! #else
!     sprintf(buf, format, a1, a2, a3, a4, a5, a6, a7, a8,
! 	    a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
! #endif
!     len = strlen(buf); /* old sprintf doesn't return the nb of bytes written */
!     if (len <= 0) return 0;
  
      return gzwrite(file, buf, len);
  }
--- 549,557 ----
      char buf[Z_PRINTF_BUFSIZE];
      int len;
  
!     len = snprintf(buf, sizeof(buf), format, a1, a2, a3, a4, a5, a6, a7, a8,
  	     a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
!     if (len <= 0 || len >= sizeof(buf)) return 0;
  
      return gzwrite(file, buf, len);
  }