CVE-2009-1759 http://sourceforge.net/tracker/?func=detail&aid=2782875&group_id=202532&atid=981959 Index: bencode.h =================================================================== --- bencode.h (revision 301) +++ bencode.h (revision 302) @@ -25,7 +25,7 @@ size_t decode_list(const char *b,size_t len,const char *keylist); size_t decode_rev(const char *b,size_t len,const char *keylist); size_t decode_query(const char *b,size_t len,const char *keylist,const char **ps,size_t *pi,int64_t *pl,int method); -size_t decode_list2path(const char *b, size_t n, char *pathname); +size_t decode_list2path(const char *b, size_t n, char *pathname, size_t maxlen); size_t bencode_buf(const char *str,size_t len,FILE *fp); size_t bencode_str(const char *str, FILE *fp); size_t bencode_int(const uint64_t integer, FILE *fp); Index: bencode.cpp =================================================================== --- bencode.cpp (revision 301) +++ bencode.cpp (revision 302) @@ -233,22 +233,28 @@ return bencode_end_dict_list(fp); } -size_t decode_list2path(const char *b, size_t n, char *pathname) +size_t decode_list2path(const char *b, size_t n, char *pathname, size_t maxlen) { const char *pb = b; const char *s = (char *) 0; + const char *endmax = pathname + maxlen - 1; size_t r,q; if( 'l' != *pb ) return 0; pb++; n--; if( !n ) return 0; - for(; n;){ + while( n && pathname < endmax ){ if(!(r = buf_str(pb, n, &s, &q)) ) return 0; + if( q >= maxlen ) return 0; memcpy(pathname, s, q); pathname += q; - pb += r; n -= r; - if( 'e' != *pb ){*pathname = PATH_SP, pathname++;} else break; + maxlen -= q; + pb += r; + n -= r; + if( 'e' == *pb ) break; + if( pathname >= endmax ) return 0; + *pathname++ = PATH_SP; } *pathname = '\0'; return (pb - b + 1); Index: btfiles.cpp =================================================================== --- btfiles.cpp (revision 301) +++ btfiles.cpp (revision 302) @@ -471,6 +471,8 @@ BTFILE *pbf_last = (BTFILE*) 0; BTFILE *pbf = (BTFILE*) 0; size_t dl; + unsigned long nfiles = 0; + if( decode_query(metabuf,metabuf_len,"info|length", (const char**) 0,(size_t*) 0,(int64_t*) 0,QUERY_LONG) ) return -1; @@ -524,12 +526,18 @@ #ifndef WINDOWS if( !pbf ) return -1; #endif + nfiles++; pbf->bf_length = t; m_total_files_length += t; r = decode_query(p, dl, "path", (const char **)0, &n, (int64_t*)0, QUERY_POS); - if( !r ) return -1; - if(!decode_list2path(p + r, n, path)) return -1; + if( !r || !decode_list2path(p + r, n, path, sizeof(path)) ){ + CONSOLE.Warning(1, + "error, invalid path in torrent data for file %lu at offset %llu", + nfiles, m_total_files_length - t); + delete pbf; + return -1; + } int f_conv; char *tmpfn = new char[strlen(path)*2+5];