From e277541de85ffb91e2962cc3950133a7878cf3f9 Mon Sep 17 00:00:00 2001 From: fly_fzc <2385803914@qq.com> Date: Mon, 21 Aug 2023 16:17:34 +0800 Subject: [PATCH] Fix CVE-2015-1197 --- ...-to-2-when-failing-to-create-symlink.patch | 34 + ...-no-absolute-filenames-make-director.patch | 31 + ...s-and-modification-times-of-symlinks.patch | 981 ++++++++++++++++++ cpio.spec | 13 +- ...ee2b407913c533f7ded8d6f8cbeec16ff6ca.patch | 218 ---- revert-CVE-2015-1197.patch | 109 -- 6 files changed, 1056 insertions(+), 330 deletions(-) create mode 100644 backport-Do-not-set-exit-code-to-2-when-failing-to-create-symlink.patch create mode 100644 backport-fix-operation-of-no-absolute-filenames-make-director.patch create mode 100644 backport-restore-access-and-modification-times-of-symlinks.patch delete mode 100644 revert-CVE-2015-1197-Fix-45b0ee2b407913c533f7ded8d6f8cbeec16ff6ca.patch delete mode 100644 revert-CVE-2015-1197.patch diff --git a/backport-Do-not-set-exit-code-to-2-when-failing-to-create-symlink.patch b/backport-Do-not-set-exit-code-to-2-when-failing-to-create-symlink.patch new file mode 100644 index 0000000..9ae8460 --- /dev/null +++ b/backport-Do-not-set-exit-code-to-2-when-failing-to-create-symlink.patch @@ -0,0 +1,34 @@ +From 2cf05f5a1826dd127d5c9063cc8cc7667746be38 Mon Sep 17 00:00:00 2001 +From: Ziyang Chen +Date: Mon, 10 Jul 2023 20:19:27 +0800 +Subject: [PATCH] Do not set exit code to 2 when failing to create symlink + +--- + src/copyin.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/src/copyin.c b/src/copyin.c +index 2e72356..2b6b361 100644 +--- a/src/copyin.c ++++ b/src/copyin.c +@@ -736,7 +736,7 @@ replace_symlink_placeholders (void) + res = UMASKED_SYMLINK (dl->source, dl->target, dl->mode); + } + if (res < 0) +- symlink_error (dl->source, dl->target); ++ error (0, errno, _("%s: Cannot create symlink to %s"), quotearg_colon (dl->target), quote_n (1, dl->source)); + else + { + if (!no_chown_flag) +@@ -789,7 +789,7 @@ copyin_link (struct cpio_file_stat *file_hdr, int in_file_des) + res = UMASKED_SYMLINK (link_name, file_hdr->c_name, file_hdr->c_mode); + } + if (res < 0) +- symlink_error (link_name, file_hdr->c_name); ++ error (0, errno, _("%s: Cannot create symlink to %s"), quotearg_colon (file_hdr->c_name), quote_n (1, link_name)); + else if (!no_chown_flag) + { + uid_t uid = set_owner_flag ? set_owner : file_hdr->c_uid; +-- +2.27.0 + diff --git a/backport-fix-operation-of-no-absolute-filenames-make-director.patch b/backport-fix-operation-of-no-absolute-filenames-make-director.patch new file mode 100644 index 0000000..43fede6 --- /dev/null +++ b/backport-fix-operation-of-no-absolute-filenames-make-director.patch @@ -0,0 +1,31 @@ +From e3cc782c610729de7622a274e532817c18262a9d Mon Sep 17 00:00:00 2001 +From: Sergey Poznyakoff +Date: Thu, 18 May 2023 09:00:12 +0300 +Subject: [PATCH] Fix operation of --no-absolute-filenames --make-directories + +* src/copyin.c (symlink_placeholder): Try to create leading +directories if unable to create placeholder. +--- + src/copyin.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/src/copyin.c b/src/copyin.c +index 1e4921f..08df12c 100644 +--- a/src/copyin.c ++++ b/src/copyin.c +@@ -668,6 +668,12 @@ symlink_placeholder (char *oldpath, char *newpath, struct cpio_file_stat *file_s + struct delayed_link *p; + size_t newlen = strlen (newpath); + ++ if (fd < 0 && create_dir_flag) ++ { ++ create_all_directories (newpath); ++ fd = open (newpath, O_WRONLY | O_CREAT | O_EXCL, 0); ++ } ++ + if (fd < 0) + { + open_error (newpath); +-- +2.27.0 + diff --git a/backport-restore-access-and-modification-times-of-symlinks.patch b/backport-restore-access-and-modification-times-of-symlinks.patch new file mode 100644 index 0000000..bbafe98 --- /dev/null +++ b/backport-restore-access-and-modification-times-of-symlinks.patch @@ -0,0 +1,981 @@ +From a3eb338a40750ecfd73de7054d44e69008866621 Mon Sep 17 00:00:00 2001 +From: Sergey Poznyakoff +Date: Wed, 17 May 2023 18:59:58 +0300 +Subject: [PATCH] Restore access and modification times of symlinks in copy-in + and copy-pass modes. + +* src/copyin.c: Update calls to set_file_times. +(copyin_link,replace_symlink_placeholders): Call set_file_times if needed. +* src/copyout.c: Update calls to set_file_times. +* src/copypass.c (process_copy_pass): Update calls to set_file_times. +Call set_file_times to restore times of extracted symlinks. +* src/extern.h (set_file_times): Take additional argument. +* src/util.c +(set_file_times): Take additional argument. Use fdutimensat to do the +job. +* tests/linktime.at: New file. +* tests/linktime01.at: New file. +* tests/Makefile.am: Add new files. +* tests/testsuite.at: Include new tests. +--- + src/copyin.c | 24 ++++++++++++----- + src/copyout.c | 4 +-- + src/copypass.c | 11 ++++++-- + src/extern.h | 2 +- + src/util.c | 7 ++--- + tests/Makefile.am | 4 ++- + tests/linktime.at | 63 +++++++++++++++++++++++++++++++++++++++++++++ + tests/linktime01.at | 51 ++++++++++++++++++++++++++++++++++++ + tests/testsuite.at | 3 +++ + 11 files changed, 155 insertions(+), 18 deletions(-) + create mode 100644 tests/linktime.at + create mode 100644 tests/linktime01.at + +diff --git a/gnu/Makefile.am b/gnu/Makefile.am +index d63397e..a208b30 100644 +--- a/gnu/Makefile.am ++++ b/gnu/Makefile.am +@@ -42,6 +42,7 @@ + # configmake \ + # dirname \ + # error \ ++# fdutimensat \ + # fileblocks \ + # fnmatch-gnu \ + # fseeko \ +@@ -71,7 +72,6 @@ + # strtoumax \ + # timespec \ + # unlocked-io \ +-# utimens \ + # utimensat \ + # version-etc-fsf \ + # xalloc \ +@@ -683,6 +683,14 @@ EXTRA_DIST += dirent-private.h + + ## end gnulib module fdopendir + ++## begin gnulib module fdutimensat ++ ++libgnu_a_SOURCES += fdutimensat.c ++ ++EXTRA_DIST += utimens.h ++ ++## end gnulib module fdutimensat ++ + ## begin gnulib module fileblocks + + if GL_COND_OBJ_FILEBLOCKS +@@ -863,6 +871,14 @@ libgnu_a_SOURCES += full-write.h full-write.c + + ## end gnulib module full-write + ++## begin gnulib module futimens ++ ++if GL_COND_OBJ_FUTIMENS ++libgnu_a_SOURCES += futimens.c ++endif ++ ++## end gnulib module futimens ++ + ## begin gnulib module gen-header + + # In 'sed', replace the pattern space with a "DO NOT EDIT" comment. +diff --git a/src/copyin.c b/src/copyin.c +index f2babb7..29ac764 100644 +--- a/src/copyin.c ++++ b/src/copyin.c +@@ -344,7 +344,7 @@ create_defered_links_to_skipped (struct cpio_file_stat *file_hdr, + empty links that are still on the deferments list. */ + + static void +-create_final_defers () ++create_final_defers (void) + { + struct deferment *d; + int link_res; +@@ -619,7 +619,7 @@ copyin_device (struct cpio_file_stat* file_hdr) + chmod_error_details (file_hdr->c_name, file_hdr->c_mode); + if (retain_time_flag) + set_file_times (-1, file_hdr->c_name, file_hdr->c_mtime, +- file_hdr->c_mtime); ++ file_hdr->c_mtime, 0); + } + + struct delayed_link +@@ -737,12 +737,18 @@ replace_symlink_placeholders (void) + } + if (res < 0) + symlink_error (dl->source, dl->target); +- else if (!no_chown_flag) ++ else + { +- uid_t uid = set_owner_flag ? set_owner : dl->uid; +- gid_t gid = set_group_flag ? set_group : dl->gid; +- if (lchown (dl->target, uid, gid) < 0 && errno != EPERM) +- chown_error_details (dl->target, uid, gid); ++ if (!no_chown_flag) ++ { ++ uid_t uid = set_owner_flag ? set_owner : dl->uid; ++ gid_t gid = set_group_flag ? set_group : dl->gid; ++ if (lchown (dl->target, uid, gid) < 0 && errno != EPERM) ++ chown_error_details (dl->target, uid, gid); ++ } ++ if (retain_time_flag) ++ set_file_times (-1, dl->target, dl->mtime, dl->mtime, ++ AT_SYMLINK_NOFOLLOW); + } + } + } +@@ -797,6 +803,10 @@ copyin_link (struct cpio_file_stat *file_hdr, int in_file_des) + if (lchown (file_hdr->c_name, uid, gid) < 0 && errno != EPERM) + chown_error_details (file_hdr->c_name, uid, gid); + } ++ ++ if (retain_time_flag) ++ set_file_times (-1, file_hdr->c_name, file_hdr->c_mtime, ++ file_hdr->c_mtime, AT_SYMLINK_NOFOLLOW); + } + free (link_name); + } +diff --git a/src/copyout.c b/src/copyout.c +index 6e82f4c..8fae895 100644 +--- a/src/copyout.c ++++ b/src/copyout.c +@@ -227,7 +227,7 @@ writeout_defered_file (struct cpio_file_stat *header, int out_file_des) + + if (reset_time_flag) + set_file_times (in_file_des, file_hdr.c_name, file_hdr.c_mtime, +- file_hdr.c_mtime); ++ file_hdr.c_mtime, 0); + if (close (in_file_des) < 0) + close_error (header->c_name); + } +@@ -725,7 +725,7 @@ process_copy_out (void) + if (reset_time_flag) + set_file_times (in_file_des, + orig_file_name, +- file_stat.st_atime, file_stat.st_mtime); ++ file_stat.st_atime, file_stat.st_mtime, 0); + if (close (in_file_des) < 0) + close_error (orig_file_name); + break; +diff --git a/src/copypass.c b/src/copypass.c +index a8280ae..09ffebb 100644 +--- a/src/copypass.c ++++ b/src/copypass.c +@@ -193,11 +193,13 @@ process_copy_pass (void) + set_file_times (in_file_des, + input_name.ds_string, + in_file_stat.st_atime, +- in_file_stat.st_mtime); ++ in_file_stat.st_mtime, ++ 0); + set_file_times (out_file_des, + output_name.ds_string, + in_file_stat.st_atime, +- in_file_stat.st_mtime); ++ in_file_stat.st_mtime, ++ 0); + } + + if (close (in_file_des) < 0) +@@ -300,6 +302,11 @@ process_copy_pass (void) + && errno != EPERM) + chown_error_details (output_name.ds_string, uid, gid); + } ++ ++ if (retain_time_flag) ++ set_file_times (-1, output_name.ds_string, ++ in_file_stat.st_atime, in_file_stat.st_mtime, ++ AT_SYMLINK_NOFOLLOW); + free (link_name); + } + #endif +diff --git a/src/extern.h b/src/extern.h +index 6afbdd2..d7c31b4 100644 +--- a/src/extern.h ++++ b/src/extern.h +@@ -204,7 +204,7 @@ void write_nuls_to_file (off_t num_bytes, int out_des, + + void set_perms (int fd, struct cpio_file_stat *header); + void set_file_times (int fd, const char *name, unsigned long atime, +- unsigned long mtime); ++ unsigned long mtime, int atflag); + void stat_to_cpio (struct cpio_file_stat *hdr, struct stat *st); + void cpio_to_stat (struct stat *st, struct cpio_file_stat *hdr); + void cpio_safer_name_suffix (char *name, bool link_target, +diff --git a/src/util.c b/src/util.c +index 7415e10..bc1ffb8 100644 +--- a/src/util.c ++++ b/src/util.c +@@ -1235,12 +1235,13 @@ set_perms (int fd, struct cpio_file_stat *header) + if (fchmod_or_chmod (fd, header->c_name, header->c_mode) < 0) + chmod_error_details (header->c_name, header->c_mode); + if (retain_time_flag) +- set_file_times (fd, header->c_name, header->c_mtime, header->c_mtime); ++ set_file_times (fd, header->c_name, header->c_mtime, header->c_mtime, 0); + } + + void + set_file_times (int fd, +- const char *name, unsigned long atime, unsigned long mtime) ++ const char *name, unsigned long atime, unsigned long mtime, ++ int atflag) + { + struct timespec ts[2]; + +@@ -1251,7 +1252,7 @@ set_file_times (int fd, + + /* Silently ignore EROFS because reading the file won't have upset its + timestamp if it's on a read-only filesystem. */ +- if (fdutimens (fd, name, ts) < 0 && errno != EROFS) ++ if (fdutimensat (fd, AT_FDCWD, name, ts, atflag) < 0 && errno != EROFS) + utime_error (name); + } + +diff --git a/tests/Makefile.am b/tests/Makefile.am +index 52503c9..28e259e 100644 +--- a/tests/Makefile.am ++++ b/tests/Makefile.am +@@ -57,7 +57,9 @@ TESTSUITE_AT = \ + version.at\ + big-block-size.at\ + CVE-2015-1197.at\ +- CVE-2019-14866.at ++ CVE-2019-14866.at\ ++ linktime.at\ ++ linktime01.at + + TESTSUITE = $(srcdir)/testsuite + +diff --git a/tests/testsuite.at b/tests/testsuite.at +index c58cbb7..4dd2afc 100644 +--- a/tests/testsuite.at ++++ b/tests/testsuite.at +@@ -45,3 +45,6 @@ m4_include([big-block-size.at]) + + m4_include([CVE-2015-1197.at]) + m4_include([CVE-2019-14866.at]) ++ ++m4_include([linktime.at]) ++m4_include([linktime01.at]) +diff --git a/m4/futimens.m4 b/m4/futimens.m4 +new file mode 100644 +index 0000000..dc0b21b +--- /dev/null ++++ b/m4/futimens.m4 +@@ -0,0 +1,69 @@ ++# serial 11 ++# See if we need to provide futimens replacement. ++ ++dnl Copyright (C) 2009-2023 Free Software Foundation, Inc. ++dnl This file is free software; the Free Software Foundation ++dnl gives unlimited permission to copy and/or distribute it, ++dnl with or without modifications, as long as this notice is preserved. ++ ++# Written by Eric Blake. ++ ++AC_DEFUN([gl_FUNC_FUTIMENS], ++[ ++ AC_REQUIRE([gl_SYS_STAT_H_DEFAULTS]) ++ AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles ++ AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS]) ++ gl_CHECK_FUNCS_ANDROID([futimens], [[#include ]]) ++ if test $ac_cv_func_futimens = no; then ++ HAVE_FUTIMENS=0 ++ case "$gl_cv_onwards_func_futimens" in ++ future*) REPLACE_FUTIMENS=1 ;; ++ esac ++ else ++ AC_CACHE_CHECK([whether futimens works], ++ [gl_cv_func_futimens_works], ++ [AC_RUN_IFELSE([AC_LANG_PROGRAM([[ ++#include ++#include ++#include ++#include ++]GL_MDA_DEFINES], ++ [[struct timespec ts[2]; ++ int fd = creat ("conftest.file", 0600); ++ struct stat st; ++ if (fd < 0) return 1; ++ ts[0].tv_sec = 1; ++ ts[0].tv_nsec = UTIME_OMIT; ++ ts[1].tv_sec = 1; ++ ts[1].tv_nsec = UTIME_NOW; ++ errno = 0; ++ if (futimens (AT_FDCWD, NULL) == 0) return 2; ++ if (errno != EBADF) return 3; ++ if (futimens (fd, ts)) return 4; ++ sleep (1); ++ ts[0].tv_nsec = UTIME_NOW; ++ ts[1].tv_nsec = UTIME_OMIT; ++ if (futimens (fd, ts)) return 5; ++ if (fstat (fd, &st)) return 6; ++ if (st.st_ctime < st.st_atime) return 7; ++ ]])], ++ [gl_cv_func_futimens_works=yes], ++ [gl_cv_func_futimens_works=no], ++ [case "$host_os" in ++ # Guess no on glibc systems. ++ *-gnu* | gnu*) gl_cv_func_futimens_works="guessing no" ;; ++ # Guess no on musl systems. ++ *-musl*) gl_cv_func_futimens_works="guessing no" ;; ++ # Guess yes otherwise. ++ *) gl_cv_func_futimens_works="guessing yes" ;; ++ esac ++ ]) ++ rm -f conftest.file]) ++ case "$gl_cv_func_futimens_works" in ++ *yes) ;; ++ *) ++ REPLACE_FUTIMENS=1 ++ ;; ++ esac ++ fi ++]) +diff --git a/tests/linktime.at b/tests/linktime.at +new file mode 100644 +index 0000000..bcee241 +--- /dev/null ++++ b/tests/linktime.at +@@ -0,0 +1,63 @@ ++# Process this file with autom4te to create testsuite. -*- Autotest -*- ++# Copyright (C) 2023 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 ++# the Free Software Foundation; either version 3, or (at your option) ++# any later version. ++ ++# This program is distributed in the hope that it will be useful, ++# but WITHOUT ANY WARRANTY; without even the implied warranty of ++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++# GNU General Public License for more details. ++ ++# You should have received a copy of the GNU General Public License along ++# with this program. If not, see . ++ ++AT_SETUP([restoring symlink times]) ++AT_KEYWORDS([linktime copyin copypass]) ++ ++AT_DATA([filelist],[file ++symlink ++]) ++ ++AT_DATA([filelist_rev],[symlink ++file ++]) ++ ++AT_CHECK( ++[mkdir dir ++cd dir ++genfile --file file ++ln -s file symlink || AT_SKIP_TEST ++genfile -th --date '2 days ago' symlink || AT_SKIP_TEST ++cd .. ++]) ++ ++AT_CHECK( ++[time_orig=$(genfile -h -Smtime dir/symlink) ++rm -f file symlink ++cpio -D dir --quiet -o < filelist > arc.cpio ++cpio -m --quiet -i < arc.cpio ++time=$(genfile -h -Smtime symlink) ++test "$time" -eq "$time_orig" ++]) ++ ++AT_CHECK( ++[time_orig=$(genfile -h -Smtime dir/symlink) ++rm -f file symlink ++cpio -D dir --quiet -o < filelist_rev > arc.cpio ++cpio -m --quiet -i < arc.cpio ++time=$(genfile -h -Smtime symlink) ++test "$time" -eq "$time_orig" ++]) ++ ++AT_CHECK( ++[time_orig=$(genfile -h -Smtime dir/symlink) ++rm -f file symlink ++cpio -D dir -m --quiet -p . < filelist ++time=$(genfile -h -Smtime symlink) ++test "$time" -eq "$time_orig" ++]) ++ ++AT_CLEANUP +diff --git a/tests/linktime01.at b/tests/linktime01.at +new file mode 100644 +index 0000000..9caa58f +--- /dev/null ++++ b/tests/linktime01.at +@@ -0,0 +1,51 @@ ++# Process this file with autom4te to create testsuite. -*- Autotest -*- ++# Copyright (C) 2023 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 ++# the Free Software Foundation; either version 3, or (at your option) ++# any later version. ++ ++# This program is distributed in the hope that it will be useful, ++# but WITHOUT ANY WARRANTY; without even the implied warranty of ++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++# GNU General Public License for more details. ++ ++# You should have received a copy of the GNU General Public License along ++# with this program. If not, see . ++ ++AT_SETUP([restoring delayed symlink times]) ++AT_KEYWORDS([linktime copyin]) ++ ++AT_CHECK( ++[mkdir dir ++genfile --file dir/file1 ++ln -s dir dirlink || AT_SKIP_TEST ++genfile -th --date '2 days ago' dirlink || AT_SKIP_TEST ++]) ++ ++AT_DATA([filelist], ++[dir ++dir/file1 ++dirlink ++]) ++ ++AT_CHECK( ++[time_orig=$(genfile -h -Smtime dirlink) ++cpio --quiet -o < filelist > arc.cpio ++mkdir extr ++cpio -D extr --quiet --no-absolute-filenames -m -i < arc.cpio ++find extr | sort ++time=$(genfile -h -Smtime extr/dirlink) ++test "$time" -eq "$time_orig" ++], ++[0], ++[extr ++extr/dir ++extr/dir/file1 ++extr/dirlink ++]) ++ ++AT_CLEANUP ++ ++ +diff --git a/m4/gnulib-comp.m4 b/m4/gnulib-comp.m4 +index ad10592..fa0c93e 100644 +--- a/m4/gnulib-comp.m4 ++++ b/m4/gnulib-comp.m4 +@@ -98,6 +98,7 @@ AC_DEFUN([gl_EARLY], + # Code from module fd-hook: + # Code from module fd-safer-flag: + # Code from module fdopendir: ++ # Code from module fdutimensat: + # Code from module fileblocks: + # Code from module filename: + # Code from module filenamecat-lgpl: +@@ -114,6 +115,7 @@ AC_DEFUN([gl_EARLY], + # Code from module fstat: + # Code from module fstatat: + # Code from module full-write: ++ # Code from module futimens: + # Code from module gen-header: + # Code from module getcwd: + # Code from module getcwd-lgpl: +@@ -411,6 +413,7 @@ AC_DEFUN([gl_INIT], + [test $HAVE_FDOPENDIR = 0 || test $REPLACE_FDOPENDIR = 1]) + gl_DIRENT_MODULE_INDICATOR([fdopendir]) + gl_MODULE_INDICATOR([fdopendir]) ++ gl_MODULE_INDICATOR([fdutimensat]) + gl_FILEBLOCKS + gl_CONDITIONAL([GL_COND_OBJ_FILEBLOCKS], + [test $ac_cv_member_struct_stat_st_blocks = no]) +@@ -475,6 +478,10 @@ AC_DEFUN([gl_INIT], + gl_CONDITIONAL([GL_COND_OBJ_FSTATAT], + [test $HAVE_FSTATAT = 0 || test $REPLACE_FSTATAT = 1]) + gl_SYS_STAT_MODULE_INDICATOR([fstatat]) ++ gl_FUNC_FUTIMENS ++ gl_CONDITIONAL([GL_COND_OBJ_FUTIMENS], ++ [test $HAVE_FUTIMENS = 0 || test $REPLACE_FUTIMENS = 1]) ++ gl_SYS_STAT_MODULE_INDICATOR([futimens]) + gl_FUNC_GETCWD + gl_CONDITIONAL([GL_COND_OBJ_GETCWD], [test $REPLACE_GETCWD = 1]) + AM_COND_IF([GL_COND_OBJ_GETCWD], [ +@@ -1278,6 +1285,7 @@ AC_DEFUN([gl_FILE_LIST], [ + lib/fd-safer-flag.c + lib/fd-safer.c + lib/fdopendir.c ++ lib/fdutimensat.c + lib/fileblocks.c + lib/filename.h + lib/filenamecat-lgpl.c +@@ -1298,6 +1306,7 @@ AC_DEFUN([gl_FILE_LIST], [ + lib/fstatat.c + lib/full-write.c + lib/full-write.h ++ lib/futimens.c + lib/getcwd-lgpl.c + lib/getcwd.c + lib/getdelim.c +@@ -1556,6 +1565,7 @@ AC_DEFUN([gl_FILE_LIST], [ + m4/fseeko.m4 + m4/fstat.m4 + m4/fstatat.m4 ++ m4/futimens.m4 + m4/getcwd-abort-bug.m4 + m4/getcwd-path-max.m4 + m4/getcwd.m4 +diff --git a/aclocal.m4 b/aclocal.m4 +index ce55bc1..d5bd65f 100644 +--- a/aclocal.m4 ++++ b/aclocal.m4 +@@ -1241,6 +1241,7 @@ m4_include([m4/fseek.m4]) + m4_include([m4/fseeko.m4]) + m4_include([m4/fstat.m4]) + m4_include([m4/fstatat.m4]) ++m4_include([m4/futimens.m4]) + m4_include([m4/getcwd-abort-bug.m4]) + m4_include([m4/getcwd-path-max.m4]) + m4_include([m4/getcwd.m4]) +diff --git a/gnu/fdutimensat.c b/gnu/fdutimensat.c +new file mode 100644 +index 0000000..5b801e0 +--- /dev/null ++++ b/gnu/fdutimensat.c +@@ -0,0 +1,57 @@ ++/* Set file access and modification times. ++ ++ Copyright (C) 2009-2023 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 the ++ Free Software Foundation, either version 3 of the License, or any ++ later version. ++ ++ This program is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ GNU General Public License for more details. ++ ++ You should have received a copy of the GNU General Public License ++ along with this program. If not, see . */ ++ ++/* Written by Eric Blake. */ ++ ++/* derived from a function in utimens.c */ ++ ++#include ++ ++#include "utimens.h" ++ ++#include ++#include ++#include ++ ++/* Set the access and modification timestamps of FD (a.k.a. FILE) to be ++ TIMESPEC[0] and TIMESPEC[1], respectively; relative to directory DIR. ++ FD must be either negative -- in which case it is ignored -- ++ or a file descriptor that is open on FILE. ++ If FD is nonnegative, then FILE can be NULL, which means ++ use just futimes (or equivalent) instead of utimes (or equivalent), ++ and fail if on an old system without futimes (or equivalent). ++ If TIMESPEC is null, set the timestamps to the current time. ++ ATFLAG is passed to utimensat if FD is negative or futimens was ++ unsupported, which can allow operation on FILE as a symlink. ++ Return 0 on success, -1 (setting errno) on failure. */ ++ ++int ++fdutimensat (int fd, int dir, char const *file, struct timespec const ts[2], ++ int atflag) ++{ ++ int result = 1; ++ if (0 <= fd) ++ result = futimens (fd, ts); ++ if (file && (fd < 0 || (result == -1 && errno == ENOSYS))) ++ result = utimensat (dir, file, ts, atflag); ++ if (result == 1) ++ { ++ errno = EBADF; ++ result = -1; ++ } ++ return result; ++} +diff --git a/gnu/futimens.c b/gnu/futimens.c +new file mode 100644 +index 0000000..5bb3049 +--- /dev/null ++++ b/gnu/futimens.c +@@ -0,0 +1,37 @@ ++/* Set the access and modification time of an open fd. ++ Copyright (C) 2009-2023 Free Software Foundation, Inc. ++ ++ This file is free software: you can redistribute it and/or modify ++ it under the terms of the GNU Lesser General Public License as ++ published by the Free Software Foundation, either version 3 of the ++ License, or (at your option) any later version. ++ ++ This file is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ GNU Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public License ++ along with this program. If not, see . */ ++ ++/* written by Eric Blake */ ++ ++#include ++ ++#include ++ ++#include "utimens.h" ++ ++/* Set the access and modification timestamps of FD to be ++ TIMESPEC[0] and TIMESPEC[1], respectively. ++ Fail with ENOSYS on systems without futimes (or equivalent). ++ If TIMESPEC is null, set the timestamps to the current time. ++ Return 0 on success, -1 (setting errno) on failure. */ ++int ++futimens (int fd, struct timespec const times[2]) ++{ ++ /* fdutimens also works around bugs in native futimens, when running ++ with glibc compiled against newer headers but on a Linux kernel ++ older than 2.6.32. */ ++ return fdutimens (fd, NULL, times); ++} +diff --git a/tests/genfile.c b/tests/genfile.c +index be4a2d3..0074c5c 100644 +--- a/tests/genfile.c ++++ b/tests/genfile.c +@@ -77,7 +77,8 @@ enum genfile_mode + mode_generate, + mode_sparse, + mode_stat, +- mode_exec ++ mode_exec, ++ mode_set_times + }; + + enum genfile_mode mode = mode_generate; +@@ -106,6 +107,9 @@ int verbose; + /* Quiet mode */ + int quiet; + ++/* Don't dereference symlinks (for --stat) */ ++int no_dereference_option; ++ + const char *argp_program_version = "genfile (" PACKAGE ") " VERSION; + const char *argp_program_bug_address = "<" PACKAGE_BUGREPORT ">"; + static char doc[] = N_("genfile manipulates data files for GNU paxutils test suite.\n" +@@ -155,6 +159,14 @@ static struct argp_option options[] = { + N_("Print contents of struct stat for each given file. Default FORMAT is: ") + DEFAULT_STAT_FORMAT, + GRP+1 }, ++ {"no-dereference", 'h', NULL, 0, ++ N_("stat symbolic links instead of referenced files"), ++ GRP+1 }, ++ ++ {"set-times", 't', NULL, 0, ++ N_("Set access and modification times of the files to the time supplied" ++ " by --date option"), ++ GRP+1 }, + + #undef GRP + #define GRP 20 +@@ -348,6 +360,14 @@ parse_opt (int key, char *arg, struct argp_state *state) + stat_format = arg; + break; + ++ case 't': ++ mode = mode_set_times; ++ break; ++ ++ case 'h': ++ no_dereference_option = 1; ++ break; ++ + case 'r': + mode = mode_exec; + checkpoint_granularity = arg ? arg : "1"; +@@ -647,7 +667,7 @@ print_stat (const char *name) + char *fmt, *p; + struct stat st; + +- if (stat (name, &st)) ++ if ((no_dereference_option ? lstat : stat) (name, &st)) + { + error (0, errno, _("stat(%s) failed"), name); + return; +@@ -725,6 +745,17 @@ print_stat (const char *name) + free (fmt); + } + ++void ++set_times (char const *name) ++{ ++ struct timespec ts[2]; ++ ++ ts[0] = ts[1] = touch_time; ++ if (utimensat (AT_FDCWD, name, ts, no_dereference_option ? AT_SYMLINK_NOFOLLOW : 0) != 0) ++ { ++ error (EXIT_FAILURE, errno, _("cannot set time on `%s'"), name); ++ } ++} + + /* Exec Mode */ + +@@ -740,7 +771,7 @@ exec_checkpoint (struct action *p) + struct timespec ts[2]; + + ts[0] = ts[1] = p->ts; +- if (utimensat (AT_FDCWD, p->name, ts, 0) != 0) ++ if (utimensat (AT_FDCWD, p->name, ts, no_dereference_option ? AT_SYMLINK_NOFOLLOW : 0) != 0) + { + error (0, errno, _("cannot set time on `%s'"), p->name); + break; +@@ -987,6 +1018,14 @@ main (int argc, char **argv) + print_stat (*argv++); + break; + ++ case mode_set_times: ++ if (argc == 0) ++ error (EXIT_USAGE, 0, _("--set-times requires file names")); ++ ++ while (argc--) ++ set_times (*argv++); ++ break; ++ + case mode_sparse: + generate_sparse_file (argc, argv); + verify_file (file_name); +diff --git a/tests/testsuite b/tests/testsuite +index 10531d1..442ab00 100755 +--- a/tests/testsuite ++++ b/tests/testsuite +@@ -625,6 +625,8 @@ at_help_all="1;version.at:19;cpio version;; + 13;big-block-size.at:17;big block size;block integer overflow; + 14;CVE-2015-1197.at:17;CVE-2015-1197 (--no-absolute-filenames for symlinks);; + 15;CVE-2019-14866.at:17;CVE-2019-14866 (tar header size overflow);; ++16;linktime.at:17;restoring symlink times;linktime copyin copypass; ++17;linktime01.at:17;restoring delayed symlink times;linktime copyin; + " + # List of the all the test groups. + at_groups_all=`printf "%s\n" "$at_help_all" | sed 's/;.*//'` +@@ -638,7 +640,7 @@ at_fn_validate_ranges () + for at_grp + do + eval at_value=\$$at_grp +- if test $at_value -lt 1 || test $at_value -gt 15; then ++ if test $at_value -lt 1 || test $at_value -gt 17; then + printf "%s\n" "invalid test group: $at_value" >&2 + exit 1 + fi +@@ -2940,3 +2942,209 @@ $at_traceon; } + ) 5>&1 2>&1 7>&- | eval $at_tee_pipe + read at_status <"$at_status_file" + #AT_STOP_15 ++#AT_START_16 ++at_fn_group_banner 16 'linktime.at:17' \ ++ "restoring symlink times" " " ++at_xfail=no ++( ++ printf "%s\n" "16. $at_setup_line: testing $at_desc ..." ++ $at_traceon ++ ++ ++ ++cat >filelist <<'_ATEOF' ++file ++symlink ++_ATEOF ++ ++ ++cat >filelist_rev <<'_ATEOF' ++symlink ++file ++_ATEOF ++ ++ ++{ set +x ++printf "%s\n" "$at_srcdir/linktime.at:28: mkdir dir ++cd dir ++genfile --file file ++ln -s file symlink || exit 77 ++genfile -th --date '2 days ago' symlink || exit 77 ++cd .. ++" ++at_fn_check_prepare_notrace 'an embedded newline' "linktime.at:28" ++( $at_check_trace; mkdir dir ++cd dir ++genfile --file file ++ln -s file symlink || exit 77 ++genfile -th --date '2 days ago' symlink || exit 77 ++cd .. ++ ++) >>"$at_stdout" 2>>"$at_stderr" 5>&- ++at_status=$? at_failed=false ++$at_check_filter ++at_fn_diff_devnull "$at_stderr" || at_failed=: ++at_fn_diff_devnull "$at_stdout" || at_failed=: ++at_fn_check_status 0 $at_status "$at_srcdir/linktime.at:28" ++$at_failed && at_fn_log_failure ++$at_traceon; } ++ ++ ++{ set +x ++printf "%s\n" "$at_srcdir/linktime.at:37: time_orig=\$(genfile -h -Smtime dir/symlink) ++rm -f file symlink ++cpio -D dir --quiet -o < filelist > arc.cpio ++cpio -m --quiet -i < arc.cpio ++time=\$(genfile -h -Smtime symlink) ++test \"\$time\" -eq \"\$time_orig\" ++" ++at_fn_check_prepare_notrace 'a $(...) command substitution' "linktime.at:37" ++( $at_check_trace; time_orig=$(genfile -h -Smtime dir/symlink) ++rm -f file symlink ++cpio -D dir --quiet -o < filelist > arc.cpio ++cpio -m --quiet -i < arc.cpio ++time=$(genfile -h -Smtime symlink) ++test "$time" -eq "$time_orig" ++ ++) >>"$at_stdout" 2>>"$at_stderr" 5>&- ++at_status=$? at_failed=false ++$at_check_filter ++at_fn_diff_devnull "$at_stderr" || at_failed=: ++at_fn_diff_devnull "$at_stdout" || at_failed=: ++at_fn_check_status 0 $at_status "$at_srcdir/linktime.at:37" ++$at_failed && at_fn_log_failure ++$at_traceon; } ++ ++ ++{ set +x ++printf "%s\n" "$at_srcdir/linktime.at:46: time_orig=\$(genfile -h -Smtime dir/symlink) ++rm -f file symlink ++cpio -D dir --quiet -o < filelist_rev > arc.cpio ++cpio -m --quiet -i < arc.cpio ++time=\$(genfile -h -Smtime symlink) ++test \"\$time\" -eq \"\$time_orig\" ++" ++at_fn_check_prepare_notrace 'a $(...) command substitution' "linktime.at:46" ++( $at_check_trace; time_orig=$(genfile -h -Smtime dir/symlink) ++rm -f file symlink ++cpio -D dir --quiet -o < filelist_rev > arc.cpio ++cpio -m --quiet -i < arc.cpio ++time=$(genfile -h -Smtime symlink) ++test "$time" -eq "$time_orig" ++ ++) >>"$at_stdout" 2>>"$at_stderr" 5>&- ++at_status=$? at_failed=false ++$at_check_filter ++at_fn_diff_devnull "$at_stderr" || at_failed=: ++at_fn_diff_devnull "$at_stdout" || at_failed=: ++at_fn_check_status 0 $at_status "$at_srcdir/linktime.at:46" ++$at_failed && at_fn_log_failure ++$at_traceon; } ++ ++ ++{ set +x ++printf "%s\n" "$at_srcdir/linktime.at:55: time_orig=\$(genfile -h -Smtime dir/symlink) ++rm -f file symlink ++cpio -D dir -m --quiet -p . < filelist ++time=\$(genfile -h -Smtime symlink) ++test \"\$time\" -eq \"\$time_orig\" ++" ++at_fn_check_prepare_notrace 'a $(...) command substitution' "linktime.at:55" ++( $at_check_trace; time_orig=$(genfile -h -Smtime dir/symlink) ++rm -f file symlink ++cpio -D dir -m --quiet -p . < filelist ++time=$(genfile -h -Smtime symlink) ++test "$time" -eq "$time_orig" ++ ++) >>"$at_stdout" 2>>"$at_stderr" 5>&- ++at_status=$? at_failed=false ++$at_check_filter ++at_fn_diff_devnull "$at_stderr" || at_failed=: ++at_fn_diff_devnull "$at_stdout" || at_failed=: ++at_fn_check_status 0 $at_status "$at_srcdir/linktime.at:55" ++$at_failed && at_fn_log_failure ++$at_traceon; } ++ ++ ++ set +x ++ $at_times_p && times >"$at_times_file" ++) 5>&1 2>&1 7>&- | eval $at_tee_pipe ++read at_status <"$at_status_file" ++#AT_STOP_16 ++#AT_START_17 ++at_fn_group_banner 17 'linktime01.at:17' \ ++ "restoring delayed symlink times" " " ++at_xfail=no ++( ++ printf "%s\n" "17. $at_setup_line: testing $at_desc ..." ++ $at_traceon ++ ++ ++ ++{ set +x ++printf "%s\n" "$at_srcdir/linktime01.at:20: mkdir dir ++genfile --file dir/file1 ++ln -s dir dirlink || exit 77 ++genfile -th --date '2 days ago' dirlink || exit 77 ++" ++at_fn_check_prepare_notrace 'an embedded newline' "linktime01.at:20" ++( $at_check_trace; mkdir dir ++genfile --file dir/file1 ++ln -s dir dirlink || exit 77 ++genfile -th --date '2 days ago' dirlink || exit 77 ++ ++) >>"$at_stdout" 2>>"$at_stderr" 5>&- ++at_status=$? at_failed=false ++$at_check_filter ++at_fn_diff_devnull "$at_stderr" || at_failed=: ++at_fn_diff_devnull "$at_stdout" || at_failed=: ++at_fn_check_status 0 $at_status "$at_srcdir/linktime01.at:20" ++$at_failed && at_fn_log_failure ++$at_traceon; } ++ ++ ++cat >filelist <<'_ATEOF' ++dir ++dir/file1 ++dirlink ++_ATEOF ++ ++ ++{ set +x ++printf "%s\n" "$at_srcdir/linktime01.at:33: time_orig=\$(genfile -h -Smtime dirlink) ++cpio --quiet -o < filelist > arc.cpio ++mkdir extr ++cpio -D extr --quiet --no-absolute-filenames -m -i < arc.cpio ++find extr | sort ++time=\$(genfile -h -Smtime extr/dirlink) ++test \"\$time\" -eq \"\$time_orig\" ++" ++at_fn_check_prepare_notrace 'a $(...) command substitution' "linktime01.at:33" ++( $at_check_trace; time_orig=$(genfile -h -Smtime dirlink) ++cpio --quiet -o < filelist > arc.cpio ++mkdir extr ++cpio -D extr --quiet --no-absolute-filenames -m -i < arc.cpio ++find extr | sort ++time=$(genfile -h -Smtime extr/dirlink) ++test "$time" -eq "$time_orig" ++ ++) >>"$at_stdout" 2>>"$at_stderr" 5>&- ++at_status=$? at_failed=false ++$at_check_filter ++at_fn_diff_devnull "$at_stderr" || at_failed=: ++echo >>"$at_stdout"; printf "%s\n" "extr ++extr/dir ++extr/dir/file1 ++extr/dirlink ++" | \ ++ $at_diff - "$at_stdout" || at_failed=: ++at_fn_check_status 0 $at_status "$at_srcdir/linktime01.at:33" ++$at_failed && at_fn_log_failure ++$at_traceon; } ++ ++ ++ set +x ++ $at_times_p && times >"$at_times_file" ++) 5>&1 2>&1 7>&- | eval $at_tee_pipe ++read at_status <"$at_status_file" ++#AT_STOP_17 diff --git a/cpio.spec b/cpio.spec index d9a4413..ba21910 100644 --- a/cpio.spec +++ b/cpio.spec @@ -1,6 +1,6 @@ Name: cpio Version: 2.14 -Release: 2 +Release: 3 Summary: A GNU archiving program License: GPLv3+ @@ -14,8 +14,9 @@ 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 -Patch7: revert-CVE-2015-1197-Fix-45b0ee2b407913c533f7ded8d6f8cbeec16ff6ca.patch -Patch8: revert-CVE-2015-1197.patch +Patch7: backport-restore-access-and-modification-times-of-symlinks.patch +Patch8: backport-fix-operation-of-no-absolute-filenames-make-director.patch +Patch9: backport-Do-not-set-exit-code-to-2-when-failing-to-create-symlink.patch Patch9000: add-option-to-add-metadata-in-copy-out-mode.patch Patch9001: Fix-use-after-free-and-return-appropriate-error.patch @@ -61,6 +62,12 @@ make check %{_datadir}/man/man1/%{name}.1.gz %changelog +* Mon Aug 21 2023 fuanan - 2.14-3 +- Type:CVE +- ID:CVE-2015-1197 +- SUG:NA +- DESC:Fix CVE-2015-1197 + * Wed Jul 26 2023 zhangruifang - 2.14-2 - Type:bugfix - ID:NA diff --git a/revert-CVE-2015-1197-Fix-45b0ee2b407913c533f7ded8d6f8cbeec16ff6ca.patch b/revert-CVE-2015-1197-Fix-45b0ee2b407913c533f7ded8d6f8cbeec16ff6ca.patch deleted file mode 100644 index 16e8401..0000000 --- a/revert-CVE-2015-1197-Fix-45b0ee2b407913c533f7ded8d6f8cbeec16ff6ca.patch +++ /dev/null @@ -1,218 +0,0 @@ -From a365d052b01a5df1ffe716ee8af3e71ee15836fa Mon Sep 17 00:00:00 2001 -From: zhangruifang2020 -Date: Mon, 17 Jul 2023 11:39:03 +0800 -Subject: [PATCH] revert Fix 45b0ee2b407913c533f7ded8d6f8cbeec16ff6ca - ---- - src/copyin.c | 173 +++++++-------------------------------------------- - 1 file changed, 22 insertions(+), 151 deletions(-) - -diff --git a/src/copyin.c b/src/copyin.c -index f2babb7..2316feb 100644 ---- a/src/copyin.c -+++ b/src/copyin.c -@@ -30,7 +30,6 @@ - #ifndef FNM_PATHNAME - # include - #endif --#include - - #ifndef HAVE_LCHOWN - # define lchown(f,u,g) 0 -@@ -622,136 +621,6 @@ copyin_device (struct cpio_file_stat* file_hdr) - file_hdr->c_mtime); - } - --struct delayed_link -- { -- /* The device and inode number of the placeholder. */ -- dev_t dev; -- ino_t ino; -- -- /* The desired link metadata. */ -- mode_t mode; -- uid_t uid; -- gid_t gid; -- time_t mtime; -- -- /* Link source and target names. */ -- char *source; -- char target[1]; -- }; -- --static Hash_table *delayed_link_table; -- --static size_t --dl_hash (void const *entry, size_t table_size) --{ -- struct delayed_link const *dl = entry; -- uintmax_t n = dl->dev; -- int nshift = (sizeof (n) - sizeof (dl->dev)) * CHAR_BIT; -- if (0 < nshift) -- n <<= nshift; -- n ^= dl->ino; -- return n % table_size; --} -- --static bool --dl_compare (void const *a, void const *b) --{ -- struct delayed_link const *da = a, *db = b; -- return (da->dev == db->dev) & (da->ino == db->ino); --} -- --static int --symlink_placeholder (char *oldpath, char *newpath, struct cpio_file_stat *file_stat) --{ -- int fd = open (newpath, O_WRONLY | O_CREAT | O_EXCL, 0); -- struct stat st; -- struct delayed_link *p; -- size_t newlen = strlen (newpath); -- -- if (fd < 0) -- { -- open_error (newpath); -- return -1; -- } -- -- if (fstat (fd, &st) != 0) -- { -- stat_error (newpath); -- close (fd); -- return -1; -- } -- -- close (fd); -- -- p = xmalloc (sizeof (*p) + strlen (oldpath) + newlen + 1); -- p->dev = st.st_dev; -- p->ino = st.st_ino; -- -- p->mode = file_stat->c_mode; -- p->uid = file_stat->c_uid; -- p->gid = file_stat->c_gid; -- p->mtime = file_stat->c_mtime; -- -- strcpy (p->target, newpath); -- p->source = p->target + newlen + 1; -- strcpy (p->source, oldpath); -- -- if (!((delayed_link_table -- || (delayed_link_table = hash_initialize (0, 0, dl_hash, -- dl_compare, free))) -- && hash_insert (delayed_link_table, p))) -- xalloc_die (); -- -- return 0; --} -- --static void --replace_symlink_placeholders (void) --{ -- struct delayed_link *dl; -- -- if (!delayed_link_table) -- return; -- for (dl = hash_get_first (delayed_link_table); -- dl; -- dl = hash_get_next (delayed_link_table, dl)) -- { -- struct stat st; -- -- /* Make sure the placeholder file is still there. If not, -- don't create a link, as the placeholder was probably -- removed by a later extraction. */ -- if (lstat (dl->target, &st) == 0 -- && st.st_dev == dl->dev -- && st.st_ino == dl->ino) -- { -- if (unlink (dl->target)) -- unlink_error (dl->target); -- else -- { -- int res = UMASKED_SYMLINK (dl->source, dl->target, dl->mode); -- if (res < 0 && create_dir_flag) -- { -- create_all_directories (dl->target); -- res = UMASKED_SYMLINK (dl->source, dl->target, dl->mode); -- } -- if (res < 0) -- symlink_error (dl->source, dl->target); -- else if (!no_chown_flag) -- { -- uid_t uid = set_owner_flag ? set_owner : dl->uid; -- gid_t gid = set_group_flag ? set_group : dl->gid; -- if (lchown (dl->target, uid, gid) < 0 && errno != EPERM) -- chown_error_details (dl->target, uid, gid); -- } -- } -- } -- } -- -- hash_free (delayed_link_table); -- delayed_link_table = NULL; --} -- - static void - copyin_link (struct cpio_file_stat *file_hdr, int in_file_des) - { -@@ -777,26 +646,29 @@ copyin_link (struct cpio_file_stat *file_hdr, int in_file_des) - link_name = xstrdup (file_hdr->c_tar_linkname); - } - -- if (no_abs_paths_flag) -- symlink_placeholder (link_name, file_hdr->c_name, file_hdr); -- else -+ cpio_safer_name_suffix (link_name, true, !no_abs_paths_flag, false); -+ -+ res = UMASKED_SYMLINK (link_name, file_hdr->c_name, -+ file_hdr->c_mode); -+ if (res < 0 && create_dir_flag) - { -- res = UMASKED_SYMLINK (link_name, file_hdr->c_name, -- file_hdr->c_mode); -- if (res < 0 && create_dir_flag) -- { -- create_all_directories (file_hdr->c_name); -- res = UMASKED_SYMLINK (link_name, file_hdr->c_name, file_hdr->c_mode); -- } -- if (res < 0) -- symlink_error (link_name, file_hdr->c_name); -- else if (!no_chown_flag) -- { -- uid_t uid = set_owner_flag ? set_owner : file_hdr->c_uid; -- gid_t gid = set_group_flag ? set_group : file_hdr->c_gid; -- if (lchown (file_hdr->c_name, uid, gid) < 0 && errno != EPERM) -- chown_error_details (file_hdr->c_name, uid, gid); -- } -+ create_all_directories (file_hdr->c_name); -+ res = UMASKED_SYMLINK (link_name, file_hdr->c_name, file_hdr->c_mode); -+ } -+ if (res < 0) -+ { -+ error (0, errno, _("%s: Cannot symlink to %s"), -+ quotearg_colon (link_name), quote_n (1, file_hdr->c_name)); -+ free (link_name); -+ return; -+ } -+ if (!no_chown_flag) -+ { -+ uid_t uid = set_owner_flag ? set_owner : file_hdr->c_uid; -+ gid_t gid = set_group_flag ? set_group : file_hdr->c_gid; -+ if ((lchown (file_hdr->c_name, uid, gid) < 0) -+ && errno != EPERM) -+ chown_error_details (file_hdr->c_name, uid, gid); - } - free (link_name); - } -@@ -1577,7 +1449,6 @@ process_copy_in (void) - if (dot_flag) - fputc ('\n', stderr); - -- replace_symlink_placeholders (); - apply_delayed_set_stat (); - - cpio_file_stat_free (&file_hdr); --- -2.27.0 - diff --git a/revert-CVE-2015-1197.patch b/revert-CVE-2015-1197.patch deleted file mode 100644 index 3019575..0000000 --- a/revert-CVE-2015-1197.patch +++ /dev/null @@ -1,109 +0,0 @@ -From 250cae97153b438f5644e5d96814a7f5cb8c80e5 Mon Sep 17 00:00:00 2001 -From: Liquor -Date: Thu, 26 Nov 2020 19:13:13 +0800 -Subject: [PATCH] revert "CVE-2015-1197" - -reason: -https://lists.gnu.org/archive/html/bug-cpio/2019-11/msg00016.html -https://lists.gnu.org/archive/html/bug-cpio/2019-11/msg00013.html - ---- - src/copyin.c | 5 ++--- - tests/CVE-2015-1197.at | 40 ---------------------------------------- - tests/Makefile.am | 1 - - tests/testsuite.at | 1 - - 4 files changed, 2 insertions(+), 45 deletions(-) - delete mode 100644 tests/CVE-2015-1197.at - -diff --git a/src/copyin.c b/src/copyin.c -index 2316feb..3960769 100644 ---- a/src/copyin.c -+++ b/src/copyin.c -@@ -646,14 +646,13 @@ copyin_link (struct cpio_file_stat *file_hdr, int in_file_des) - link_name = xstrdup (file_hdr->c_tar_linkname); - } - -- cpio_safer_name_suffix (link_name, true, !no_abs_paths_flag, false); -- - res = UMASKED_SYMLINK (link_name, file_hdr->c_name, - file_hdr->c_mode); - if (res < 0 && create_dir_flag) - { - create_all_directories (file_hdr->c_name); -- res = UMASKED_SYMLINK (link_name, file_hdr->c_name, file_hdr->c_mode); -+ res = UMASKED_SYMLINK (link_name, file_hdr->c_name, -+ file_hdr->c_mode); - } - if (res < 0) - { -diff --git a/tests/CVE-2015-1197.at b/tests/CVE-2015-1197.at -deleted file mode 100644 -index 74591b1..0000000 ---- a/tests/CVE-2015-1197.at -+++ /dev/null -@@ -1,40 +0,0 @@ --# Process this file with autom4te to create testsuite. -*- Autotest -*- --# Copyright (C) 2009-2023 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 --# the Free Software Foundation; either version 3, or (at your option) --# any later version. --# --# This program is distributed in the hope that it will be useful, --# but WITHOUT ANY WARRANTY; without even the implied warranty of --# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --# GNU General Public License for more details. --# --# You should have received a copy of the GNU General Public License --# along with this program. If not, see . -- --AT_SETUP([CVE-2015-1197 (--no-absolute-filenames for symlinks)]) --AT_CHECK([ --tempdir=$(pwd)/tmp --mkdir $tempdir --touch $tempdir/file --ln -s $tempdir dir --AT_DATA([filelist], --[dir --dir/file --]) --cpio -o < filelist > test.cpio --rm -rf dir $tempdir --cpio --no-absolute-filenames -iv < test.cpio --], --[2], --[], --[1 block --dir --cpio: dir/file: Cannot open: Not a directory --dir/file --1 block --]) --AT_CLEANUP -- -diff --git a/tests/Makefile.am b/tests/Makefile.am -index 52503c9..022a856 100644 ---- a/tests/Makefile.am -+++ b/tests/Makefile.am -@@ -56,7 +56,6 @@ TESTSUITE_AT = \ - symlink-to-stdout.at\ - version.at\ - big-block-size.at\ -- CVE-2015-1197.at\ - CVE-2019-14866.at - - TESTSUITE = $(srcdir)/testsuite -diff --git a/tests/testsuite.at b/tests/testsuite.at -index c58cbb7..da3ba75 100644 ---- a/tests/testsuite.at -+++ b/tests/testsuite.at -@@ -43,5 +43,4 @@ m4_include([setstat04.at]) - m4_include([setstat05.at]) - m4_include([big-block-size.at]) - --m4_include([CVE-2015-1197.at]) - m4_include([CVE-2019-14866.at]) --- -2.27.0 -