View Issue Details

IDProjectCategoryView StatusLast Update
0006263unrealircdpublic2023-04-22 14:43
Reporterimmibis Assigned Tosyzop  
PrioritynormalSeveritymajorReproducibilityalways
Status resolvedResolutionfixed 
PlatformLinuxOSLinuxOS Version5.14.41-gentoo
Product Version6.0.7 
Fixed in Version6.1.0 
Summary0006263: Memory leak when TLS connections fails synchronously
Descriptionvalgrind reports:
==20706== 293,977 (25,120 direct, 268,857 indirect) bytes in 4 blocks are definitely lost in loss record 2,669 of 2,672
==20706== at 0x48407E4: malloc (vg_replace_malloc.c:393)
==20706== by 0x4A78859: CRYPTO_zalloc (in /usr/lib64/libcrypto.so.1.1)
==20706== by 0x48B7405: SSL_new (in /usr/lib64/libssl.so.1.1)
==20706== by 0x162F21: unreal_tls_client_handshake (tls.c:659)
==20706== by 0x15419A: fd_select (dispatch.c:530)
==20706== by 0x123F67: SocketLoop (ircd.c:916)
==20706== by 0x122D83: main (ircd.c:883)

Looking at the code, I don't see where the SSL context is freed in unreal_tls_client_handshake if unreal_tls_connect returns -1.
I also see that client_starttls DOES free the SSL context if unreal_tls_connect returns -1.
Steps To Reproduce* Start the server in valgrind: valgrind --leak-check=full install/bin/unrealircd -F
* Wait for at least two failed connection attempts.
* Stop the server: ./unrealircd stop

I isolated it to a specific link block from pissnet:
link snode.comploti.st {
  incoming {mask *;}
  outgoing {
    hostname 2a01:4f8:a0:380f::1;
    port 6900;
    options {tls; autoconnect;};
  };
  password "XVmmWLq/LyPWShdKial7Beyxb1Hs7e4E0WU/1eX9ywQ=" {spkifp;};
  class servers;
};

This server address returns ICMP destination unreachable (prohibited) which causes connect to return error EACCES ("Permission denied"), a combination I've never seen before. Anyway, this is somehow returned synchronously (maybe it's cached?) from SSL_connect and the SSL context is leaked.

This is likely reproducible with any other synchronous connect error, perhaps "unreachable network".
Additional InformationSeverity is marked as "major" because this does cause a server crash after several weeks - however this does not occur on properly administered servers where all link blocks point to correct addresses :) and probably also does not occur if the connect failure is reported asynchronously (which is the case for most failures).
TagsNo tags attached.
3rd party modules

Activities

syzop

2023-04-22 13:24

administrator   ~0022842

Thanks, will check it out :)

syzop

2023-04-22 14:43

administrator   ~0022843

Thanks for the clear report! It was was basically exactly like you said.
I could reproduce it with an iptables OUTPUT rule with -j REJECT.
Fixed in https://github.com/unrealircd/unrealircd/commit/f467c031c1812c8ec94decd89072a6207ce24e41 which will become 6.1.0.

commit f467c031c1812c8ec94decd89072a6207ce24e41 (HEAD -> unreal60_dev, origin/unreal60_dev, origin/HEAD)
Author: Bram Matthys <[email protected]>
Date: Sat Apr 22 14:36:21 2023 +0200

    Fix memory leak when an outgoing TLS_connect() fails.
    Reported by immibis in https://bugs.unrealircd.org/view.php?id=6263

Issue History

Date Modified Username Field Change
2023-04-22 10:36 immibis New Issue
2023-04-22 13:24 syzop Assigned To => syzop
2023-04-22 13:24 syzop Status new => acknowledged
2023-04-22 13:24 syzop Note Added: 0022842
2023-04-22 14:43 syzop Status acknowledged => resolved
2023-04-22 14:43 syzop Resolution open => fixed
2023-04-22 14:43 syzop Note Added: 0022843
2023-04-22 14:43 syzop Fixed in Version => 6.1.0