Magellan Linux

Annotation of /trunk/cpio/patches/cpio-2.6-security_fixes-1.patch

Parent Directory Parent Directory | Revision Log Revision Log


Revision 144 - (hide annotations) (download)
Tue May 8 20:06:05 2007 UTC (17 years, 1 month ago) by niro
File size: 12970 byte(s)
-import

1 niro 144 Submitted By: Ken Moffat <ken@kenmoffat.uklinux.net>
2     Date: 2005-07-29
3     Initial Package Version: 2.6
4     Upstream Status: Unknown
5     Origin: from Mandrake
6     Description: Vulnerability fixes, rediffed so that they all apply with
7     -p1 and consolidated to single patch. Also applicable to earlier versions.
8     (1.) CAN-1999-1572 (still seems to apply to 2.6) cpio uses a 0 umask when
9     creating files with -O or -F options, which creates the files with mode 0666
10     and allows local users to overwrite them. Fix originally fom debian.
11     (2.) CAN-2005-1111 Race condition in 2.6 and earlier allows local users to
12     modify permissions of arbitrary files via a hard-link attack. Fix
13     originally from fedora.
14     (3.) CAN-2005-1229 Directory traversal vulnerability allows remote
15     attackers to write to arbitrary directories via a dot dot in a cpio file.
16     Fix by Peter Vrabec at RedHat.
17    
18     diff -Naur cpio-2.6.vanilla/doc/cpio.1 cpio-2.6/doc/cpio.1
19     --- cpio-2.6.vanilla/doc/cpio.1 2004-08-30 17:21:48.000000000 +0100
20     +++ cpio-2.6/doc/cpio.1 2005-07-29 13:46:42.000000000 +0100
21     @@ -20,7 +20,7 @@
22     [\-\-unconditional] [\-\-verbose] [\-\-block-size=blocks] [\-\-swap-halfwords]
23     [\-\-io-size=bytes] [\-\-pattern-file=file] [\-\-format=format]
24     [\-\-owner=[user][:.][group]] [\-\-no-preserve-owner] [\-\-message=message]
25     -[\-\-force\-local] [\-\-no\-absolute\-filenames] [\-\-sparse]
26     +[\-\-force\-local] [\-\-absolute\-filenames] [\-\-sparse]
27     [\-\-only\-verify\-crc] [\-\-quiet] [\-\-rsh-command=command] [\-\-help]
28     [\-\-version] [pattern...] [< archive]
29    
30     diff -Naur cpio-2.6.vanilla/doc/cpio.info cpio-2.6/doc/cpio.info
31     --- cpio-2.6.vanilla/doc/cpio.info 2004-02-27 12:42:01.000000000 +0000
32     +++ cpio-2.6/doc/cpio.info 2005-07-29 13:46:42.000000000 +0100
33     @@ -203,7 +203,7 @@
34     [--swap-halfwords] [--io-size=bytes] [--pattern-file=file]
35     [--format=format] [--owner=[user][:.][group]]
36     [--no-preserve-owner] [--message=message] [--help] [--version]
37     - [-no-absolute-filenames] [--sparse] [-only-verify-crc] [-quiet]
38     + [--absolute-filenames] [--sparse] [-only-verify-crc] [-quiet]
39     [--rsh-command=command] [pattern...] [< archive]
40    
41     
42     @@ -358,9 +358,9 @@
43     Show numeric UID and GID instead of translating them into names
44     when using the `--verbose option'.
45    
46     -`--no-absolute-filenames'
47     - Create all files relative to the current directory in copy-in
48     - mode, even if they have an absolute file name in the archive.
49     +`--absolute-filenames'
50     + Do not strip leading file name components that contain ".."
51     + and leading slashes from file names in copy-in mode
52    
53     `--no-preserve-owner'
54     Do not change the ownership of the files; leave them owned by the
55     diff -Naur cpio-2.6.vanilla/src/copyin.c cpio-2.6/src/copyin.c
56     --- cpio-2.6.vanilla/src/copyin.c 2004-09-08 12:10:02.000000000 +0100
57     +++ cpio-2.6/src/copyin.c 2005-07-29 13:46:42.000000000 +0100
58     @@ -25,6 +25,7 @@
59     #include "dstring.h"
60     #include "extern.h"
61     #include "defer.h"
62     +#include "dirname.h"
63     #include <rmt.h>
64     #ifndef FNM_PATHNAME
65     #include <fnmatch.h>
66     @@ -389,19 +390,26 @@
67     continue;
68     }
69    
70     - if (close (out_file_des) < 0)
71     - error (0, errno, "%s", d->header.c_name);
72     -
73     + /*
74     + * Avoid race condition.
75     + * Set chown and chmod before closing the file desc.
76     + * pvrabec@redhat.com
77     + */
78     +
79     /* File is now copied; set attributes. */
80     if (!no_chown_flag)
81     - if ((chown (d->header.c_name,
82     + if ((fchown (out_file_des,
83     set_owner_flag ? set_owner : d->header.c_uid,
84     set_group_flag ? set_group : d->header.c_gid) < 0)
85     && errno != EPERM)
86     error (0, errno, "%s", d->header.c_name);
87     /* chown may have turned off some permissions we wanted. */
88     - if (chmod (d->header.c_name, (int) d->header.c_mode) < 0)
89     + if (fchmod (out_file_des, (int) d->header.c_mode) < 0)
90     error (0, errno, "%s", d->header.c_name);
91     +
92     + if (close (out_file_des) < 0)
93     + error (0, errno, "%s", d->header.c_name);
94     +
95     if (retain_time_flag)
96     {
97     times.actime = times.modtime = d->header.c_mtime;
98     @@ -557,6 +565,25 @@
99     write (out_file_des, "", 1);
100     delayed_seek_count = 0;
101     }
102     +
103     + /*
104     + * Avoid race condition.
105     + * Set chown and chmod before closing the file desc.
106     + * pvrabec@redhat.com
107     + */
108     +
109     + /* File is now copied; set attributes. */
110     + if (!no_chown_flag)
111     + if ((fchown (out_file_des,
112     + set_owner_flag ? set_owner : file_hdr->c_uid,
113     + set_group_flag ? set_group : file_hdr->c_gid) < 0)
114     + && errno != EPERM)
115     + error (0, errno, "%s", file_hdr->c_name);
116     +
117     + /* chown may have turned off some permissions we wanted. */
118     + if (fchmod (out_file_des, (int) file_hdr->c_mode) < 0)
119     + error (0, errno, "%s", file_hdr->c_name);
120     +
121     if (close (out_file_des) < 0)
122     error (0, errno, "%s", file_hdr->c_name);
123    
124     @@ -567,18 +594,6 @@
125     file_hdr->c_name, crc, file_hdr->c_chksum);
126     }
127    
128     - /* File is now copied; set attributes. */
129     - if (!no_chown_flag)
130     - if ((chown (file_hdr->c_name,
131     - set_owner_flag ? set_owner : file_hdr->c_uid,
132     - set_group_flag ? set_group : file_hdr->c_gid) < 0)
133     - && errno != EPERM)
134     - error (0, errno, "%s", file_hdr->c_name);
135     -
136     - /* chown may have turned off some permissions we wanted. */
137     - if (chmod (file_hdr->c_name, (int) file_hdr->c_mode) < 0)
138     - error (0, errno, "%s", file_hdr->c_name);
139     -
140     if (retain_time_flag)
141     {
142     struct utimbuf times; /* For setting file times. */
143     @@ -589,7 +604,7 @@
144     if (utime (file_hdr->c_name, &times) < 0)
145     error (0, errno, "%s", file_hdr->c_name);
146     }
147     -
148     +
149     tape_skip_padding (in_file_des, file_hdr->c_filesize);
150     if (file_hdr->c_nlink > 1
151     && (archive_format == arf_newascii || archive_format == arf_crcascii) )
152     @@ -1335,6 +1350,53 @@
153     }
154     }
155    
156     +/* Return a safer suffix of FILE_NAME, or "." if it has no safer
157     + suffix. Check for fully specified file names and other atrocities. */
158     +
159     +static const char *
160     +safer_name_suffix (char const *file_name)
161     +{
162     + char const *p;
163     +
164     + /* Skip file system prefixes, leading file name components that contain
165     + "..", and leading slashes. */
166     +
167     + size_t prefix_len = FILE_SYSTEM_PREFIX_LEN (file_name);
168     +
169     + for (p = file_name + prefix_len; *p;)
170     + {
171     + if (p[0] == '.' && p[1] == '.' && (ISSLASH (p[2]) || !p[2]))
172     + prefix_len = p + 2 - file_name;
173     +
174     + do
175     + {
176     + char c = *p++;
177     + if (ISSLASH (c))
178     + break;
179     + }
180     + while (*p);
181     + }
182     +
183     + for (p = file_name + prefix_len; ISSLASH (*p); p++)
184     + continue;
185     + prefix_len = p - file_name;
186     +
187     + if (prefix_len)
188     + {
189     + char *prefix = alloca (prefix_len + 1);
190     + memcpy (prefix, file_name, prefix_len);
191     + prefix[prefix_len] = '\0';
192     +
193     +
194     + error (0, 0, _("Removing leading `%s' from member names"), prefix);
195     + }
196     +
197     + if (!*p)
198     + p = ".";
199     +
200     + return p;
201     +}
202     +
203     /* Read the collection from standard input and create files
204     in the file system. */
205    
206     @@ -1445,18 +1507,11 @@
207    
208     /* Do we have to ignore absolute paths, and if so, does the filename
209     have an absolute path? */
210     - if (no_abs_paths_flag && file_hdr.c_name && file_hdr.c_name [0] == '/')
211     + if (!abs_paths_flag && file_hdr.c_name && file_hdr.c_name [0])
212     {
213     - char *p;
214     + const char *p = safer_name_suffix (file_hdr.c_name);
215    
216     - p = file_hdr.c_name;
217     - while (*p == '/')
218     - ++p;
219     - if (*p == '\0')
220     - {
221     - strcpy (file_hdr.c_name, ".");
222     - }
223     - else
224     + if (p != file_hdr.c_name)
225     {
226     /* Debian hack: file_hrd.c_name is sometimes set to
227     point to static memory by code in tar.c. This
228     diff -Naur cpio-2.6.vanilla/src/copypass.c cpio-2.6/src/copypass.c
229     --- cpio-2.6.vanilla/src/copypass.c 2004-09-06 13:09:04.000000000 +0100
230     +++ cpio-2.6/src/copypass.c 2005-07-29 13:46:07.000000000 +0100
231     @@ -181,19 +181,25 @@
232     }
233     if (close (in_file_des) < 0)
234     error (0, errno, "%s", input_name.ds_string);
235     - if (close (out_file_des) < 0)
236     - error (0, errno, "%s", output_name.ds_string);
237     -
238     + /*
239     + * Avoid race condition.
240     + * Set chown and chmod before closing the file desc.
241     + * pvrabec@redhat.com
242     + */
243     /* Set the attributes of the new file. */
244     if (!no_chown_flag)
245     - if ((chown (output_name.ds_string,
246     + if ((fchown (out_file_des,
247     set_owner_flag ? set_owner : in_file_stat.st_uid,
248     set_group_flag ? set_group : in_file_stat.st_gid) < 0)
249     && errno != EPERM)
250     error (0, errno, "%s", output_name.ds_string);
251     /* chown may have turned off some permissions we wanted. */
252     - if (chmod (output_name.ds_string, in_file_stat.st_mode) < 0)
253     + if (fchmod (out_file_des, in_file_stat.st_mode) < 0)
254     + error (0, errno, "%s", output_name.ds_string);
255     +
256     + if (close (out_file_des) < 0)
257     error (0, errno, "%s", output_name.ds_string);
258     +
259     if (reset_time_flag)
260     {
261     times.actime = in_file_stat.st_atime;
262     diff -Naur cpio-2.6.vanilla/src/extern.h cpio-2.6/src/extern.h
263     --- cpio-2.6.vanilla/src/extern.h 2004-09-08 11:49:57.000000000 +0100
264     +++ cpio-2.6/src/extern.h 2005-07-29 13:47:34.000000000 +0100
265     @@ -46,7 +46,7 @@
266     extern int sparse_flag;
267     extern int quiet_flag;
268     extern int only_verify_crc_flag;
269     -extern int no_abs_paths_flag;
270     +extern int abs_paths_flag;
271     extern unsigned int warn_option;
272    
273     /* Values for warn_option */
274     @@ -91,6 +91,7 @@
275     extern char input_is_seekable;
276     extern char output_is_seekable;
277     extern char *program_name;
278     +extern mode_t sys_umask;
279     extern int (*xstat) ();
280     extern void (*copy_function) ();
281    
282     diff -Naur cpio-2.6.vanilla/src/global.c cpio-2.6/src/global.c
283     --- cpio-2.6.vanilla/src/global.c 2004-09-08 11:23:44.000000000 +0100
284     +++ cpio-2.6/src/global.c 2005-07-29 13:47:34.000000000 +0100
285     @@ -100,7 +100,7 @@
286     int only_verify_crc_flag = false;
287    
288     /* If true, don't use any absolute paths, prefix them by `./'. */
289     -int no_abs_paths_flag = false;
290     +int abs_paths_flag = false;
291    
292     #ifdef DEBUG_CPIO
293     /* If true, print debugging information. */
294     @@ -195,6 +195,9 @@
295     /* The name this program was run with. */
296     char *program_name;
297    
298     +/* Debian hack to make the -d option honor the umask. */
299     +mode_t sys_umask;
300     +
301     /* A pointer to either lstat or stat, depending on whether
302     dereferencing of symlinks is done for input files. */
303     int (*xstat) ();
304     diff -Naur cpio-2.6.vanilla/src/main.c cpio-2.6/src/main.c
305     --- cpio-2.6.vanilla/src/main.c 2004-11-23 00:42:18.000000000 +0000
306     +++ cpio-2.6/src/main.c 2005-07-29 13:47:34.000000000 +0100
307     @@ -41,6 +41,7 @@
308    
309     enum cpio_options {
310     NO_ABSOLUTE_FILENAMES_OPTION=256,
311     + ABSOLUTE_FILENAMES_OPTION,
312     NO_PRESERVE_OWNER_OPTION,
313     ONLY_VERIFY_CRC_OPTION,
314     RENAME_BATCH_FILE_OPTION,
315     @@ -134,6 +135,8 @@
316     N_("In copy-in mode, read additional patterns specifying filenames to extract or list from FILE"), 210},
317     {"no-absolute-filenames", NO_ABSOLUTE_FILENAMES_OPTION, 0, 0,
318     N_("Create all files relative to the current directory"), 210},
319     + {"absolute-filenames", ABSOLUTE_FILENAMES_OPTION, 0, 0,
320     + N_("do not strip leading file name components that contain \"..\" and leading slashes from file names"), 210},
321     {"only-verify-crc", ONLY_VERIFY_CRC_OPTION, 0, 0,
322     N_("When reading a CRC format archive in copy-in mode, only verify the CRC's of each file in the archive, don't actually extract the files"), 210},
323     {"rename", 'r', 0, 0,
324     @@ -392,7 +395,11 @@
325     break;
326    
327     case NO_ABSOLUTE_FILENAMES_OPTION: /* --no-absolute-filenames */
328     - no_abs_paths_flag = true;
329     + abs_paths_flag = false;
330     + break;
331     +
332     + case ABSOLUTE_FILENAMES_OPTION: /* --absolute-filenames */
333     + abs_paths_flag = true;
334     break;
335    
336     case NO_PRESERVE_OWNER_OPTION: /* --no-preserve-owner */
337     @@ -631,7 +638,7 @@
338     _("--append is used but no archive file name is given (use -F or -O options")));
339    
340     CHECK_USAGE(rename_batch_file, "--rename-batch-file", "--create");
341     - CHECK_USAGE(no_abs_paths_flag, "--no-absolute-pathnames", "--create");
342     + CHECK_USAGE(abs_paths_flag, "--absolute-pathnames", "--create");
343     CHECK_USAGE(input_archive_name, "-I", "--create");
344     if (archive_name && output_archive_name)
345     USAGE_ERROR ((0, 0, _("Both -O and -F are used in copy-out mode")));
346     @@ -658,7 +665,7 @@
347     CHECK_USAGE(rename_flag, "--rename", "--pass-through");
348     CHECK_USAGE(append_flag, "--append", "--pass-through");
349     CHECK_USAGE(rename_batch_file, "--rename-batch-file", "--pass-through");
350     - CHECK_USAGE(no_abs_paths_flag, "--no-absolute-pathnames",
351     + CHECK_USAGE(abs_paths_flag, "--absolute-pathnames",
352     "--pass-through");
353     CHECK_USAGE(to_stdout_option, "--to-stdout", "--pass-through");
354    
355     @@ -740,7 +747,6 @@
356     textdomain (PACKAGE);
357    
358     program_name = argv[0];
359     - umask (0);
360    
361     #ifdef __TURBOC__
362     _fmode = O_BINARY; /* Put stdin and stdout in binary mode. */
363     @@ -751,6 +757,7 @@
364     #endif
365    
366     process_args (argc, argv);
367     + sys_umask = umask (0);
368    
369     initialize_buffers ();
370