rakshasa / rtorrent

rTorrent BitTorrent client
https://github.com/rakshasa/rtorrent/wiki
GNU General Public License v2.0
4.06k stars 412 forks source link

Security issue? #86

Open q53 opened 11 years ago

q53 commented 11 years ago

rtorrent 0.8.9/0.12.9 with ipv6 patch. My rtorrent crash with: rtorrent: Handshake::fill_read_buffer(...) Buffer overflow.

I'm using a selinux policy, so I took a look into audit.log: type=AVC msg=audit(1344800018.036:36614): avc: denied { read } for pid=24872 comm="rtorrent" name="cpuinfo" dev=proc ino=4026532030 scontext=unconfined_u:unconfined_r:rtorrent_t:s0 tcontext=system_u:object_r:proc_t:s0 tclass=file

Look like somebody tried hack my host. Unfortunately, there is no a core file. I haven't found any security issues for this case and believe the developer should know.

rakshasa commented 11 years ago

The exception catches reads beyond the end of the buffer, so there is no exploit possible.

And the bug is likely fixed in current release so closing.

q53 commented 11 years ago

The exception catches reads beyond the end of the buffer, so there is no exploit possible.

Yes, I know. That's just a sign something is wrong. The problem is the audit message: rtorrent trying get access to /proc/cpuinfo, which forbidden and never should happed for normal run. That is can do only some "introduced" code (exploit). Off course, it is possible that there was a piece of ipv6 code exploited, but i very doubt.

rakshasa commented 11 years ago

This happens after the stack has unwinded and the catch in rtorrent main prints out the message, so tr reproducing it by throwing exceptions and see if it gives the same selinux warning.

q53 commented 11 years ago

Do you advise me recompile rtorrent with hardcoded "throw"? Hardly an exception handler would search anything in /proc/cpuonfo.

Dmole commented 10 years ago

Same issue in rTorrent 0.9.2/0.13.2

iceton commented 10 years ago

Same issue in 0.8.9/0.12.9. Why is this not an issue if rTorrent crashes? Is it possible to make rTorrent ignore reads beyond the buffer?

q53 commented 9 years ago

Crashs became pretty often and annoying. So i have checked futher versions and didn't find any changes which could fix the error (the message from Dmole confirms it). So here is a quick dirty fix which works for me and can be applied for the current version: http://pastebin.com/raw.php?i=6VBpYQyD

hilalafridi commented 8 years ago

getting something similar 1445534229 C Caught internal_error: 'Handshake::fill_read_buffer(...) Buffer overflow.'. ---DUMP--- /opt/lib/libtorrent.so.19(_ZN7torrent14internal_error10initializeERKSs+0x202) [0x7f142eae6672] /opt/bin/p2pedia-delivery-agentrtorrent(_ZN7torrent14internal_errorC2EPKc+0x3e) [0x445f9e] /opt/lib/libtorrent.so.19(+0xbfa1a) [0x7f142eb73a1a] /opt/lib/libtorrent.so.19(+0xc2a5c) [0x7f142eb76a5c] /opt/lib/libtorrent.so.19(_ZN7torrent9PollEPoll7performEv+0xd7) [0x7f142eaf7a37] /opt/lib/libtorrent.so.19(_ZN7torrent9PollEPoll7do_pollEli+0x50) [0x7f142eaf7ae0] /opt/lib/libtorrent.so.19(_ZN7torrent11thread_base10eventloopEPS0+0x11c) [0x7f142eb317ac] /opt/bin/rtorrent() [0x41216d] /lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xf5) [0x7f142d6aaec5] /opt/bin/p2pedia-delivery-agentrtorrent() [0x4128b4]

---END---

rakshasa commented 8 years ago

The code makes sure at a low level that no security issuses will happen. For patches to fix related issues please inform me.

hilalafridi commented 8 years ago

hi, what information do you need from my side?

samhocevar commented 2 years ago

This issue still happens to us once in a while, but it looks more like a problem with libtorrent. We use version 0.13.8.

I reviewed the protocol code to try to figure out what was causing the crash and I am a bit puzzled, because everything looks fine to me.

Most calls to Handshake::fill_read_buffer(int size) are safe because they fall into one of these two categories:

There are two exceptions, both in event_read():

    case READ_ENC_PAD:
      if (m_readPos) {
        // Read padC + lenIA or padD; pad length in m_readPos.
        if (!fill_read_buffer(m_readPos + (m_incoming ? 2 : 0)))
          // This can be improved (consume as much as was read)
          break;

This situation is indirectly handled in Handshake::read_encryption_negotiation(), which ensures that m_readPos <= enc_pad_size and throws handshake_error otherwise.

And this is the second one:

    case READ_ENC_IA:
      // Just read (and automatically decrypt) the initial payload
      // and leave it in the buffer for READ_INFO later.
      if (m_encryption.length_ia() > 0 && !fill_read_buffer(m_encryption.length_ia()))
        break;

This is also indirectly handled in Handshake::read_negotiation_reply(), which ensures that m_encryption.length_ia() <= handshake_size and throws handshake_error otherwise.

Did I miss something maybe?