[Pkg-net-snmp-devel] Bug#344979: snmpd: segfaults on amd64 when receiving some traps

Ginter, Benjamin bginter at trigeo.com
Fri Feb 13 21:15:05 UTC 2009

Package: net-snmpd
Version: 5.2.3-7
Severity: important

Following up on Nicole's initial report, I have duplicated this error and have included a patch that resolves it.  This error occurs on the amd64 architecture when the syslog string encoding of the received snmp trap exceeds 1024 bytes.

In the file snmplib/snmp_logging.c, the function snmp_vlog( int, char*, va_list ) attempts to vsnprintf on the va_list passed in from snmp_log().  It captures the number of bytes written and writes the snmp log string if the length is not zero and could be formatted.  It functions correctly as long as the length value is less than LOGLENGTH (defined as 1024).

If the string length is >= LOGLENGTH, it needs to malloc the length of the string plus one byte for the null terminator.  If successful, it attempts to vsnprintf into the buffer using the same va_list ap.  This is where the fault occurs because the value of ap is "indeterminate" after the first call where we fetched the length.  This is documented in the ISO C99 specification in section 7.15 (3) (http://www.open-std.org/JTC1/SC22/WG14/www/docs/n1256.pdf).

To overcome this, we must make a copy of the va_list variable before the first vsnprintf.  If the number of bytes written is less than LOGLENGTH, we just discard the value with va_end().  However, if the dynamically sized buffer must be used, the second call to vsnprintf will use the virgin copy of the original va_list variable (the original is tainted at this point).  Here too, va_end() must be called after we are finished.  The va_end call for the original va_list ap variable happens in the caller, snmp_log().

These changes already exist in the latest net-snmp distribution.

diff -ubBr pristine/net-snmp-5.2.3/snmplib/snmp_logging.c net-snmp-5.2.3/snmplib/snmp_logging.c
--- pristine/net-snmp-5.2.3/snmplib/snmp_logging.c      2006-01-25 08:28:12.000000000 -0800
+++ net-snmp-5.2.3/snmplib/snmp_logging.c       2009-02-12 16:29:48.000000000 -0800
@@ -1135,19 +1135,26 @@
     char            buffer[LOGLENGTH];
     int             length;
     char           *dynamic;
+    va_list         aq;

+    va_copy( aq, ap );
     length = vsnprintf(buffer, LOGLENGTH, format, ap);
+    va_end( aq );

-    if (length == 0)
+    if (length == 0) {
+      va_end( aq );
         return (0);             /* Empty string */
+    }

     if (length == -1) {
         snmp_log_string(LOG_ERR, "Could not format log-string\n");
+        va_end( aq );
         return (-1);

     if (length < LOGLENGTH) {
         snmp_log_string(priority, buffer);
+        va_end(aq);
         return (0);

@@ -1156,12 +1163,14 @@
                         "Could not allocate memory for log-message\n");
         snmp_log_string(priority, buffer);
+        va_end(aq);
         return (-2);

-    vsnprintf(dynamic, length + 1, format, ap);
+    vsnprintf(dynamic, length + 1, format, aq);
     snmp_log_string(priority, dynamic);
+    va_end(aq);
     return 0;

-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.alioth.debian.org/pipermail/pkg-net-snmp-devel/attachments/20090213/1076edc3/attachment.htm 

More information about the Pkg-net-snmp-devel mailing list