valgrinding a SSL application

classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

valgrinding a SSL application

Matthias Apitz

Hello,

I'm 'valgrinding' a huge client/server application, where the server
runs on Linux (SLES 12) and uses SSL (OpenSSL) to communicate with the
clients.

Valgrind is complaining a lot on any SSL function call (some 20.000
lines) before the first data is exchanged, i.e. on creating the SSL
socket and accepting the connection.

I know how to suppress such complaints which I can not solve because the
full function stack is inside the libssl.so or libcrypto.so

But, when I read bytes in clear text from the SSL connection the
resulting returned 'buf' is invalid too and this goes up the way as
invalid into my application layers. See the example below and the
resulting valgrind complaints. It does not even help to strncpy(3) the
buffer and work with the result. The data in it remains
invalid/uninitialized.

What is the correct way to deal with this?

Thanks


example code:

int SLNPOpensslRead(int sock, char *buf, int maxlen)
{
    int r, i;
    int sslError = 0;
    char *env;
    char sslBuf[SLNPBufLen+1];

    ...
    while (1) {
        bzero(sslBuf, maxlen);
        r = BIO_gets(slnpSSL[i].io, sslBuf, maxlen);
        bzero(buf, maxlen);
        if (r >= 0)
            strncpy(buf, sslBuf, r);

        write(2, buf, r);
        ...
   }

   return r;
}  


valgrind output for the above lines:

==15677== Conditional jump or move depends on uninitialised value(s)
==15677==    at 0x737B702: buffer_gets (in /usr/local/sisis-pap/lib/libcrypto.so.1.0.0)
==15677==    by 0x7377635: BIO_gets (in /usr/local/sisis-pap/lib/libcrypto.so.1.0.0)
==15677==    by 0x574E9B7: SLNPOpensslRead (SLNPOpenssl.c:610)
==15677==    by 0x575273B: SlnpReadBuffer (SLNPSendReceive.c:1248)
==15677==    by 0x5751FE2: SlnpReceive (SLNPSendReceive.c:746)
==15677==    by 0x805A7BD: SlnpMainLoop (OPServer.c:866)
==15677==    by 0x805A11B: OPServer (OPServer.c:256)
==15677==    by 0x8059A84: main (OPDaemon.c:400)
==15677==
{
   <insert_a_suppression_name_here>
   Memcheck:Cond
   fun:buffer_gets
   fun:BIO_gets
   fun:SLNPOpensslRead
   fun:SlnpReadBuffer
   fun:SlnpReceive
   fun:SlnpMainLoop
   fun:OPServer
   fun:main
}
==15677== Conditional jump or move depends on uninitialised value(s)
==15677==    at 0x402C6E7: strncpy (vg_replace_strmem.c:545)
==15677==    by 0x574E9EE: SLNPOpensslRead (SLNPOpenssl.c:613)
==15677==    by 0x575273B: SlnpReadBuffer (SLNPSendReceive.c:1248)
==15677==    by 0x5751FE2: SlnpReceive (SLNPSendReceive.c:746)
==15677==    by 0x805A7BD: SlnpMainLoop (OPServer.c:866)
==15677==    by 0x805A11B: OPServer (OPServer.c:256)
==15677==    by 0x8059A84: main (OPDaemon.c:400)
==15677==
{
   <insert_a_suppression_name_here>
   Memcheck:Cond
   fun:strncpy
   fun:SLNPOpensslRead
   fun:SlnpReadBuffer
   fun:SlnpReceive
   fun:SlnpMainLoop
   fun:OPServer
   fun:main
}
==15677== Conditional jump or move depends on uninitialised value(s)
==15677==    at 0x402C6FD: strncpy (vg_replace_strmem.c:545)
==15677==    by 0x574E9EE: SLNPOpensslRead (SLNPOpenssl.c:613)
==15677==    by 0x575273B: SlnpReadBuffer (SLNPSendReceive.c:1248)
==15677==    by 0x5751FE2: SlnpReceive (SLNPSendReceive.c:746)
==15677==    by 0x805A7BD: SlnpMainLoop (OPServer.c:866)
==15677==    by 0x805A11B: OPServer (OPServer.c:256)
==15677==    by 0x8059A84: main (OPDaemon.c:400)
==15677==
{
   <insert_a_suppression_name_here>
   Memcheck:Cond
   fun:strncpy
   fun:SLNPOpensslRead
   fun:SlnpReadBuffer
   fun:SlnpReceive
   fun:SlnpMainLoop
   fun:OPServer
   fun:main
}
==15677== Syscall param write(buf) points to uninitialised byte(s)
==15677==    at 0x765F2B3: __write_nocancel (in /lib/libc-2.19.so)
==15677==    by 0x574EA08: SLNPOpensslRead (SLNPOpenssl.c:615)
==15677==    by 0x575273B: SlnpReadBuffer (SLNPSendReceive.c:1248)
==15677==    by 0x5751FE2: SlnpReceive (SLNPSendReceive.c:746)
==15677==    by 0x805A7BD: SlnpMainLoop (OPServer.c:866)
==15677==    by 0x805A11B: OPServer (OPServer.c:256)
==15677==    by 0x8059A84: main (OPDaemon.c:400)
==15677==  Address 0xfef41aff is on thread 1's stack
==15677==  in frame #3, created by SlnpReceive (SLNPSendReceive.c:680)
==15677==
{
   <insert_a_suppression_name_here>
   Memcheck:Param
   write(buf)
   fun:__write_nocancel
   fun:SLNPOpensslRead
   fun:SlnpReadBuffer
   fun:SlnpReceive
   fun:SlnpMainLoop
   fun:OPServer
   fun:main
}
...


--
Matthias Apitz, ✉ [hidden email], ⌂ http://www.unixarea.de/  ☎ +49-176-38902045

------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, SlashDot.org! http://sdm.link/slashdot
_______________________________________________
Valgrind-users mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/valgrind-users
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: valgrinding a SSL application

iraisr


2017-01-05 12:54 GMT+01:00 Matthias Apitz <[hidden email]>:

Hello,

I'm 'valgrinding' a huge client/server application, where the server
runs on Linux (SLES 12) and uses SSL (OpenSSL) to communicate with the
clients.

Valgrind is complaining a lot on any SSL function call (some 20.000
lines) before the first data is exchanged, i.e. on creating the SSL
socket and accepting the connection.

I know how to suppress such complaints which I can not solve because the
full function stack is inside the libssl.so or libcrypto.so

But, when I read bytes in clear text from the SSL connection the
resulting returned 'buf' is invalid too and this goes up the way as
invalid into my application layers. See the example below and the
resulting valgrind complaints. It does not even help to strncpy(3) the
buffer and work with the result. The data in it remains
invalid/uninitialized.

What is the correct way to deal with this?

One of the straightforward ways (workarounds) will be to use a Valgrind
client request to explicitly set the data buffer as defined.
See memcheck.h, VALGRIND_MAKE_MEM_DEFINED.
I.

------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, SlashDot.org! http://sdm.link/slashdot
_______________________________________________
Valgrind-users mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/valgrind-users
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: valgrinding a SSL application

Tom Hughes-2
On 05/01/17 15:46, Ivo Raisr wrote:

> 2017-01-05 12:54 GMT+01:00 Matthias Apitz <[hidden email]
> <mailto:[hidden email]>>:
>
>     I'm 'valgrinding' a huge client/server application, where the server
>     runs on Linux (SLES 12) and uses SSL (OpenSSL) to communicate with the
>     clients.
>
>     Valgrind is complaining a lot on any SSL function call (some 20.000
>     lines) before the first data is exchanged, i.e. on creating the SSL
>     socket and accepting the connection.
>
>     I know how to suppress such complaints which I can not solve because the
>     full function stack is inside the libssl.so or libcrypto.so
>
>     But, when I read bytes in clear text from the SSL connection the
>     resulting returned 'buf' is invalid too and this goes up the way as
>     invalid into my application layers. See the example below and the
>     resulting valgrind complaints. It does not even help to strncpy(3) the
>     buffer and work with the result. The data in it remains
>     invalid/uninitialized.
>
>     What is the correct way to deal with this?
>
> One of the straightforward ways (workarounds) will be to use a Valgrind
> client request to explicitly set the data buffer as defined.
> See memcheck.h, VALGRIND_MAKE_MEM_DEFINED.

Doing that at the top level is going to be messy though and you probably
wont get rid of everything.

The underlying problem is likely to be that OpenSSL deliberately mixes
uninitialised memory into the entropy pool for it's random number
generator which then pollutes everything derived from that.

It's a fairly well known issue, as anybody that remembers the infamous
Debian incident where the valgrind warnings were "fixed" by stopping it
mixing in that uninitialised memory (and in the process destroying the
randomness) will know...

The ideal solution would be to alter OpenSSL to call
VALGRIND_MAKE_MEM_DEFINED on that unitialised memory when it adds it to
the entropy pool so that valgrind thinks it is defined.

Tom

--
Tom Hughes ([hidden email])
http://compton.nu/

------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, SlashDot.org! http://sdm.link/slashdot
_______________________________________________
Valgrind-users mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/valgrind-users
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: valgrinding a SSL application

John Reiser
In reply to this post by Matthias Apitz
> Valgrind is complaining a lot on any SSL function call (some 20.000
> lines) before the first data is exchanged
     [[snip]]

> What is the correct way to deal with this?

The FAQ for Openssl gives the solution.



------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, SlashDot.org! http://sdm.link/slashdot
_______________________________________________
Valgrind-users mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/valgrind-users
Loading...