Bug#776504: unblock: privoxy/3.0.21-7
Package: release.debian.org
Severity: normal
User: release.debian.org@packages.debian.org
Usertags: unblock
Please unblock package privoxy/3.0.21-7
I just uploaded privoxy 3.0.21-7, which should fix CVE-2015-1380,
CVE-2015-1381 and CVE-2015-1381, which are reported in #776490.
A debdiff between 3.0.21-5 and 3.0.21-7 is attached.
(I jumped over 3.0.21-6 since I mixed up the CVE number of the last
patch in there).
It contains 3 quilt patches, which are extracted from upstream 3.0.23.
Greetings
Roland
diff -Nru privoxy-3.0.21/debian/changelog privoxy-3.0.21/debian/changelog
--- privoxy-3.0.21/debian/changelog 2015-01-12 08:44:24.000000000 +0100
+++ privoxy-3.0.21/debian/changelog 2015-01-28 19:48:07.000000000 +0100
@@ -1,3 +1,13 @@
+privoxy (3.0.21-7) unstable; urgency=medium
+
+ * 37_CVE-2015-1380: denial of service.
+ * 38_CVE-2015-1381: multiple segmentation faults and memory leaks in the
+ pcrs code.
+ * 39_CVE-2015-1382: invalid read.
+ * These 3 patches Closes: #776490.
+
+ -- Roland Rosenfeld <roland@debian.org> Wed, 28 Jan 2015 19:46:42 +0100
+
privoxy (3.0.21-5) unstable; urgency=low
* 34_CVE-2015-1030: Fix memory leak in rfc2553_connect_to(). CID 66382
diff -Nru privoxy-3.0.21/debian/patches/37_CVE-2015-1380.patch privoxy-3.0.21/debian/patches/37_CVE-2015-1380.patch
--- privoxy-3.0.21/debian/patches/37_CVE-2015-1380.patch 1970-01-01 01:00:00.000000000 +0100
+++ privoxy-3.0.21/debian/patches/37_CVE-2015-1380.patch 2015-01-28 17:39:40.000000000 +0100
@@ -0,0 +1,33 @@
+Author: Fabian Keil <fk@fabiankeil.de>
+Description: chunked_body_is_complete(): Check input more carefully
+ Previously a nul-chunk without mandatory trailing "\r\n" would
+ not be rejected as invalid. When compiled with assertions enabled,
+ this would cause Privoxy to abort().
+ Reported by Matthew Daley.
+Bug-Debian: http://bugs.debian.org/776490
+Origin: upstream, http://ijbswa.cvs.sourceforge.net/viewvc/ijbswa/current/jcc.c?r1=1.433&r2=1.434
+
+--- a/jcc.c
++++ b/jcc.c
+@@ -1348,12 +1348,15 @@
+ {
+ return CHUNK_STATUS_PARSE_ERROR;
+ }
+- /*
+- * Skip "\r\n", the chunk data and another "\r\n".
+- * Moving p to either the beginning of the next chunk-size
+- * or one byte beyond the end of the chunked data.
+- */
+- p += 2 + chunksize + 2;
++ /* Move beyond the chunkdata. */
++ p += 2 + chunksize;
++
++ /* There should be another "\r\n" to skip */
++ if (memcmp(p, "\r\n", 2))
++ {
++ return CHUNK_STATUS_PARSE_ERROR;
++ }
++ p += 2;
+ } while (chunksize > 0U);
+
+ *length = (size_t)(p - iob->cur);
diff -Nru privoxy-3.0.21/debian/patches/38_CVE-2015-1381.patch privoxy-3.0.21/debian/patches/38_CVE-2015-1381.patch
--- privoxy-3.0.21/debian/patches/38_CVE-2015-1381.patch 1970-01-01 01:00:00.000000000 +0100
+++ privoxy-3.0.21/debian/patches/38_CVE-2015-1381.patch 2015-01-28 17:45:19.000000000 +0100
@@ -0,0 +1,54 @@
+Author: Fabian Keil <fk@fabiankeil.de>
+Description: pcrs_compile_replacement(): Fix multiple segfaults and memory
+ leaks ... and report errors more reliably. Previously some invalid
+ pcrs commands were silently accepted but didn't work as expected.
+ Partially discovered with afl-fuzz.
+Bug-Debian: http://bugs.debian.org/776490
+Origin: upstream, http://ijbswa.cvs.sourceforge.net/viewvc/ijbswa/current/pcrs.c?r1=1.46&r2=1.47
+
+--- a/pcrs.c
++++ b/pcrs.c
+@@ -319,6 +319,13 @@
+ if (replacement[i] == '$' && !quoted && i < (int)(length - 1))
+ {
+ char *symbol, symbols[] = "'`+&";
++ if (l >= PCRS_MAX_SUBMATCHES)
++ {
++ freez(text);
++ freez(r);
++ *errptr = PCRS_WARN_BADREF;
++ return NULL;
++ }
+ r->block_length[l] = (size_t)(k - r->block_offset[l]);
+
+ /* Numerical backreferences */
+@@ -330,7 +337,10 @@
+ }
+ if (r->backref[l] > capturecount)
+ {
++ freez(text);
++ freez(r);
+ *errptr = PCRS_WARN_BADREF;
++ return NULL;
+ }
+ }
+
+@@ -360,14 +370,17 @@
+ }
+
+ /* Valid and in range? -> record */
+- if (r->backref[l] < PCRS_MAX_SUBMATCHES + 2)
++ if (0 <= r->backref[l] && r->backref[l] < PCRS_MAX_SUBMATCHES + 2)
+ {
+ r->backref_count[r->backref[l]] += 1;
+ r->block_offset[++l] = k;
+ }
+ else
+ {
++ freez(text);
++ freez(r);
+ *errptr = PCRS_WARN_BADREF;
++ return NULL;
+ }
+ continue;
+ }
diff -Nru privoxy-3.0.21/debian/patches/39_CVE-2015-1382.patch privoxy-3.0.21/debian/patches/39_CVE-2015-1382.patch
--- privoxy-3.0.21/debian/patches/39_CVE-2015-1382.patch 1970-01-01 01:00:00.000000000 +0100
+++ privoxy-3.0.21/debian/patches/39_CVE-2015-1382.patch 2015-01-28 17:48:32.000000000 +0100
@@ -0,0 +1,100 @@
+Author: Fabian Keil <fk@fabiankeil.de>
+Description: Add parse_time_header(), a wrapper around parse_header_time()
+ ... which skips the header name for the callers which means
+ they can't get it wrong. Previously two callers did. This could
+ result in 'invalid read of size X' issues in case of value-less
+ headers.
+ On the systems I tested, X was always 1 and nobody but valgrind
+ cared, but with different malloc() implementations Privoxy might
+ be less lucky and segfault.
+ Partially discovered with afl-fuzz.
+Bug-Debian: http://bugs.debian.org/776490
+Origin: upstream, http://ijbswa.cvs.sourceforge.net/viewvc/ijbswa/current/parsers.c?r1=1.297&r2=1.298
+
+--- a/parsers.c
++++ b/parsers.c
+@@ -96,6 +96,7 @@
+ static jb_err scan_headers(struct client_state *csp);
+ static jb_err header_tagger(struct client_state *csp, char *header);
+ static jb_err parse_header_time(const char *header_time, time_t *result);
++static jb_err parse_time_header(const char *header, time_t *result);
+
+ static jb_err crumble (struct client_state *csp, char **header);
+ static jb_err filter_header (struct client_state *csp, char **header);
+@@ -2666,13 +2667,12 @@
+ }
+ else if (0 == strcmpic(newval, "randomize"))
+ {
+- const char *header_time = *header + sizeof("Last-Modified:");
+-
+ log_error(LOG_LEVEL_HEADER, "Randomizing: %s", *header);
+
+- if (JB_ERR_OK != parse_header_time(header_time, &last_modified))
++ if (JB_ERR_OK != parse_time_header(*header, &last_modified))
+ {
+- log_error(LOG_LEVEL_HEADER, "Couldn't parse: %s in %s (crunching!)", header_time, *header);
++ log_error(LOG_LEVEL_HEADER,
++ "Couldn't parse time in %s (crunching!)", *header);
+ freez(*header);
+ }
+ else
+@@ -3384,11 +3384,10 @@
+ }
+ else /* add random value */
+ {
+- const char *header_time = *header + sizeof("If-Modified-Since:");
+-
+- if (JB_ERR_OK != parse_header_time(header_time, &tm))
++ if (JB_ERR_OK != parse_time_header(*header, &tm))
+ {
+- log_error(LOG_LEVEL_HEADER, "Couldn't parse: %s in %s (crunching!)", header_time, *header);
++ log_error(LOG_LEVEL_HEADER,
++ "Couldn't parse time in %s (crunching!)", *header);
+ freez(*header);
+ }
+ else
+@@ -4372,6 +4371,44 @@
+
+ }
+
++/*********************************************************************
++ *
++ * Function : parse_time_header
++ *
++ * Description : Parses the time in an HTTP time header to get
++ * the numerical respresentation.
++ *
++ * Parameters :
++ * 1 : header = HTTP header with a time value
++ * 2 : result = storage for header_time in seconds
++ *
++ * Returns : JB_ERR_OK if the time format was recognized, or
++ * JB_ERR_PARSE otherwise.
++ *
++ *********************************************************************/
++static jb_err parse_time_header(const char *header, time_t *result)
++{
++ const char *header_time;
++
++ header_time = strchr(header, ':');
++
++ /*
++ * Currently this can't happen as all callers are called
++ * through sed() which requires a header name followed by
++ * a colon.
++ */
++ assert(header_time != NULL);
++
++ header_time++;
++ if (*header_time == ' ')
++ {
++ header_time++;
++ }
++
++ return parse_header_time(header_time, result);
++
++}
++
+
+ /*********************************************************************
+ *
diff -Nru privoxy-3.0.21/debian/patches/series privoxy-3.0.21/debian/patches/series
--- privoxy-3.0.21/debian/patches/series 2015-01-12 08:41:43.000000000 +0100
+++ privoxy-3.0.21/debian/patches/series 2015-01-28 19:47:58.000000000 +0100
@@ -11,3 +11,6 @@
34_CVE-2015-1030.patch
35_CVE-2015-1031-CID66394.patch
36_CVE-2015-1031-CID66376.patch
+37_CVE-2015-1380.patch
+38_CVE-2015-1381.patch
+39_CVE-2015-1382.patch
Reply to: