[AGENT++] receive_snmp_response() recvfrom() unitialized value

Kasperowski, Richard richard.kasperowski at centrepath.com
Thu Nov 4 19:09:09 CET 2004


I ran my snmp++ 3.2.14-based application under valgrind on Linux kernel 2.4.20-28.7smp.  valgrind identified an unitialized value thet resulted from one of my many calls to Snmp::get(Pdu&, SnmpTarget const&):

-----
==2004-11-04 15:53:27.064 12024== Conditional jump or move depends on uninitialised value(s)
==2004-11-04 15:53:27.064 12024==    at 0x1BF4A5E0: receive_snmp_response(int, Snmp&, Pdu&, UdpAddress&, bool) (uxsnmp.cpp:322)
==2004-11-04 15:53:27.064 12024==    by 0x1BF3DCD3: CSNMPMessageQueue::HandleEvents(int, fd_set const&, fd_set const&, fd_set const&) (msgqueue.cpp:480)
==2004-11-04 15:53:27.065 12024==    by 0x1BF39BD0: CEventList::HandleEvents(int, fd_set const&, fd_set const&, fd_set const&) (eventlist.cpp:183)
==2004-11-04 15:53:27.065 12024==    by 0x1BF3A4A4: EventListHolder::SNMPProcessPendingEvents() (eventlistholder.cpp:213)
==2004-11-04 15:53:27.065 12024==    by 0x1BF3A6C2: EventListHolder::SNMPProcessEvents(int) (eventlistholder.cpp:266)
==2004-11-04 15:53:27.065 12024==    by 0x1BF3A30C: EventListHolder::SNMPBlockForResponse(unsigned long, Pdu&) (eventlistholder.cpp:161)
==2004-11-04 15:53:27.065 12024==    by 0x1BF4DA3F: Snmp::snmp_engine(Pdu&, long, long, SnmpTarget const&, void (*)(int, Snmp*, Pdu&, SnmpTarget&, void*), void const*) (uxsnmp.cpp:1739)
==2004-11-04 15:53:27.065 12024==    by 0x1BF4BCAA: Snmp::get(Pdu&, SnmpTarget const&) (uxsnmp.cpp:970)
-----

File uxsnmp.cpp line 322 is:

-----
  if (((sockaddr_in&)from_addr).sin_family == AF_INET)
-----

and the full context is:

-----
  do {
    receive_buffer_len = (long) recvfrom(sock, (char *) receive_buffer,
                                         MAX_SNMP_PACKET, 0,
                                         (struct sockaddr*) &from_addr,
                                         &fromlen);
    debugprintf(2, "++ SNMP++: something received...");
  } while ((receive_buffer_len < 0) && (EINTR == errno));

  if (receive_buffer_len <= 0 )                // error or no data pending
    return SNMP_CLASS_TL_FAILED;
  debugprintf(6, "Length received %i from socket %i; fromlen %i",
              receive_buffer_len, sock, fromlen);

  if (((sockaddr_in&)from_addr).sin_family == AF_INET)
  {
-----

This is very difficult to reproduce, and happens very infrequently, but it appears to be a real bug.  It looks like valgrind is complaining that from_addr has not been initialized.  I think this means that there is a weird case in which recvfrom() doesn't fill it in.

I don't know whether the bug is in the kernel or in snmp++, but, either way, I can cope with it in snmp++.  As a fix, I plan to put something like this in our copy uxsnmp.cpp, at line 296:

-----
#ifdef SNMP_PP_IPv6
  struct sockaddr_storage from_addr;
#else
  struct sockaddr_in from_addr;
#endif
  // Must initialize from_addr in case recvfrom doesn't fill it in.
  bzero(&from_addr, sizeof(from_addr));
-----

Is my analysis correct?  Does my proposed fix sound OK?  Is there a better fix?

Thanks,

--
Richard Kasperowski
CentrePath




More information about the AGENTPP mailing list