]>
Commit | Line | Data |
---|---|---|
dd714b8a MT |
1 | Submitted By: Ken Moffat <ken at linuxfromscratch dot org> |
2 | Date: 2006-04-14 | |
3 | Initial Package Version: 1.15.1 | |
4 | Origin: gentoo, backported from CVS, rediffed to apply with -p1 | |
5 | Description: addresses vulnerability CVE-2006-0300 | |
6 | ||
7 | diff -Naurp tar-1.15.1-vanilla/src/xheader.c tar-1.15.1/src/xheader.c | |
8 | --- tar-1.15.1-vanilla/src/xheader.c 2004-09-06 12:31:14.000000000 +0100 | |
9 | +++ tar-1.15.1/src/xheader.c 2006-04-14 16:26:26.000000000 +0100 | |
10 | @@ -783,6 +783,32 @@ code_num (uintmax_t value, char const *k | |
11 | xheader_print (xhdr, keyword, sbuf); | |
12 | } | |
13 | ||
14 | +static bool | |
15 | +decode_num (uintmax_t *num, char const *arg, uintmax_t maxval, | |
16 | + char const *keyword) | |
17 | +{ | |
18 | + uintmax_t u; | |
19 | + char *arg_lim; | |
20 | + | |
21 | + if (! (ISDIGIT (*arg) | |
22 | + && (errno = 0, u = strtoumax (arg, &arg_lim, 10), !*arg_lim))) | |
23 | + { | |
24 | + ERROR ((0, 0, _("Malformed extended header: invalid %s=%s"), | |
25 | + keyword, arg)); | |
26 | + return false; | |
27 | + } | |
28 | + | |
29 | + if (! (u <= maxval && errno != ERANGE)) | |
30 | + { | |
31 | + ERROR ((0, 0, _("Extended header %s=%s is out of range"), | |
32 | + keyword, arg)); | |
33 | + return false; | |
34 | + } | |
35 | + | |
36 | + *num = u; | |
37 | + return true; | |
38 | +} | |
39 | + | |
40 | static void | |
41 | dummy_coder (struct tar_stat_info const *st __attribute__ ((unused)), | |
42 | char const *keyword __attribute__ ((unused)), | |
43 | @@ -821,7 +847,7 @@ static void | |
44 | gid_decoder (struct tar_stat_info *st, char const *arg) | |
45 | { | |
46 | uintmax_t u; | |
47 | - if (xstrtoumax (arg, NULL, 10, &u, "") == LONGINT_OK) | |
48 | + if (decode_num (&u, arg, TYPE_MAXIMUM (gid_t), "gid")) | |
49 | st->stat.st_gid = u; | |
50 | } | |
51 | ||
52 | @@ -903,7 +929,7 @@ static void | |
53 | size_decoder (struct tar_stat_info *st, char const *arg) | |
54 | { | |
55 | uintmax_t u; | |
56 | - if (xstrtoumax (arg, NULL, 10, &u, "") == LONGINT_OK) | |
57 | + if (decode_num (&u, arg, TYPE_MAXIMUM (off_t), "size")) | |
58 | st->archive_file_size = st->stat.st_size = u; | |
59 | } | |
60 | ||
61 | @@ -918,7 +944,7 @@ static void | |
62 | uid_decoder (struct tar_stat_info *st, char const *arg) | |
63 | { | |
64 | uintmax_t u; | |
65 | - if (xstrtoumax (arg, NULL, 10, &u, "") == LONGINT_OK) | |
66 | + if (decode_num (&u, arg, TYPE_MAXIMUM (uid_t), "uid")) | |
67 | st->stat.st_uid = u; | |
68 | } | |
69 | ||
70 | @@ -946,7 +972,7 @@ static void | |
71 | sparse_size_decoder (struct tar_stat_info *st, char const *arg) | |
72 | { | |
73 | uintmax_t u; | |
74 | - if (xstrtoumax (arg, NULL, 10, &u, "") == LONGINT_OK) | |
75 | + if (decode_num (&u, arg, TYPE_MAXIMUM (off_t), "GNU.sparse.size")) | |
76 | st->stat.st_size = u; | |
77 | } | |
78 | ||
79 | @@ -962,10 +988,10 @@ static void | |
80 | sparse_numblocks_decoder (struct tar_stat_info *st, char const *arg) | |
81 | { | |
82 | uintmax_t u; | |
83 | - if (xstrtoumax (arg, NULL, 10, &u, "") == LONGINT_OK) | |
84 | + if (decode_num (&u, arg, SIZE_MAX, "GNU.sparse.numblocks")) | |
85 | { | |
86 | st->sparse_map_size = u; | |
87 | - st->sparse_map = calloc(st->sparse_map_size, sizeof(st->sparse_map[0])); | |
88 | + st->sparse_map = xcalloc (u, sizeof st->sparse_map[0]); | |
89 | st->sparse_map_avail = 0; | |
90 | } | |
91 | } | |
92 | @@ -982,8 +1008,14 @@ static void | |
93 | sparse_offset_decoder (struct tar_stat_info *st, char const *arg) | |
94 | { | |
95 | uintmax_t u; | |
96 | - if (xstrtoumax (arg, NULL, 10, &u, "") == LONGINT_OK) | |
97 | + if (decode_num (&u, arg, TYPE_MAXIMUM (off_t), "GNU.sparse.offset")) | |
98 | + { | |
99 | + if (st->sparse_map_avail < st->sparse_map_size) | |
100 | st->sparse_map[st->sparse_map_avail].offset = u; | |
101 | + else | |
102 | + ERROR ((0, 0, _("Malformed extended header: excess %s=%s"), | |
103 | + "GNU.sparse.offset", arg)); | |
104 | + } | |
105 | } | |
106 | ||
107 | static void | |
108 | @@ -998,15 +1030,13 @@ static void | |
109 | sparse_numbytes_decoder (struct tar_stat_info *st, char const *arg) | |
110 | { | |
111 | uintmax_t u; | |
112 | - if (xstrtoumax (arg, NULL, 10, &u, "") == LONGINT_OK) | |
113 | + if (decode_num (&u, arg, SIZE_MAX, "GNU.sparse.numbytes")) | |
114 | { | |
115 | if (st->sparse_map_avail == st->sparse_map_size) | |
116 | - { | |
117 | - st->sparse_map_size *= 2; | |
118 | - st->sparse_map = xrealloc (st->sparse_map, | |
119 | - st->sparse_map_size | |
120 | - * sizeof st->sparse_map[0]); | |
121 | - } | |
122 | + st->sparse_map = x2nrealloc (st->sparse_map, | |
123 | + &st->sparse_map_size, | |
124 | + sizeof st->sparse_map[0]); | |
125 | + | |
126 | st->sparse_map[st->sparse_map_avail++].numbytes = u; | |
127 | } | |
128 | } |