diff --git a/Fix-CVE-2019-14866.patch b/Fix-CVE-2019-14866.patch deleted file mode 100644 index e7b10f9..0000000 --- a/Fix-CVE-2019-14866.patch +++ /dev/null @@ -1,322 +0,0 @@ -From 7293fc357b13ba490daf0b99b505b3a019f1eb2a Mon Sep 17 00:00:00 2001 -From: Sergey Poznyakoff -Date: Sun, 3 Nov 2019 23:59:39 +0200 -Subject: [PATCH] Fix CVE-2019-14866 - -* src/copyout.c (to_ascii): Additional argument nul controls whether -to add the terminating nul character. -(field_width_error): Improve diagnostics: print the actual and the -maximum allowed field value. -* src/extern.h (to_ascii, field_width_error): New prototypes. -* src/tar.c (to_oct): Remove. -(to_oct_or_error): New function. -(TO_OCT): New macro. -(write_out_tar_header): Use TO_OCT and to_ascii. Return 0 on -success, 1 on error. - -backport from http://git.savannah.gnu.org/cgit/cpio.git/commit/?id=7554e3e42cd72f6f8304410c47fe6f8918e9bfd7 ---- - src/copyout.c | 49 +++++++++++++++++++++-------------- - src/extern.h | 15 +++++++++-- - src/tar.c | 72 +++++++++++++++++++++++---------------------------- - 3 files changed, 76 insertions(+), 60 deletions(-) - -diff --git a/src/copyout.c b/src/copyout.c -index dcae449..1ae5477 100644 ---- a/src/copyout.c -+++ b/src/copyout.c -@@ -269,26 +269,32 @@ writeout_final_defers (int out_des) - so it should be moved to paxutils too. - Allowed values for logbase are: 1 (binary), 2, 3 (octal), 4 (hex) */ - int --to_ascii (char *where, uintmax_t v, size_t digits, unsigned logbase) -+to_ascii (char *where, uintmax_t v, size_t digits, unsigned logbase, bool nul) - { - static char codetab[] = "0123456789ABCDEF"; -- int i = digits; -- -- do -+ -+ if (nul) -+ where[--digits] = 0; -+ while (digits > 0) - { -- where[--i] = codetab[(v & ((1 << logbase) - 1))]; -+ where[--digits] = codetab[(v & ((1 << logbase) - 1))]; - v >>= logbase; - } -- while (i); - - return v != 0; - } - --static void --field_width_error (const char *filename, const char *fieldname) -+void -+field_width_error (const char *filename, const char *fieldname, -+ uintmax_t value, size_t width, bool nul) - { -- error (1, 0, _("%s: field width not sufficient for storing %s"), -- filename, fieldname); -+ char valbuf[UINTMAX_STRSIZE_BOUND + 1]; -+ char maxbuf[UINTMAX_STRSIZE_BOUND + 1]; -+ error (0, 0, _("%s: value %s %s out of allowed range 0..%s"), -+ filename, fieldname, -+ STRINGIFY_BIGINT (value, valbuf), -+ STRINGIFY_BIGINT (MAX_VAL_WITH_DIGITS (width - nul, LG_8), -+ maxbuf)); - } - - static void -@@ -303,7 +309,7 @@ to_ascii_or_warn (char *where, uintmax_t n, size_t digits, - unsigned logbase, - const char *filename, const char *fieldname) - { -- if (to_ascii (where, n, digits, logbase)) -+ if (to_ascii (where, n, digits, logbase, false)) - field_width_warning (filename, fieldname); - } - -@@ -312,9 +318,9 @@ to_ascii_or_error (char *where, uintmax_t n, size_t digits, - unsigned logbase, - const char *filename, const char *fieldname) - { -- if (to_ascii (where, n, digits, logbase)) -+ if (to_ascii (where, n, digits, logbase, false)) - { -- field_width_error (filename, fieldname); -+ field_width_error (filename, fieldname, n, digits, false); - return 1; - } - return 0; -@@ -371,7 +377,7 @@ write_out_new_ascii_header (const char *magic_string, - _("name size"))) - return 1; - p += 8; -- to_ascii (p, file_hdr->c_chksum & 0xffffffff, 8, LG_16); -+ to_ascii (p, file_hdr->c_chksum & 0xffffffff, 8, LG_16, false); - - tape_buffered_write (ascii_header, out_des, sizeof ascii_header); - -@@ -388,7 +394,7 @@ write_out_old_ascii_header (dev_t dev, dev_t rdev, - char ascii_header[76]; - char *p = ascii_header; - -- to_ascii (p, file_hdr->c_magic, 6, LG_8); -+ to_ascii (p, file_hdr->c_magic, 6, LG_8, false); - p += 6; - to_ascii_or_warn (p, dev, 6, LG_8, file_hdr->c_name, _("device number")); - p += 6; -@@ -492,7 +498,10 @@ write_out_binary_header (dev_t rdev, - short_hdr.c_namesize = file_hdr->c_namesize & 0xFFFF; - if (short_hdr.c_namesize != file_hdr->c_namesize) - { -- field_width_error (file_hdr->c_name, _("name size")); -+ char maxbuf[UINTMAX_STRSIZE_BOUND + 1]; -+ error (0, 0, _("%s: value %s %s out of allowed range 0..%u"), -+ file_hdr->c_name, _("name size"), -+ STRINGIFY_BIGINT (file_hdr->c_namesize, maxbuf), 0xFFFFu); - return 1; - } - -@@ -502,7 +511,10 @@ write_out_binary_header (dev_t rdev, - if (((off_t)short_hdr.c_filesizes[0] << 16) + short_hdr.c_filesizes[1] - != file_hdr->c_filesize) - { -- field_width_error (file_hdr->c_name, _("file size")); -+ char maxbuf[UINTMAX_STRSIZE_BOUND + 1]; -+ error (0, 0, _("%s: value %s %s out of allowed range 0..%lu"), -+ file_hdr->c_name, _("file size"), -+ STRINGIFY_BIGINT (file_hdr->c_namesize, maxbuf), 0xFFFFFFFFlu); - return 1; - } - -@@ -552,8 +564,7 @@ write_out_header (struct cpio_file_stat *file_hdr, int out_des) - error (0, 0, _("%s: file name too long"), file_hdr->c_name); - return 1; - } -- write_out_tar_header (file_hdr, out_des); /* FIXME: No error checking */ -- return 0; -+ return write_out_tar_header (file_hdr, out_des); - - case arf_binary: - return write_out_binary_header (makedev (file_hdr->c_rdev_maj, -diff --git a/src/extern.h b/src/extern.h -index e27d662..f9ef56a 100644 ---- a/src/extern.h -+++ b/src/extern.h -@@ -117,6 +117,10 @@ void print_name_with_quoting (char *p); - /* copyout.c */ - int write_out_header (struct cpio_file_stat *file_hdr, int out_des); - void process_copy_out (void); -+int to_ascii (char *where, uintmax_t v, size_t digits, unsigned logbase, -+ bool nul); -+void field_width_error (const char *filename, const char *fieldname, -+ uintmax_t value, size_t width, bool nul); - - /* copypass.c */ - void process_copy_pass (void); -@@ -145,7 +149,7 @@ int make_path (char *argpath, uid_t owner, gid_t group, - const char *verbose_fmt_string); - - /* tar.c */ --void write_out_tar_header (struct cpio_file_stat *file_hdr, int out_des); -+int write_out_tar_header (struct cpio_file_stat *file_hdr, int out_des); - int null_block (long *block, int size); - void read_in_tar_header (struct cpio_file_stat *file_hdr, int in_des); - int otoa (char *s, unsigned long *n); -@@ -204,9 +208,16 @@ void cpio_safer_name_suffix (char *name, bool link_target, - int cpio_create_dir (struct cpio_file_stat *file_hdr, int existing_dir); - void change_dir (void); - --/* FIXME: These two defines should be defined in paxutils */ -+/* FIXME: The following three should be defined in paxutils */ - #define LG_8 3 - #define LG_16 4 -+/* The maximum uintmax_t value that can be represented with DIGITS digits, -+ assuming that each digit is BITS_PER_DIGIT wide. */ -+#define MAX_VAL_WITH_DIGITS(digits, bits_per_digit) \ -+ ((digits) * (bits_per_digit) < sizeof (uintmax_t) * CHAR_BIT \ -+ ? ((uintmax_t) 1 << ((digits) * (bits_per_digit))) - 1 \ -+ : (uintmax_t) -1) -+ - - uintmax_t from_ascii (char const *where, size_t digs, unsigned logbase); - -diff --git a/src/tar.c b/src/tar.c -index e2b5f45..1a1f8c8 100644 ---- a/src/tar.c -+++ b/src/tar.c -@@ -1,6 +1,5 @@ - /* tar.c - read in write tar headers for cpio -- Copyright (C) 1992, 2001, 2004, 2006-2007, 2010, 2014-2015 Free -- Software Foundation, Inc. -+ Copyright (C) 1992-2019 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by -@@ -81,36 +80,17 @@ stash_tar_filename (char *prefix, char *filename) - return hold_tar_filename; - } - --/* Convert a number into a string of octal digits. -- Convert long VALUE into a DIGITS-digit field at WHERE, -- including a trailing space and room for a NUL. DIGITS==3 means -- 1 digit, a space, and room for a NUL. -- -- We assume the trailing NUL is already there and don't fill it in. -- This fact is used by start_header and finish_header, so don't change it! -- -- This is be equivalent to: -- sprintf (where, "%*lo ", digits - 2, value); -- except that sprintf fills in the trailing NUL and we don't. */ -- --static void --to_oct (register long value, register int digits, register char *where) -+static int -+to_oct_or_error (uintmax_t value, size_t digits, char *where, char const *field, -+ char const *file) - { -- --digits; /* Leave the trailing NUL slot alone. */ -- -- /* Produce the digits -- at least one. */ -- do -+ if (to_ascii (where, value, digits, LG_8, true)) - { -- where[--digits] = '0' + (char) (value & 7); /* One octal digit. */ -- value >>= 3; -+ field_width_error (file, field, value, digits, true); -+ return 1; - } -- while (digits > 0 && value != 0); -- -- /* Add leading zeroes, if necessary. */ -- while (digits > 0) -- where[--digits] = '0'; -+ return 0; - } -- - - - /* Compute and return a checksum for TAR_HDR, -@@ -136,10 +116,22 @@ tar_checksum (struct tar_header *tar_hdr) - return sum; - } - -+#define TO_OCT(file_hdr, c_fld, digits, tar_hdr, tar_field) \ -+ do \ -+ { \ -+ if (to_oct_or_error (file_hdr -> c_fld, \ -+ digits, \ -+ tar_hdr -> tar_field, \ -+ #tar_field, \ -+ file_hdr->c_name)) \ -+ return 1; \ -+ } \ -+ while (0) -+ - /* Write out header FILE_HDR, including the file name, to file - descriptor OUT_DES. */ - --void -+int - write_out_tar_header (struct cpio_file_stat *file_hdr, int out_des) - { - int name_len; -@@ -168,11 +160,11 @@ write_out_tar_header (struct cpio_file_stat *file_hdr, int out_des) - - /* Ustar standard (POSIX.1-1988) requires the mode to contain only 3 octal - digits */ -- to_oct (file_hdr->c_mode & MODE_ALL, 8, tar_hdr->mode); -- to_oct (file_hdr->c_uid, 8, tar_hdr->uid); -- to_oct (file_hdr->c_gid, 8, tar_hdr->gid); -- to_oct (file_hdr->c_filesize, 12, tar_hdr->size); -- to_oct (file_hdr->c_mtime, 12, tar_hdr->mtime); -+ TO_OCT (file_hdr, c_mode & MODE_ALL, 8, tar_hdr, mode); -+ TO_OCT (file_hdr, c_uid, 8, tar_hdr, uid); -+ TO_OCT (file_hdr, c_gid, 8, tar_hdr, gid); -+ TO_OCT (file_hdr, c_filesize, 12, tar_hdr, size); -+ TO_OCT (file_hdr, c_mtime, 12, tar_hdr, mtime); - - switch (file_hdr->c_mode & CP_IFMT) - { -@@ -184,7 +176,7 @@ write_out_tar_header (struct cpio_file_stat *file_hdr, int out_des) - strncpy (tar_hdr->linkname, file_hdr->c_tar_linkname, - TARLINKNAMESIZE); - tar_hdr->typeflag = LNKTYPE; -- to_oct (0, 12, tar_hdr->size); -+ to_ascii (tar_hdr->size, 0, 12, LG_8, true); - } - else - tar_hdr->typeflag = REGTYPE; -@@ -210,7 +202,7 @@ write_out_tar_header (struct cpio_file_stat *file_hdr, int out_des) - than TARLINKNAMESIZE. */ - strncpy (tar_hdr->linkname, file_hdr->c_tar_linkname, - TARLINKNAMESIZE); -- to_oct (0, 12, tar_hdr->size); -+ to_ascii (tar_hdr->size, 0, 12, LG_8, true); - break; - #endif /* CP_IFLNK */ - } -@@ -229,13 +221,15 @@ write_out_tar_header (struct cpio_file_stat *file_hdr, int out_des) - if (name) - strcpy (tar_hdr->gname, name); - -- to_oct (file_hdr->c_rdev_maj, 8, tar_hdr->devmajor); -- to_oct (file_hdr->c_rdev_min, 8, tar_hdr->devminor); -+ TO_OCT (file_hdr, c_rdev_maj, 8, tar_hdr, devmajor); -+ TO_OCT (file_hdr, c_rdev_min, 8, tar_hdr, devminor); - } - -- to_oct (tar_checksum (tar_hdr), 8, tar_hdr->chksum); -+ to_ascii (tar_hdr->chksum, tar_checksum (tar_hdr), 8, LG_8, true); - - tape_buffered_write ((char *) &tar_rec, out_des, TARRECORDSIZE); -+ -+ return 0; - } - - /* Return nonzero iff all the bytes in BLOCK are NUL. --- -2.18.1 - diff --git a/Fix-out-of-bounds-read.patch b/Fix-out-of-bounds-read.patch deleted file mode 100644 index 1cbb88f..0000000 --- a/Fix-out-of-bounds-read.patch +++ /dev/null @@ -1,71 +0,0 @@ -From 7d55037f89ab630125c37e6fc571cf36bb0a94c3 Mon Sep 17 00:00:00 2001 -From: Sergey Poznyakoff -Date: Thu, 10 Nov 2016 12:48:19 +0200 -Subject: [PATCH 02/15] Fix out-of-bounds read - -* src/copyin.c (process_copy_in): Skip records with zero filename length. ---- - src/copyin.c | 41 +++++++++++++++++++++++------------------ - 1 file changed, 23 insertions(+), 18 deletions(-) - -diff --git a/src/copyin.c b/src/copyin.c -index cde911e..05279d2 100644 ---- a/src/copyin.c -+++ b/src/copyin.c -@@ -1378,30 +1378,35 @@ process_copy_in () - - } - #endif -- /* Is this the header for the TRAILER file? */ -- if (strcmp (CPIO_TRAILER_NAME, file_hdr.c_name) == 0) -+ if (file_hdr.c_namesize == 0) -+ skip_file = true; -+ else - { -- done = true; -- break; -- } -+ /* Is this the header for the TRAILER file? */ -+ if (strcmp (CPIO_TRAILER_NAME, file_hdr.c_name) == 0) -+ { -+ done = true; -+ break; -+ } - -- cpio_safer_name_suffix (file_hdr.c_name, false, !no_abs_paths_flag, -- false); -+ cpio_safer_name_suffix (file_hdr.c_name, false, !no_abs_paths_flag, -+ false); - -- /* Does the file name match one of the given patterns? */ -- if (num_patterns <= 0) -- skip_file = false; -- else -- { -- skip_file = copy_matching_files; -- for (i = 0; i < num_patterns -- && skip_file == copy_matching_files; i++) -+ /* Does the file name match one of the given patterns? */ -+ if (num_patterns <= 0) -+ skip_file = false; -+ else - { -- if (fnmatch (save_patterns[i], file_hdr.c_name, 0) == 0) -- skip_file = !copy_matching_files; -+ skip_file = copy_matching_files; -+ for (i = 0; i < num_patterns -+ && skip_file == copy_matching_files; i++) -+ { -+ if (fnmatch (save_patterns[i], file_hdr.c_name, 0) == 0) -+ skip_file = !copy_matching_files; -+ } - } - } -- -+ - if (skip_file) - { - /* If we're skipping a file with links, there might be other --- -1.8.3.1 - diff --git a/Fix-signed-integer-overflow-big-block-sizes.patch b/Fix-signed-integer-overflow-big-block-sizes.patch deleted file mode 100644 index dcf595c..0000000 --- a/Fix-signed-integer-overflow-big-block-sizes.patch +++ /dev/null @@ -1,25 +0,0 @@ -From 404600ebb4d417238bfabf7ec1561a62dc83c168 Mon Sep 17 00:00:00 2001 -From: grajagandev -Date: Mon, 8 Feb 2016 07:58:45 -0800 -Subject: [PATCH 04/15] Fix signed integer overflow - big block sizes - ---- - src/main.c | 2 +- - 1 files changed, 1 insertions(+), 1 deletions(-) - -diff --git a/src/main.c b/src/main.c -index a13861f..5a30a7b 100644 ---- a/src/main.c -+++ b/src/main.c -@@ -321,7 +321,7 @@ parse_opt (int key, char *arg, struct argp_state *state) - - case BLOCK_SIZE_OPTION: /* --block-size */ - io_block_size = atoi (arg); -- if (io_block_size < 1) -+ if (io_block_size < 1 || io_block_size > INT_MAX/512) - USAGE_ERROR ((0, 0, _("invalid block size"))); - io_block_size *= 512; - break; --- -1.8.3.1 - diff --git a/Fix-use-after-free-and-return-appropriate-error.patch b/Fix-use-after-free-and-return-appropriate-error.patch new file mode 100644 index 0000000..e7c8706 --- /dev/null +++ b/Fix-use-after-free-and-return-appropriate-error.patch @@ -0,0 +1,61 @@ +From 356ad51812edb47fd76aa59b8c935d55b879541a Mon Sep 17 00:00:00 2001 +From: Roberto Sassu +Date: Thu, 2 Jul 2020 10:23:44 +0200 +Subject: [PATCH] cpio: fix use after free and return appropriate errors + +--- + src/copyout.c | 23 +++++++++++++++-------- + 1 file changed, 15 insertions(+), 8 deletions(-) + +diff --git a/src/copyout.c b/src/copyout.c +index 29d2198..7feed00 100644 +--- a/src/copyout.c ++++ b/src/copyout.c +@@ -600,15 +600,19 @@ write_xattrs (int metadata_fd, char *path) + list_ptr = xattr_list = malloc(list_len); + if (!list_ptr) { + error (0, 0, _("out of memory")); +- return ret; ++ return -ENOMEM; + } + + len = llistxattr(path, xattr_list, list_len); +- if (len != list_len) ++ if (len != list_len) { ++ ret = -EIO; + goto out; ++ } + +- if (ftruncate(metadata_fd, 0)) ++ if (ftruncate(metadata_fd, 0)) { ++ ret = -EIO; + goto out; ++ } + + lseek(metadata_fd, 0, SEEK_SET); + +@@ -658,13 +662,16 @@ write_xattrs (int metadata_fd, char *path) + } + + free(xattr_value); +-out: +- free(xattr_list); + +- if (list_ptr != xattr_list + list_len) +- return ret; ++ if (list_ptr != xattr_list + list_len) { ++ ret = -EINVAL; ++ goto out; ++ } + +- return 0; ++ ret = 0; ++out: ++ free(xattr_list); ++ return ret; + } + + /* Read a list of file names from the standard input +-- +2.27.GIT + diff --git a/add-option-to-add-metadata-in-copy-out-mode.patch b/add-option-to-add-metadata-in-copy-out-mode.patch new file mode 100644 index 0000000..fa5b548 --- /dev/null +++ b/add-option-to-add-metadata-in-copy-out-mode.patch @@ -0,0 +1,428 @@ +From 531cabc88e9ecdc3231fad6e4856869baa9a91ef Mon Sep 17 00:00:00 2001 +From: Roberto Sassu +Date: Wed, 22 May 2019 09:04:39 +0200 +Subject: [PATCH] cpio: add option to add file metadata in copy-out mode + +This patch adds the -e option to include file metadata in the +image. At the moment, only the xattr type is supported. + +If the xattr type is selected, the patch includes an additional file for +each file passed to stdin, with special name 'METADATA!!!'. The +additional file might contain multiple metadata records. The format of +each record is: + + + +The format of metadata for the xattr type is: + +\0 + +Signed-off-by: Roberto Sassu +--- + doc/cpio.texi | 3 ++ + src/copyout.c | 140 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-- + src/dstring.c | 26 +++++++++-- + src/dstring.h | 1 + + src/extern.h | 4 +- + src/global.c | 2 + + src/initramfs.h | 21 +++++++++ + src/main.c | 22 +++++++++ + 8 files changed, 211 insertions(+), 8 deletions(-) + create mode 100644 src/initramfs.h + +diff --git a/doc/cpio.texi b/doc/cpio.texi +index 31a15fa..03d9585 100644 +--- a/doc/cpio.texi ++++ b/doc/cpio.texi +@@ -276,6 +276,9 @@ Set the I/O block size to the given @var{number} of bytes. + @item -D @var{dir} + @itemx --directory=@var{dir} + Change to directory @var{dir} ++@item -e @var{type} ++@itemx --file-metadata=@var{type} ++Include in the image file metadata with the specified type. + @item --force-local + Treat the archive file as local, even if its name contains colons. + @item -F [[@var{user}@@]@var{host}:]@var{archive-file} +diff --git a/src/copyout.c b/src/copyout.c +index 4b7336b..fdafb37 100644 +--- a/src/copyout.c ++++ b/src/copyout.c +@@ -22,6 +22,7 @@ + #include + #include + #include ++#include + #include "filetypes.h" + #include "cpiohdr.h" + #include "dstring.h" +@@ -589,6 +590,94 @@ assign_string (char **pvar, char *value) + *pvar = p; + } + ++static int ++write_xattrs (int metadata_fd, char *path) ++{ ++ struct metadata_hdr hdr = { .c_version = 1, .c_type = TYPE_XATTR }; ++ char str[sizeof(hdr.c_size) + 1]; ++ char *xattr_list = NULL; ++ char *list_ptr = NULL; ++ char *xattr_value = NULL; ++ ssize_t list_len, name_len, value_len, len; ++ int ret = -EINVAL; ++ ++ if (metadata_fd < 0) ++ return 0; ++ ++ list_len = llistxattr(path, NULL, 0); ++ if (list_len <= 0) ++ return -ENOENT; ++ ++ list_ptr = xattr_list = malloc(list_len); ++ if (!list_ptr) { ++ error (0, 0, _("out of memory")); ++ return ret; ++ } ++ ++ len = llistxattr(path, xattr_list, list_len); ++ if (len != list_len) ++ goto out; ++ ++ if (ftruncate(metadata_fd, 0)) ++ goto out; ++ ++ lseek(metadata_fd, 0, SEEK_SET); ++ ++ while (list_ptr < xattr_list + list_len) { ++ name_len = strlen(list_ptr); ++ ++ value_len = lgetxattr(path, list_ptr, NULL, 0); ++ if (value_len < 0) { ++ error (0, 0, _("cannot get xattrs")); ++ break; ++ } ++ ++ if (value_len) { ++ xattr_value = malloc(value_len); ++ if (!xattr_value) { ++ error (0, 0, _("out of memory")); ++ break; ++ } ++ } else { ++ xattr_value = NULL; ++ } ++ ++ len = lgetxattr(path, list_ptr, xattr_value, value_len); ++ if (len != value_len) ++ break; ++ ++ snprintf(str, sizeof(str), "%.8lx", ++ sizeof(hdr) + name_len + 1 + value_len); ++ ++ memcpy(hdr.c_size, str, sizeof(hdr.c_size)); ++ ++ if (write(metadata_fd, &hdr, sizeof(hdr)) != sizeof(hdr)) ++ break; ++ ++ if (write(metadata_fd, list_ptr, name_len + 1) != name_len + 1) ++ break; ++ ++ if (write(metadata_fd, xattr_value, value_len) != value_len) ++ break; ++ ++ if (fsync(metadata_fd)) ++ break; ++ ++ list_ptr += name_len + 1; ++ free(xattr_value); ++ xattr_value = NULL; ++ } ++ ++ free(xattr_value); ++out: ++ free(xattr_list); ++ ++ if (list_ptr != xattr_list + list_len) ++ return ret; ++ ++ return 0; ++} ++ + /* Read a list of file names from the standard input + and write a cpio collection on the standard output. + The format of the header depends on the compatibility (-c) flag. */ +@@ -603,6 +692,8 @@ process_copy_out () + int in_file_des; /* Source file descriptor. */ + int out_file_des; /* Output file descriptor. */ + char *orig_file_name = NULL; ++ char template[] = "/tmp/cpio-metadata-XXXXXX"; ++ int ret, metadata_fd, metadata = 0, old_metadata, hard_link; + + /* Initialize the copy out. */ + ds_init (&input_name, 128); +@@ -635,9 +726,37 @@ process_copy_out () + prepare_append (out_file_des); + } + ++ /* Create a temporary file to store file metadata */ ++ if (metadata_type != TYPE_NONE) { ++ metadata_fd = mkstemp(template); ++ if (metadata_fd < 0) { ++ error (0, 0, _("cannot create temporary file")); ++ return; ++ } ++ } ++ + /* Copy files with names read from stdin. */ +- while (ds_fgetstr (stdin, &input_name, name_end) != NULL) ++ while ((metadata_type != TYPE_NONE && metadata) || ++ ds_fgetstr (stdin, &input_name, name_end) != NULL) + { ++ old_metadata = metadata; ++ hard_link = 0; ++ ++ if (metadata) { ++ metadata = 0; ++ ++ if (metadata_type != TYPE_XATTR) { ++ error (0, 0, _("metadata type not supported")); ++ continue; ++ } ++ ++ ret = write_xattrs(metadata_fd, orig_file_name); ++ if (ret < 0) ++ continue; ++ ++ ds_sgetstr (template, &input_name, name_end); ++ } ++ + /* Check for blank line. */ + if (input_name.ds_string[0] == 0) + { +@@ -667,8 +786,15 @@ process_copy_out () + } + } + } +- +- assign_string (&orig_file_name, input_name.ds_string); ++ ++ if (old_metadata) { ++ assign_string (&orig_file_name, template); ++ ds_sgetstr (METADATA_FILENAME, &input_name, name_end); ++ file_hdr.c_mode |= 0x10000; ++ } else { ++ assign_string (&orig_file_name, input_name.ds_string); ++ } ++ + cpio_safer_name_suffix (input_name.ds_string, false, + !no_abs_paths_flag, true); + cpio_set_c_name (&file_hdr, input_name.ds_string); +@@ -700,6 +826,7 @@ process_copy_out () + else + { + add_link_defer (&file_hdr); ++ hard_link = 1; + break; + } + } +@@ -836,6 +963,8 @@ process_copy_out () + fprintf (stderr, "%s\n", orig_file_name); + if (dot_flag) + fputc ('.', stderr); ++ if (metadata_type != TYPE_NONE && !old_metadata && !hard_link) ++ metadata = 1; + } + } + +@@ -875,6 +1004,11 @@ process_copy_out () + (unsigned long) blocks), (unsigned long) blocks); + } + cpio_file_stat_free (&file_hdr); ++ ++ if (metadata_type != TYPE_NONE) { ++ close(metadata_fd); ++ unlink(template); ++ } + } + + +diff --git a/src/dstring.c b/src/dstring.c +index e9c063f..1021d21 100644 +--- a/src/dstring.c ++++ b/src/dstring.c +@@ -58,8 +58,8 @@ ds_resize (dynamic_string *string, int size) + Return NULL if end of file is detected. Otherwise, + Return a pointer to the null-terminated string in S. */ + +-char * +-ds_fgetstr (FILE *f, dynamic_string *s, char eos) ++static char * ++ds_fgetstr_common (FILE *f, char *input_string, dynamic_string *s, char eos) + { + int insize; /* Amount needed for line. */ + int strsize; /* Amount allocated for S. */ +@@ -70,7 +70,10 @@ ds_fgetstr (FILE *f, dynamic_string *s, char eos) + strsize = s->ds_length; + + /* Read the input string. */ +- next_ch = getc (f); ++ if (input_string) ++ next_ch = *input_string++; ++ else ++ next_ch = getc (f); + while (next_ch != eos && next_ch != EOF) + { + if (insize >= strsize - 1) +@@ -79,7 +82,10 @@ ds_fgetstr (FILE *f, dynamic_string *s, char eos) + strsize = s->ds_length; + } + s->ds_string[insize++] = next_ch; +- next_ch = getc (f); ++ if (input_string) ++ next_ch = *input_string++; ++ else ++ next_ch = getc (f); + } + s->ds_string[insize++] = '\0'; + +@@ -90,6 +96,12 @@ ds_fgetstr (FILE *f, dynamic_string *s, char eos) + } + + char * ++ds_fgetstr (FILE *f, dynamic_string *s, char eos) ++{ ++ return ds_fgetstr_common (f, NULL, s, eos); ++} ++ ++char * + ds_fgets (FILE *f, dynamic_string *s) + { + return ds_fgetstr (f, s, '\n'); +@@ -100,3 +112,9 @@ ds_fgetname (FILE *f, dynamic_string *s) + { + return ds_fgetstr (f, s, '\0'); + } ++ ++char * ++ds_sgetstr (char *input_string, dynamic_string *s, char eos) ++{ ++ return ds_fgetstr_common (NULL, input_string, s, eos); ++} +diff --git a/src/dstring.h b/src/dstring.h +index b5135fe..f5f95ec 100644 +--- a/src/dstring.h ++++ b/src/dstring.h +@@ -49,3 +49,4 @@ void ds_resize (dynamic_string *string, int size); + char *ds_fgetname (FILE *f, dynamic_string *s); + char *ds_fgets (FILE *f, dynamic_string *s); + char *ds_fgetstr (FILE *f, dynamic_string *s, char eos); ++char *ds_sgetstr (char *input_string, dynamic_string *s, char eos); +diff --git a/src/extern.h b/src/extern.h +index 11ac6bf..f295fcf 100644 +--- a/src/extern.h ++++ b/src/extern.h +@@ -19,6 +19,7 @@ + + #include "paxlib.h" + #include "quotearg.h" ++#include "initramfs.h" + #include "quote.h" + + enum archive_format +@@ -99,7 +100,8 @@ extern char output_is_seekable; + extern int (*xstat) (); + extern void (*copy_function) (); + extern char *change_directory_option; +- ++extern enum metadata_types metadata_type; ++ + + /* copyin.c */ + void warn_junk_bytes (long bytes_skipped); +diff --git a/src/global.c b/src/global.c +index fb3abe9..0c40be0 100644 +--- a/src/global.c ++++ b/src/global.c +@@ -199,3 +199,5 @@ char *change_directory_option; + int renumber_inodes_option; + int ignore_devno_option; + ++/* include file metadata into the image */ ++enum metadata_types metadata_type = TYPE_NONE; +diff --git a/src/initramfs.h b/src/initramfs.h +new file mode 100644 +index 0000000..88abae7 +--- /dev/null ++++ b/src/initramfs.h +@@ -0,0 +1,21 @@ ++/* SPDX-License-Identifier: GPL-2.0+ */ ++/* ++ * include/linux/initramfs.h ++ * ++ * Include file for file metadata in the initial ram disk. ++ */ ++#ifndef _LINUX_INITRAMFS_H ++#define _LINUX_INITRAMFS_H ++ ++#define METADATA_FILENAME "METADATA!!!" ++ ++enum metadata_types { TYPE_NONE, TYPE_XATTR, TYPE__LAST }; ++ ++struct metadata_hdr { ++ char c_size[8]; /* total size including c_size field */ ++ char c_version; /* header version */ ++ char c_type; /* metadata type */ ++ char c_metadata[]; /* metadata */ ++} __attribute__((packed)); ++ ++#endif /*_LINUX_INITRAMFS_H*/ +diff --git a/src/main.c b/src/main.c +index 6f90055..e343286 100644 +--- a/src/main.c ++++ b/src/main.c +@@ -199,6 +199,8 @@ static struct argp_option options[] = { + {"device-independent", DEVICE_INDEPENDENT_OPTION, NULL, 0, + N_("Create device-independent (reproducible) archives") }, + {"reproducible", 0, NULL, OPTION_ALIAS }, ++ {"file-metadata", 'e', N_("TYPE"), 0, ++ N_("Include file metadata"), GRID+1 }, + #undef GRID + + /* ********** */ +@@ -292,6 +294,22 @@ warn_control (char *arg) + return 1; + } + ++static enum metadata_types ++parse_metadata_type(char *arg) ++{ ++ static char *metadata_type_str[TYPE__LAST] = { ++ [TYPE_NONE] = "none", ++ [TYPE_XATTR] = "xattr", ++ }; ++ int i; ++ ++ for (i = 0; i < TYPE__LAST; i++) ++ if (!strcmp (metadata_type_str[i], arg)) ++ return i; ++ ++ return TYPE_NONE; ++} ++ + static error_t + parse_opt (int key, char *arg, struct argp_state *state) + { +@@ -354,6 +372,10 @@ parse_opt (int key, char *arg, struct argp_state *state) + copy_matching_files = false; + break; + ++ case 'e': /* Metadata type. */ ++ metadata_type = parse_metadata_type(arg); ++ break; ++ + case 'E': /* Pattern file name. */ + pattern_file_name = arg; + break; +-- +1.8.3.1 + diff --git a/cpio-2.12.tar.bz2 b/cpio-2.12.tar.bz2 deleted file mode 100644 index 80bda2b..0000000 Binary files a/cpio-2.12.tar.bz2 and /dev/null differ diff --git a/cpio-2.9-dev_number.patch b/cpio-2.13-dev_number.patch similarity index 86% rename from cpio-2.9-dev_number.patch rename to cpio-2.13-dev_number.patch index cf6d242..20943a3 100644 --- a/cpio-2.9-dev_number.patch +++ b/cpio-2.13-dev_number.patch @@ -3,10 +3,10 @@ Date: Mon, 14 Sep 2015 09:37:15 +0200 Subject: [PATCH 3/7] Support major/minor device numbers over 127 (bz#450109) diff --git a/src/copyin.c b/src/copyin.c -index cde911e..12bd27c 100644 +index b29f348..1142d6a 100644 --- a/src/copyin.c +++ b/src/copyin.c -@@ -1196,15 +1196,15 @@ read_in_binary (struct cpio_file_stat *file_hdr, +@@ -1123,15 +1123,15 @@ read_in_binary (struct cpio_file_stat *file_hdr, swab_array ((char *) short_hdr, 13); } @@ -25,4 +25,4 @@ index cde911e..12bd27c 100644 + file_hdr->c_rdev_min = minor ((unsigned short)short_hdr->c_rdev); file_hdr->c_mtime = (unsigned long) short_hdr->c_mtimes[0] << 16 | short_hdr->c_mtimes[1]; - + file_hdr->c_filesize = (unsigned long) short_hdr->c_filesizes[0] << 16 diff --git a/cpio-2.13-exitCode.patch b/cpio-2.13-exitCode.patch new file mode 100644 index 0000000..4af7736 --- /dev/null +++ b/cpio-2.13-exitCode.patch @@ -0,0 +1,39 @@ +Subject: [PATCH 2/7] set exit code to 1 when cpio fails to store file > 4GB + (#183224) + +diff --git a/src/copyout.c b/src/copyout.c +index 8b0beb6..4b7336b 100644 +--- a/src/copyout.c ++++ b/src/copyout.c +@@ -290,7 +290,7 @@ field_width_error (const char *filename, const char *fieldname, + { + char valbuf[UINTMAX_STRSIZE_BOUND + 1]; + char maxbuf[UINTMAX_STRSIZE_BOUND + 1]; +- error (0, 0, _("%s: value %s %s out of allowed range 0..%s"), ++ error (1, 0, _("%s: value %s %s out of allowed range 0..%s"), + filename, fieldname, + STRINGIFY_BIGINT (value, valbuf), + STRINGIFY_BIGINT (MAX_VAL_WITH_DIGITS (width - nul, LG_8), +diff --git a/tests/CVE-2019-14866.at b/tests/CVE-2019-14866.at +index e877b39..50ad60b 100644 +--- a/tests/CVE-2019-14866.at ++++ b/tests/CVE-2019-14866.at +@@ -30,6 +30,5 @@ fi + [0], + [], + [cpio: file: value size 17179869184 out of allowed range 0..8589934591 +-2 blocks + ]) + AT_CLEANUP +diff --git a/tests/testsuite b/tests/testsuite +index b45c731..fd8454d 100755 +--- a/tests/testsuite ++++ b/tests/testsuite +@@ -2885,7 +2885,6 @@ fi + at_status=$? at_failed=false + $at_check_filter + echo >>"$at_stderr"; $as_echo "cpio: file: value size 17179869184 out of allowed range 0..8589934591 +-2 blocks + " | \ + $at_diff - "$at_stderr" || at_failed=: + at_fn_diff_devnull "$at_stdout" || at_failed=: diff --git a/cpio-2.13.tar.bz2 b/cpio-2.13.tar.bz2 new file mode 100644 index 0000000..ed2aa3e Binary files /dev/null and b/cpio-2.13.tar.bz2 differ diff --git a/cpio-2.9-exitCode.patch b/cpio-2.9-exitCode.patch deleted file mode 100644 index e4a4781..0000000 --- a/cpio-2.9-exitCode.patch +++ /dev/null @@ -1,18 +0,0 @@ -From: Peter Vrabec -Date: Mon, 14 Sep 2015 09:31:08 +0200 -Subject: [PATCH 2/7] set exit code to 1 when cpio fails to store file > 4GB - (#183224) - -diff --git a/src/copyout.c b/src/copyout.c -index 1f0987a..dcae449 100644 ---- a/src/copyout.c -+++ b/src/copyout.c -@@ -287,7 +287,7 @@ to_ascii (char *where, uintmax_t v, size_t digits, unsigned logbase) - static void - field_width_error (const char *filename, const char *fieldname) - { -- error (0, 0, _("%s: field width not sufficient for storing %s"), -+ error (1, 0, _("%s: field width not sufficient for storing %s"), - filename, fieldname); - } - diff --git a/cpio.spec b/cpio.spec index 55de345..cc0932e 100644 --- a/cpio.spec +++ b/cpio.spec @@ -1,6 +1,6 @@ Name: cpio -Version: 2.12 -Release: 14 +Version: 2.13 +Release: 1 Summary: A GNU archiving program License: GPLv3+ @@ -8,15 +8,14 @@ URL: https://www.gnu.org/software/cpio Source0: https://ftp.gnu.org/gnu/cpio/%{name}-%{version}.tar.bz2 Patch0: cpio-2.9-rh.patch -Patch1: cpio-2.9-exitCode.patch -Patch2: cpio-2.9-dev_number.patch +Patch1: cpio-2.13-exitCode.patch +Patch2: cpio-2.13-dev_number.patch Patch3: cpio-2.9.90-defaultremoteshell.patch Patch4: cpio-2.10-patternnamesigsegv.patch Patch5: cpio-2.10-longnames-split.patch Patch6: cpio-2.11-crc-fips-nit.patch -Patch6000: Fix-out-of-bounds-read.patch -Patch6001: Fix-signed-integer-overflow-big-block-sizes.patch -Patch6002: Fix-CVE-2019-14866.patch +Patch7: add-option-to-add-metadata-in-copy-out-mode.patch +Patch8: Fix-use-after-free-and-return-appropriate-error.patch Provides: bundled(gnulib) Provides: /bin/cpio @@ -37,7 +36,6 @@ tape, or a pipe. %make_build %install -rm -rf %RPM_BUILD_ROOT %make_install rm -rf %{buildroot}/usr/share/man/man8* rm -rf %{buildroot}/usr/libexec/ @@ -59,6 +57,15 @@ make check %{_datadir}/man/man1/%{name}.1.gz %changelog +* Sun Aug 23 2020 chengquan - 2.13-1 +- Update software to v2.13 + +* Wed Aug 12 2020 Liquor - 2.12-15 +- Type:bugfix +- ID:NA +- SUG:NA +- DESC:use /etc/rmt as default rmt command + * Sat Dec 21 2019 openEuler Buildteam - 2.12-14 - Fix CVE-2019-14866