Date: Tue, 31 Mar 2015 14:29:27 +0000 (UTC) From: Christian Weisgerber <naddy@FreeBSD.org> To: ports-committers@freebsd.org, svn-ports-all@freebsd.org, svn-ports-head@freebsd.org Subject: svn commit: r382823 - in head/archivers/gcpio: . files Message-ID: <201503311429.t2VETRYL020193@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: naddy Date: Tue Mar 31 14:29:26 2015 New Revision: 382823 URL: https://svnweb.freebsd.org/changeset/ports/382823 QAT: https://qat.redports.org/buildarchive/r382823/ Log: CVE-2014-9112: Heap-based buffer overflow in the process_copy_in function allows remote attackers to cause a denial of service via a large block value in a cpio archive. Fix from a series of upstream commits by Sergey Poznyakoff. CVE-2015-1197: cpio, when using the --no-absolute-filenames option, allows local users to write to arbitrary files via a symlink attack on a file in an archive. Fix from Vitezslav Cizek after 3.5 years of gestation in the SUSE bug tracker. PR: 198954 Obtained from: Debian Added: head/archivers/gcpio/files/patch-src_copyin.c (contents, props changed) head/archivers/gcpio/files/patch-src_extern.h (contents, props changed) head/archivers/gcpio/files/patch-src_global.c (contents, props changed) head/archivers/gcpio/files/patch-src_main.c (contents, props changed) head/archivers/gcpio/files/patch-src_util.c (contents, props changed) Modified: head/archivers/gcpio/Makefile head/archivers/gcpio/files/patch-doc_Makefile.in head/archivers/gcpio/files/patch-doc_cpio.1 head/archivers/gcpio/files/patch-gnu_Makefile.in head/archivers/gcpio/files/patch-src_filetypes.h Modified: head/archivers/gcpio/Makefile ============================================================================== --- head/archivers/gcpio/Makefile Tue Mar 31 14:27:40 2015 (r382822) +++ head/archivers/gcpio/Makefile Tue Mar 31 14:29:26 2015 (r382823) @@ -2,7 +2,7 @@ PORTNAME= cpio PORTVERSION= 2.11 -PORTREVISION= 2 +PORTREVISION= 3 CATEGORIES= archivers MASTER_SITES= ${MASTER_SITE_GNU} MASTER_SITE_SUBDIR= ${PORTNAME} Modified: head/archivers/gcpio/files/patch-doc_Makefile.in ============================================================================== --- head/archivers/gcpio/files/patch-doc_Makefile.in Tue Mar 31 14:27:40 2015 (r382822) +++ head/archivers/gcpio/files/patch-doc_Makefile.in Tue Mar 31 14:29:26 2015 (r382823) @@ -1,5 +1,5 @@ ---- doc/Makefile.in.orig 2010-03-25 22:34:54.000000000 +0100 -+++ doc/Makefile.in 2010-03-25 22:35:08.000000000 +0100 +--- doc/Makefile.in.orig 2010-03-10 13:00:35 UTC ++++ doc/Makefile.in @@ -813,7 +813,7 @@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ Modified: head/archivers/gcpio/files/patch-doc_cpio.1 ============================================================================== --- head/archivers/gcpio/files/patch-doc_cpio.1 Tue Mar 31 14:27:40 2015 (r382822) +++ head/archivers/gcpio/files/patch-doc_cpio.1 Tue Mar 31 14:29:26 2015 (r382823) @@ -1,8 +1,7 @@ ---- doc/cpio.1.orig 2009-02-14 19:15:50.000000000 +0100 -+++ doc/cpio.1 2010-03-25 22:35:50.000000000 +0100 +--- doc/cpio.1.orig 2009-02-14 18:15:50 UTC ++++ doc/cpio.1 @@ -1,8 +1,8 @@ --.TH CPIO 1L \" -*- nroff -*- -+.TH GCPIO 1L \" -*- nroff -*- + .TH CPIO 1L \" -*- nroff -*- .SH NAME -cpio \- copy files to and from archives +gcpio \- copy files to and from archives @@ -21,8 +20,11 @@ {\-i|\-\-extract} [\-bcdfmnrtsuvBSV] [\-C bytes] [\-E file] [\-H format] [\-M message] [\-R [user][:.][group]] [\-I [[user@]host:]archive] [\-F [[user@]host:]archive] [\-\-file=[[user@]host:]archive] -@@ -24,7 +24,7 @@ cpio \- copy files to and from archives +@@ -22,9 +22,10 @@ cpio \- copy files to and from archives + [\-\-owner=[user][:.][group]] [\-\-no-preserve-owner] [\-\-message=message] + [\-\-force\-local] [\-\-no\-absolute\-filenames] [\-\-sparse] [\-\-only\-verify\-crc] [\-\-to\-stdout] [\-\-quiet] [\-\-rsh-command=command] ++[\-\-extract\-over\-symlinks] [\-\-help] [\-\-version] [pattern...] [< archive] -.B cpio Modified: head/archivers/gcpio/files/patch-gnu_Makefile.in ============================================================================== --- head/archivers/gcpio/files/patch-gnu_Makefile.in Tue Mar 31 14:27:40 2015 (r382822) +++ head/archivers/gcpio/files/patch-gnu_Makefile.in Tue Mar 31 14:29:26 2015 (r382823) @@ -1,5 +1,5 @@ ---- gnu/Makefile.in.orig 2010-03-25 22:13:33.000000000 +0100 -+++ gnu/Makefile.in 2010-03-25 22:14:21.000000000 +0100 +--- gnu/Makefile.in.orig 2010-03-10 13:00:36 UTC ++++ gnu/Makefile.in @@ -1720,7 +1720,7 @@ inttypes.h: inttypes.in.h $(WARN_ON_USE_ # avoid installing it. Added: head/archivers/gcpio/files/patch-src_copyin.c ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ head/archivers/gcpio/files/patch-src_copyin.c Tue Mar 31 14:29:26 2015 (r382823) @@ -0,0 +1,184 @@ +--- src/copyin.c.orig 2010-02-15 10:02:23 UTC ++++ src/copyin.c +@@ -124,10 +124,30 @@ tape_skip_padding (int in_file_des, off_ + if (pad != 0) + tape_toss_input (in_file_des, pad); + } +- ++ ++static char * ++get_link_name (struct cpio_file_stat *file_hdr, int in_file_des) ++{ ++ char *link_name; ++ ++ if (file_hdr->c_filesize < 0 || file_hdr->c_filesize > SIZE_MAX-1) ++ { ++ error (0, 0, _("%s: stored filename length is out of range"), ++ file_hdr->c_name); ++ link_name = NULL; ++ } ++ else ++ { ++ link_name = xmalloc (file_hdr->c_filesize + 1); ++ tape_buffered_read (link_name, in_file_des, file_hdr->c_filesize); ++ link_name[file_hdr->c_filesize] = '\0'; ++ tape_skip_padding (in_file_des, file_hdr->c_filesize); ++ } ++ return link_name; ++} + + static void +-list_file(struct cpio_file_stat* file_hdr, int in_file_des) ++list_file (struct cpio_file_stat* file_hdr, int in_file_des) + { + if (verbose_flag) + { +@@ -136,21 +156,16 @@ list_file(struct cpio_file_stat* file_hd + { + if (archive_format != arf_tar && archive_format != arf_ustar) + { +- char *link_name = NULL; /* Name of hard and symbolic links. */ +- +- link_name = (char *) xmalloc ((unsigned int) file_hdr->c_filesize + 1); +- link_name[file_hdr->c_filesize] = '\0'; +- tape_buffered_read (link_name, in_file_des, file_hdr->c_filesize); +- long_format (file_hdr, link_name); +- free (link_name); +- tape_skip_padding (in_file_des, file_hdr->c_filesize); +- return; ++ char *link_name = get_link_name (file_hdr, in_file_des); ++ if (link_name) ++ { ++ long_format (file_hdr, link_name); ++ free (link_name); ++ } + } + else +- { +- long_format (file_hdr, file_hdr->c_tar_linkname); +- return; +- } ++ long_format (file_hdr, file_hdr->c_tar_linkname); ++ return; + } + else + #endif +@@ -640,7 +655,7 @@ copyin_device (struct cpio_file_stat* fi + } + + static void +-copyin_link(struct cpio_file_stat *file_hdr, int in_file_des) ++copyin_link (struct cpio_file_stat *file_hdr, int in_file_des) + { + char *link_name = NULL; /* Name of hard and symbolic links. */ + int res; /* Result of various function calls. */ +@@ -650,10 +665,9 @@ copyin_link(struct cpio_file_stat *file_ + + if (archive_format != arf_tar && archive_format != arf_ustar) + { +- link_name = (char *) xmalloc ((unsigned int) file_hdr->c_filesize + 1); +- link_name[file_hdr->c_filesize] = '\0'; +- tape_buffered_read (link_name, in_file_des, file_hdr->c_filesize); +- tape_skip_padding (in_file_des, file_hdr->c_filesize); ++ link_name = get_link_name (file_hdr, in_file_des); ++ if (!link_name) ++ return; + } + else + { +@@ -686,6 +700,51 @@ copyin_link(struct cpio_file_stat *file_ + free (link_name); + } + ++ ++static int ++path_contains_symlink(char *path) ++{ ++ struct stat st; ++ char *slash; ++ char *nextslash; ++ ++ /* we got NULL pointer or empty string */ ++ if (!path || !*path) { ++ return false; ++ } ++ ++ slash = path; ++ ++ while ((nextslash = strchr(slash + 1, '/')) != NULL) { ++ slash = nextslash; ++ *slash = '\0'; ++ ++ if (lstat(path, &st) != 0) { ++ if (errno == ELOOP) { ++ /* ELOOP - too many symlinks */ ++ *slash = '/'; ++ return true; ++ } else if (errno == ENOMEM) { ++ /* No memory for lstat - terminate */ ++ xalloc_die(); ++ } else { ++ /* cannot lstat path - give up */ ++ *slash = '/'; ++ return false; ++ } ++ } ++ ++ if (S_ISLNK(st.st_mode)) { ++ *slash = '/'; ++ return true; ++ } ++ ++ *slash = '/'; ++ } ++ ++ return false; ++} ++ + static void + copyin_file (struct cpio_file_stat *file_hdr, int in_file_des) + { +@@ -1005,7 +1064,7 @@ read_in_header (struct cpio_file_stat *f + + file_hdr->c_tar_linkname = NULL; + +- tape_buffered_read (magic.str, in_des, 6L); ++ tape_buffered_read (magic.str, in_des, sizeof (magic.str)); + while (1) + { + if (append_flag) +@@ -1050,8 +1109,8 @@ read_in_header (struct cpio_file_stat *f + break; + } + bytes_skipped++; +- memmove (magic.str, magic.str + 1, 5); +- tape_buffered_read (magic.str, in_des, 1L); ++ memmove (magic.str, magic.str + 1, sizeof (magic.str) - 1); ++ tape_buffered_read (magic.str + sizeof (magic.str) - 1, in_des, 1L); + } + } + +@@ -1457,6 +1516,23 @@ process_copy_in () + { + /* Copy the input file into the directory structure. */ + ++ /* Can we write files over symlinks? */ ++ if (!extract_over_symlinks) ++ { ++ if (path_contains_symlink(file_hdr.c_name)) ++ { ++ /* skip the file */ ++ /* ++ fprintf(stderr, "Can't write over symlinks. Skipping %s\n", file_hdr.c_name); ++ tape_toss_input (in_file_des, file_hdr.c_filesize); ++ tape_skip_padding (in_file_des, file_hdr.c_filesize); ++ continue; ++ */ ++ /* terminate */ ++ error (1, 0, _("Can't write over symlinks: %s\n"), file_hdr.c_name); ++ } ++ } ++ + /* Do we need to rename the file? */ + if (rename_flag || rename_batch_file) + { Added: head/archivers/gcpio/files/patch-src_extern.h ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ head/archivers/gcpio/files/patch-src_extern.h Tue Mar 31 14:29:26 2015 (r382823) @@ -0,0 +1,10 @@ +--- src/extern.h.orig 2010-02-15 10:02:23 UTC ++++ src/extern.h +@@ -95,6 +95,7 @@ extern char input_is_special; + extern char output_is_special; + extern char input_is_seekable; + extern char output_is_seekable; ++extern bool extract_over_symlinks; + extern int (*xstat) (); + extern void (*copy_function) (); + Modified: head/archivers/gcpio/files/patch-src_filetypes.h ============================================================================== --- head/archivers/gcpio/files/patch-src_filetypes.h Tue Mar 31 14:27:40 2015 (r382822) +++ head/archivers/gcpio/files/patch-src_filetypes.h Tue Mar 31 14:29:26 2015 (r382823) @@ -1,5 +1,5 @@ ---- src/filetypes.h.orig 2010-04-19 22:01:16.000000000 +0200 -+++ src/filetypes.h 2010-04-19 22:04:16.000000000 +0200 +--- src/filetypes.h.orig 2010-02-12 10:19:23 UTC ++++ src/filetypes.h @@ -81,5 +81,9 @@ #ifndef S_ISLNK #define lstat stat Added: head/archivers/gcpio/files/patch-src_global.c ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ head/archivers/gcpio/files/patch-src_global.c Tue Mar 31 14:29:26 2015 (r382823) @@ -0,0 +1,12 @@ +--- src/global.c.orig 2010-02-12 10:19:23 UTC ++++ src/global.c +@@ -187,6 +187,9 @@ bool to_stdout_option = false; + /* The name this program was run with. */ + char *program_name; + ++/* Extract files over symbolic links */ ++bool extract_over_symlinks; ++ + /* A pointer to either lstat or stat, depending on whether + dereferencing of symlinks is done for input files. */ + int (*xstat) (); Added: head/archivers/gcpio/files/patch-src_main.c ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ head/archivers/gcpio/files/patch-src_main.c Tue Mar 31 14:29:26 2015 (r382823) @@ -0,0 +1,32 @@ +--- src/main.c.orig 2010-02-12 11:35:09 UTC ++++ src/main.c +@@ -57,7 +57,8 @@ enum cpio_options { + FORCE_LOCAL_OPTION, + DEBUG_OPTION, + BLOCK_SIZE_OPTION, +- TO_STDOUT_OPTION ++ TO_STDOUT_OPTION, ++ EXTRACT_OVER_SYMLINKS + }; + + const char *program_authors[] = +@@ -222,6 +223,8 @@ static struct argp_option options[] = { + N_("Create leading directories where needed"), GRID+1 }, + {"no-preserve-owner", NO_PRESERVE_OWNER_OPTION, 0, 0, + N_("Do not change the ownership of the files"), GRID+1 }, ++ {"extract-over-symlinks", EXTRACT_OVER_SYMLINKS, 0, 0, ++ N_("Force writing over symbolic links"), GRID+1 }, + {"unconditional", 'u', NULL, 0, + N_("Replace all files unconditionally"), GRID+1 }, + {"sparse", SPARSE_OPTION, NULL, 0, +@@ -412,6 +415,10 @@ crc newc odc bin ustar tar (all-caps als + no_chown_flag = true; + break; + ++ case EXTRACT_OVER_SYMLINKS: /* --extract-over-symlinks */ ++ extract_over_symlinks = true; ++ break; ++ + case 'o': /* Copy-out mode. */ + if (copy_function != 0) + error (PAXEXIT_FAILURE, 0, _("Mode already defined")); Added: head/archivers/gcpio/files/patch-src_util.c ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ head/archivers/gcpio/files/patch-src_util.c Tue Mar 31 14:29:26 2015 (r382823) @@ -0,0 +1,14 @@ +--- src/util.c.orig 2010-03-10 10:22:30 UTC ++++ src/util.c +@@ -206,10 +206,7 @@ tape_fill_input_buffer (int in_des, int + if (input_size < 0) + error (1, errno, _("read error")); + if (input_size == 0) +- { +- error (0, 0, _("premature end of file")); +- exit (1); +- } ++ error (PAXEXIT_FAILURE, 0, _("premature end of file")); + input_bytes += input_size; + } +
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201503311429.t2VETRYL020193>