Gentoo Archives: gentoo-commits

From: "Alex Legler (a3li)" <a3li@g.o>
To: gentoo-commits@l.g.o
Subject: [gentoo-commits] gentoo-x86 commit in net-p2p/ctorrent/files: ctorrent-CVE-2009-1759.patch
Date: Mon, 30 Aug 2010 10:52:19
Message-Id: 20100830105208.ABA9920047@flycatcher.gentoo.org
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; }