aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMaxim Konovalov <maxim@FreeBSD.org>2005-07-02 08:29:27 +0000
committerMaxim Konovalov <maxim@FreeBSD.org>2005-07-02 08:29:27 +0000
commitdfa7b73d12f67de55c2ac092c1cbc063484b6d38 (patch)
tree5192a13d08c907480906b6ebaa4ae6ec7d2a41c1
parent609fd3652ebd63cac2f7260fb879c2b33d87c1ad (diff)
downloadsrc-dfa7b73d12f67de55c2ac092c1cbc063484b6d38.tar.gz
src-dfa7b73d12f67de55c2ac092c1cbc063484b6d38.zip
Merge SA-05:14.bzip2 and SA-05:15.tcp.
Approved by: so (cperciva)
Notes
Notes: svn path=/releng/4.9/; revision=147738
-rw-r--r--UPDATING5
-rw-r--r--contrib/bzip2/bzip2.c43
-rw-r--r--contrib/bzip2/bzlib.c51
-rw-r--r--contrib/bzip2/compress.c12
-rw-r--r--contrib/bzip2/decompress.c16
-rw-r--r--contrib/bzip2/huffman.c19
-rw-r--r--sys/conf/newvers.sh2
-rw-r--r--sys/netinet/tcp_input.c28
-rw-r--r--sys/netinet/tcp_seq.h1
9 files changed, 138 insertions, 39 deletions
diff --git a/UPDATING b/UPDATING
index 5ef4b00fd5d1..32e0951222b1 100644
--- a/UPDATING
+++ b/UPDATING
@@ -17,6 +17,11 @@ minimal number of processes, if possible, for that patch. For those
updates that don't have an advisory, or to be safe, you can do a full
build and install as described in the COMMON ITEMS section.
+20050702: p19 FreeBSD-SA-05:14.bzip2, FreeBSD-SA-05:15.tcp
+ Correct bzip2 denial of service and permission race vulnerabilities.
+
+ Correct TCP connection stall denial of service vulnerabilities.
+
20050610: p18 FreeBSD-SA-05:11.gzip
Correct directory traversal and race condition vulnerabilities in gzip.
diff --git a/contrib/bzip2/bzip2.c b/contrib/bzip2/bzip2.c
index 807f420aed6b..ce48999e6202 100644
--- a/contrib/bzip2/bzip2.c
+++ b/contrib/bzip2/bzip2.c
@@ -312,6 +312,7 @@ static void compressedStreamEOF ( void ) NORETURN;
static void copyFileName ( Char*, Char* );
static void* myMalloc ( Int32 );
+static int applySavedFileAttrToOutputFile ( int fd );
@@ -457,6 +458,10 @@ void compressStream ( FILE *stream, FILE *zStream )
ret = fflush ( zStream );
if (ret == EOF) goto errhandler_io;
if (zStream != stdout) {
+ int fd = fileno ( zStream );
+ if (fd < 0) goto errhandler_io;
+ ret = applySavedFileAttrToOutputFile ( fd );
+ if (ret != 0) goto errhandler_io;
ret = fclose ( zStream );
outputHandleJustInCase = NULL;
if (ret == EOF) goto errhandler_io;
@@ -525,6 +530,7 @@ Bool uncompressStream ( FILE *zStream, FILE *stream )
UChar obuf[5000];
UChar unused[BZ_MAX_UNUSED];
Int32 nUnused;
+ void* unusedTmpV;
UChar* unusedTmp;
nUnused = 0;
@@ -554,9 +560,10 @@ Bool uncompressStream ( FILE *zStream, FILE *stream )
}
if (bzerr != BZ_STREAM_END) goto errhandler;
- BZ2_bzReadGetUnused ( &bzerr, bzf, (void**)(&unusedTmp), &nUnused );
+ BZ2_bzReadGetUnused ( &bzerr, bzf, &unusedTmpV, &nUnused );
if (bzerr != BZ_OK) panic ( "decompress:bzReadGetUnused" );
+ unusedTmp = (UChar*)unusedTmpV;
for (i = 0; i < nUnused; i++) unused[i] = unusedTmp[i];
BZ2_bzReadClose ( &bzerr, bzf );
@@ -567,6 +574,12 @@ Bool uncompressStream ( FILE *zStream, FILE *stream )
closeok:
if (ferror(zStream)) goto errhandler_io;
+ if ( stream != stdout) {
+ int fd = fileno ( stream );
+ if (fd < 0) goto errhandler_io;
+ ret = applySavedFileAttrToOutputFile ( fd );
+ if (ret != 0) goto errhandler_io;
+ }
ret = fclose ( zStream );
if (ret == EOF) goto errhandler_io;
@@ -639,6 +652,7 @@ Bool testStream ( FILE *zStream )
UChar obuf[5000];
UChar unused[BZ_MAX_UNUSED];
Int32 nUnused;
+ void* unusedTmpV;
UChar* unusedTmp;
nUnused = 0;
@@ -662,9 +676,10 @@ Bool testStream ( FILE *zStream )
}
if (bzerr != BZ_STREAM_END) goto errhandler;
- BZ2_bzReadGetUnused ( &bzerr, bzf, (void**)(&unusedTmp), &nUnused );
+ BZ2_bzReadGetUnused ( &bzerr, bzf, &unusedTmpV, &nUnused );
if (bzerr != BZ_OK) panic ( "test:bzReadGetUnused" );
+ unusedTmp = (UChar*)unusedTmpV;
for (i = 0; i < nUnused; i++) unused[i] = unusedTmp[i];
BZ2_bzReadClose ( &bzerr, bzf );
@@ -1125,7 +1140,7 @@ void saveInputFileMetaInfo ( Char *srcName )
static
-void applySavedMetaInfoToOutputFile ( Char *dstName )
+void applySavedTimeInfoToOutputFile ( Char *dstName )
{
# if BZ_UNIX
IntNative retVal;
@@ -1134,16 +1149,26 @@ void applySavedMetaInfoToOutputFile ( Char *dstName )
uTimBuf.actime = fileMetaInfo.st_atime;
uTimBuf.modtime = fileMetaInfo.st_mtime;
- retVal = chmod ( dstName, fileMetaInfo.st_mode );
- ERROR_IF_NOT_ZERO ( retVal );
-
retVal = utime ( dstName, &uTimBuf );
ERROR_IF_NOT_ZERO ( retVal );
+# endif
+}
+
+static
+int applySavedFileAttrToOutputFile ( int fd )
+{
+# if BZ_UNIX
+ IntNative retVal;
+
+ retVal = fchmod ( fd, fileMetaInfo.st_mode );
+ if (retVal != 0)
+ return retVal;
- retVal = chown ( dstName, fileMetaInfo.st_uid, fileMetaInfo.st_gid );
+ (void) fchown ( fd, fileMetaInfo.st_uid, fileMetaInfo.st_gid );
/* chown() will in many cases return with EPERM, which can
be safely ignored.
*/
+ return 0;
# endif
}
@@ -1366,7 +1391,7 @@ void compress ( Char *name )
/*--- If there was an I/O error, we won't get here. ---*/
if ( srcMode == SM_F2F ) {
- applySavedMetaInfoToOutputFile ( outName );
+ applySavedTimeInfoToOutputFile ( outName );
deleteOutputOnInterrupt = False;
if ( !keepInputFiles ) {
IntNative retVal = remove ( inName );
@@ -1544,7 +1569,7 @@ void uncompress ( Char *name )
/*--- If there was an I/O error, we won't get here. ---*/
if ( magicNumberOK ) {
if ( srcMode == SM_F2F ) {
- applySavedMetaInfoToOutputFile ( outName );
+ applySavedTimeInfoToOutputFile ( outName );
deleteOutputOnInterrupt = False;
if ( !keepInputFiles ) {
IntNative retVal = remove ( inName );
diff --git a/contrib/bzip2/bzlib.c b/contrib/bzip2/bzlib.c
index 7d1cb275f5b9..7fb5683674bb 100644
--- a/contrib/bzip2/bzlib.c
+++ b/contrib/bzip2/bzlib.c
@@ -574,8 +574,11 @@ int BZ_API(BZ2_bzDecompressInit)
/*---------------------------------------------------*/
+/* Return True iff data corruption is discovered.
+ Returns False if there is no problem.
+*/
static
-void unRLE_obuf_to_output_FAST ( DState* s )
+Bool unRLE_obuf_to_output_FAST ( DState* s )
{
UChar k1;
@@ -584,7 +587,7 @@ void unRLE_obuf_to_output_FAST ( DState* s )
while (True) {
/* try to finish existing run */
while (True) {
- if (s->strm->avail_out == 0) return;
+ if (s->strm->avail_out == 0) return False;
if (s->state_out_len == 0) break;
*( (UChar*)(s->strm->next_out) ) = s->state_out_ch;
BZ_UPDATE_CRC ( s->calculatedBlockCRC, s->state_out_ch );
@@ -594,10 +597,13 @@ void unRLE_obuf_to_output_FAST ( DState* s )
s->strm->total_out_lo32++;
if (s->strm->total_out_lo32 == 0) s->strm->total_out_hi32++;
}
-
+
/* can a new run be started? */
- if (s->nblock_used == s->save_nblock+1) return;
+ if (s->nblock_used == s->save_nblock+1) return False;
+ /* Only caused by corrupt data stream? */
+ if (s->nblock_used > s->save_nblock+1)
+ return True;
s->state_out_len = 1;
s->state_out_ch = s->k0;
@@ -667,6 +673,10 @@ void unRLE_obuf_to_output_FAST ( DState* s )
cs_avail_out--;
}
}
+ /* Only caused by corrupt data stream? */
+ if (c_nblock_used > s_save_nblockPP)
+ return True;
+
/* can a new run be started? */
if (c_nblock_used == s_save_nblockPP) {
c_state_out_len = 0; goto return_notr;
@@ -712,6 +722,7 @@ void unRLE_obuf_to_output_FAST ( DState* s )
s->strm->avail_out = cs_avail_out;
/* end save */
}
+ return False;
}
@@ -732,8 +743,11 @@ __inline__ Int32 BZ2_indexIntoF ( Int32 indx, Int32 *cftab )
/*---------------------------------------------------*/
+/* Return True iff data corruption is discovered.
+ Returns False if there is no problem.
+*/
static
-void unRLE_obuf_to_output_SMALL ( DState* s )
+Bool unRLE_obuf_to_output_SMALL ( DState* s )
{
UChar k1;
@@ -742,7 +756,7 @@ void unRLE_obuf_to_output_SMALL ( DState* s )
while (True) {
/* try to finish existing run */
while (True) {
- if (s->strm->avail_out == 0) return;
+ if (s->strm->avail_out == 0) return False;
if (s->state_out_len == 0) break;
*( (UChar*)(s->strm->next_out) ) = s->state_out_ch;
BZ_UPDATE_CRC ( s->calculatedBlockCRC, s->state_out_ch );
@@ -754,8 +768,11 @@ void unRLE_obuf_to_output_SMALL ( DState* s )
}
/* can a new run be started? */
- if (s->nblock_used == s->save_nblock+1) return;
-
+ if (s->nblock_used == s->save_nblock+1) return False;
+
+ /* Only caused by corrupt data stream? */
+ if (s->nblock_used > s->save_nblock+1)
+ return True;
s->state_out_len = 1;
s->state_out_ch = s->k0;
@@ -788,7 +805,7 @@ void unRLE_obuf_to_output_SMALL ( DState* s )
while (True) {
/* try to finish existing run */
while (True) {
- if (s->strm->avail_out == 0) return;
+ if (s->strm->avail_out == 0) return False;
if (s->state_out_len == 0) break;
*( (UChar*)(s->strm->next_out) ) = s->state_out_ch;
BZ_UPDATE_CRC ( s->calculatedBlockCRC, s->state_out_ch );
@@ -800,7 +817,11 @@ void unRLE_obuf_to_output_SMALL ( DState* s )
}
/* can a new run be started? */
- if (s->nblock_used == s->save_nblock+1) return;
+ if (s->nblock_used == s->save_nblock+1) return False;
+
+ /* Only caused by corrupt data stream? */
+ if (s->nblock_used > s->save_nblock+1)
+ return True;
s->state_out_len = 1;
s->state_out_ch = s->k0;
@@ -830,6 +851,7 @@ void unRLE_obuf_to_output_SMALL ( DState* s )
/*---------------------------------------------------*/
int BZ_API(BZ2_bzDecompress) ( bz_stream *strm )
{
+ Bool corrupt;
DState* s;
if (strm == NULL) return BZ_PARAM_ERROR;
s = strm->state;
@@ -840,12 +862,13 @@ int BZ_API(BZ2_bzDecompress) ( bz_stream *strm )
if (s->state == BZ_X_IDLE) return BZ_SEQUENCE_ERROR;
if (s->state == BZ_X_OUTPUT) {
if (s->smallDecompress)
- unRLE_obuf_to_output_SMALL ( s ); else
- unRLE_obuf_to_output_FAST ( s );
+ corrupt = unRLE_obuf_to_output_SMALL ( s ); else
+ corrupt = unRLE_obuf_to_output_FAST ( s );
+ if (corrupt) return BZ_DATA_ERROR;
if (s->nblock_used == s->save_nblock+1 && s->state_out_len == 0) {
BZ_FINALISE_CRC ( s->calculatedBlockCRC );
if (s->verbosity >= 3)
- VPrintf2 ( " {0x%x, 0x%x}", s->storedBlockCRC,
+ VPrintf2 ( " {0x%08x, 0x%08x}", s->storedBlockCRC,
s->calculatedBlockCRC );
if (s->verbosity >= 2) VPrintf0 ( "]" );
if (s->calculatedBlockCRC != s->storedBlockCRC)
@@ -863,7 +886,7 @@ int BZ_API(BZ2_bzDecompress) ( bz_stream *strm )
Int32 r = BZ2_decompress ( s );
if (r == BZ_STREAM_END) {
if (s->verbosity >= 3)
- VPrintf2 ( "\n combined CRCs: stored = 0x%x, computed = 0x%x",
+ VPrintf2 ( "\n combined CRCs: stored = 0x%08x, computed = 0x%08x",
s->storedCombinedCRC, s->calculatedCombinedCRC );
if (s->calculatedCombinedCRC != s->storedCombinedCRC)
return BZ_DATA_ERROR;
diff --git a/contrib/bzip2/compress.c b/contrib/bzip2/compress.c
index 56501c115533..b9855a207e71 100644
--- a/contrib/bzip2/compress.c
+++ b/contrib/bzip2/compress.c
@@ -488,9 +488,11 @@ void sendMTFValues ( EState* s )
/*--
Recompute the tables based on the accumulated frequencies.
--*/
+ /* maxLen was changed from 20 to 17 in bzip2-1.0.3. See
+ comment in huffman.c for details. */
for (t = 0; t < nGroups; t++)
BZ2_hbMakeCodeLengths ( &(s->len[t][0]), &(s->rfreq[t][0]),
- alphaSize, 20 );
+ alphaSize, 17 /*20*/ );
}
@@ -527,7 +529,7 @@ void sendMTFValues ( EState* s )
if (s->len[t][i] > maxLen) maxLen = s->len[t][i];
if (s->len[t][i] < minLen) minLen = s->len[t][i];
}
- AssertH ( !(maxLen > 20), 3004 );
+ AssertH ( !(maxLen > 17 /*20*/ ), 3004 );
AssertH ( !(minLen < 1), 3005 );
BZ2_hbAssignCodes ( &(s->code[t][0]), &(s->len[t][0]),
minLen, maxLen, alphaSize );
@@ -651,8 +653,8 @@ void BZ2_compressBlock ( EState* s, Bool is_last_block )
if (s->blockNo > 1) s->numZ = 0;
if (s->verbosity >= 2)
- VPrintf4( " block %d: crc = 0x%8x, "
- "combined CRC = 0x%8x, size = %d\n",
+ VPrintf4( " block %d: crc = 0x%08x, "
+ "combined CRC = 0x%08x, size = %d\n",
s->blockNo, s->blockCRC, s->combinedCRC, s->nblock );
BZ2_blockSort ( s );
@@ -703,7 +705,7 @@ void BZ2_compressBlock ( EState* s, Bool is_last_block )
bsPutUChar ( s, 0x50 ); bsPutUChar ( s, 0x90 );
bsPutUInt32 ( s, s->combinedCRC );
if (s->verbosity >= 2)
- VPrintf1( " final combined CRC = 0x%x\n ", s->combinedCRC );
+ VPrintf1( " final combined CRC = 0x%08x\n ", s->combinedCRC );
bsFinishWrite ( s );
}
}
diff --git a/contrib/bzip2/decompress.c b/contrib/bzip2/decompress.c
index e9213473acf4..0e85649196d1 100644
--- a/contrib/bzip2/decompress.c
+++ b/contrib/bzip2/decompress.c
@@ -524,17 +524,23 @@ Int32 BZ2_decompress ( DState* s )
if (s->origPtr < 0 || s->origPtr >= nblock)
RETURN(BZ_DATA_ERROR);
+ /*-- Set up cftab to facilitate generation of T^(-1) --*/
+ s->cftab[0] = 0;
+ for (i = 1; i <= 256; i++) s->cftab[i] = s->unzftab[i-1];
+ for (i = 1; i <= 256; i++) s->cftab[i] += s->cftab[i-1];
+ for (i = 0; i <= 256; i++) {
+ if (s->cftab[i] < 0 || s->cftab[i] > nblock) {
+ /* s->cftab[i] can legitimately be == nblock */
+ RETURN(BZ_DATA_ERROR);
+ }
+ }
+
s->state_out_len = 0;
s->state_out_ch = 0;
BZ_INITIALISE_CRC ( s->calculatedBlockCRC );
s->state = BZ_X_OUTPUT;
if (s->verbosity >= 2) VPrintf0 ( "rt+rld" );
- /*-- Set up cftab to facilitate generation of T^(-1) --*/
- s->cftab[0] = 0;
- for (i = 1; i <= 256; i++) s->cftab[i] = s->unzftab[i-1];
- for (i = 1; i <= 256; i++) s->cftab[i] += s->cftab[i-1];
-
if (s->smallDecompress) {
/*-- Make a copy of cftab, used in generation of T --*/
diff --git a/contrib/bzip2/huffman.c b/contrib/bzip2/huffman.c
index 293095c170c0..bea35a95c3f4 100644
--- a/contrib/bzip2/huffman.c
+++ b/contrib/bzip2/huffman.c
@@ -162,7 +162,24 @@ void BZ2_hbMakeCodeLengths ( UChar *len,
if (! tooLong) break;
- for (i = 1; i < alphaSize; i++) {
+ /* 17 Oct 04: keep-going condition for the following loop used
+ to be 'i < alphaSize', which missed the last element,
+ theoretically leading to the possibility of the compressor
+ looping. However, this count-scaling step is only needed if
+ one of the generated Huffman code words is longer than
+ maxLen, which up to and including version 1.0.2 was 20 bits,
+ which is extremely unlikely. In version 1.0.3 maxLen was
+ changed to 17 bits, which has minimal effect on compression
+ ratio, but does mean this scaling step is used from time to
+ time, enough to verify that it works.
+
+ This means that bzip2-1.0.3 and later will only produce
+ Huffman codes with a maximum length of 17 bits. However, in
+ order to preserve backwards compatibility with bitstreams
+ produced by versions pre-1.0.3, the decompressor must still
+ handle lengths of up to 20. */
+
+ for (i = 1; i <= alphaSize; i++) {
j = weight[i] >> 8;
j = 1 + (j / 2);
weight[i] = j << 8;
diff --git a/sys/conf/newvers.sh b/sys/conf/newvers.sh
index 741455b47b70..edfecfca1623 100644
--- a/sys/conf/newvers.sh
+++ b/sys/conf/newvers.sh
@@ -36,7 +36,7 @@
TYPE="FreeBSD"
REVISION="4.9"
-BRANCH="RELEASE-p18"
+BRANCH="RELEASE-p19"
RELEASE="${REVISION}-${BRANCH}"
VERSION="${TYPE} ${RELEASE}"
diff --git a/sys/netinet/tcp_input.c b/sys/netinet/tcp_input.c
index 39772282d292..ee37a764a81e 100644
--- a/sys/netinet/tcp_input.c
+++ b/sys/netinet/tcp_input.c
@@ -916,7 +916,7 @@ after_listen:
* XXX this is tradtitional behavior, may need to be cleaned up.
*/
tcp_dooptions(&to, optp, optlen, thflags & TH_SYN);
- if (thflags & TH_SYN) {
+ if (tp->t_state == TCPS_SYN_SENT && (thflags & TH_SYN)) {
if (to.to_flags & TOF_SCALE) {
tp->t_flags |= TF_RCVD_SCALE;
tp->requested_s_scale = to.to_requested_s_scale;
@@ -1569,11 +1569,25 @@ trimthenstep6:
/*
* If last ACK falls within this segment's sequence numbers,
* record its timestamp.
- * NOTE that the test is modified according to the latest
- * proposal of the tcplw@cray.com list (Braden 1993/04/26).
+ * NOTE:
+ * 1) That the test incorporates suggestions from the latest
+ * proposal of the tcplw@cray.com list (Braden 1993/04/26).
+ * 2) That updating only on newer timestamps interferes with
+ * our earlier PAWS tests, so this check should be solely
+ * predicated on the sequence space of this segment.
+ * 3) That we modify the segment boundary check to be
+ * Last.ACK.Sent <= SEG.SEQ + SEG.Len
+ * instead of RFC1323's
+ * Last.ACK.Sent < SEG.SEQ + SEG.Len,
+ * This modified check allows us to overcome RFC1323's
+ * limitations as described in Stevens TCP/IP Illustrated
+ * Vol. 2 p.869. In such cases, we can still calculate the
+ * RTT correctly when RCV.NXT == Last.ACK.Sent.
*/
if ((to.to_flags & TOF_TS) != 0 &&
- SEQ_LEQ(th->th_seq, tp->last_ack_sent)) {
+ SEQ_LEQ(th->th_seq, tp->last_ack_sent) &&
+ SEQ_LEQ(tp->last_ack_sent, th->th_seq + tlen +
+ ((thflags & (TH_SYN|TH_FIN)) != 0))) {
tp->ts_recent_age = ticks;
tp->ts_recent = to.to_tsval;
}
@@ -2342,6 +2356,12 @@ tcp_dooptions(to, cp, cnt, is_syn)
bcopy((char *)cp + 6,
(char *)&to->to_tsecr, sizeof(to->to_tsecr));
to->to_tsecr = ntohl(to->to_tsecr);
+ /*
+ * If echoed timestamp is later than the current time,
+ * fall back to non RFC1323 RTT calculation.
+ */
+ if ((to->to_tsecr != 0) && TSTMP_GT(to->to_tsecr, ticks))
+ to->to_tsecr = 0;
break;
case TCPOPT_CC:
if (optlen != TCPOLEN_CC)
diff --git a/sys/netinet/tcp_seq.h b/sys/netinet/tcp_seq.h
index 90dd97d92af2..bc989b7faa9a 100644
--- a/sys/netinet/tcp_seq.h
+++ b/sys/netinet/tcp_seq.h
@@ -48,6 +48,7 @@
/* for modulo comparisons of timestamps */
#define TSTMP_LT(a,b) ((int)((a)-(b)) < 0)
+#define TSTMP_GT(a,b) ((int)((a)-(b)) > 0)
#define TSTMP_GEQ(a,b) ((int)((a)-(b)) >= 0)
/*