Bug 747167 - SIGSEGV in gnutls code in openvas-libraries when connecting to scanner over SSL/TLS
SIGSEGV in gnutls code in openvas-libraries when connecting to scanner over S...
Status: CLOSED ERRATA
Product: Fedora
Classification: Fedora
Component: gnutls (Show other bugs)
16
i686 Linux
unspecified Severity high
: ---
: ---
Assigned To: Tomas Mraz
Fedora Extras Quality Assurance
:
Depends On:
Blocks:
  Show dependency treegraph
 
Reported: 2011-10-18 21:14 EDT by Michal Ambroz
Modified: 2012-01-24 14:56 EST (History)
10 users (show)

See Also:
Fixed In Version: openvas-libraries-4.0.6-3.fc16
Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of:
Environment:
Last Closed: 2012-01-23 10:54:33 EST
Type: ---
Regression: ---
Mount Type: ---
Documentation: ---
CRM:
Verified Versions:
Category: ---
oVirt Team: ---
RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: ---


Attachments (Terms of Use)
openvas-libraries-4.0.6-key.patch (912 bytes, patch)
2012-01-08 21:27 EST, Michal Ambroz
no flags Details | Diff

  None (edit)
Description Michal Ambroz 2011-10-18 21:14:57 EDT
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.
Comment 1 Michal Ambroz 2011-10-18 21:57:35 EDT
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 ?? ()
Comment 2 Michal Ambroz 2011-10-18 22:32:03 EDT
(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)
Comment 3 Michal Ambroz 2011-11-05 09:38:17 EDT
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
Comment 4 Michal Ambroz 2011-11-05 09:40:37 EDT
Please maintainers of gnutls - could you help?
Comment 5 Tomas Mraz 2011-11-07 02:36:07 EST
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?
Comment 6 Michal Ambroz 2011-11-07 11:39:34 EST
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
Comment 7 Michal Ambroz 2012-01-07 16:05:34 EST
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
Comment 8 Michal Ambroz 2012-01-08 21:23:13 EST
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
Comment 9 Michal Ambroz 2012-01-08 21:27:37 EST
Created attachment 551478 [details]
openvas-libraries-4.0.6-key.patch
Comment 10 Fedora Update System 2012-01-08 22:34:13 EST
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
Comment 11 Tomas Mraz 2012-01-09 02:33:56 EST
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.
Comment 12 Richard Colley 2012-01-10 19:39:07 EST
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.
Comment 13 Fedora Update System 2012-01-11 03:22:30 EST
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
Comment 14 Michal Ambroz 2012-01-15 11:55:00 EST
Tested 2.12.14 + openvas-libraries without patch and it seems to work.
Thank you.
Comment 15 Fedora Update System 2012-01-17 15:29:32 EST
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.
Comment 16 Michal Ambroz 2012-01-23 10:54:33 EST
Gnutls is available in the stable repository.
With this one even older builds of openvas-libraries do work.
Thank you for fixing.

Michal Ambroz
Comment 17 Fedora Update System 2012-01-23 11:21:14 EST
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
Comment 18 Fedora Update System 2012-01-24 14:56:30 EST
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.

Note You need to log in before you can comment on or make changes to this bug.