git-svn-id: file:///var/lib/svn/clamav-devel/trunk/clamav-devel@1306 77e5149b-7576-45b1-b177-96237e5ba77b
Trog authored on 2005/02/04 19:04:09... | ... |
@@ -1,3 +1,7 @@ |
1 |
+Fri Feb 4 10:02:08 GMT 2005 (trog) |
|
2 |
+----------------------------------- |
|
3 |
+ * libclamav/special.c: check RIFF files for MS05-002. Not yet activated. |
|
4 |
+ |
|
1 | 5 |
Thu Feb 3 21:09:34 GMT 2005 (njh) |
2 | 6 |
---------------------------------- |
3 | 7 |
* libclamav/mbox.c: Speed improvements in the handling of bounce messages |
... | ... |
@@ -1,5 +1,5 @@ |
1 | 1 |
/* |
2 |
- * Copyright (C) 2004 trog@uncon.org |
|
2 |
+ * Copyright (C) 2004-2005 trog@uncon.org |
|
3 | 3 |
* |
4 | 4 |
* This program is free software; you can redistribute it and/or modify |
5 | 5 |
* it under the terms of the GNU General Public License as published by |
... | ... |
@@ -25,6 +25,8 @@ |
25 | 25 |
#include "clamav.h" |
26 | 26 |
#include "others.h" |
27 | 27 |
|
28 |
+#define FALSE (0) |
|
29 |
+#define TRUE (1) |
|
28 | 30 |
|
29 | 31 |
int cli_check_mydoom_log(int desc, const char **virname) |
30 | 32 |
{ |
... | ... |
@@ -114,3 +116,115 @@ int cli_check_jpeg_exploit(int fd) |
114 | 114 |
} |
115 | 115 |
} |
116 | 116 |
} |
117 |
+ |
|
118 |
+#if WORDS_BIGENDIAN == 0 |
|
119 |
+#define riff_endian_convert_32(v) (v) |
|
120 |
+#else |
|
121 |
+static uint32_t riff_endian_convert_32(uint32_t v) |
|
122 |
+{ |
|
123 |
+ return ((v >> 24) | ((v & 0x00FF0000) >> 8) | |
|
124 |
+ ((v & 0x0000FF00) << 8) | (v << 24)); |
|
125 |
+} |
|
126 |
+#endif |
|
127 |
+ |
|
128 |
+static int riff_read_chunk(int fd, int big_endian, int rec_level) |
|
129 |
+{ |
|
130 |
+ uint32_t chunk_id; |
|
131 |
+ uint32_t chunk_size; |
|
132 |
+ int length; |
|
133 |
+ uint32_t list_type; |
|
134 |
+ off_t offset, cur_offset; |
|
135 |
+ |
|
136 |
+ if (rec_level > 1000) { |
|
137 |
+ cli_dbgmsg("riff_read_chunk: recursion level exceeded\n"); |
|
138 |
+ return 0; |
|
139 |
+ } |
|
140 |
+ |
|
141 |
+ length = sizeof(uint32_t); |
|
142 |
+ if (cli_readn(fd, &chunk_id, length) != length) { |
|
143 |
+ return 0; |
|
144 |
+ } |
|
145 |
+ if (cli_readn(fd, &chunk_size, length) != length) { |
|
146 |
+ return 0; |
|
147 |
+ } |
|
148 |
+ if (big_endian) { |
|
149 |
+ chunk_size = riff_endian_convert_32(chunk_size); |
|
150 |
+ } |
|
151 |
+ |
|
152 |
+ if (memcmp(&chunk_id, "RIFF", 4) == 0) { |
|
153 |
+ return 0; |
|
154 |
+ } else if (memcmp(&chunk_id, "RIFX", 4) == 0) { |
|
155 |
+ return 0; |
|
156 |
+ } |
|
157 |
+ |
|
158 |
+ if ((memcmp(&chunk_id, "LIST", 4) == 0) || |
|
159 |
+ (memcmp(&chunk_id, "PROP", 4) == 0) || |
|
160 |
+ (memcmp(&chunk_id, "FORM", 4) == 0) || |
|
161 |
+ (memcmp(&chunk_id, "CAT ", 4) == 0)) { |
|
162 |
+ if (cli_readn(fd, &list_type, sizeof(list_type)) != sizeof(list_type)) { |
|
163 |
+ cli_dbgmsg("riff_read_chunk: read list type failed\n"); |
|
164 |
+ return 0; |
|
165 |
+ } |
|
166 |
+ return riff_read_chunk(fd, big_endian, ++rec_level); |
|
167 |
+ } |
|
168 |
+ |
|
169 |
+ cur_offset = lseek(fd, 0, SEEK_CUR); |
|
170 |
+ offset = cur_offset + chunk_size; |
|
171 |
+ /* Check for odd alignment */ |
|
172 |
+ if ((offset & 0x01) == 1) { |
|
173 |
+ offset++; |
|
174 |
+ } |
|
175 |
+ if (offset < cur_offset) { |
|
176 |
+ return 0; |
|
177 |
+ } |
|
178 |
+ if (lseek(fd, offset, SEEK_SET) != offset) { |
|
179 |
+ return 2; |
|
180 |
+ } |
|
181 |
+ return 1; |
|
182 |
+} |
|
183 |
+ |
|
184 |
+int cli_check_riff_exploit(int fd) |
|
185 |
+{ |
|
186 |
+ uint32_t chunk_id; |
|
187 |
+ uint32_t chunk_size; |
|
188 |
+ uint32_t form_type; |
|
189 |
+ int length, big_endian, retval; |
|
190 |
+ off_t offset; |
|
191 |
+ |
|
192 |
+ cli_dbgmsg("in cli_check_riff_exploit()\n"); |
|
193 |
+ |
|
194 |
+ length = sizeof(uint32_t); |
|
195 |
+ if (cli_readn(fd, &chunk_id, length) != length) { |
|
196 |
+ return 0; |
|
197 |
+ } |
|
198 |
+ if (cli_readn(fd, &chunk_size, length) != length) { |
|
199 |
+ return 0; |
|
200 |
+ } |
|
201 |
+ if (cli_readn(fd, &form_type, length) != length) { |
|
202 |
+ return 0; |
|
203 |
+ } |
|
204 |
+ |
|
205 |
+ if (memcmp(&chunk_id, "RIFF", 4) == 0) { |
|
206 |
+ big_endian = FALSE; |
|
207 |
+ } else if (memcmp(&chunk_id, "RIFX", 4) == 0) { |
|
208 |
+ big_endian = TRUE; |
|
209 |
+ } else { |
|
210 |
+ /* Not a RIFF file */ |
|
211 |
+ return 0; |
|
212 |
+ } |
|
213 |
+ |
|
214 |
+ if (big_endian) { |
|
215 |
+ chunk_size = riff_endian_convert_32(chunk_size); |
|
216 |
+ } |
|
217 |
+ |
|
218 |
+ do { |
|
219 |
+ retval = riff_read_chunk(fd, big_endian, 1); |
|
220 |
+ } while (retval == 1); |
|
221 |
+ |
|
222 |
+ offset = lseek(fd, 0, SEEK_CUR); |
|
223 |
+ |
|
224 |
+ if (offset < chunk_size) { |
|
225 |
+ retval = 2; |
|
226 |
+ }; |
|
227 |
+ return retval; |
|
228 |
+} |