From: Peter Marko <[email protected]>

Pick patch mentioned in NVD CVE description.
Resolve trivial conflicts.

Signed-off-by: Peter Marko <[email protected]>
---
 meta/recipes-extended/cpio/cpio_2.15.bb       |   1 +
 .../cpio/files/CVE-2026-66486.patch           | 497 ++++++++++++++++++
 2 files changed, 498 insertions(+)
 create mode 100644 meta/recipes-extended/cpio/files/CVE-2026-66486.patch

diff --git a/meta/recipes-extended/cpio/cpio_2.15.bb 
b/meta/recipes-extended/cpio/cpio_2.15.bb
index 9b4ab52228..f4a49b3cd9 100644
--- a/meta/recipes-extended/cpio/cpio_2.15.bb
+++ b/meta/recipes-extended/cpio/cpio_2.15.bb
@@ -11,6 +11,7 @@ SRC_URI = "${GNU_MIRROR}/cpio/cpio-${PV}.tar.gz \
            file://test.sh \
            file://CVE-2026-66485.patch \
            file://CVE-2026-66484.patch \
+           file://CVE-2026-66486.patch \
            "
 
 SRC_URI[sha256sum] = 
"efa50ef983137eefc0a02fdb51509d624b5e3295c980aa127ceee4183455499e"
diff --git a/meta/recipes-extended/cpio/files/CVE-2026-66486.patch 
b/meta/recipes-extended/cpio/files/CVE-2026-66486.patch
new file mode 100644
index 0000000000..93199a337e
--- /dev/null
+++ b/meta/recipes-extended/cpio/files/CVE-2026-66486.patch
@@ -0,0 +1,497 @@
+From 2ff9600c9ef32e88759843cdbde74c8db5ae9b30 Mon Sep 17 00:00:00 2001
+From: Sergey Poznyakoff <[email protected]>
+Date: Thu, 23 Jul 2026 17:26:05 +0300
+Subject: [PATCH] Quote file names in error messages and in listings.
+
+* NEWS: Document changes.
+* doc/cpio.texi: Likewise.
+* src/copyin.c: Quote file and member names.
+* src/copyout.c: Likewise.
+* src/copypass.c: Likewise.
+* src/main.c: New options: --quoting-style and --quote-chars.
+(process_args): Set default quoting style.
+* tests/CVE-2019-14866.at: Fix expected output.
+
+CVE: CVE-2026-66485
+Upstream-Status: Backport 
[https://git.savannah.gnu.org/cgit/cpio.git/commit/?id=2ff9600c9ef32e88759843cdbde74c8db5ae9b30]
+Signed-off-by: Peter Marko <[email protected]>
+---
+ NEWS                    | 16 ++++++++++++-
+ doc/cpio.texi           | 13 ++++++++++
+ src/copyin.c            | 39 +++++++++++++++++-------------
+ src/copyout.c           | 26 ++++++++++----------
+ src/copypass.c          | 11 +++++----
+ src/main.c              | 53 +++++++++++++++++++++++++++++++++++++++--
+ tests/CVE-2019-14866.at |  2 +-
+ 7 files changed, 123 insertions(+), 37 deletions(-)
+
+diff --git a/NEWS b/NEWS
+index d036665..24d85b5 100644
+--- a/NEWS
++++ b/NEWS
+@@ -1,8 +1,22 @@
+-GNU cpio NEWS -- history of user-visible changes. 2024-01-14
++GNU cpio NEWS -- history of user-visible changes. 2026-07-23
+ Copyright (C) 2003-2024 Free Software Foundation, Inc.
+ See the end of file for copying conditions.
+ 
+ Please send cpio bug reports to <[email protected]>.
++
++Version 2.15.? (git)
++
++* New options
++
++  --quoting-style=STYLE
++    Set name quoting style used when printing file names. Valid styles
++    are: c, c-maybe, clocale, escape, help (displays available styles
++    and exits), literal (default), locale, shell, shell-always,
++    shell-escape, and shell-escape-always.
++
++  --quote-chars=STRING
++    Additionally quote characters from STRING when printing file names.
++
+ 
+ Version 2.15 - Sergey Poznyakoff, 2024-01-14
+ 
+diff --git a/doc/cpio.texi b/doc/cpio.texi
+index 8d596fb..dc69a4d 100644
+--- a/doc/cpio.texi
++++ b/doc/cpio.texi
+@@ -814,6 +814,19 @@ Run in copy-pass mode.
+ [@ref{copy-in},@ref{copy-out},@ref{copy-pass}]
+ @*Do not print the number of blocks copied.
+ 
++@item --quote-chars=@var{string}
++Always quote characters from @var{string}, even if the selected
++quoting style would not quote them (@pxref{quoting styles,,,tar,GNU
++tar}).
++
++@item --quoting-style=@var{style}
++Set quoting style to use when printing member and file names
++(@pxref{quoting styles,,,tar,GNU tar}). Valid @var{style} values are:
++@code{literal}, @code{shell}, @code{shell-always}, @code{c},
++@code{escape}, @code{locale}, and @code{clocale}. Default quoting
++style is @code{literal}, unless overridden while configuring the
++package.
++
+ @item -r
+ @itemx --rename
+ [@ref{copy-in}]
+diff --git a/src/copyin.c b/src/copyin.c
+index 59ce98b..2afc9d4 100644
+--- a/src/copyin.c
++++ b/src/copyin.c
+@@ -114,7 +114,7 @@ get_link_name (struct cpio_file_stat *file_hdr, int 
in_file_des)
+   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);
++           quote (file_hdr->c_name));
+       link_name = NULL;
+     }
+   else
+@@ -150,7 +150,11 @@ list_file (struct cpio_file_stat* file_hdr, int 
in_file_des)
+       }
+       else
+ #endif
+-      long_format (file_hdr, (char *) 0);
++      long_format (file_hdr, NULL);
++    }
++  else if (name_end == '\n' && isatty (fileno (stdout)))
++    {
++      printf ("%s%c", quotearg (file_hdr->c_name), name_end);
+     }
+   else
+     {
+@@ -173,7 +177,7 @@ list_file (struct cpio_file_stat* file_hdr, int 
in_file_des)
+       if (crc != file_hdr->c_chksum)
+       {
+         error (0, 0, _("%s: checksum error (0x%x, should be 0x%x)"),
+-               file_hdr->c_name, crc, file_hdr->c_chksum);
++               quote (file_hdr->c_name), crc, file_hdr->c_chksum);
+       }
+     }
+ }
+@@ -200,7 +204,7 @@ try_existing_file (struct cpio_file_stat* file_hdr, int 
in_file_des,
+              && file_hdr->c_mtime <= file_stat.st_mtime)
+       {
+         error (0, 0, _("%s not created: newer or same age version exists"),
+-               file_hdr->c_name);
++               quote (file_hdr->c_name));
+         tape_toss_input (in_file_des, file_hdr->c_filesize);
+         tape_skip_padding (in_file_des, file_hdr->c_filesize);
+         return -1;    /* Go to the next file.  */
+@@ -210,7 +214,7 @@ try_existing_file (struct cpio_file_stat* file_hdr, int 
in_file_des,
+               : unlink (file_hdr->c_name))
+       {
+         error (0, errno, _("cannot remove current %s"),
+-               file_hdr->c_name);
++               quote (file_hdr->c_name));
+         tape_toss_input (in_file_des, file_hdr->c_filesize);
+         tape_skip_padding (in_file_des, file_hdr->c_filesize);
+         return -1;    /* Go to the next file.  */
+@@ -271,7 +275,8 @@ create_defered_links (struct cpio_file_stat *file_hdr)
+         if (link_res < 0)
+           {
+             error (0, errno, _("cannot link %s to %s"),
+-                   d->header.c_name, file_hdr->c_name);
++                   quote_n (0, d->header.c_name),
++                   quote_n (1, file_hdr->c_name));
+           }
+         if (d_prev != NULL)
+           d_prev->next = d->next;
+@@ -467,7 +472,8 @@ copyin_regular_file (struct cpio_file_stat* file_hdr, int 
in_file_des)
+         if (link_res < 0)
+           {
+             error (0, errno, _("cannot link %s to %s"),
+-                   file_hdr->c_tar_linkname, file_hdr->c_name);
++                   quote_n (0, file_hdr->c_tar_linkname),
++                   quote_n (1, file_hdr->c_name));
+           }
+         return;
+       }
+@@ -500,7 +506,7 @@ copyin_regular_file (struct cpio_file_stat* file_hdr, int 
in_file_des)
+       swapping_halfwords = true;
+       else
+       error (0, 0, _("cannot swap halfwords of %s: odd number of halfwords"),
+-             file_hdr->c_name);
++             quote (file_hdr->c_name));
+     }
+   if (swap_bytes_flag)
+     {
+@@ -508,7 +514,7 @@ copyin_regular_file (struct cpio_file_stat* file_hdr, int 
in_file_des)
+       swapping_bytes = true;
+       else
+       error (0, 0, _("cannot swap bytes of %s: odd number of bytes"),
+-             file_hdr->c_name);
++             quote (file_hdr->c_name));
+     }
+   copy_files_tape_to_disk (in_file_des, out_file_des, file_hdr->c_filesize);
+   disk_empty_output_buffer (out_file_des, true);
+@@ -519,7 +525,7 @@ copyin_regular_file (struct cpio_file_stat* file_hdr, int 
in_file_des)
+       {
+         if (crc != file_hdr->c_chksum)
+           error (0, 0, _("%s: checksum error (0x%x, should be 0x%x)"),
+-                 file_hdr->c_name, crc, file_hdr->c_chksum);
++                 quote (file_hdr->c_name), crc, file_hdr->c_chksum);
+       }
+       tape_skip_padding (in_file_des, file_hdr->c_filesize);
+       return;
+@@ -534,7 +540,7 @@ copyin_regular_file (struct cpio_file_stat* file_hdr, int 
in_file_des)
+     {
+       if (crc != file_hdr->c_chksum)
+       error (0, 0, _("%s: checksum error (0x%x, should be 0x%x)"),
+-             file_hdr->c_name, crc, file_hdr->c_chksum);
++             quote (file_hdr->c_name), crc, file_hdr->c_chksum);
+     }
+ 
+   tape_skip_padding (in_file_des, file_hdr->c_filesize);
+@@ -582,7 +588,8 @@ copyin_device (struct cpio_file_stat* file_hdr)
+       if (link_res < 0)
+       {
+         error (0, errno, _("cannot link %s to %s"),
+-               file_hdr->c_tar_linkname, file_hdr->c_name);
++               quote_n (0, file_hdr->c_tar_linkname),
++               quote_n (1, file_hdr->c_name));
+         /* Something must be wrong, because we couldn't
+            find the file to link to.  But can we assume
+            that the device maj/min numbers are correct
+@@ -855,7 +862,7 @@ copyin_file (struct cpio_file_stat *file_hdr, int 
in_file_des)
+ #endif
+ 
+     default:
+-      error (0, 0, _("%s: unknown file type"), file_hdr->c_name);
++      error (0, 0, _("%s: unknown file type"), quote (file_hdr->c_name));
+       tape_toss_input (in_file_des, file_hdr->c_filesize);
+       tape_skip_padding (in_file_des, file_hdr->c_filesize);
+     }
+@@ -1550,13 +1557,13 @@ process_copy_in (void)
+           if (crc != file_hdr.c_chksum)
+             {
+               error (0, 0, _("%s: checksum error (0x%x, should be 0x%x)"),
+-                     file_hdr.c_name, crc, file_hdr.c_chksum);
++                     quote (file_hdr.c_name), crc, file_hdr.c_chksum);
+             }
+        /* Debian hack: -v and -V now work with --only-verify-crc.
+           (99/11/10) -BEM */
+           if (verbose_flag)
+             {
+-              fprintf (stderr, "%s\n", file_hdr.c_name);
++              fprintf (stderr, "%s\n", quotearg (file_hdr.c_name));
+             }
+           if (dot_flag)
+             {
+@@ -1581,7 +1588,7 @@ process_copy_in (void)
+         copyin_file(&file_hdr, in_file_des);
+ 
+         if (verbose_flag)
+-          fprintf (stderr, "%s\n", file_hdr.c_name);
++          fprintf (stderr, "%s\n", quotearg (file_hdr.c_name));
+         if (dot_flag)
+           fputc ('.', stderr);
+       }
+diff --git a/src/copyout.c b/src/copyout.c
+index fd88080..b9fb676 100644
+--- a/src/copyout.c
++++ b/src/copyout.c
+@@ -46,7 +46,8 @@ read_for_checksum (int in_file_des, off_t file_size, char 
*file_name)
+     {
+       bytes_read = read (in_file_des, buf, BUFSIZ);
+       if (bytes_read < 0)
+-      error (PAXEXIT_FAILURE, errno, _("cannot read checksum for %s"), 
file_name);
++      error (PAXEXIT_FAILURE, errno, _("cannot read checksum for %s"),
++             quote (file_name));
+       if (bytes_read == 0)
+       break;
+       for (i = 0; i < bytes_read; i++)
+@@ -54,7 +55,8 @@ read_for_checksum (int in_file_des, off_t file_size, char 
*file_name)
+       file_size -= bytes_read;
+     }
+   if (lseek (in_file_des, 0L, SEEK_SET))
+-    error (PAXEXIT_FAILURE, errno, _("cannot read checksum for %s"), 
file_name);
++    error (PAXEXIT_FAILURE, errno, _("cannot read checksum for %s"),
++         quote (file_name));
+ 
+   return crc;
+ }
+@@ -288,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"),
+-       filename, fieldname,
++       quote (filename), fieldname,
+        STRINGIFY_BIGINT (value, valbuf),
+        STRINGIFY_BIGINT (MAX_VAL_WITH_DIGITS (width - nul, LG_8),
+                          maxbuf));
+@@ -298,7 +300,7 @@ static void
+ field_width_warning (const char *filename, const char *fieldname)
+ {
+   if (warn_option & CPIO_WARN_TRUNCATE)
+-    error (0, 0, _("%s: truncating %s"), filename, fieldname);
++        error (0, 0, _("%s: truncating %s"), quote (filename), fieldname);
+ }
+ 
+ void
+@@ -466,7 +468,7 @@ write_out_binary_header (dev_t rdev,
+   short_hdr.c_dev = makedev (file_hdr->c_dev_maj, file_hdr->c_dev_min);
+ 
+   if ((warn_option & CPIO_WARN_TRUNCATE) && (file_hdr->c_ino >> 16) != 0)
+-    error (0, 0, _("%s: truncating inode number"), file_hdr->c_name);
++    error (0, 0, _("%s: truncating inode number"), quote (file_hdr->c_name));
+ 
+   short_hdr.c_ino = file_hdr->c_ino & 0xFFFF;
+   if (short_hdr.c_ino != file_hdr->c_ino)
+@@ -497,7 +499,7 @@ write_out_binary_header (dev_t rdev,
+     {
+       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"),
++           quote (file_hdr->c_name), _("name size"),
+            STRINGIFY_BIGINT (file_hdr->c_namesize, maxbuf), 0xFFFFu);
+       return 1;
+     }
+@@ -510,7 +512,7 @@ write_out_binary_header (dev_t rdev,
+     {
+       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"),
++           quote (file_hdr->c_name), _("file size"),
+            STRINGIFY_BIGINT (file_hdr->c_namesize, maxbuf), 0xFFFFFFFFlu);
+       return 1;
+     }
+@@ -558,7 +560,7 @@ write_out_header (struct cpio_file_stat *file_hdr, int 
out_des)
+     case arf_ustar:
+       if (is_tar_filename_too_long (file_hdr->c_name))
+       {
+-        error (0, 0, _("%s: file name too long"), file_hdr->c_name);
++        error (0, 0, _("%s: file name too long"), quote (file_hdr->c_name));
+         return 1;
+       }
+       return write_out_tar_header (file_hdr, out_des);
+@@ -749,7 +751,7 @@ process_copy_out (void)
+             if (archive_format == arf_tar)
+               {
+                 error (0, 0, _("%s not dumped: not a regular file"),
+-                       orig_file_name);
++                       quote (orig_file_name));
+                 continue;
+               }
+             else if (archive_format == arf_ustar)
+@@ -800,7 +802,7 @@ process_copy_out (void)
+                   if (link_size + 1 > 100)
+                     {
+                       error (0, 0, _("%s: symbolic link too long"),
+-                             file_hdr.c_name);
++                             quote (file_hdr.c_name));
+                     }
+                   else
+                     {
+@@ -823,11 +825,11 @@ process_copy_out (void)
+ #endif
+ 
+           default:
+-            error (0, 0, _("%s: unknown file type"), orig_file_name);
++            error (0, 0, _("%s: unknown file type"), quote (orig_file_name));
+           }
+ 
+         if (verbose_flag)
+-          fprintf (stderr, "%s\n", orig_file_name);
++          fprintf (stderr, "%s\n", quote (orig_file_name));
+         if (dot_flag)
+           fputc ('.', stderr);
+       }
+diff --git a/src/copypass.c b/src/copypass.c
+index 7d7e970..928990f 100644
+--- a/src/copypass.c
++++ b/src/copypass.c
+@@ -127,7 +127,7 @@ process_copy_pass (void)
+                  && in_file_stat.st_mtime <= out_file_stat.st_mtime)
+           {
+             error (0, 0, _("%s not created: newer or same age version 
exists"),
+-                   output_name.ds_string);
++                   quote (output_name.ds_string));
+             continue;         /* Go to the next file.  */
+           }
+         else if (S_ISDIR (out_file_stat.st_mode)
+@@ -135,7 +135,7 @@ process_copy_pass (void)
+                       : unlink (output_name.ds_string))
+           {
+             error (0, errno, _("cannot remove current %s"),
+-                   output_name.ds_string);
++                   quote (output_name.ds_string));
+             continue;         /* Go to the next file.  */
+           }
+       }
+@@ -312,7 +312,8 @@ process_copy_pass (void)
+ #endif
+       else
+       {
+-        error (0, 0, _("%s: unknown file type"), input_name.ds_string);
++        error (0, 0, _("%s: unknown file type"),
++               quote (input_name.ds_string));
+       }
+ 
+       if (verbose_flag)
+@@ -388,12 +389,12 @@ link_to_name (char const *link_name, char const 
*link_target)
+     {
+       if (verbose_flag)
+       error (0, 0, _("%s linked to %s"),
+-             link_target, link_name);
++             quote_n (0, link_target), quote_n (1, link_name));
+     }
+   else if (link_flag)
+     {
+       error (0, errno, _("cannot link %s to %s"),
+-           link_target, link_name);
++           quote_n (0, link_target), quote_n (1, link_name));
+     }
+   return res;
+ }
+diff --git a/src/main.c b/src/main.c
+index 978dfff..dcd40b8 100644
+--- a/src/main.c
++++ b/src/main.c
+@@ -61,7 +61,9 @@ enum cpio_options {
+   RENUMBER_INODES_OPTION,
+   IGNORE_DEVNO_OPTION,
+   IGNORE_DIRNLINK_OPTION,
+-  DEVICE_INDEPENDENT_OPTION
++  DEVICE_INDEPENDENT_OPTION,
++  QUOTING_STYLE_OPTION,
++  QUOTE_CHARS_OPTION
+ };
+ 
+ const char *program_authors[] =
+@@ -141,6 +143,12 @@ static struct argp_option options[] = {
+    N_("Control warning display. Currently FLAG is one of 'none', 'truncate', 
'all'. Multiple options accumulate."), GRID+1 },
+   {"owner", 'R', N_("[USER][:.][GROUP]"), 0,
+    N_("Set the ownership of all files created to the specified USER and/or 
GROUP"), GRID+1 },
++  {"quoting-style", QUOTING_STYLE_OPTION, N_("STYLE"), 0,
++   N_("set name quoting style; use --quoting-style=help for a list of valid 
STYLE values"),
++   GRID+1 },
++  {"quote-chars", QUOTE_CHARS_OPTION, N_("STRING"), 0,
++   N_("additionally quote characters from STRING"),
++   GRID+1 },
+ #undef GRID
+ 
+ #define GRID 110
+@@ -295,6 +303,36 @@ warn_control (char *arg)
+   return 1;
+ }
+ 
++static void
++cpio_list_quoting_styles (int indent)
++{
++  int i;
++
++  for (i = 0; quoting_style_args[i]; i++)
++    printf ("%*.*s%s\n", indent, indent, "", quoting_style_args[i]);
++}
++
++static void
++cpio_set_quoting_style (char *arg)
++{
++  if (strcmp (arg, "help") == 0)
++    {
++      cpio_list_quoting_styles (0);
++      exit (EXIT_SUCCESS);
++    }
++
++  for (idx_t i = 0; quoting_style_args[i]; i++)
++    if (strcmp (arg, quoting_style_args[i]) == 0)
++      {
++      set_quoting_style (NULL, i);
++      return;
++      }
++  USAGE_ERROR ((0, 0,
++              _("Unknown quoting style '%s'."
++                " Try '%s --quoting-style=help' to get a list."),
++              arg, program_name));
++}
++
+ static error_t
+ parse_opt (int key, char *arg, struct argp_state *state)
+ {
+@@ -454,10 +492,19 @@ crc newc odc bin ustar tar (all-caps also recognized)"), 
arg));
+       copy_function = process_copy_pass;
+       break;
+ 
++    case QUOTE_CHARS_OPTION:
++      for (;*arg; arg++)
++      set_char_quoting (NULL, *arg, 1);
++      break;
++
++    case QUOTING_STYLE_OPTION:
++      cpio_set_quoting_style (arg);
++      break;
++
+     case IGNORE_DEVNO_OPTION:
+       ignore_devno_option = 1;
+       break;
+-
++ 
+     case RENUMBER_INODES_OPTION:
+       renumber_inodes_option = 1;
+       break;
+@@ -593,6 +640,8 @@ process_args (int argc, char *argv[])
+ 
+   xstat = lstat;
+ 
++  set_quoting_style (NULL, DEFAULT_QUOTING_STYLE);
++
+   if (argp_parse (&argp, argc, argv, ARGP_IN_ORDER, &index, NULL))
+     exit (PAXEXIT_FAILURE);
+ 
+diff --git a/tests/CVE-2019-14866.at b/tests/CVE-2019-14866.at
+index 2bfdabc..bdf6a04 100644
+--- a/tests/CVE-2019-14866.at
++++ b/tests/CVE-2019-14866.at
+@@ -29,7 +29,7 @@ fi
+ ],
+ [0],
+ [],
+-[cpio: file: value size 17179869184 out of allowed range 0..8589934591
++[cpio: 'file': value size 17179869184 out of allowed range 0..8589934591
+ 2 blocks
+ ])
+ AT_CLEANUP
-=-=-=-=-=-=-=-=-=-=-=-
Links: You receive all messages sent to this group.
View/Reply Online (#243306): 
https://lists.openembedded.org/g/openembedded-core/message/243306
Mute This Topic: https://lists.openembedded.org/mt/120724494/21656
Group Owner: [email protected]
Unsubscribe: https://lists.openembedded.org/g/openembedded-core/unsub 
[[email protected]]
-=-=-=-=-=-=-=-=-=-=-=-

Reply via email to