Package: snmpd Version: 5.2.1.2-2 Tags: patch Followup-For: Bug #321713
Hi, After investigation, I found the cause of this problem. But WAIT! There's more! snmpd won't survive an snmpwalk (looking at this problem right now) The segfault happens in snmplib/tools.c:401, netsnmp_hex_to_binary(), called from agent/mibgroup/ip-mib/data_access/ipaddress_linux.c:_load_v6() 370 int 371 netsnmp_hex_to_binary(u_char ** buf, size_t * buf_len, size_t * out_len, 372 int allow_realloc, const char *hex, const char *delim) 373 { 374 int subid = 0; 375 const char *cp = hex; ... 397 if ((*out_len >= *buf_len) && 398 !(allow_realloc && snmp_realloc(buf, buf_len))) { 399 return 0; 400 } 401 *(*buf + *out_len) = (u_char) subid; ... Printing out the value of *buf and (*buf + *out_len) after line 400 gives: *buf = 0x5eaa8c, (*buf + *out_len) = 0x10005eaa8c Printing the values of *buf_len and *out_len reveals that they're WAY to high to be OK. As both buf_len and out_len are affected, the realloc check doesn't trigger, unfortunately. Investigating the caller reveals this: 144 int 145 _load_v6(netsnmp_container *container, int idx_offset) 146 { 147 FILE *in; 148 char line[80], addr[33], if_name[IFNAMSIZ]; 149 u_char *buf; 150 int if_index, pfx_len, scope, flags, rc = 0, in_len, out_len; 151 netsnmp_ipaddress_entry *entry; 152 _ioctl_extras *extras; 153 static int log_open_err = 1; ... 201 in_len = entry->ia_address_len = sizeof(entry->ia_address); 202 netsnmp_assert(16 == in_len); 203 out_len = 0; 204 buf = entry->ia_address; 205 if(1 != snmp_hex_to_binary(&buf, 206 &in_len, &out_len, 0, addr)) { 207 snmp_log(LOG_ERR,"error parsing '%s', skipping\n", 208 entry->ia_address); 209 netsnmp_access_ipaddress_entry_free(entry); 210 continue; 211 } 212 netsnmp_assert(16 == out_len); 213 entry->ia_address_len = out_len; ... See line 206 ? See line 150 ? See line 371 above ? The types for in_len (buf_len) and out_len (out_len) ARE FUCKING WRONG. int is signed, 32 bits, and size_t on amd64 is unsigned, 64 bits. KABOOM. This bug only triggers on machines with IPv6 support. Patch attached, changing in_len and out_len to be size_t, which is the data type expected by netsnmp_hex_to_binary(). Please print it out, stick it on a big, heavy cluebat and use the said cluebat to vigorously, repeatedly LART upstream. Thanks. And, please, build net-snmp with -Wall enabled in the debian package. JB. -- System Information: Debian Release: testing/unstable APT prefers unstable APT policy: (500, 'unstable') Architecture: amd64 (x86_64) Shell: /bin/sh linked to /bin/bash Kernel: Linux 2.6.12 Locale: LANG=C, [EMAIL PROTECTED] (charmap=ISO-8859-15) Versions of packages snmpd depends on: ii libc6 2.3.5-3 GNU C Library: Shared libraries an ii libsensors3 1:2.9.1-5 library to read temperature/voltag ii libsnmp5 5.2.1.2-2 NET SNMP (Simple Network Managemen ii libwrap0 7.6.dbs-8 Wietse Venema's TCP wrappers libra snmpd recommends no packages. -- no debconf information
--- ipaddress_linux.c~ 2004-10-19 05:23:59.000000000 +0200 +++ ipaddress_linux.c 2005-08-14 12:24:51.497056312 +0200 @@ -174,7 +174,8 @@ FILE *in; char line[80], addr[33], if_name[IFNAMSIZ]; u_char *buf; - int if_index, pfx_len, scope, flags, rc = 0, in_len, out_len; + int if_index, pfx_len, scope, flags, rc = 0; + size_t in_len, out_len; netsnmp_ipaddress_entry *entry; _ioctl_extras *extras; static int log_open_err = 1;