Bug#823409: proftpd RMemoryLimit large file transfer fails ( possible memory leak )

Daniel Swarbrick daniel.swarbrick at profitbricks.com
Thu Dec 1 13:09:01 UTC 2016


We are also seeing what appears to be a memory leak, which becomes quite
a problem when users upload large files. We are _not_ using RMemoryLimit.

On one of our FTP servers, a user is currently uploading a large file,
430 GB so far, and the proftpd process has used almost 10 GB of memory.
It seems to be concentrated in a single large allocation, according to pmap:

$ sudo pmap 54962 | grep anon
00000000006cb000     48K rw---   [ anon ]
00000000009fc000    720K rw---   [ anon ]
0000000000ab0000      4K rw---   [ anon ]
0000000000ab1000      4K rw---   [ anon ]
0000000000ab2000      4K rw---   [ anon ]
0000000000ab3000     56K rw---   [ anon ]
0000000000ac1000 9698984K rw---   [ anon ]
00007f3232069000      4K rw---   [ anon ]
00007f3232acb000      4K rw---   [ anon ]
00007f3232ffb000      8K rw---   [ anon ]
00007f3234d68000     16K rw---   [ anon ]
00007f32361de000      8K rw---   [ anon ]
00007f32363ed000      4K rw---   [ anon ]
00007f3237681000      8K rw---   [ anon ]
00007f3237fb0000      8K rw---   [ anon ]
00007f32381cf000     40K rw---   [ anon ]
00007f32389f1000     84K rw---   [ anon ]
00007f3238e44000     16K rw---   [ anon ]
00007f32393fa000     16K rw---   [ anon ]
00007f323a25c000     12K rw---   [ anon ]
00007f323a4c3000      4K rw---   [ anon ]
00007f323ad5c000    184K rw---   [ anon ]
00007f323af99000     40K rw---   [ anon ]
00007f323afa7000     16K rw---   [ anon ]
00007f323afad000      8K rw---   [ anon ]
00007fff913c3000      8K r----   [ anon ]
00007fff913c5000      8K r-x--   [ anon ]
ffffffffff600000      4K r-x--   [ anon ]

Digging though the proftpd source code a bit, I see that it implements
memory pools, so this single large allocation may consist of multiple
smaller buffers. I also ran an strace on the process, and can see it
making brk() syscalls every few seconds (i.e., malloc / realloc and
friends).

$ sudo strace -r -e trace=memory -p 54962
Process 54962 attached
     0.000000 brk(0x204b9b000)          = 0x204b9b000
     8.002960 brk(0x204bbc000)          = 0x204bbc000
     3.572409 brk(0x204bdd000)          = 0x204bdd000
     2.019134 brk(0x204bfe000)          = 0x204bfe000
     3.794139 brk(0x204c1f000)          = 0x204c1f000
     0.934894 brk(0x204c40000)          = 0x204c40000
     7.322138 brk(0x204c61000)          = 0x204c61000
     8.286779 brk(0x204c82000)          = 0x204c82000
     8.196694 brk(0x204ca3000)          = 0x204ca3000
     8.105567 brk(0x204cc4000)          = 0x204cc4000
     8.548908 brk(0x204ce5000)          = 0x204ce5000
     8.066531 brk(0x204d06000)          = 0x204d06000
     8.020094 brk(0x204d27000)          = 0x204d27000
     7.149787 brk(0x204d48000)          = 0x204d48000
     7.566161 brk(0x204d69000)          = 0x204d69000
     2.763174 brk(0x204d8a000)          = 0x204d8a000
     5.481161 brk(0x204dab000)          = 0x204dab000
     7.637086 brk(0x204dcc000)          = 0x204dcc000
     2.111138 brk(0x204ded000)          = 0x204ded000
     5.650550 brk(0x204e0e000)          = 0x204e0e000
     6.037580 brk(0x204e2f000)          = 0x204e2f000
     6.959830 brk(0x204e50000)          = 0x204e50000
     7.927986 brk(0x204e71000)          = 0x204e71000
^CProcess 54962 detached

Each time the delta is 135168 bytes, which is exactly 132 KiB. A
slightly more detailed strace shows the brk() always occurring after a
socket read (which lsof showed was the data connection socket):

     0.000027 write(16, "mZ\373G\266\270\271k\205\236(\242\206\3362\204\261\16\371g\\\256\24\22\334\237L\326\207\206\26\362"..., 4380) = 4380
     0.000042 select(1, [0], [], NULL, {0, 0}) = 0 (Timeout)
     0.000032 select(19, [18], [], NULL, {1, 0}) = 1 (in [18], left {0, 999998})
     0.000039 read(18, "\31\274B\270\373\215\345\364\30\357[\37\n\276\33j\177\32|}\246\370wA\263k\255KR\223d1"..., 87380) = 2920
     0.000047 brk(0x207ee9000)          = 0x207ee9000

It looks very much like proftpd is allocating some kind of socket receive buffer, and forgetting to free it.



More information about the Pkg-proftpd-maintainers mailing list