y500 / libtorrent

Automatically exported from code.google.com/p/libtorrent
0 stars 0 forks source link

buffer overflow in peer_connection.cpp:236 #720

Open GoogleCodeExporter opened 8 years ago

GoogleCodeExporter commented 8 years ago
qbittorrent crashed:

==3376== ERROR: AddressSanitizer: global-buffer-overflow on address 
0x0000014073f7 at pc 0xe301b4 bp 0x7f6018ac0660 sp 0x7f6018ac0658
READ of size 1 at 0x0000014073f7 thread T3
    #0 0xe301b3 (/home/ivan/d/qbittorrent-build/qbittorrent+0xe301b3)
    #1 0xcae73c (/home/ivan/d/qbittorrent-build/qbittorrent+0xcae73c)
    #2 0xa939a2 (/home/ivan/d/qbittorrent-build/qbittorrent+0xa939a2)
    #3 0xef5545 (/home/ivan/d/qbittorrent-build/qbittorrent+0xef5545)
    #4 0xa252b7 (/home/ivan/d/qbittorrent-build/qbittorrent+0xa252b7)
    #5 0x90d840 (/home/ivan/d/qbittorrent-build/qbittorrent+0x90d840)
    #6 0x953044 (/home/ivan/d/qbittorrent-build/qbittorrent+0x953044)
    #7 0x97888a (/home/ivan/d/qbittorrent-build/qbittorrent+0x97888a)
    #8 0x80dd77 (/home/ivan/d/qbittorrent-build/qbittorrent+0x80dd77)
    #9 0x81ff6b (/home/ivan/d/qbittorrent-build/qbittorrent+0x81ff6b)
    #10 0x820402 (/home/ivan/d/qbittorrent-build/qbittorrent+0x820402)
    #11 0x940893 (/home/ivan/d/qbittorrent-build/qbittorrent+0x940893)
    #12 0x957f2b (/home/ivan/d/qbittorrent-build/qbittorrent+0x957f2b)
    #13 0x7fe8c3 (/home/ivan/d/qbittorrent-build/qbittorrent+0x7fe8c3)
    #14 0x7f602c722b97 (/usr/lib/x86_64-linux-gnu/libasan.so.0.0.0+0x18b97)
    #15 0x7f602a0ff181 (/lib/x86_64-linux-gnu/libpthread-2.19.so+0x8181)
    #16 0x7f602960befc (/lib/x86_64-linux-gnu/libc-2.19.so+0xfaefc)
0x0000014073f7 is located 41 bytes to the left of global variable '*.LC0 
(asio_ssl.cpp)' (0x1407420) of size 9
  '*.LC0 (asio_ssl.cpp)' is ascii string 'asio.ssl'
0x0000014073f7 is located 0 bytes to the right of global variable 
'GeoIP_country_code (GeoIP.c)' (0x1407100) of size 759
  'GeoIP_country_code (GeoIP.c)' is ascii string '--'
Shadow bytes around the buggy address:
  0x000080278e20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x000080278e30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x000080278e40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x000080278e50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x000080278e60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x000080278e70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00[07]f9
  0x000080278e80: f9 f9 f9 f9 00 01 f9 f9 f9 f9 f9 f9 00 07 f9 f9
  0x000080278e90: f9 f9 f9 f9 00 06 f9 f9 f9 f9 f9 f9 00 04 f9 f9
  0x000080278ea0: f9 f9 f9 f9 00 00 f9 f9 f9 f9 f9 f9 00 00 01 f9
  0x000080278eb0: f9 f9 f9 f9 00 00 01 f9 f9 f9 f9 f9 00 00 00 01
  0x000080278ec0: f9 f9 f9 f9 00 00 f9 f9 f9 f9 f9 f9 00 00 00 03
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07 
  Heap left redzone:     fa
  Heap righ redzone:     fb
  Freed Heap region:     fd
  Stack left redzone:    f1
  Stack mid redzone:     f2
  Stack right redzone:   f3
  Stack partial redzone: f4
  Stack after return:    f5
  Stack use after scope: f8
  Global redzone:        f9
  Global init order:     f6
  Poisoned by user:      f7
  ASan internal:         fe
Thread T3 created by T0 here:
    #0 0x7f602c714b5b (/usr/lib/x86_64-linux-gnu/libasan.so.0.0.0+0xab5b)
    #1 0x823343 (/home/ivan/d/qbittorrent-build/qbittorrent+0x823343)
==3376== ABORTING

$ addr2line 0xe301b3 0xcae73c 0xa939a2 0xef5545 0xa252b7 0x90d840 0x953044 
0x97888a 0x80dd77 0x81ff6b 0x820402 0x940893 0x957f2b 0x7fe8c3 -p -e 
/home/ivan/d/qbittorrent-build/qbittorrent
/home/ivan/d/libtorrent-svn-1_0/src/peer_connection.cpp:236
/home/ivan/d/libtorrent-svn-1_0/src/bt_peer_connection.cpp:130
/home/ivan/d/libtorrent-svn-1_0/src/torrent.cpp:5925 (discriminator 4)
/home/ivan/d/libtorrent-svn-1_0/src/policy.cpp:1615
/home/ivan/d/libtorrent-svn-1_0/src/torrent.cpp:8929
/home/ivan/d/libtorrent-svn-1_0/src/session_impl.cpp:4577
/home/ivan/d/libtorrent-svn-1_0/src/session_impl.cpp:3494
/usr/include/boost/bind/mem_fn_template.hpp:165
/usr/include/boost/asio/detail/task_io_service_operation.hpp:37
/usr/include/boost/asio/detail/impl/task_io_service.ipp:153 (discriminator 1)   

/usr/include/boost/asio/impl/io_service.ipp:66                                  

/home/ivan/d/libtorrent-svn-1_0/src/session_impl.cpp:4886                       

/usr/include/boost/bind/mem_fn_template.hpp:49                                  

/usr/include/boost/asio/detail/impl/posix_thread.ipp:64                         

ivan@liberty:~$ addr2line 0xe301b3 0xcae73c 0xa939a2 0xef5545 0xa252b7 0x90d840 
0x953044 0x97888a 0x80dd77 0x81ff6b 0x820402 0x940893 0x957f2b 0x7fe8c3 -e 
/home/ivan/d/qbittorrent-build/qbittorrent                                      

/home/ivan/d/libtorrent-svn-1_0/src/peer_connection.cpp:236                     

/home/ivan/d/libtorrent-svn-1_0/src/bt_peer_connection.cpp:130                  

/home/ivan/d/libtorrent-svn-1_0/src/torrent.cpp:5925 (discriminator 4)          

/home/ivan/d/libtorrent-svn-1_0/src/policy.cpp:1615                             

/home/ivan/d/libtorrent-svn-1_0/src/torrent.cpp:8929                            

/home/ivan/d/libtorrent-svn-1_0/src/session_impl.cpp:4577                       

/home/ivan/d/libtorrent-svn-1_0/src/session_impl.cpp:3494                       

/usr/include/boost/bind/mem_fn_template.hpp:165                                 

/usr/include/boost/asio/detail/task_io_service_operation.hpp:37                 

/usr/include/boost/asio/detail/impl/task_io_service.ipp:153 (discriminator 1)   

/usr/include/boost/asio/impl/io_service.ipp:66                                  

/home/ivan/d/libtorrent-svn-1_0/src/session_impl.cpp:4886                       

/usr/include/boost/bind/mem_fn_template.hpp:49                                  

/usr/include/boost/asio/detail/impl/posix_thread.ipp:64                         

Original issue reported on code.google.com by vanya...@gmail.com on 12 Feb 2015 at 11:21

GoogleCodeExporter commented 8 years ago
revision 10529

Original comment by vanya...@gmail.com on 12 Feb 2015 at 11:22

GoogleCodeExporter commented 8 years ago
that looks like a false positive.

It looks like an optimistic read, which is common in optimizations, especially 
in string handling. Note how it's 0 bytes past the end of the block of country 
names in GeoIP.c. it's as if the 3 byte string was read with a 4 byte (full 
word) read. It's a fairly typical optimization since reading off the end of 
your buffer is OK, and page boundaries won't be crossed with anyway, since it's 
an aligned read.

Is there a way to tell address sanitizer to suppress this particular read? 
otherwise, you could also turn off geoip, to not trigger this.

Original comment by arvid.no...@gmail.com on 13 Feb 2015 at 4:17

GoogleCodeExporter commented 8 years ago
> It's a fairly typical optimization since reading off the end of your buffer 
is OK, and page boundaries won't be crossed with anyway, since it's an aligned 
read.

Address sanitizer is special compiler option, not binary instrumentation. Also 
authors claim there is no false positives. 
http://static.googleusercontent.com/media/research.google.com/en//pubs/archive/3
7752.pdf -- see 3.6.

Assuming there is no false positives this is either bug in address sanitizer or 
GeoIP.

Original comment by vanya...@gmail.com on 13 Feb 2015 at 8:58

GoogleCodeExporter commented 8 years ago
Could _GeoIP_seek_record returns index that is out of bounds of 
GeoIP_country_code?

Original comment by vanya...@gmail.com on 13 Feb 2015 at 9:02

GoogleCodeExporter commented 8 years ago
0x0000014073f7 is located 0 bytes to the right of global variable 
'GeoIP_country_code (GeoIP.c)' (0x1407100) of size 759

759 = 253 * 3

/home/ivan/d/libtorrent-svn-1_0/src/peer_connection.cpp:236

    m_country[0] = country[0];

If I understand correctly this error happened because _GeoIP_seek_record 
returned 253.

Original comment by vanya...@gmail.com on 13 Feb 2015 at 9:07

GoogleCodeExporter commented 8 years ago
I have made a very simple patch to test my hypothesis:

diff --git a/src/GeoIP.c b/src/GeoIP.c
index cb4437e..f868e80 100644
--- a/src/GeoIP.c
+++ b/src/GeoIP.c
@@ -788,6 +788,11 @@ const char *GeoIP_country_name_by_ipnum (GeoIP* gi, 
unsigned long ipnum) {
 const char *GeoIP_country_code_by_ipnum (GeoIP* gi, unsigned long ipnum) {
        int country_id;
        country_id = GeoIP_id_by_ipnum(gi, ipnum);
+       if (country_id >= 253)
+       {
+               fprintf(stderr, "country_id is out of range %d, ip: %lu\n", 
country_id, ipnum);
+               return NULL;
+       }
        return (country_id > 0) ? GeoIP_country_code[country_id] : NULL;
 }

diff --git a/src/session_impl.cpp b/src/session_impl.cpp
index ff65680..db07478 100644
--- a/src/session_impl.cpp
+++ b/src/session_impl.cpp
@@ -1441,6 +1441,16 @@ namespace aux {
                TORRENT_ASSERT(is_network_thread());

                if (!a.is_v4() || m_country_db == 0) return 0;
+
+               for (size_t i = 0; i != 100; ++i)
+               {
+                       unsigned a = rand() % 256;
+                       unsigned b = rand() % 256;
+                       unsigned c = rand() % 256;
+                       unsigned d = rand() % 256;
+                       GeoIP_country_code_by_ipnum(m_country_db, (a << 24) | 
(b << 16) | (c << 8) | d);
+               }
+
                return GeoIP_country_code_by_ipnum(m_country_db, a.to_v4().to_ulong());
        }

Almost instantly after I started qbittorrent I've got an error:

country_id is out of range 254, ip: 693073990

If I do my arithmetic right it corresponds to ip address 41.79.120.70 (or 
70.120.79.41, not sure).

Original comment by vanya...@gmail.com on 16 Feb 2015 at 12:59

GoogleCodeExporter commented 8 years ago
Yes. There are lots of them:

country_id is out of range 253, ip: 3194056757
country_id is out of range 253, ip: 3131009708
country_id is out of range 254, ip: 702434290
country_id is out of range 253, ip: 3362477991
country_id is out of range 253, ip: 3187950232

Original comment by vanya...@gmail.com on 16 Feb 2015 at 1:02

GoogleCodeExporter commented 8 years ago
would you mind reporting this to maxmind? It probably makes sense to grab their 
latest version of GeoIP.c first, to confirm it still happens in there.

It probably makes sense to update the libtorrent version to the latest on 
github anyway.

https://github.com/maxmind/geoip-api-c/tree/master/libGeoIP

It looks like they may have fixed this issue though, by failing with an error 
"invalid database".

Original comment by arvid.no...@gmail.com on 16 Feb 2015 at 1:26

GoogleCodeExporter commented 8 years ago
I've reported a issue https://github.com/maxmind/geoip-api-c/issues/53

I still don't see why the same error couldn't occur on corrupted database in 
the latest version.

Original comment by vanya...@gmail.com on 16 Feb 2015 at 8:48