1 |
a3li 10/08/30 10:52:08 |
2 |
|
3 |
Added: ctorrent-CVE-2009-1759.patch |
4 |
Log: |
5 |
Non-maintainer commit: Revision bump to fix CVE-2009-1759, bug 266953. |
6 |
(Portage version: 2.2_rc67/cvs/Linux x86_64) |
7 |
|
8 |
Revision Changes Path |
9 |
1.1 net-p2p/ctorrent/files/ctorrent-CVE-2009-1759.patch |
10 |
|
11 |
file : http://sources.gentoo.org/viewvc.cgi/gentoo-x86/net-p2p/ctorrent/files/ctorrent-CVE-2009-1759.patch?rev=1.1&view=markup |
12 |
plain: http://sources.gentoo.org/viewvc.cgi/gentoo-x86/net-p2p/ctorrent/files/ctorrent-CVE-2009-1759.patch?rev=1.1&content-type=text/plain |
13 |
|
14 |
Index: ctorrent-CVE-2009-1759.patch |
15 |
=================================================================== |
16 |
Patch for CVE-2009-1759. |
17 |
Source: Upstream SVN, rev 302 from the drorrent-3 branch. |
18 |
|
19 |
Index: bencode.h |
20 |
=================================================================== |
21 |
--- bencode.h (revision 300) |
22 |
+++ bencode.h (revision 302) |
23 |
@@ -25,7 +25,7 @@ |
24 |
size_t decode_list(const char *b,size_t len,const char *keylist); |
25 |
size_t decode_rev(const char *b,size_t len,const char *keylist); |
26 |
size_t decode_query(const char *b,size_t len,const char *keylist,const char **ps,size_t *pi,int64_t *pl,int method); |
27 |
-size_t decode_list2path(const char *b, size_t n, char *pathname); |
28 |
+size_t decode_list2path(const char *b, size_t n, char *pathname, size_t maxlen); |
29 |
size_t bencode_buf(const char *str,size_t len,FILE *fp); |
30 |
size_t bencode_str(const char *str, FILE *fp); |
31 |
size_t bencode_int(const uint64_t integer, FILE *fp); |
32 |
Index: bencode.cpp |
33 |
=================================================================== |
34 |
--- bencode.cpp (revision 300) |
35 |
+++ bencode.cpp (revision 302) |
36 |
@@ -233,22 +233,28 @@ |
37 |
return bencode_end_dict_list(fp); |
38 |
} |
39 |
|
40 |
-size_t decode_list2path(const char *b, size_t n, char *pathname) |
41 |
+size_t decode_list2path(const char *b, size_t n, char *pathname, size_t maxlen) |
42 |
{ |
43 |
const char *pb = b; |
44 |
const char *s = (char *) 0; |
45 |
+ const char *endmax = pathname + maxlen - 1; |
46 |
size_t r,q; |
47 |
|
48 |
if( 'l' != *pb ) return 0; |
49 |
pb++; |
50 |
n--; |
51 |
if( !n ) return 0; |
52 |
- for(; n;){ |
53 |
+ while( n && pathname < endmax ){ |
54 |
if(!(r = buf_str(pb, n, &s, &q)) ) return 0; |
55 |
+ if( q >= maxlen ) return 0; |
56 |
memcpy(pathname, s, q); |
57 |
pathname += q; |
58 |
- pb += r; n -= r; |
59 |
- if( 'e' != *pb ){*pathname = PATH_SP, pathname++;} else break; |
60 |
+ maxlen -= q; |
61 |
+ pb += r; |
62 |
+ n -= r; |
63 |
+ if( 'e' == *pb ) break; |
64 |
+ if( pathname >= endmax ) return 0; |
65 |
+ *pathname++ = PATH_SP; |
66 |
} |
67 |
*pathname = '\0'; |
68 |
return (pb - b + 1); |
69 |
Index: btfiles.cpp |
70 |
=================================================================== |
71 |
--- btfiles.cpp (revision 300) |
72 |
+++ btfiles.cpp (revision 302) |
73 |
@@ -449,7 +449,8 @@ |
74 |
return 0; |
75 |
} |
76 |
|
77 |
-int btFiles::BuildFromMI(const char *metabuf, const size_t metabuf_len, const char *saveas) |
78 |
+int btFiles::BuildFromMI(const char *metabuf, const size_t metabuf_len, |
79 |
+ const char *saveas, unsigned char exam_only) |
80 |
{ |
81 |
char path[MAXPATHLEN]; |
82 |
const char *s, *p; |
83 |
@@ -458,11 +459,19 @@ |
84 |
int f_warned = 0; |
85 |
|
86 |
if( !decode_query(metabuf, metabuf_len, "info|name", &s, &q, (int64_t*)0, |
87 |
- QUERY_STR) || MAXPATHLEN <= q ) |
88 |
+ QUERY_STR) || MAXPATHLEN <= q ){ |
89 |
+ errno = EINVAL; |
90 |
return -1; |
91 |
+ } |
92 |
|
93 |
memcpy(path, s, q); |
94 |
path[q] = '\0'; |
95 |
+ if( !exam_only && |
96 |
+ (PATH_SP == path[0] || '/' == path[0] || 0==strncmp("..", path, 2)) ){ |
97 |
+ CONSOLE.Warning(1, "error, unsafe path \"%s\" in torrent data", path); |
98 |
+ errno = EINVAL; |
99 |
+ return -1; |
100 |
+ } |
101 |
|
102 |
r = decode_query(metabuf, metabuf_len, "info|files", (const char**)0, &q, |
103 |
(int64_t*)0, QUERY_POS); |
104 |
@@ -471,21 +480,31 @@ |
105 |
BTFILE *pbf_last = (BTFILE*) 0; |
106 |
BTFILE *pbf = (BTFILE*) 0; |
107 |
size_t dl; |
108 |
+ unsigned long nfiles = 0; |
109 |
+ |
110 |
if( decode_query(metabuf,metabuf_len,"info|length", |
111 |
- (const char**) 0,(size_t*) 0,(int64_t*) 0,QUERY_LONG) ) |
112 |
+ (const char**) 0,(size_t*) 0,(int64_t*) 0,QUERY_LONG) ){ |
113 |
+ errno = EINVAL; |
114 |
return -1; |
115 |
+ } |
116 |
|
117 |
if( saveas ){ |
118 |
m_directory = new char[strlen(saveas) + 1]; |
119 |
#ifndef WINDOWS |
120 |
- if(!m_directory) return -1; |
121 |
+ if( !m_directory ){ |
122 |
+ errno = ENOMEM; |
123 |
+ return -1; |
124 |
+ } |
125 |
#endif |
126 |
strcpy(m_directory,saveas); |
127 |
}else{ |
128 |
int f_conv; |
129 |
char *tmpfn = new char[strlen(path)*2+5]; |
130 |
#ifndef WINDOWS |
131 |
- if( !tmpfn ) return -1; |
132 |
+ if( !tmpfn ){ |
133 |
+ errno = ENOMEM; |
134 |
+ return -1; |
135 |
+ } |
136 |
#endif |
137 |
if( f_conv = ConvertFilename(tmpfn, path, strlen(path)*2+5) ){ |
138 |
if( arg_flg_convert_filenames ){ |
139 |
@@ -493,6 +512,7 @@ |
140 |
#ifndef WINDOWS |
141 |
if( !m_directory ){ |
142 |
delete []tmpfn; |
143 |
+ errno = ENOMEM; |
144 |
return -1; |
145 |
} |
146 |
#endif |
147 |
@@ -507,7 +527,10 @@ |
148 |
if( !f_conv || !arg_flg_convert_filenames ){ |
149 |
m_directory = new char[strlen(path) + 1]; |
150 |
#ifndef WINDOWS |
151 |
- if( !m_directory ) return -1; |
152 |
+ if( !m_directory ){ |
153 |
+ errno = ENOMEM; |
154 |
+ return -1; |
155 |
+ } |
156 |
#endif |
157 |
strcpy(m_directory,path); |
158 |
} |
159 |
@@ -517,24 +540,50 @@ |
160 |
p = metabuf + r + 1; |
161 |
q--; |
162 |
for(; q && 'e' != *p; p += dl, q -= dl){ |
163 |
- if(!(dl = decode_dict(p, q, (const char*) 0)) ) return -1; |
164 |
- if( !decode_query(p, dl, "length", (const char**) 0, |
165 |
- (size_t*) 0,&t,QUERY_LONG) ) return -1; |
166 |
+ if( !(dl = decode_dict(p, q, (const char*) 0)) || |
167 |
+ !decode_query(p, dl, "length", (const char**) 0, (size_t*) 0, &t, |
168 |
+ QUERY_LONG) ){ |
169 |
+ errno = EINVAL; |
170 |
+ return -1; |
171 |
+ } |
172 |
pbf = _new_bfnode(); |
173 |
#ifndef WINDOWS |
174 |
- if( !pbf ) return -1; |
175 |
+ if( !pbf ){ |
176 |
+ errno = ENOMEM; |
177 |
+ return -1; |
178 |
+ } |
179 |
#endif |
180 |
+ nfiles++; |
181 |
pbf->bf_length = t; |
182 |
m_total_files_length += t; |
183 |
r = decode_query(p, dl, "path", (const char **)0, &n, (int64_t*)0, |
184 |
QUERY_POS); |
185 |
- if( !r ) return -1; |
186 |
- if(!decode_list2path(p + r, n, path)) return -1; |
187 |
+ if( !r || !decode_list2path(p + r, n, path, sizeof(path)) ){ |
188 |
+ CONSOLE.Warning(1, |
189 |
+ "error, invalid path in torrent data for file %lu at offset %llu", |
190 |
+ nfiles, m_total_files_length - t); |
191 |
+ delete pbf; |
192 |
+ errno = EINVAL; |
193 |
+ return -1; |
194 |
+ } |
195 |
+ if( !exam_only && |
196 |
+ (PATH_SP == path[0] || '/' == path[0] || 0==strncmp("..", path, 2)) ){ |
197 |
+ CONSOLE.Warning(1, |
198 |
+ "error, unsafe path \"%s\" in torrent data for file %lu", |
199 |
+ path, nfiles); |
200 |
+ delete pbf; |
201 |
+ errno = EINVAL; |
202 |
+ return -1; |
203 |
+ } |
204 |
|
205 |
+ |
206 |
int f_conv; |
207 |
char *tmpfn = new char[strlen(path)*2+5]; |
208 |
#ifndef WINDOWS |
209 |
- if( !tmpfn ) return -1; |
210 |
+ if( !tmpfn ){ |
211 |
+ errno = ENOMEM; |
212 |
+ return -1; |
213 |
+ } |
214 |
#endif |
215 |
if( f_conv = ConvertFilename(tmpfn, path, strlen(path)*2+5) ){ |
216 |
if( arg_flg_convert_filenames ){ |
217 |
@@ -542,6 +591,7 @@ |
218 |
#ifndef WINDOWS |
219 |
if( !pbf->bf_filename ){ |
220 |
delete []tmpfn; |
221 |
+ errno = ENOMEM; |
222 |
return -1; |
223 |
} |
224 |
#endif |
225 |
@@ -556,7 +606,10 @@ |
226 |
if( !f_conv || !arg_flg_convert_filenames ){ |
227 |
pbf->bf_filename = new char[strlen(path) + 1]; |
228 |
#ifndef WINDOWS |
229 |
- if( !pbf->bf_filename ) return -1; |
230 |
+ if( !pbf->bf_filename ){ |
231 |
+ errno = ENOMEM; |
232 |
+ return -1; |
233 |
+ } |
234 |
#endif |
235 |
strcpy(pbf->bf_filename, path); |
236 |
} |
237 |
@@ -564,30 +617,42 @@ |
238 |
pbf_last = pbf; |
239 |
} |
240 |
}else{ |
241 |
- if( !decode_query(metabuf,metabuf_len,"info|length", |
242 |
- (const char**) 0,(size_t*) 0,&t,QUERY_LONG) ) |
243 |
+ if( !decode_query(metabuf,metabuf_len, "info|length", |
244 |
+ (const char**)0, (size_t*) 0, &t, QUERY_LONG) ){ |
245 |
+ errno = EINVAL; |
246 |
return -1; |
247 |
+ } |
248 |
m_btfhead = _new_bfnode(); |
249 |
#ifndef WINDOWS |
250 |
- if( !m_btfhead) return -1; |
251 |
+ if( !m_btfhead ){ |
252 |
+ errno = ENOMEM; |
253 |
+ return -1; |
254 |
+ } |
255 |
#endif |
256 |
m_btfhead->bf_length = m_total_files_length = t; |
257 |
if( saveas ){ |
258 |
m_btfhead->bf_filename = new char[strlen(saveas) + 1]; |
259 |
#ifndef WINDOWS |
260 |
- if(!m_btfhead->bf_filename ) return -1; |
261 |
+ if( !m_btfhead->bf_filename ){ |
262 |
+ errno = ENOMEM; |
263 |
+ return -1; |
264 |
+ } |
265 |
#endif |
266 |
strcpy(m_btfhead->bf_filename, saveas); |
267 |
}else if( arg_flg_convert_filenames ){ |
268 |
char *tmpfn = new char[strlen(path)*2+5]; |
269 |
#ifndef WINDOWS |
270 |
- if( !tmpfn ) return -1; |
271 |
+ if( !tmpfn ){ |
272 |
+ errno = ENOMEM; |
273 |
+ return -1; |
274 |
+ } |
275 |
#endif |
276 |
ConvertFilename(tmpfn, path, strlen(path)*2+5); |
277 |
m_btfhead->bf_filename = new char[strlen(tmpfn) + 1]; |
278 |
#ifndef WINDOWS |
279 |
if( !m_btfhead->bf_filename ){ |
280 |
delete []tmpfn; |
281 |
+ errno = ENOMEM; |
282 |
return -1; |
283 |
} |
284 |
#endif |
285 |
@@ -596,7 +661,10 @@ |
286 |
}else{ |
287 |
m_btfhead->bf_filename = new char[strlen(path) + 1]; |
288 |
#ifndef WINDOWS |
289 |
- if(!m_btfhead->bf_filename ) return -1; |
290 |
+ if( !m_btfhead->bf_filename ){ |
291 |
+ errno = ENOMEM; |
292 |
+ return -1; |
293 |
+ } |
294 |
#endif |
295 |
strcpy(m_btfhead->bf_filename, path); |
296 |
} |
297 |
@@ -694,6 +762,32 @@ |
298 |
size_t btFiles::FillMetaInfo(FILE* fp) |
299 |
{ |
300 |
BTFILE *p; |
301 |
+ const char *refname, *s; |
302 |
+ char path[MAXPATHLEN]; |
303 |
+ |
304 |
+ refname = m_directory ? m_directory : m_btfhead->bf_filename; |
305 |
+ while( (s = strchr(refname, PATH_SP)) && *(s + 1) ){ |
306 |
+ refname = s + 1; |
307 |
+ } |
308 |
+ if( m_directory && '.' == *refname ){ |
309 |
+ char dir[MAXPATHLEN]; |
310 |
+ if( getcwd(dir, sizeof(dir)) && 0==chdir(m_directory) ){ |
311 |
+ if( getcwd(path, sizeof(path)) ){ |
312 |
+ refname = path; |
313 |
+ while( (s = strchr(refname, PATH_SP)) && *(s + 1) ){ |
314 |
+ refname = s + 1; |
315 |
+ } |
316 |
+ } |
317 |
+ chdir(dir); |
318 |
+ } |
319 |
+ } |
320 |
+ if( '/' == *refname || '\0' == *refname || '.' == *refname ){ |
321 |
+ CONSOLE.Warning(1, "error, inappropriate file or directory name \"%s\"", |
322 |
+ m_directory ? m_directory : m_btfhead->bf_filename); |
323 |
+ errno = EINVAL; |
324 |
+ return 0; |
325 |
+ } |
326 |
+ |
327 |
if( m_directory ){ |
328 |
// multi files |
329 |
if( bencode_str("files", fp) != 1 ) return 0; |
330 |
@@ -715,16 +809,15 @@ |
331 |
if(bencode_end_dict_list(fp) != 1 ) return 0; |
332 |
|
333 |
if(bencode_str("name", fp) != 1) return 0; |
334 |
- return bencode_str(m_directory, fp); |
335 |
- |
336 |
+ return bencode_str(refname, fp); |
337 |
}else{ |
338 |
if( bencode_str("length", fp) != 1 ) return 0; |
339 |
if( bencode_int(m_btfhead->bf_length, fp) != 1) return 0; |
340 |
|
341 |
if( bencode_str("name", fp) != 1 ) return 0; |
342 |
- return bencode_str(m_btfhead->bf_filename, fp); |
343 |
+ return bencode_str(refname, fp); |
344 |
} |
345 |
- return 1; |
346 |
+ return 0; |
347 |
} |
348 |
|
349 |
|
350 |
Index: btcontent.cpp |
351 |
=================================================================== |
352 |
--- btcontent.cpp (revision 300) |
353 |
+++ btcontent.cpp (revision 302) |
354 |
@@ -357,7 +357,11 @@ |
355 |
|
356 |
cfg_req_queue_length = (m_piece_length / cfg_req_slice_size) * 2 - 1; |
357 |
|
358 |
- if( m_btfiles.BuildFromMI(b, flen, saveas) < 0 ) ERR_RETURN(); |
359 |
+ if( m_btfiles.BuildFromMI(b, flen, saveas, arg_flg_exam_only) < 0 ){ |
360 |
+ if( EINVAL == errno ) |
361 |
+ CONSOLE.Warning(1, "Torrent metainfo file data is invalid or unusable."); |
362 |
+ ERR_RETURN(); |
363 |
+ } |
364 |
|
365 |
delete []b; |
366 |
b = (char *)0; |
367 |
Index: btfiles.h |
368 |
=================================================================== |
369 |
--- btfiles.h (revision 300) |
370 |
+++ btfiles.h (revision 302) |
371 |
@@ -61,7 +61,7 @@ |
372 |
|
373 |
int BuildFromFS(const char *pathname); |
374 |
int BuildFromMI(const char *metabuf, const size_t metabuf_len, |
375 |
- const char *saveas); |
376 |
+ const char *saveas, unsigned char exam_only); |
377 |
|
378 |
char *GetDataName() const; |
379 |
uint64_t GetTotalLength() const { return m_total_files_length; } |