gojue/ecapture

detectOpenssl consumes huge amount of memory

Closed this issue · 1 comments

Describe the bug
In tls mode, if the supplied libssl contains big .rodata section, then the current logic to detect openssl version in detectOpenssl() consumes huge amount of memory.

To Reproduce

Note: For my scenario, I had to intercept network calls from node applications. As the node runtime binaries doesn't uses OS libssl.so, instead they are statically linked with their own openssl. I figured this out by searching for SSL_write symbol in its symbols using readelf -s.

Steps to reproduce the behavior:

  1. Download the latest version of ecapture & extract it.
  2. Download latest node from here & extract it.
  3. Run ecapture in tls-mode with libssl=node
sudo ecapture-v0.7.0-linux-x86_64/ecapture tls --libssl="node-v20.10.0-linux-x64/bin/node" --mapsize 256
  1. In another terminal, use pmap command to see memory mappings
sudo pmap -x `pidof ecapture`

Response:

758667:   ecapture-v0.7.0-linux-x86_64/ecapture tls --libssl=node-v20.10.0-linux-x64/bin/node --mapsize 256
Address           Kbytes     RSS   Dirty Mode  Mapping
0000000000400000    4504    4056       0 r-x-- ecapture
0000000000866000    5228    3756       0 r---- ecapture
0000000000d81000    3260     572      72 rw--- ecapture
00000000010b0000    6568    6340    6340 rw---   [ anon ]
000000c000000000 2060288 1972460 1972460 rw---   [ anon ]
000000c07dc00000   36864       0       0 -----   [ anon ]
00007f696a325000    1028       4       0 rw-s-   [ anon ]
00007f696a426000    1028       4       0 rw-s-   [ anon ]
00007f696a527000    1028       4       0 rw-s-   [ anon ]
00007f696a628000    1028       4       0 rw-s-   [ anon ]
00007f696a729000    1028       8       4 rw-s-   [ anon ]
00007f696a82a000    1028       4       0 rw-s-   [ anon ]
00007f696a92b000    1028       4       0 rw-s-   [ anon ]
00007f696aa2c000    1028       4       0 rw-s-   [ anon ]
00007f696ab2d000    1028       4       0 rw-s-   [ anon ]
00007f696ac2e000    1028       4       0 rw-s-   [ anon ]
00007f696ad2f000    1028       4       0 rw-s-   [ anon ]
00007f696ae30000    1028       4       0 rw-s-   [ anon ]
00007f696af31000    1028       4       0 rw-s-   [ anon ]
00007f696b032000    1028       4       0 rw-s-   [ anon ]
00007f696b133000    1028       4       0 rw-s-   [ anon ]
00007f696b234000    1028       4       0 rw-s-   [ anon ]
00007f696b335000    7796    6656    6656 rw---   [ anon ]
00007f696bada000   33120   31768   31768 rw---   [ anon ]
00007f696db32000    1024      64      64 rw---   [ anon ]
00007f696dc32000    1108    1108    1108 rw---   [ anon ]
00007f696dd47000     740       0       0 rw---   [ anon ]
00007f696de00000   30720       4       4 rw---   [ anon ]
00007f696fc00000    1308       0       0 rw---   [ anon ]
00007f696fd47000  263680       0       0 -----   [ anon ]
00007f697fec7000       4       4       4 rw---   [ anon ]
00007f697fec8000  524284       0       0 -----   [ anon ]
00007f699fec7000       4       4       4 rw---   [ anon ]
00007f699fec8000  293564       0       0 -----   [ anon ]
00007f69b1d77000       4       4       4 rw---   [ anon ]
00007f69b1d78000   36692       0       0 -----   [ anon ]
00007f69b414d000       4       4       4 rw---   [ anon ]
00007f69b414e000    4580       0       0 -----   [ anon ]
00007f69b45c7000       4       4       4 rw---   [ anon ]
00007f69b45c8000     508       0       0 -----   [ anon ]
00007f69b4647000     384      52      52 rw---   [ anon ]
00007ffeda7b5000     132      16      16 rw---   [ stack ]
00007ffeda7ef000      16       0       0 r----   [ anon ]
00007ffeda7f3000       8       8       0 r-x--   [ anon ]
ffffffffff600000       4       0       0 --x--   [ anon ]
---------------- ------- ------- -------
total kB         3332848 2026948 2018564

  1. Notice the 5th huge allocation

Expected behavior

eCapture shouldn't consume this much memory

Additional context

The bug is in the detectOpenssl() method. Currently the logic flow is like this;

  1. we first try to read whole of the .rodata section into a slice,
  2. split it by \x00, to get slice of slice,
  3. creating dumpString map by iterating through the slice we get in step-2,
  4. finally iterating through map values & applying regex to figure out the version

The steps 1-3 takes hug memory if the .rodata section is of large size

In #438, I have improved logic to consume less memory.

merged, thanks.