Description of problem: Openvas scanner always throws SIGSEGV error in the gnutls code in gnutls_handshake. Gnutls gets called from the openvas-libraries. As a result scanner daemon is running, but it throws away each attempt for connection. One issue is to gnutls as it should detect error state and report some sane error message instead of core dumping. Second issue is probably about openvas-libraries to use gnutls in such particular way it dies on SIGSEGV Version-Release number of selected component (if applicable): openvas-libraries.i686 4.0.3-2.fc16 openvas-libraries.i686 4.0.5-5.fc16 openvas-scanner.i686 3.2.3-1.fc16 gnutls.i686 2.12.7-2.fc16 How reproducible: 100% Steps to Reproduce: 1) Install openvas scanner yum install openvas-scanner openvas-libraries yum install openvas-scanner-debuginfo openvas-libraries-debugin 2) Configure the certificate openvas-mkcert (Enter, enter ...) 3) Download signatures openvas-nvt-sync 4) Run the openvas-scanner in debugger gdb --args openvas-scanner -f -p 9391 set follow-fork-mode child run 5) In seccond session run some ssl/tls client for example gnutls-cli --insecure -p 9391 127.0.0.1 Actual results: Connection is established to the openvassdm but the child forked process dies instantly with SIGSEGV thus dropping the connection. Expected results: SSL/TLS connection should be established. If there is some error the gnutls should report some sane error and not just SIGSEGV.
Sorry the point 4) shuold be: 4) Run the openvas-scanner in debugger gdb --args openvas-scanner -f -p 9391 set follow-fork-mode child run Program received signal SIGSEGV, Segmentation fault. 0x4caba11c in _gnutls_pkcs1_rsa_decrypt (plaintext=0x0, ciphertext=0xabd79c8, params= 0xabd7968, params_len=0, btype=0) at gnutls_pk.c:220 220 pk_params.params[i] = params[i]; (gdb) where #0 0x4caba11c in _gnutls_pkcs1_rsa_decrypt (plaintext=0x0, ciphertext=0xabd79c8, params=0xabd7968, params_len=0, btype=0) at gnutls_pk.c:220 #1 0x00000000 in ?? ()
(gbd) br ovas_scanner_context_attach (gbd) br gnutls_handshake (gbd) br _gnutls_handshake_server (gdb) br _gnutls_recv_client_kx_message Breakpoint 4, ovas_scanner_context_attach (ctx=0xabcafc0, soc=9) at /usr/src/debug/openvas-libraries-4.0.5/misc/network.c:1285 1285 ret = gnutls_handshake (fp->tls_session); (gdb) where #0 ovas_scanner_context_attach (ctx=0xabcafc0, soc=9) at /usr/src/debug/openvas-libraries-4.0.5/misc/network.c:1285 #1 0x0805578b in scanner_thread (globals=0xabd6298) at /usr/src/debug/openvas-scanner-3.2.3/src/openvassd.c:456 #2 0x0805bf95 in create_process (function=0x80555e0 <scanner_thread>, argument= 0xabd6298) at /usr/src/debug/openvas-scanner-3.2.3/src/processes.c:106 #3 0x080561d2 in main_loop () at /usr/src/debug/openvas-scanner-3.2.3/src/openvassd.c:876 #4 0x0804f126 in main (argc=1, argv=0xbffff5d4, envp=0xbffff5e8) at /usr/src/debug/openvas-scanner-3.2.3/src/openvassd.c:1251 Breakpoint 1, gnutls_handshake (session=0xabd8a18) at gnutls_handshake.c:2652 2652 { (gdb) cont Continuing. Program received signal SIGSEGV, Segmentation fault. 0x4caba11c in _gnutls_pkcs1_rsa_decrypt (plaintext=0x0, ciphertext=0xabd79c8, params= 0xabd7968, params_len=0, btype=0) at gnutls_pk.c:220 220 pk_params.params[i] = params[i]; (gdb) where #0 0x4caba11c in _gnutls_pkcs1_rsa_decrypt (plaintext=0x0, ciphertext=0xabd79c8, params=0xabd7968, params_len=0, btype=0) at gnutls_pk.c:220 #1 0x00000000 in ?? () (gdb)
Issue remains in the 4.0.6 openvas-libraries-4.0.6 https://koji.fedoraproject.org/koji/buildinfo?buildID=272497 openvas-scanner-3.2.5 https://koji.fedoraproject.org/koji/buildinfo?buildID=272500
Please maintainers of gnutls - could you help?
How is the gnutls initialized in the openvas scanner daemon? Is it initialized in the parent and then the handshake is started in the child process? I suspect that it can be caused by this. Could the code be changed to not initialize gnutls in the parent process but only after the accept is done in the child?
Hi Tomas, thanks for the hint. I will try to focus more in this direction. AFAIK in case of openvas-server the gnutls is initiated in the child, but I admit it is possible I overlooked something important what is done on global level. I believe the gnutls_init and most of the other initialisation is called from the child process within the same function as the gnutls_handshake: openvas-libraries-4.0.6/misc/network.c:ovas_scanner_context_attach Best regards Michal Ambroz
Issue still persists in : gnutls-2.12.7-2.fc16.i686 openvas-scanner-3.3+beta2-1.fc16.i686 openvas-libraries-5.0+beta2-1.fc16.i686 I believe it is a bug in gnutls. In the function _gnutls_pkcs1_rsa_decrypt there is a code which copies data from function parameter to internal local structure without checking the maximum alocated size. This allows for buffer overflow and potentially code execution. gdb --args openvassd -f -p 9391 >set follow-fork-mode child >br gnutls_kx.c:456 >br auth_rsa.c:180 >br gnutls_privkey.c:614 >br gnutls_pk.c:220 >run >bt #0 _gnutls_pkcs1_rsa_decrypt (plaintext=0xbffff0b0, ciphertext=0xbffff0b8, params=0xab86b50, params_len=65281, btype=2) at gnutls_pk.c:220 #1 0x4f2a3e03 in gnutls_privkey_decrypt_data (key=0xab862e0, flags=0, ciphertext=0xbffff0b8, plaintext=0xbffff0b0) at gnutls_privkey.c:614 #2 0x4f28837e in proc_rsa_client_kx (session=0xab87900, data=0xab88990 "", _data_size=130) at auth_rsa.c:180 #3 0x4f280c62 in _gnutls_recv_client_kx_message (session=0xab87900) at gnutls_kx.c:456 #4 0x4f27ca66 in _gnutls_handshake_server (session=0xab87900) at gnutls_handshake.c:3059 #5 0x4f27d350 in gnutls_handshake (session=0xab87900) at gnutls_handshake.c:2677 #6 0x0011ea3b in ovas_scanner_context_attach (ctx=0xab7af08, soc=9) at /usr/src/debug/openvas-libraries-5.0+beta2/misc/network.c:1286 #7 0x0805586b in scanner_thread (globals=0xab88ef0) at /usr/src/debug/openvas-scanner-3.3+beta2/src/openvassd.c:456 #8 0x0805c185 in create_process (function=0x80556c0 <scanner_thread>, argument= 0xab88ef0) at /usr/src/debug/openvas-scanner-3.3+beta2/src/processes.c:106 #9 0x080562e2 in main_loop () at /usr/src/debug/openvas-scanner-3.3+beta2/src/openvassd.c:876 #10 0x0804eea5 in main (argc=1, argv=0xbffff5d4, envp=0xbffff5e8) at /usr/src/debug/openvas-scanner-3.3+beta2/src/openvassd.c:1259 This code in gnutls (gnutls_pk.c:220) will overwrite the stack because the function trusts that the declared size of the pk_params.params will be bigger than the size of parameters from the configured pkcs11 key: 209 _gnutls_pkcs1_rsa_decrypt (gnutls_datum_t * plaintext, 210 const gnutls_datum_t * ciphertext, 211 bigint_t * params, unsigned params_len, 212 unsigned btype) 213 { 214 unsigned int k, i; 215 int ret; 216 size_t esize, mod_bits; 217 gnutls_pk_params_st pk_params; 218 219 for (i = 0; i < params_len; i++) 220 pk_params.params[i] = params[i]; 221 pk_params.params_nr = params_len; 222
Bug on the side of openvas-libraries was caused by freeing the key memory after adding the key to session context. This caused that the key memory gets reused and overwriten. Attaching the patch. On the GnuTLS side I would recommed to limit the for cycle with the min( params_len, sizeof(pk_params.params) ) to ensure that the buffer will not get overwritten with broken or intentionally crafted data. Michal Ambroz
Created attachment 551478 [details] openvas-libraries-4.0.6-key.patch
openvas-libraries-4.0.6-2.fc16 has been submitted as an update for Fedora 16. https://admin.fedoraproject.org/updates/openvas-libraries-4.0.6-2.fc16
The private key is 'trusted' data so this should not be a security issue however I agree that just from defensive programming point of view the check, as you recommend it, would be appropriate.
I think the root cause of this problem is a change in gnutls. The function gnutls_certificate_set_x509_key() used to copy data in v2.10, but 2.12 started copying pointers only. Apparently, 2.12.10+ has reverted this behavoiur. Please see this thread for more details. http://comments.gmane.org/gmane.network.gnutls.general/2544 So, probably the correct solution is to update gnutls past 2.12.10 or patch it to revert the behaviour. Otherwise fedora will be different to other distros behaviour.
gnutls-2.12.14-1.fc16 has been submitted as an update for Fedora 16. https://admin.fedoraproject.org/updates/gnutls-2.12.14-1.fc16
Tested 2.12.14 + openvas-libraries without patch and it seems to work. Thank you.
gnutls-2.12.14-1.fc16 has been pushed to the Fedora 16 stable repository. If problems still persist, please make note of it in this bug report.
Gnutls is available in the stable repository. With this one even older builds of openvas-libraries do work. Thank you for fixing. Michal Ambroz
openvas-libraries-4.0.6-3.fc16 has been submitted as an update for Fedora 16. https://admin.fedoraproject.org/updates/openvas-libraries-4.0.6-3.fc16
openvas-libraries-4.0.6-3.fc16 has been pushed to the Fedora 16 stable repository. If problems still persist, please make note of it in this bug report.