diff options
author | Pacho Ramos <pacho@gentoo.org> | 2012-04-02 20:04:21 +0000 |
---|---|---|
committer | Pacho Ramos <pacho@gentoo.org> | 2012-04-02 20:04:21 +0000 |
commit | 9f13a1659e8225889b595d8b1a9fa924e702cb6a (patch) | |
tree | 296ec362b2c276df4597420d8fc78e90942957a5 /dev-util | |
parent | Respect get_libdir variable, bug #255698 by Nathan Phillip Brink (binki). Rem... (diff) | |
download | gentoo-2-9f13a1659e8225889b595d8b1a9fa924e702cb6a.tar.gz gentoo-2-9f13a1659e8225889b595d8b1a9fa924e702cb6a.tar.bz2 gentoo-2-9f13a1659e8225889b595d8b1a9fa924e702cb6a.zip |
Fix overflows with ThePythonicCow's patches, bug #380473 by Marcin Mirosław.
(Portage version: 2.1.10.54/cvs/Linux x86_64)
Diffstat (limited to 'dev-util')
-rw-r--r-- | dev-util/xdelta/ChangeLog | 12 | ||||
-rw-r--r-- | dev-util/xdelta/files/01_bigger_print_buffers.patch | 83 | ||||
-rw-r--r-- | dev-util/xdelta/files/02_replace_sprintf_with_snprintf.patch | 226 | ||||
-rw-r--r-- | dev-util/xdelta/files/03_fix_pipe_draining_and_closing.patch | 62 | ||||
-rw-r--r-- | dev-util/xdelta/xdelta-3.0.0-r1.ebuild | 65 |
5 files changed, 446 insertions, 2 deletions
diff --git a/dev-util/xdelta/ChangeLog b/dev-util/xdelta/ChangeLog index ee6a327a6bd7..865b957a6bfe 100644 --- a/dev-util/xdelta/ChangeLog +++ b/dev-util/xdelta/ChangeLog @@ -1,6 +1,14 @@ # ChangeLog for dev-util/xdelta -# Copyright 1999-2011 Gentoo Foundation; Distributed under the GPL v2 -# $Header: /var/cvsroot/gentoo-x86/dev-util/xdelta/ChangeLog,v 1.62 2011/08/05 22:35:09 hwoarang Exp $ +# Copyright 1999-2012 Gentoo Foundation; Distributed under the GPL v2 +# $Header: /var/cvsroot/gentoo-x86/dev-util/xdelta/ChangeLog,v 1.63 2012/04/02 20:04:21 pacho Exp $ + +*xdelta-3.0.0-r1 (02 Apr 2012) + + 02 Apr 2012; Pacho Ramos <pacho@gentoo.org> + +files/01_bigger_print_buffers.patch, + +files/02_replace_sprintf_with_snprintf.patch, + +files/03_fix_pipe_draining_and_closing.patch, +xdelta-3.0.0-r1.ebuild: + Fix overflows with ThePythonicCow's patches, bug #380473 by Marcin Mirosław. 05 Aug 2011; Markos Chandras <hwoarang@gentoo.org> -xdelta-3.0v.ebuild, -xdelta-3.0z.ebuild: diff --git a/dev-util/xdelta/files/01_bigger_print_buffers.patch b/dev-util/xdelta/files/01_bigger_print_buffers.patch new file mode 100644 index 000000000000..85e098c768f8 --- /dev/null +++ b/dev-util/xdelta/files/01_bigger_print_buffers.patch @@ -0,0 +1,83 @@ +From: Paul Jackson <pj@usa.net>, Paul Jackson <thepythoniccow@gmail.com> + +xdelta3 (version 3.0.0) has numerous sprintf and strcpy calls that +write into 32 byte char buffers that are on the stack or are static +allocations. With sufficiently large files, these strings can overflow +the 32 char buffers, and some recent gnu libc versions will detect this +and immediately abort with the error "*** buffer overflow detected ***" + +This patch, the first of three, is the only essential patch for this fix. +It increases the 32 byte stack buffers to 48 bytes each. + +The subsequent two patches will replace sprintf calls with snprintf, +to safely avoid overflowing these stack buffers in all cases, and will +fix a hang caused by not properly closing and flushing pipes. + +--- + xdelta3-blkcache.h | 10 +++++----- + xdelta3-main.h | 14 +++++++------- + 2 files changed, 12 insertions(+), 12 deletions(-) + +--- xdelta3.0.0.orig/xdelta3-blkcache.h 2012-03-26 22:55:03.447784216 -0500 ++++ xdelta3.0.0/xdelta3-blkcache.h 2012-03-26 23:22:54.871899533 -0500 +@@ -233,11 +233,11 @@ main_set_source (xd3_stream *stream, xd3 + + if (option_verbose) + { +- static char srcszbuf[32]; +- static char srccntbuf[32]; +- static char winszbuf[32]; +- static char blkszbuf[32]; +- static char nbufs[32]; ++ static char srcszbuf[48]; ++ static char srccntbuf[48]; ++ static char winszbuf[48]; ++ static char blkszbuf[48]; ++ static char nbufs[48]; + + if (sfile->size_known) + { +--- xdelta3.0.0.orig/xdelta3-main.h 2012-03-26 22:55:03.455784458 -0500 ++++ xdelta3.0.0/xdelta3-main.h 2012-03-26 23:22:54.859899160 -0500 +@@ -633,7 +633,7 @@ static char* + main_format_rate (xoff_t bytes, long millis, char *buf) + { + xoff_t r = (xoff_t)(1.0 * bytes / (1.0 * millis / 1000.0)); +- static char lbuf[32]; ++ static char lbuf[48]; + + main_format_bcnt (r, lbuf); + sprintf (buf, "%s/s", lbuf); +@@ -2954,7 +2954,7 @@ static usize_t + main_get_winsize (main_file *ifile) { + xoff_t file_size = 0; + usize_t size = option_winsize; +- static char iszbuf[32]; ++ static char iszbuf[48]; + + if (main_file_stat (ifile, &file_size) == 0) + { +@@ -3328,10 +3328,10 @@ main_input (xd3_cmd cmd, + + if (option_verbose) + { +- char rrateavg[32], wrateavg[32], tm[32]; +- char rdb[32], wdb[32]; +- char trdb[32], twdb[32]; +- char srcpos[32]; ++ char rrateavg[48], wrateavg[48], tm[48]; ++ char rdb[48], wdb[48]; ++ char trdb[48], twdb[48]; ++ char srcpos[48]; + long millis = get_millisecs_since (); + usize_t this_read = (usize_t)(stream.total_in - + last_total_in); +@@ -3460,7 +3460,7 @@ done: + + if (option_verbose) + { +- char tm[32]; ++ char tm[48]; + long end_time = get_millisecs_now (); + xoff_t nwrite = ofile != NULL ? ofile->nwrite : 0; + diff --git a/dev-util/xdelta/files/02_replace_sprintf_with_snprintf.patch b/dev-util/xdelta/files/02_replace_sprintf_with_snprintf.patch new file mode 100644 index 000000000000..bdb731c23dca --- /dev/null +++ b/dev-util/xdelta/files/02_replace_sprintf_with_snprintf.patch @@ -0,0 +1,226 @@ +From: Paul Jackson <pj@usa.net>, Paul Jackson <thepythoniccow@gmail.com> + +xdelta3 (version 3.0.0) has numerous sprintf and strcpy calls that +write into 32 byte char buffers that are on the stack or are static +allocations. With sufficiently large files, these strings can overflow +the 32 char buffers, and some recent gnu libc versions will detect this +and immediately abort with the error "*** buffer overflow detected ***" + +The first patch in this series increased these buffers from 32 to 48 bytes. + +This patch, the second in the series, replaces sprintf calls with +snprintf, to safely avoid overflowing these stack buffers in all cases. +This change necessitated changing the main_format_bcnt() and +main_format_millis() API's, to pass the size of the buffer. + +The third patch will fix a hang caused by not properly closing and flushing +pipes. + +--- + xdelta3-blkcache.h | 12 ++++----- + xdelta3-main.h | 64 ++++++++++++++++++++++++++--------------------------- + 2 files changed, 38 insertions(+), 38 deletions(-) + +--- xdelta3.0.0.orig/xdelta3-blkcache.h 2012-03-26 23:06:12.280521538 -0500 ++++ xdelta3.0.0/xdelta3-blkcache.h 2012-03-26 23:06:47.049599301 -0500 +@@ -241,27 +241,27 @@ main_set_source (xd3_stream *stream, xd3 + + if (sfile->size_known) + { +- sprintf (srcszbuf, "source size %s [%"Q"u]", +- main_format_bcnt (source_size, srccntbuf), ++ snprintf (srcszbuf, sizeof(srcszbuf), "source size %s [%"Q"u]", ++ main_format_bcnt (source_size, srccntbuf, sizeof(srccntbuf)), + source_size); + } + else + { +- strcpy(srcszbuf, "source size unknown"); ++ strncpy(srcszbuf, "source size unknown", sizeof(srcszbuf)); + } + + nbufs[0] = 0; + + if (option_verbose > 1) + { +- sprintf(nbufs, " #bufs %u", lru_size); ++ snprintf(nbufs, sizeof(nbufs), " #bufs %u", lru_size); + } + + XPR(NT "source %s %s blksize %s window %s%s%s\n", + sfile->filename, + srcszbuf, +- main_format_bcnt (blksize, blkszbuf), +- main_format_bcnt (option_srcwinsz, winszbuf), ++ main_format_bcnt (blksize, blkszbuf, sizeof(blkszbuf)), ++ main_format_bcnt (option_srcwinsz, winszbuf, sizeof(winszbuf)), + nbufs, + do_src_fifo ? " (FIFO)" : ""); + } +--- xdelta3.0.0.orig/xdelta3-main.h 2012-03-26 23:06:12.296522032 -0500 ++++ xdelta3.0.0/xdelta3-main.h 2012-03-26 23:22:32.255191072 -0500 +@@ -354,7 +354,7 @@ static int main_read_primary_input (main + usize_t size, + usize_t *nread); + +-static const char* main_format_bcnt (xoff_t r, char *buf); ++static const char* main_format_bcnt (xoff_t r, char *buf, int szbuf); + static int main_help (void); + + /* The code in xdelta3-blk.h is essentially part of this unit, see +@@ -576,7 +576,7 @@ get_millisecs_since (void) + } + + static const char* +-main_format_bcnt (xoff_t r, char *buf) ++main_format_bcnt (xoff_t r, char *buf, int szbuf) + { + static const char* fmts[] = { "B", "KiB", "MiB", "GiB", "TiB", "PiB", "EiB" }; + usize_t i; +@@ -587,25 +587,25 @@ main_format_bcnt (xoff_t r, char *buf) + + if (r == 0) + { +- sprintf (buf, "0 %s", fmts[i]); ++ snprintf (buf, szbuf, "0 %s", fmts[i]); + return buf; + } + + if (r >= 1 && r < 10) + { +- sprintf (buf, "%.2f %s", (double) r, fmts[i]); ++ snprintf (buf, szbuf, "%.2f %s", (double) r, fmts[i]); + return buf; + } + + if (r >= 10 && r < 100) + { +- sprintf (buf, "%.1f %s", (double) r, fmts[i]); ++ snprintf (buf, szbuf, "%.1f %s", (double) r, fmts[i]); + return buf; + } + + if (r >= 100 && r < 1000) + { +- sprintf (buf, "%"Q"u %s", r, fmts[i]); ++ snprintf (buf, szbuf, "%"Q"u %s", r, fmts[i]); + return buf; + } + +@@ -613,13 +613,13 @@ main_format_bcnt (xoff_t r, char *buf) + + if (new_r < 10) + { +- sprintf (buf, "%.2f %s", (double) r / 1024.0, fmts[i + 1]); ++ snprintf (buf, szbuf, "%.2f %s", (double) r / 1024.0, fmts[i + 1]); + return buf; + } + + if (new_r < 100) + { +- sprintf (buf, "%.1f %s", (double) r / 1024.0, fmts[i + 1]); ++ snprintf (buf, szbuf, "%.1f %s", (double) r / 1024.0, fmts[i + 1]); + return buf; + } + +@@ -630,22 +630,22 @@ main_format_bcnt (xoff_t r, char *buf) + } + + static char* +-main_format_rate (xoff_t bytes, long millis, char *buf) ++main_format_rate (xoff_t bytes, long millis, char *buf, int szbuf) + { + xoff_t r = (xoff_t)(1.0 * bytes / (1.0 * millis / 1000.0)); + static char lbuf[48]; + +- main_format_bcnt (r, lbuf); +- sprintf (buf, "%s/s", lbuf); ++ main_format_bcnt (r, lbuf, sizeof(lbuf)); ++ snprintf (buf, szbuf, "%s/s", lbuf); + return buf; + } + + static char* +-main_format_millis (long millis, char *buf) ++main_format_millis (long millis, char *buf, int szbuf) + { +- if (millis < 1000) { sprintf (buf, "%lu ms", millis); } +- else if (millis < 10000) { sprintf (buf, "%.1f sec", millis / 1000.0); } +- else { sprintf (buf, "%lu sec", millis / 1000L); } ++ if (millis < 1000) { snprintf (buf, szbuf, "%lu ms", millis); } ++ else if (millis < 10000) { snprintf (buf, szbuf, "%.1f sec", millis / 1000.0); } ++ else { snprintf (buf, szbuf, "%lu sec", millis / 1000L); } + return buf; + } + +@@ -2739,11 +2739,11 @@ main_set_appheader (xd3_stream *stream, + + if (sfile->filename == NULL) + { +- sprintf ((char*)appheader_used, "%s/%s", iname, icomp); ++ snprintf ((char*)appheader_used, len, "%s/%s", iname, icomp); + } + else + { +- sprintf ((char*)appheader_used, "%s/%s/%s/%s", ++ snprintf ((char*)appheader_used, len, "%s/%s/%s/%s", + iname, icomp, sname, scomp); + } + } +@@ -2967,7 +2967,7 @@ main_get_winsize (main_file *ifile) { + { + XPR(NT "input %s window size %s\n", + ifile->filename, +- main_format_bcnt (size, iszbuf)); ++ main_format_bcnt (size, iszbuf, sizeof(iszbuf))); + } + + return size; +@@ -3345,25 +3345,25 @@ main_input (xd3_cmd cmd, + XPR(NT "%"Q"u: in %s (%s): out %s (%s): " + "total in %s: out %s: %s: srcpos %s\n", + stream.current_window, +- main_format_bcnt (this_read, rdb), +- main_format_rate (this_read, millis, rrateavg), +- main_format_bcnt (this_write, wdb), +- main_format_rate (this_write, millis, wrateavg), +- main_format_bcnt (stream.total_in, trdb), +- main_format_bcnt (stream.total_out, twdb), +- main_format_millis (millis, tm), +- main_format_bcnt (sfile->source_position, srcpos)); ++ main_format_bcnt (this_read, rdb, sizeof(rdb)), ++ main_format_rate (this_read, millis, rrateavg, sizeof(rrateavg)), ++ main_format_bcnt (this_write, wdb, sizeof(wdb)), ++ main_format_rate (this_write, millis, wrateavg, sizeof(wrateavg)), ++ main_format_bcnt (stream.total_in, trdb, sizeof(trdb)), ++ main_format_bcnt (stream.total_out, twdb, sizeof(twdb)), ++ main_format_millis (millis, tm, sizeof(tm)), ++ main_format_bcnt (sfile->source_position, srcpos, sizeof(srcpos))); + } + else + { + XPR(NT "%"Q"u: in %s: out %s: total in %s: " + "out %s: %s\n", + stream.current_window, +- main_format_bcnt (this_read, rdb), +- main_format_bcnt (this_write, wdb), +- main_format_bcnt (stream.total_in, trdb), +- main_format_bcnt (stream.total_out, twdb), +- main_format_millis (millis, tm)); ++ main_format_bcnt (this_read, rdb, sizeof(rdb)), ++ main_format_bcnt (this_write, wdb, sizeof(wdb)), ++ main_format_bcnt (stream.total_in, trdb, sizeof(trdb)), ++ main_format_bcnt (stream.total_out, twdb, sizeof(twdb)), ++ main_format_millis (millis, tm, sizeof(tm))); + } + } + } +@@ -3465,7 +3465,7 @@ done: + xoff_t nwrite = ofile != NULL ? ofile->nwrite : 0; + + XPR(NT "finished in %s; input %"Q"u output %"Q"u bytes (%0.2f%%)\n", +- main_format_millis (end_time - start_time, tm), ++ main_format_millis (end_time - start_time, tm, sizeof(tm)), + ifile->nread, nwrite, 100.0 * nwrite / ifile->nread); + } + diff --git a/dev-util/xdelta/files/03_fix_pipe_draining_and_closing.patch b/dev-util/xdelta/files/03_fix_pipe_draining_and_closing.patch new file mode 100644 index 000000000000..6ea665b8aec2 --- /dev/null +++ b/dev-util/xdelta/files/03_fix_pipe_draining_and_closing.patch @@ -0,0 +1,62 @@ +From: Paul Jackson <pj@usa.net>, Paul Jackson <thepythoniccow@gmail.com> + +xdelta3 automatically sets up child compression and decompression +processes and pipes data to and from them, in various cases. + +Sometimes this can hang, due to improper closing, or lose +data, due to improper flushing. + +This patch purports to fix this, but has not been tested +very well at all. More work may be needed here. + +The patch also makes one error message less scary. + +--- + xdelta3-main.h | 15 ++++++++++----- + 1 file changed, 10 insertions(+), 5 deletions(-) + +--- xdelta3.0.0.orig/xdelta3-main.h 2012-03-26 23:11:26.346316918 -0500 ++++ xdelta3.0.0/xdelta3-main.h 2012-03-26 23:11:40.218752082 -0500 +@@ -2135,9 +2135,11 @@ main_waitpid_check(pid_t pid) + } + else if (! WIFEXITED (status)) + { +- ret = ECHILD; +- XPR(NT "external compression [pid %d] signal %d\n", +- pid, WIFSIGNALED (status) ? WTERMSIG (status) : WSTOPSIG (status)); ++ if ( ! (WIFSIGNALED (status) && WTERMSIG (status) == SIGPIPE) ) { ++ ret = ECHILD; ++ XPR(NT "external compression [pid %d] signal %d\n", ++ pid, WIFSIGNALED (status) ? WTERMSIG (status) : WSTOPSIG (status)); ++ } + } + else if (WEXITSTATUS (status) != 0) + { +@@ -2221,7 +2223,8 @@ main_pipe_copier (uint8_t *pipe_buf, + int force_drain = 0; + if (nread > 0 && (ret = main_pipe_write (outfd, pipe_buf, nread))) + { +- if (option_force && ret == EPIPE) ++ /* Next line: Until better fix, *always* drain if EPIPE. */ ++ if ( /* option_force && */ ret == EPIPE) + { + /* This causes the loop to continue reading until nread + * == 0. */ +@@ -2265,7 +2268,7 @@ main_pipe_copier (uint8_t *pipe_buf, + + if (garbage != 0) + { +- XPR(NT "trailing garbage ignored in %s (%"Q"u bytes)\n", ++ XPR(NT "skipped trailing bytes in %s (%"Q"u bytes)\n", + ifile->filename, garbage); + } + return 0; +@@ -2354,6 +2357,8 @@ main_input_decompress_setup (const main_ + } + + if (close (inpipefd[PIPE_READ_FD]) || ++ close (outpipefd[PIPE_READ_FD]) || ++ close (outpipefd[PIPE_WRITE_FD]) || + main_pipe_copier (pipe_buf, pipe_bufsize, pipe_avail, + ifile, inpipefd[PIPE_WRITE_FD]) || + close (inpipefd[PIPE_WRITE_FD])) diff --git a/dev-util/xdelta/xdelta-3.0.0-r1.ebuild b/dev-util/xdelta/xdelta-3.0.0-r1.ebuild new file mode 100644 index 000000000000..828b023dcb58 --- /dev/null +++ b/dev-util/xdelta/xdelta-3.0.0-r1.ebuild @@ -0,0 +1,65 @@ +# Copyright 1999-2012 Gentoo Foundation +# Distributed under the terms of the GNU General Public License v2 +# $Header: /var/cvsroot/gentoo-x86/dev-util/xdelta/xdelta-3.0.0-r1.ebuild,v 1.1 2012/04/02 20:04:21 pacho Exp $ + +EAPI=4 +PYTHON_DEPEND="2:2.6" + +inherit distutils toolchain-funcs eutils + +DESCRIPTION="a binary diff and differential compression tools. VCDIFF (RFC 3284) delta compression." +HOMEPAGE="http://xdelta.org" +SRC_URI="http://${PN}.googlecode.com/files/${P/-}.tar.gz" + +LICENSE="GPL-2" +SLOT="3" +KEYWORDS="~alpha ~amd64 ~hppa ~ia64 ~ppc ~ppc64 ~sparc ~x86" +IUSE="test" + +DEPEND="test? ( app-arch/ncompress )" +RDEPEND="" + +S="${WORKDIR}/${P/-}" + +DOCS="draft-korn-vcdiff.txt" + +pkg_setup() { + python_set_active_version 2 + python_pkg_setup +} + +src_prepare() { + sed -i -e 's:-O3:-Wall:' setup.py || die "setup.py sed failed" + sed \ + -e 's:-O3::g' \ + -e 's:$(CC):$(CC) $(LDFLAGS):g' \ + -e 's:CFLAGS=:CFLAGS+=:' \ + -i Makefile || die "Makefile sed failed" + + EPATCH_SOURCE="${FILESDIR}" epatch \ + 01_bigger_print_buffers.patch \ + 02_replace_sprintf_with_snprintf.patch \ + 03_fix_pipe_draining_and_closing.patch +} + +src_test() { + if [ $UID != 0 ]; then + emake test + else + ewarn "Tests can't be run as root, skipping." + fi +} + +src_compile() { + tc-export CC CXX + distutils_src_compile + emake xdelta3 + if use test; then + emake xdelta3-debug + fi +} + +src_install() { + dobin xdelta3 + distutils_src_install +} |