Menu

#2803 use-after-free in _sess_open() cause a crash on OpenBSD 6.1-CURRENT

openBSD
closed
Crash (1)
7
2017-10-20
2017-09-19
No

Good morning

I'm a developer at Zabbix and we use Net-snmp for implenting snmp monitoring. While establishing a session for performing some snmp checks, the process can crash due to the fact that inside _sess_open() an already freed pointer is re-used. Here is a back trace:

#0  thrkill () at -:3
#1  0x00000c4b902b435d in _libc_abort () at /usr/src/lib/libc/stdlib/abort.c:51
#2  0x00000c4934dc0e28 in log_fatal_signal (sig=11, siginfo=0x7f7fffe7ae80, context=0x7f7fffe7ad90) at sighandler.c:33
#3  0x00000c4934dc09de in fatal_signal_handler (sig=11, siginfo=0x7f7fffe7ae80, context=0x7f7fffe7ad90) at sighandler.c:60
#4  <signal handler called>
#5  strlen () at /usr/src/lib/libc/arch/amd64/string/strlen.S:124
#6  0x00000c4b90310f62 in _libc_strdup (str=0xc4c1d74ee00 <Address 0xc4c1d74ee00 out of bounds>) at /usr/src/lib/libc/string/strdup.c:44
#7  0x00000c4b7322f16c in netsnmp_ds_set_string () from /usr/local/lib/libnetsnmp.so.14.0
#8  0x00000c4b731ffeac in snmp_sess_open () from /usr/local/lib/libnetsnmp.so.14.0
#9  0x00000c4b731ffde9 in snmp_open () from /usr/local/lib/libnetsnmp.so.14.0
#10 0x00000c4934d1ea54 in zbx_snmp_open_session (item=0x7f7fffe7ee30, error=0x7f7fffe7b840 "", max_error_len=2048) at checks_snmp.c:630
#11 0x00000c4934d1dbaf in get_values_snmp (items=0x7f7fffe7ee30, results=0x7f7fffe7ce30, errcodes=0x7f7fffe7cc30, num=1) at checks_snmp.c:2097
#12 0x00000c4934d26dbd in get_values (poller_type=0 '\0', nextcheck=0x7f7fffff86ac) at poller.c:571
#13 0x00000c4934d25717 in poller_thread (args=0x7f7fffff8748) at poller.c:778
#14 0x00000c4934dd0f91 in zbx_thread_start (handler=0xc4934d25590 <poller_thread>, thread_args=0x7f7fffff8748) at threads.c:128
#15 0x00000c4934d0f54c in MAIN_ZABBIX_ENTRY (flags=2) at server.c:1040
#16 0x00000c4934dbf854 in daemon_start (allow_root=0, user=0x0, flags=2) at daemon.c:392
#17 0x00000c4934d0eca2 in main (argc=3, argv=0x7f7fffff96d8) at server.c:819

The problem is also reproducible on Linux using valgrind (but it will not cause a crash). The problematic code is here (some additional comments for clarity):

static void    *
_sess_open(netsnmp_session * in_session)
{
    netsnmp_transport *transport = NULL;
    int rc;

    in_session->s_snmp_errno = 0;
    in_session->s_errno = 0;

    _init_snmp();

    {
        char *clientaddr_save = NULL;

        if (NULL != in_session->localname) {
    // returns pointer stored in netsnmp_ds_strings[NETSNMP_DS_LIBRARY_ID][NETSNMP_DS_LIB_CLIENT_ADDR]
            clientaddr_save =
                netsnmp_ds_get_string(NETSNMP_DS_LIBRARY_ID,
                                      NETSNMP_DS_LIB_CLIENT_ADDR);

    // frees pointer stored in netsnmp_ds_strings[NETSNMP_DS_LIBRARY_ID][NETSNMP_DS_LIB_CLIENT_ADDR]
            netsnmp_ds_set_string(NETSNMP_DS_LIBRARY_ID,
                                  NETSNMP_DS_LIB_CLIENT_ADDR,
                                  in_session->localname);
        }

        if (in_session->flags & SNMP_FLAGS_STREAM_SOCKET) {
            transport =
                netsnmp_tdomain_transport_full("snmp", in_session->peername,
                                               in_session->local_port, "tcp,tcp6",
                                               NULL);
        } else {
            transport =
                netsnmp_tdomain_transport_full("snmp", in_session->peername,
                                               in_session->local_port, "udp,udp6",
                                               NULL);
        }

        if (NULL != clientaddr_save)
    // tries to use saved pointer which was already freed
            netsnmp_ds_set_string(NETSNMP_DS_LIBRARY_ID,
                                  NETSNMP_DS_LIB_CLIENT_ADDR, clientaddr_save);
    }

We also tried to check if we were using the library incorrectly, but it doesn't seems the case. If you think that this is not a bug and we need to do something different, just advise.

I can be contacted at: andrea.biscuola@zabbix.com

Discussion

  • Stuart Henderson

    Possible patch attached..

     
  • Anonymous

    Anonymous - 2017-10-19

    A definitive patch tested and working for OpenBSD attached (committed by Stuart Henderson in the ports tree):

     
  • Bart Van Assche

    Bart Van Assche - 2017-10-20

    It seems like that patch has been generated against an old version of Net-SNMP? Anyway, a somewhat modified version of this patch has been applied on the v5.7 and master branches. See also https://sourceforge.net/p/net-snmp/code/ci/d687248669257328805cf0a6ff00428d0f8db66c/.

     
    • Anonymous

      Anonymous - 2017-10-20

      Actually the patch was generated from net-snmp 5.7.3 as present in the OpenBSD ports tree. Also I don't see patch versions for it.
      Anyway, thanks for fixing the problem!

       
  • Bart Van Assche

    Bart Van Assche - 2017-10-20
    • status: open --> closed
    • assigned_to: bart
     

Log in to post a comment.