diff options
author | Denis Vlasenko <vda.linux@googlemail.com> | 2008-07-12 09:20:44 +0000 |
---|---|---|
committer | Denis Vlasenko <vda.linux@googlemail.com> | 2008-07-12 09:20:44 +0000 |
commit | a46dd89e9451ec73a4df54427110cdfc28d8b031 (patch) | |
tree | 2e470b3c0236524905a6d399c5207cccaef2fc7b /archival/libunarchive | |
parent | 39acf453353a41a78fbc220360e884eb0eb33a59 (diff) | |
download | busybox-w32-a46dd89e9451ec73a4df54427110cdfc28d8b031.tar.gz busybox-w32-a46dd89e9451ec73a4df54427110cdfc28d8b031.tar.bz2 busybox-w32-a46dd89e9451ec73a4df54427110cdfc28d8b031.zip |
cpio: internalize archive_xread_all_eof. add a few paranoia checks
for corrupted cpio files.
modprobe-small: remove stray include
route: small code shrink
function old new delta
get_header_cpio 958 980 +22
archive_xread_all_eof 33 - -33
------------------------------------------------------------------------------
(add/remove: 0/1 grow/shrink: 1/0 up/down: 22/-33) Total: -11 bytes
Diffstat (limited to 'archival/libunarchive')
-rw-r--r-- | archival/libunarchive/Kbuild | 2 | ||||
-rw-r--r-- | archival/libunarchive/archive_xread_all_eof.c | 20 | ||||
-rw-r--r-- | archival/libunarchive/get_header_cpio.c | 69 | ||||
-rw-r--r-- | archival/libunarchive/get_header_tar.c | 2 |
4 files changed, 38 insertions, 55 deletions
diff --git a/archival/libunarchive/Kbuild b/archival/libunarchive/Kbuild index 609bc50cb..468a7e82a 100644 --- a/archival/libunarchive/Kbuild +++ b/archival/libunarchive/Kbuild | |||
@@ -19,8 +19,6 @@ lib-y:= \ | |||
19 | header_list.o \ | 19 | header_list.o \ |
20 | header_verbose_list.o \ | 20 | header_verbose_list.o \ |
21 | \ | 21 | \ |
22 | archive_xread_all_eof.o \ | ||
23 | \ | ||
24 | seek_by_read.o \ | 22 | seek_by_read.o \ |
25 | seek_by_jump.o \ | 23 | seek_by_jump.o \ |
26 | \ | 24 | \ |
diff --git a/archival/libunarchive/archive_xread_all_eof.c b/archival/libunarchive/archive_xread_all_eof.c deleted file mode 100644 index f11a7fd32..000000000 --- a/archival/libunarchive/archive_xread_all_eof.c +++ /dev/null | |||
@@ -1,20 +0,0 @@ | |||
1 | /* vi: set sw=4 ts=4: */ | ||
2 | /* | ||
3 | * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. | ||
4 | */ | ||
5 | |||
6 | #include "libbb.h" | ||
7 | #include "unarchive.h" | ||
8 | |||
9 | ssize_t FAST_FUNC archive_xread_all_eof(archive_handle_t *archive_handle, | ||
10 | unsigned char *buf, size_t count) | ||
11 | { | ||
12 | ssize_t size; | ||
13 | |||
14 | size = full_read(archive_handle->src_fd, buf, count); | ||
15 | if (size != 0 && size != (ssize_t)count) { | ||
16 | bb_error_msg_and_die("short read: %u of %u", | ||
17 | (unsigned)size, (unsigned)count); | ||
18 | } | ||
19 | return size; | ||
20 | } | ||
diff --git a/archival/libunarchive/get_header_cpio.c b/archival/libunarchive/get_header_cpio.c index 307d2a66d..93f6c61aa 100644 --- a/archival/libunarchive/get_header_cpio.c +++ b/archival/libunarchive/get_header_cpio.c | |||
@@ -21,26 +21,28 @@ char FAST_FUNC get_header_cpio(archive_handle_t *archive_handle) | |||
21 | { | 21 | { |
22 | file_header_t *file_header = archive_handle->file_header; | 22 | file_header_t *file_header = archive_handle->file_header; |
23 | char cpio_header[110]; | 23 | char cpio_header[110]; |
24 | char dummy[16]; | ||
25 | int namesize; | 24 | int namesize; |
26 | int major, minor, nlink, mode, inode; | 25 | int major, minor, nlink, mode, inode; |
27 | unsigned size, uid, gid, mtime; | 26 | unsigned size, uid, gid, mtime; |
28 | 27 | ||
29 | #define saved_hardlinks (*(hardlinks_t **)(&archive_handle->ah_priv[0])) | 28 | #define hardlinks_to_create (*(hardlinks_t **)(&archive_handle->ah_priv[0])) |
30 | #define saved_hardlinks_created (*(hardlinks_t **)(&archive_handle->ah_priv[1])) | 29 | #define created_hardlinks (*(hardlinks_t **)(&archive_handle->ah_priv[1])) |
31 | // if (!archive_handle->ah_priv_inited) { | 30 | // if (!archive_handle->ah_priv_inited) { |
32 | // archive_handle->ah_priv_inited = 1; | 31 | // archive_handle->ah_priv_inited = 1; |
33 | // saved_hardlinks = NULL; | 32 | // hardlinks_to_create = NULL; |
34 | // saved_hardlinks_created = NULL; | 33 | // created_hardlinks = NULL; |
35 | // } | 34 | // } |
36 | 35 | ||
37 | /* There can be padding before archive header */ | 36 | /* There can be padding before archive header */ |
38 | data_align(archive_handle, 4); | 37 | data_align(archive_handle, 4); |
39 | 38 | ||
40 | //TODO: this function is used only here, make it static? | 39 | size = full_read(archive_handle->src_fd, cpio_header, 110); |
41 | if (archive_xread_all_eof(archive_handle, (unsigned char*)cpio_header, 110) == 0) { | 40 | if (size == 0) { |
42 | goto create_hardlinks; | 41 | goto create_hardlinks; |
43 | } | 42 | } |
43 | if (size != 110) { | ||
44 | bb_error_msg_and_die("short read"); | ||
45 | } | ||
44 | archive_handle->offset += 110; | 46 | archive_handle->offset += 110; |
45 | 47 | ||
46 | if (strncmp(&cpio_header[0], "07070", 5) != 0 | 48 | if (strncmp(&cpio_header[0], "07070", 5) != 0 |
@@ -49,20 +51,21 @@ char FAST_FUNC get_header_cpio(archive_handle_t *archive_handle) | |||
49 | bb_error_msg_and_die("unsupported cpio format, use newc or crc"); | 51 | bb_error_msg_and_die("unsupported cpio format, use newc or crc"); |
50 | } | 52 | } |
51 | 53 | ||
52 | sscanf(cpio_header + 6, | 54 | if (sscanf(cpio_header + 6, |
53 | "%8x" "%8x" "%8x" "%8x" | 55 | "%8x" "%8x" "%8x" "%8x" |
54 | "%8x" "%8x" "%8x" /*maj,min:*/ "%16c" | 56 | "%8x" "%8x" "%8x" /*maj,min:*/ "%*16c" |
55 | /*rmaj,rmin:*/"%8x" "%8x" "%8x" /*chksum:*/ "%8c", | 57 | /*rmaj,rmin:*/"%8x" "%8x" "%8x" /*chksum: "%*8c"*/, |
56 | &inode, &mode, &uid, &gid, | 58 | &inode, &mode, &uid, &gid, |
57 | &nlink, &mtime, &size, dummy, | 59 | &nlink, &mtime, &size, |
58 | &major, &minor, &namesize, dummy); | 60 | &major, &minor, &namesize) != 10) |
61 | bb_error_msg_and_die("damaged cpio file"); | ||
59 | file_header->mode = mode; | 62 | file_header->mode = mode; |
60 | file_header->uid = uid; | 63 | file_header->uid = uid; |
61 | file_header->gid = gid; | 64 | file_header->gid = gid; |
62 | file_header->mtime = mtime; | 65 | file_header->mtime = mtime; |
63 | file_header->size = size; | 66 | file_header->size = size; |
64 | 67 | ||
65 | namesize &= 0x1fff; /* paranoia: names can't be that long */ | 68 | namesize &= 0x1fff; /* paranoia: limit names to 8k chars */ |
66 | file_header->name = xzalloc(namesize + 1); | 69 | file_header->name = xzalloc(namesize + 1); |
67 | /* Read in filename */ | 70 | /* Read in filename */ |
68 | xread(archive_handle->src_fd, file_header->name, namesize); | 71 | xread(archive_handle->src_fd, file_header->name, namesize); |
@@ -77,17 +80,17 @@ char FAST_FUNC get_header_cpio(archive_handle_t *archive_handle) | |||
77 | goto create_hardlinks; | 80 | goto create_hardlinks; |
78 | } | 81 | } |
79 | 82 | ||
83 | file_header->link_target = NULL; | ||
80 | if (S_ISLNK(file_header->mode)) { | 84 | if (S_ISLNK(file_header->mode)) { |
85 | file_header->size &= 0x1fff; /* paranoia: limit names to 8k chars */ | ||
81 | file_header->link_target = xzalloc(file_header->size + 1); | 86 | file_header->link_target = xzalloc(file_header->size + 1); |
82 | xread(archive_handle->src_fd, file_header->link_target, file_header->size); | 87 | xread(archive_handle->src_fd, file_header->link_target, file_header->size); |
83 | archive_handle->offset += file_header->size; | 88 | archive_handle->offset += file_header->size; |
84 | file_header->size = 0; /* Stop possible seeks in future */ | 89 | file_header->size = 0; /* Stop possible seeks in future */ |
85 | } else { | ||
86 | file_header->link_target = NULL; | ||
87 | } | 90 | } |
88 | 91 | ||
89 | // TODO: data_extract_all can't deal with hardlinks to non-files... | 92 | // TODO: data_extract_all can't deal with hardlinks to non-files... |
90 | // (should be !S_ISDIR instead of S_ISREG here) | 93 | // when fixed, change S_ISREG to !S_ISDIR here |
91 | 94 | ||
92 | if (nlink > 1 && S_ISREG(file_header->mode)) { | 95 | if (nlink > 1 && S_ISREG(file_header->mode)) { |
93 | hardlinks_t *new = xmalloc(sizeof(*new) + namesize); | 96 | hardlinks_t *new = xmalloc(sizeof(*new) + namesize); |
@@ -99,13 +102,13 @@ char FAST_FUNC get_header_cpio(archive_handle_t *archive_handle) | |||
99 | strcpy(new->name, file_header->name); | 102 | strcpy(new->name, file_header->name); |
100 | /* Put file on a linked list for later */ | 103 | /* Put file on a linked list for later */ |
101 | if (size == 0) { | 104 | if (size == 0) { |
102 | new->next = saved_hardlinks; | 105 | new->next = hardlinks_to_create; |
103 | saved_hardlinks = new; | 106 | hardlinks_to_create = new; |
104 | return EXIT_SUCCESS; /* Skip this one */ | 107 | return EXIT_SUCCESS; /* Skip this one */ |
105 | /* TODO: this breaks cpio -t (it does not show hardlinks) */ | 108 | /* TODO: this breaks cpio -t (it does not show hardlinks) */ |
106 | } | 109 | } |
107 | new->next = saved_hardlinks_created; | 110 | new->next = created_hardlinks; |
108 | saved_hardlinks_created = new; | 111 | created_hardlinks = new; |
109 | } | 112 | } |
110 | file_header->device = makedev(major, minor); | 113 | file_header->device = makedev(major, minor); |
111 | 114 | ||
@@ -129,18 +132,23 @@ char FAST_FUNC get_header_cpio(archive_handle_t *archive_handle) | |||
129 | free(file_header->link_target); | 132 | free(file_header->link_target); |
130 | free(file_header->name); | 133 | free(file_header->name); |
131 | 134 | ||
132 | while (saved_hardlinks) { | 135 | while (hardlinks_to_create) { |
133 | hardlinks_t *cur; | 136 | hardlinks_t *cur; |
134 | hardlinks_t *make_me = saved_hardlinks; | 137 | hardlinks_t *make_me = hardlinks_to_create; |
135 | saved_hardlinks = make_me->next; | 138 | |
139 | hardlinks_to_create = make_me->next; | ||
136 | 140 | ||
137 | memset(file_header, 0, sizeof(*file_header)); | 141 | memset(file_header, 0, sizeof(*file_header)); |
142 | file_header->mtime = make_me->mtime; | ||
138 | file_header->name = make_me->name; | 143 | file_header->name = make_me->name; |
139 | file_header->mode = make_me->mode; | 144 | file_header->mode = make_me->mode; |
145 | file_header->uid = make_me->uid; | ||
146 | file_header->gid = make_me->gid; | ||
140 | /*file_header->size = 0;*/ | 147 | /*file_header->size = 0;*/ |
148 | /*file_header->link_target = NULL;*/ | ||
141 | 149 | ||
142 | /* Try to find a file we are hardlinked to */ | 150 | /* Try to find a file we are hardlinked to */ |
143 | cur = saved_hardlinks_created; | 151 | cur = created_hardlinks; |
144 | while (cur) { | 152 | while (cur) { |
145 | /* TODO: must match maj/min too! */ | 153 | /* TODO: must match maj/min too! */ |
146 | if (cur->inode == make_me->inode) { | 154 | if (cur->inode == make_me->inode) { |
@@ -155,20 +163,17 @@ char FAST_FUNC get_header_cpio(archive_handle_t *archive_handle) | |||
155 | } | 163 | } |
156 | /* Oops... no file with such inode was created... do it now | 164 | /* Oops... no file with such inode was created... do it now |
157 | * (happens when hardlinked files are empty (zero length)) */ | 165 | * (happens when hardlinked files are empty (zero length)) */ |
158 | file_header->mtime = make_me->mtime; | ||
159 | file_header->uid = make_me->uid ; | ||
160 | file_header->gid = make_me->gid ; | ||
161 | if (archive_handle->filter(archive_handle) == EXIT_SUCCESS) | 166 | if (archive_handle->filter(archive_handle) == EXIT_SUCCESS) |
162 | archive_handle->action_data(archive_handle); | 167 | archive_handle->action_data(archive_handle); |
163 | /* Move to the list of created hardlinked files */ | 168 | /* Move to the list of created hardlinked files */ |
164 | make_me->next = saved_hardlinks_created; | 169 | make_me->next = created_hardlinks; |
165 | saved_hardlinks_created = make_me; | 170 | created_hardlinks = make_me; |
166 | next_link: ; | 171 | next_link: ; |
167 | } | 172 | } |
168 | 173 | ||
169 | while (saved_hardlinks_created) { | 174 | while (created_hardlinks) { |
170 | hardlinks_t *p = saved_hardlinks_created; | 175 | hardlinks_t *p = created_hardlinks; |
171 | saved_hardlinks_created = p->next; | 176 | created_hardlinks = p->next; |
172 | free(p); | 177 | free(p); |
173 | } | 178 | } |
174 | 179 | ||
diff --git a/archival/libunarchive/get_header_tar.c b/archival/libunarchive/get_header_tar.c index e9c730d65..7e3c482df 100644 --- a/archival/libunarchive/get_header_tar.c +++ b/archival/libunarchive/get_header_tar.c | |||
@@ -364,7 +364,7 @@ char FAST_FUNC get_header_tar(archive_handle_t *archive_handle) | |||
364 | archive_handle->offset += file_header->size; | 364 | archive_handle->offset += file_header->size; |
365 | 365 | ||
366 | free(file_header->link_target); | 366 | free(file_header->link_target); |
367 | /* Do not free(file_header->name)! */ | 367 | /* Do not free(file_header->name)! (why?) */ |
368 | #if ENABLE_FEATURE_TAR_UNAME_GNAME | 368 | #if ENABLE_FEATURE_TAR_UNAME_GNAME |
369 | free(file_header->uname); | 369 | free(file_header->uname); |
370 | free(file_header->gname); | 370 | free(file_header->gname); |