generic-poky/meta/recipes-extended/cpio/cpio-2.12/0001-Fix-CVE-2015-1197.patch

179 lines
5.3 KiB
Diff
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

From dcee489f821c1260a0136fcdfdb6ff4dd11086ac Mon Sep 17 00:00:00 2001
From: Alexander Kanavin <alex.kanavin@gmail.com>
Date: Wed, 9 Dec 2015 17:58:03 +0200
Subject: [PATCH] Fix CVE-2015-1197
Apply patch by Vitezslav Cizek of SuSE to fix CVE-2015-1197.
Upstream is dormant or no longer existing. To restore the old
behaviour use --extract-over-symlinks (Closes: #774669)
This issue has been discovered by Alexander Cherepanov.
Author: Vitezslav Cizek <vcizek@suse.cz>
Bug-Debian: https://bugs.debian.org/774669
Upstream-Status: Pending
CVE: CVE-2015-1197
Signed-off-by: Robert Yang <liezhi.yang@windriver.com>
Signed-off-by: Alexander Kanavin <alex.kanavin@gmail.com>
---
doc/cpio.1 | 1 +
src/copyin.c | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
src/extern.h | 1 +
src/global.c | 3 +++
src/main.c | 7 +++++++
5 files changed, 74 insertions(+)
diff --git a/doc/cpio.1 b/doc/cpio.1
index 2a68241..dc4676c 100644
--- a/doc/cpio.1
+++ b/doc/cpio.1
@@ -49,6 +49,7 @@ cpio \- copy files to and from archives
[\fB\-\-no\-preserve\-owner\fR] [\fB\-\-message=\fIMESSAGE\fR]
[\fB\-\-force\-local\fR] [\fB\-\-no\-absolute\-filenames\fR] [\fB\-\-sparse\fR]
[\fB\-\-only\-verify\-crc\fR] [\fB\-\-to\-stdout\fR] [\fB\-\-quiet\fR]
+[\fB\-\-extract\-over\-symlinks\fR]
[\fB\-\-rsh\-command=\fICOMMAND\fR]
[\fIpattern\fR...] [\fB<\fR \fIarchive\fR]
diff --git a/src/copyin.c b/src/copyin.c
index cde911e..053afe7 100644
--- a/src/copyin.c
+++ b/src/copyin.c
@@ -695,6 +695,51 @@ copyin_link (struct cpio_file_stat *file_hdr, int in_file_des)
free (link_name);
}
+
+static int
+path_contains_symlink(char *path)
+{
+ struct stat st;
+ char *slash;
+ char *nextslash;
+
+ /* we got NULL pointer or empty string */
+ if (!path || !*path) {
+ return false;
+ }
+
+ slash = path;
+
+ while ((nextslash = strchr(slash + 1, '/')) != NULL) {
+ slash = nextslash;
+ *slash = '\0';
+
+ if (lstat(path, &st) != 0) {
+ if (errno == ELOOP) {
+ /* ELOOP - too many symlinks */
+ *slash = '/';
+ return true;
+ } else if (errno == ENOMEM) {
+ /* No memory for lstat - terminate */
+ xalloc_die();
+ } else {
+ /* cannot lstat path - give up */
+ *slash = '/';
+ return false;
+ }
+ }
+
+ if (S_ISLNK(st.st_mode)) {
+ *slash = '/';
+ return true;
+ }
+
+ *slash = '/';
+ }
+
+ return false;
+}
+
static void
copyin_file (struct cpio_file_stat *file_hdr, int in_file_des)
{
@@ -1468,6 +1513,23 @@ process_copy_in ()
{
/* Copy the input file into the directory structure. */
+ /* Can we write files over symlinks? */
+ if (!extract_over_symlinks)
+ {
+ if (path_contains_symlink(file_hdr.c_name))
+ {
+ /* skip the file */
+ /*
+ fprintf(stderr, "Can't write over symlinks. Skipping %s\n", file_hdr.c_name);
+ tape_toss_input (in_file_des, file_hdr.c_filesize);
+ tape_skip_padding (in_file_des, file_hdr.c_filesize);
+ continue;
+ */
+ /* terminate */
+ error (1, 0, _("Can't write over symlinks: %s\n"), file_hdr.c_name);
+ }
+ }
+
/* Do we need to rename the file? */
if (rename_flag || rename_batch_file)
{
diff --git a/src/extern.h b/src/extern.h
index e27d662..d864bde 100644
--- a/src/extern.h
+++ b/src/extern.h
@@ -96,6 +96,7 @@ extern char input_is_special;
extern char output_is_special;
extern char input_is_seekable;
extern char output_is_seekable;
+extern bool extract_over_symlinks;
extern int (*xstat) ();
extern void (*copy_function) ();
extern char *change_directory_option;
diff --git a/src/global.c b/src/global.c
index 57e505a..336fce4 100644
--- a/src/global.c
+++ b/src/global.c
@@ -187,6 +187,9 @@ bool to_stdout_option = false;
/* The name this program was run with. */
char *program_name;
+/* Extract files over symbolic links */
+bool extract_over_symlinks;
+
/* A pointer to either lstat or stat, depending on whether
dereferencing of symlinks is done for input files. */
int (*xstat) ();
diff --git a/src/main.c b/src/main.c
index a13861f..87cb309 100644
--- a/src/main.c
+++ b/src/main.c
@@ -59,6 +59,7 @@ enum cpio_options {
DEBUG_OPTION,
BLOCK_SIZE_OPTION,
TO_STDOUT_OPTION,
+ EXTRACT_OVER_SYMLINKS,
RENUMBER_INODES_OPTION,
IGNORE_DEVNO_OPTION,
DEVICE_INDEPENDENT_OPTION
@@ -243,6 +244,8 @@ static struct argp_option options[] = {
N_("Create leading directories where needed"), GRID+1 },
{"no-preserve-owner", NO_PRESERVE_OWNER_OPTION, 0, 0,
N_("Do not change the ownership of the files"), GRID+1 },
+ {"extract-over-symlinks", EXTRACT_OVER_SYMLINKS, 0, 0,
+ N_("Force writing over symbolic links"), GRID+1 },
{"unconditional", 'u', NULL, 0,
N_("Replace all files unconditionally"), GRID+1 },
{"sparse", SPARSE_OPTION, NULL, 0,
@@ -432,6 +435,10 @@ crc newc odc bin ustar tar (all-caps also recognized)"), arg));
no_chown_flag = true;
break;
+ case EXTRACT_OVER_SYMLINKS: /* --extract-over-symlinks */
+ extract_over_symlinks = true;
+ break;
+
case 'o': /* Copy-out mode. */
if (copy_function != 0)
USAGE_ERROR ((0, 0, _("Mode already defined")));
--
2.6.2