When parsing mib files, various commands (snmpwalk,
snmptranslate, etc) will seg fault and die if the mib
files generate a lot of unlinked oid messages. There
are a few bug reports that seem similar to this, but I
don't know how to attach a file as a followup, so I'm
starting a new report.
I see this behavior in the snmp utilities included in
redhat 7.x; I think that is net-snmp 5.0.7. I also see
similar behavior with net-snmp 5.0.8 under cygwin on
windows 2K. All the examples below will be with
net-snmp 5.0.8 on cygwin, locally compiled with gcc.
Version 5.0.3 on cygwin on w2k doesn't seem to have
this behavior.
The problem looks like
$ snmptranslate -m ALL -TB system
Unlinked OID in WINS-MIB: wins ::= { software 2 }
[ lots of unlinked oid messages ]
Undefined identifier: enterprises near line 22 of
/usr/local/share/snmp/mibs/EventLogMon.mib
Segmentation fault (core dumped)
Running snmptranslate through gdb gives
Program received signal SIGSEGV, Segmentation fault.
0x004281d9 in find_tree_node (name=0x1 <Address 0x1 out
of bounds>, modid=-1) at parse.c:1174
1174 if (!name || !*name)
(gdb) p name
$1 = 0x1 <Address 0x1 out of bounds>
(gdb) p *name
Cannot access memory at address 0x1
The backtrace looks like
(gdb) bt
#0 0x004281d9 in find_tree_node (name=0x1 <Address 0x1
out of bounds>, modid=-1) at parse.c:1174
#1 0x0042e153 in adopt_orphans () at parse.c:3761
#2 0x00430522 in read_all_mibs () at parse.c:4657
#3 0x00408ddd in init_mib () at mib.c:2517
#4 0x00411bf7 in init_snmp (type=0x401b51 "snmpapp")
at snmp_api.c:791
#5 0x00402067 in main (argc=5, argv=0xa042748) at
snmptranslate.c:224
Going to adopt_orphans(), the problem seems to be the
for loop in this snippet:
for (np = nbuckets[i]; np != NULL; np = np->next) {
tp = find_tree_node(np->parent, -1);
if (tp) {
do_subtree(tp, &np);
adopted = 1;
}
}
It seems the test for np != NULL can pass (ie, np is
not null), but np->next is NULL.
(gdb) p np
$11 = (struct node *) 0xa0edfe8
(gdb) p np->next
$12 = (struct node *) 0x0
(gdb) p np
The assignment of np is then made, and then used in the
call to find_tree_node().
My ugly workaround is to check np before calling
find_tree_node() (see attached diff file); I don't know
if it is safe enough for general use, but at least it
doesn't seg fault when trying to read in the mib files
anymore (for me anyway). Maybe the for loop test should
be (np != NULL && np->next != NULL) instead of what I
did....
I think find_tree_node() is still weak, since the
changes doesn't protect find_tree_node() from trying to
derefernce a non-NULL, but invalid memory address.
WL
wliao@generationec.com
diff -c parse.c parse.c.orig