pkgsrc-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[pkgsrc/pkgsrc-2005Q3]: pkgsrc/www/libwww Pullup ticket 886 - requested by Lu...



details:   https://anonhg.NetBSD.org/pkgsrc/rev/34f76ebb5dc7
branches:  pkgsrc-2005Q3
changeset: 499668:34f76ebb5dc7
user:      snj <snj%pkgsrc.org@localhost>
date:      Sat Nov 05 17:25:26 2005 +0000

description:
Pullup ticket 886 - requested by Lubomir Sedlacik
security fix for libwww

Revisions pulled up:
- pkgsrc/www/libwww/Makefile            1.62
- pkgsrc/www/libwww/distinfo            1.21
- pkgsrc/www/libwww/patches/patch-ap    1.1

   Module Name:    pkgsrc
   Committed By:   salo
   Date:           Thu Nov  3 15:51:59 UTC 2005

   Modified Files:
           pkgsrc/www/libwww: Makefile distinfo
   Added Files:
           pkgsrc/www/libwww/patches: patch-ap

   Log Message:
   Security fix for SA17119:

   "A vulnerability was found in W3C Libwww, which potentially can be
   exploited by malicious people to cause a DoS (Denial of Service).

   The vulnerability is caused due to a boundary error in the
   "HTBoundary_put_block()" function when processing multipart MIME data.
   This may be exploited to cause an illegal memory access past the end of
   the input buffer via specially crafted multipart MIME data.

   Successful exploitation can potentially cause an application that uses
   Libwww to crash."

   http://secunia.com/advisories/17119/
   https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=159597

   Bump PKGREVISION.
   Patch from RedHat.

diffstat:

 www/libwww/Makefile         |    4 +-
 www/libwww/distinfo         |    3 +-
 www/libwww/patches/patch-ap |  524 ++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 528 insertions(+), 3 deletions(-)

diffs (truncated from 556 to 300 lines):

diff -r 90364ae21ab3 -r 34f76ebb5dc7 www/libwww/Makefile
--- a/www/libwww/Makefile       Sat Nov 05 17:20:33 2005 +0000
+++ b/www/libwww/Makefile       Sat Nov 05 17:25:26 2005 +0000
@@ -1,8 +1,8 @@
-# $NetBSD: Makefile,v 1.61 2005/05/31 20:51:59 salo Exp $
+# $NetBSD: Makefile,v 1.61.4.1 2005/11/05 17:25:26 snj Exp $
 
 DISTNAME=              w3c-libwww-5.4.0
 PKGNAME=               libwww-5.4.0
-PKGREVISION=           3
+PKGREVISION=           4
 CATEGORIES=            www devel
 MASTER_SITES=          http://www.w3.org/Library/Distribution/ \
                        ftp://ftp.uni-hannover.de/pub/mirror/info-systems/WWW/libwww/
diff -r 90364ae21ab3 -r 34f76ebb5dc7 www/libwww/distinfo
--- a/www/libwww/distinfo       Sat Nov 05 17:20:33 2005 +0000
+++ b/www/libwww/distinfo       Sat Nov 05 17:25:26 2005 +0000
@@ -1,4 +1,4 @@
-$NetBSD: distinfo,v 1.20 2005/05/31 20:51:46 salo Exp $
+$NetBSD: distinfo,v 1.20.4.1 2005/11/05 17:25:26 snj Exp $
 
 SHA1 (w3c-libwww-5.4.0.tgz) = 2394cb4e0dc4e2313a9a0ddbf508e4b726e9af63
 RMD160 (w3c-libwww-5.4.0.tgz) = 12e55ecb2435f9048d627e56f8ae60d4c246648b
@@ -19,3 +19,4 @@
 SHA1 (patch-am) = 8252ce567efc056daa10af39eeca314f9a915f90
 SHA1 (patch-an) = e7195c25ce08e13e0c8b64b05b737e9a5f5157a8
 SHA1 (patch-ao) = fa5c98f6c4e873f816e5a5bc48481d1462c946dc
+SHA1 (patch-ap) = 506ee8ddd2e627aa6ba84b933ca39a6934b95689
diff -r 90364ae21ab3 -r 34f76ebb5dc7 www/libwww/patches/patch-ap
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/www/libwww/patches/patch-ap       Sat Nov 05 17:25:26 2005 +0000
@@ -0,0 +1,524 @@
+$NetBSD: patch-ap,v 1.1.2.2 2005/11/05 17:25:26 snj Exp $
+
+--- Library/src/HTBound.c.orig 1999-02-22 23:10:10.000000000 +0100
++++ Library/src/HTBound.c      2005-11-03 16:43:25.000000000 +0100
+@@ -11,9 +11,12 @@
+ **
+ ** Authors
+ **    HF      Henrik Frystyk <frystyk%w3.org@localhost>
++**      SV      Sam Varshavchik <mrsam%courier-mta.com@localhost>
+ **
+ ** History:
+ **    Nov 95  Written from scratch
++**   SV Jun 05  Rewrote HTBoundary_put_block.  Fixed many bugs+segfaults.
++**   SV Jul 05  Fix double-counting of processed bytes.
+ **
+ */
+ 
+@@ -23,104 +26,395 @@
+ #include "WWWCore.h"
+ #include "HTMerge.h"
+ #include "HTReqMan.h"
++#include "HTNetMan.h"
++#include "HTChannl.h"
+ #include "HTBound.h"                                   /* Implemented here */
+ 
+-#define PUTBLOCK(b, l)        (*me->target->isa->put_block)(me->target, b, l)
++#define PUTBLOCK(b, l)        (me->target ? (*me->target->isa->put_block)(me->target, b, l):HT_OK)
++
+ #define PUTDEBUG(b, l)        (*me->debug->isa->put_block)(me->debug, b, l)
+ #define FREE_TARGET   (*me->target->isa->_free)(me->target)
+ 
+ struct _HTStream {
+     const HTStreamClass *     isa;
++    HTNet *                      net;
+     HTStream *                        target;
+     HTStream *                        orig_target;
+     HTFormat                  format;
+     HTStream *                        debug;            /* For preamble and epilog */
+     HTRequest *                       request;
+-    BOOL                      body;             /* Body or preamble|epilog */
+-    HTEOLState                        state;
+-    int                               dash;                    /* Number of dashes */
+     char *                    boundary;
+-    char *                    bpos;
++
++    BOOL                        keptcrlf;
++    int                         (*state)(HTStream *, const char *, int);
++
++    char                        *boundary_ptr;
++
+ };
+ 
++PRIVATE int HTBoundary_flush (HTStream * me);
++
+ /* ------------------------------------------------------------------------- */
+ 
++PRIVATE int start_of_line (HTStream * me, const char * b, int l);
++PRIVATE int seen_dash (HTStream * me, const char * b, int l);
++PRIVATE int seen_doubledash (HTStream * me, const char * b, int l);
++PRIVATE int seen_delimiter_nonterminal(HTStream * me, const char * b, int l);
++PRIVATE int seen_delimiter_nonterminal_CR(HTStream * me, const char * b, int l);
++PRIVATE int seen_delimiter_dash(HTStream * me, const char * b, int l);
++PRIVATE int seen_delimiter_terminal(HTStream * me, const char * b, int l);
++PRIVATE int seen_delimiter_terminal_CR(HTStream * me, const char * b, int l);
++PRIVATE int not_delimiter(HTStream * me, const char * b, int l, int extra);
++PRIVATE int seen_nothing(HTStream * me, const char * b, int l);
++PRIVATE int seen_cr(HTStream * me, const char * b, int l);
++PRIVATE void process_boundary(HTStream *me, int isterminal);
++
++#define UNUSED(l) (l=l)    /* Shut up about unused variables */
++
+ PRIVATE int HTBoundary_put_block (HTStream * me, const char * b, int l)
+ {
+-    const char *start = b;
+-    const char *end = b;
+-    while (l-- > 0) {
+-      if (me->state == EOL_FCR) {
+-          me->state = (*b == LF) ? EOL_FLF : EOL_BEGIN;
+-      } else if (me->state == EOL_FLF) {
+-          if (me->dash == 2) {
+-              while (l>0 && *me->bpos && *me->bpos==*b) l--, me->bpos++, b++;
+-              if (!*me->bpos) {
+-                  HTTRACE(STREAM_TRACE, "Boundary.... `%s\' found\n" _ me->boundary);
+-                  me->bpos = me->boundary;
+-                  me->body = YES;
+-                  me->state = EOL_DOT;
+-              } else if (l>0) {
+-                  me->dash = 0;
+-                  me->bpos = me->boundary;
+-                  me->state = EOL_BEGIN;
+-              }
+-          }
+-          if (*b == '-') {
+-              me->dash++;
+-          } else if (*b != CR && *b != LF) {
+-              me->dash = 0;
+-              me->state = EOL_BEGIN;
+-          }
+-      } else if (me->state == EOL_SLF) {          /* Look for closing '--' */
+-          if (me->dash == 4) {
+-              if (end > start) {
+-                  int status = PUTBLOCK(start, end-start);
+-                  if (status != HT_OK) return status;
+-              }
+-              HTTRACE(STREAM_TRACE, "Boundary.... Ending\n");
+-              start = b;
+-              me->dash = 0;
+-              me->state = EOL_BEGIN;
+-          }
+-          if (*b == '-') {
+-              me->dash++;
+-          } else if (*b != CR && *b != LF) {
+-              me->dash = 0;
+-              me->state = EOL_BEGIN;
+-          }
+-          me->body = NO;
+-      } else if (me->state == EOL_DOT) {
+-          int status;
+-          if (me->body) {
+-              if (me->target) FREE_TARGET;
+-              me->target = HTStreamStack(WWW_MIME,me->format,
+-                                         HTMerge(me->orig_target, 2),
+-                                         me->request, YES);
+-              if (end > start) {
+-                  if ((status = PUTBLOCK(start, end-start)) != HT_OK)
+-                      return status;
++      /*
++      ** The HTBoundary object gets attached downstream of HTMime.
++      ** The HTBoundary object creates another HTMime object downstream of
++      ** the HTBoundary object.
++      **
++      ** When we push data downstream to the second HTBoundary object, it
++      ** updates the bytes read count in the HTNet object.
++      **
++      ** When we return to the parent HTMime object, itupdates the
++      ** bytes read count in the HTNet object again.  Oops.
++      **
++      ** Same thing happens with the consumed byte count.  We can prevent
++      ** the consumed byte counts from being updated by temporary setting
++      ** the input channel stream pointer to NULL, but for the byte counts
++      ** we have to save them and restore them before existing.
++      **
++      ** This bug was discovered by chance when a multipart/partial response
++      ** was partially received, and as a result of double-counting the
++      ** real response got cut off (because HTMime thought that more bytes
++      ** were processed than actually were, thus it processed only the
++      ** partial count of the remaining bytes in the response).  When the
++      ** multipart/partial response was received all at once this bug did
++      ** not get triggered.
++      */
++
++      HTHost *host=HTNet_host(me->net);
++      HTChannel *c=HTHost_channel(host);
++      HTInputStream *i=HTChannel_input(c);
++
++      long saveBytesRead=HTNet_bytesRead(me->net);
++      long saveHeaderBytesRead=HTNet_headerBytesRead(me->net);
++
++      if (i)
++              HTChannel_setInput(c, NULL);
++
++      HTTRACE(STREAM_TRACE, "Boundary: processing %d bytes\n" _ l);
++      /* Main loop consumes all input */
++
++      while (l)
++      {
++              int n= (*me->state)(me, b, l);
++
++              if (n == 0)
++                      return HT_ERROR;
++              b += n;
++              l -= n;
++      }
++
++      if (i)
++              HTChannel_setInput(c, i);
++      HTNet_setBytesRead(me->net, saveBytesRead);
++      HTNet_setHeaderBytesRead(me->net, saveHeaderBytesRead);
++
++      return HT_OK;
++}
++
++/*
++** Start of line, keptcrlf=YES if we've kept the preceding CRLF from downstream
++** and we'll pass it along if we decide that this is not a boundary delimiter.
++*/
++
++PRIVATE int start_of_line (HTStream * me, const char * b, int l)
++{
++      if (*b != '-')
++              return not_delimiter(me, b, l, 0);
++
++      HTTRACE(STREAM_TRACE, "Boundary: start of line: input '-'\n");
++
++      me->state= seen_dash;
++
++      return 1;
++}
++
++/*
++** Line: -
++*/
++
++PRIVATE int seen_dash (HTStream * me, const char * b, int l)
++{
++      if (*b != '-')
++              return not_delimiter(me, b, l, 1);
++
++      HTTRACE(STREAM_TRACE, "Boundary: start of line: input '--'\n");
++
++      me->state= seen_doubledash;
++      me->boundary_ptr=me->boundary;
++      return 1;
++}
++
++/*
++** Line: --
++*/
++
++PRIVATE int seen_doubledash (HTStream * me, const char * b, int l)
++{
++      me->state=seen_doubledash;
++
++      if (*me->boundary_ptr)
++      {
++              if (*b != *me->boundary_ptr)
++              {
++                      return not_delimiter(me, b, l,
++                                           me->boundary_ptr - me->boundary
++                                           + 2);
+               }
+-          } else {
+-              if (me->debug)
+-                  if ((status = PUTDEBUG(start, end-start)) != HT_OK)
+-                      return status;
++              ++me->boundary_ptr;
++              return 1;
+           }
+-          start = b;
+-          if (*b == '-') me->dash++;
+-          me->state = EOL_SLF;
+-      } else if (*b == CR) {
+-          me->state = EOL_FCR;
+-          end = b;
+-      } else if (*b == LF) {
+-          if (me->state != EOL_FCR) end = b;
+-          me->state = EOL_FLF;
++
++      /*
++      ** Line: --delimiter
++      */
++
++      if (*b == '-')
++      {
++              HTTRACE(STREAM_TRACE,
++                      "Boundary: start of line: input '--%s-'\n"
++                      _ me->boundary);
++
++              me->state=seen_delimiter_dash;
++              return 1;
+       }
+-      b++;
++
++      HTTRACE(STREAM_TRACE,
++              "Boundary: Found: '--%s'\n" _ me->boundary);
++      
++      return seen_delimiter_nonterminal(me, b, l);
++}



Home | Main Index | Thread Index | Old Index