summaryrefslogtreecommitdiffstats
path: root/meta/recipes-extended/cpio/cpio-2.11/cpio-CVE-2015-1197.patch
blob: b54afb867feea43f2a61b0ff617d1dc391185a24 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
Description: 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: Backport

Signed-off-by: Robert Yang <liezhi.yang@windriver.com>

--- cpio-2.11+dfsg.orig/doc/cpio.1
+++ cpio-2.11+dfsg/doc/cpio.1
@@ -22,6 +22,7 @@ cpio \- copy files to and from archives
 [\-\-owner=[user][:.][group]] [\-\-no-preserve-owner] [\-\-message=message]
 [\-\-force\-local] [\-\-no\-absolute\-filenames] [\-\-sparse]
 [\-\-only\-verify\-crc] [\-\-to\-stdout] [\-\-quiet] [\-\-rsh-command=command]
+[\-\-extract\-over\-symlinks]
 [\-\-help] [\-\-version] [pattern...] [< archive]
 
 .B cpio
--- cpio-2.11+dfsg.orig/src/copyin.c
+++ cpio-2.11+dfsg/src/copyin.c
@@ -700,6 +700,51 @@ copyin_link (struct cpio_file_stat *file
   free (link_name);
 }
 
+
+static int
+path_contains_symlink(char *path)
+{
+  struct stat st;
+  char *slash;
+  char *nextslash;
+
+  /* we got NULL pointer or empty string */
+  if (!path || !*path) {
+    return false;
+  }
+
+  slash = path;
+
+  while ((nextslash = strchr(slash + 1, '/')) != NULL) {
+    slash = nextslash;
+    *slash = '\0';
+
+    if (lstat(path, &st) != 0) {
+      if (errno == ELOOP) {
+        /* ELOOP - too many symlinks */
+        *slash = '/';
+        return true;
+      } else if (errno == ENOMEM) {
+        /* No memory for lstat - terminate */
+        xalloc_die();
+      } else {
+        /* cannot lstat path - give up */
+        *slash = '/';
+        return false;
+      }
+    }
+
+    if (S_ISLNK(st.st_mode)) {
+      *slash = '/';
+      return true;
+    }
+
+    *slash = '/';
+  }
+
+  return false;
+}
+
 static void
 copyin_file (struct cpio_file_stat *file_hdr, int in_file_des)
 {
@@ -1471,6 +1516,23 @@ process_copy_in ()
 	{
 	  /* Copy the input file into the directory structure.  */
 
+          /* Can we write files over symlinks? */
+          if (!extract_over_symlinks)
+            {
+              if (path_contains_symlink(file_hdr.c_name))
+                {
+                  /* skip the file */
+                  /*
+                  fprintf(stderr, "Can't write over symlinks. Skipping %s\n", file_hdr.c_name);
+                  tape_toss_input (in_file_des, file_hdr.c_filesize);
+                  tape_skip_padding (in_file_des, file_hdr.c_filesize);
+                  continue;
+                  */
+                  /* terminate */
+	          error (1, 0, _("Can't write over symlinks: %s\n"), file_hdr.c_name);
+                }
+            }
+
 	  /* Do we need to rename the file? */
 	  if (rename_flag || rename_batch_file)
 	    {
--- cpio-2.11+dfsg.orig/src/extern.h
+++ cpio-2.11+dfsg/src/extern.h
@@ -95,6 +95,7 @@ extern char input_is_special;
 extern char output_is_special;
 extern char input_is_seekable;
 extern char output_is_seekable;
+extern bool extract_over_symlinks;
 extern int (*xstat) ();
 extern void (*copy_function) ();
 
--- cpio-2.11+dfsg.orig/src/global.c
+++ cpio-2.11+dfsg/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) ();
--- cpio-2.11+dfsg.orig/src/main.c
+++ cpio-2.11+dfsg/src/main.c
@@ -57,7 +57,8 @@ enum cpio_options {
   FORCE_LOCAL_OPTION,            
   DEBUG_OPTION,                  
   BLOCK_SIZE_OPTION,             
-  TO_STDOUT_OPTION
+  TO_STDOUT_OPTION,
+  EXTRACT_OVER_SYMLINKS
 };
 
 const char *program_authors[] =
@@ -222,6 +223,8 @@ static struct argp_option options[] = {
    N_("Create leading directories where needed"), GRID+1 },
   {"no-preserve-owner", NO_PRESERVE_OWNER_OPTION, 0, 0,
    N_("Do not change the ownership of the files"), GRID+1 },
+  {"extract-over-symlinks", EXTRACT_OVER_SYMLINKS, 0, 0,
+   N_("Force writing over symbolic links"), GRID+1 },
   {"unconditional", 'u', NULL, 0,
    N_("Replace all files unconditionally"), GRID+1 },
   {"sparse", SPARSE_OPTION, NULL, 0,
@@ -412,6 +415,10 @@ crc newc odc bin ustar tar (all-caps als
       no_chown_flag = true;
       break;
 
+    case EXTRACT_OVER_SYMLINKS:		        /* --extract-over-symlinks */
+      extract_over_symlinks = true;
+      break;
+
     case 'o':		/* Copy-out mode.  */
       if (copy_function != 0)
 	error (PAXEXIT_FAILURE, 0, _("Mode already defined"));