This problem was discussed here before, but there was no solution:
http://www.mail-archive.com/[email protected]/msg00533.html
nfacctd from pmacct 0.11.3 with mysql plugin segfaults in
sql_handlers.c:MY_count_ip_proto_handler() on FreeBSD-i386 5.2.1:
$ gdb nfacctd nfacctd.core
GNU gdb 5.2.1 (FreeBSD)
...
Program terminated with signal 11, Segmentation fault.
...
#0 0x283223f8 in __vfprintf () from /lib/libc.so.5
(gdb) bt
#0 0x283223f8 in __vfprintf () from /lib/libc.so.5
#1 0x2831e3a3 in snprintf () from /lib/libc.so.5
#2 0x0807832c in MY_count_ip_proto_handler (cache_elem=0x842aba0,
idata=0xbfbdc980, num=5, ptr_values=0xbfbdc4ac, ptr_where=0xbfbdc4a8)
at sql_handlers.c:151
#3 0x08070c22 in MY_cache_dbop (db=0x80ba4dc, cache_elem=0x842aba0,
idata=0xbfbdc980) at mysql_plugin.c:294
#4 0x08076e72 in sql_query (bed=0x80c3ac0, elem=0x842aba0, idata=0xbfbdc980)
at sql_common.c:1109
#5 0x080712c9 in MY_cache_purge (queue=0x8437000, index=929, idata=0xbfbdc980)
at mysql_plugin.c:426
#6 0x08070821 in mysql_plugin (pipe_fd=5, cfgptr=0x80c6908, ptr=0x80ab2e0)
at mysql_plugin.c:199
#7 0x0805760b in load_plugins (req=0xbfbfed9f) at plugin_hooks.c:173
#8 0x08052fba in main (argc=3, argv=0xbfbfedd4, envp=0xbfbfede4)
at nfacctd.c:471
#9 0x08051a62 in _start ()
(gdb) up 2
#2 0x0807832c in MY_count_ip_proto_handler (cache_elem=0x842aba0,
idata=0xbfbdc980, num=5, ptr_values=0xbfbdc4ac, ptr_where=0xbfbdc4a8)
at sql_handlers.c:151
151 snprintf(*ptr_where, SPACELEFT(where_clause), where[num].string,
cache_elem->primitives.proto);
(gdb) p where[num].string
$1 = " AND ip_proto='%s'", '\0' <repeats 237 times>
(gdb) pt cache_elem->primitives.proto
type = unsigned char
(gdb) p cache_elem->primitives.proto
$2 = 139 '\213'
I.e. wrong argument type is used for snprintf format string (unsigned
char is used where pointer to a string expected). This happens when
protocol number is not found in number->name mapping table. Example
patch is included below.
The first part of the patch adds "#include <pthread.h>" to pmacct.h
to help compile pmacct on older FreeBSD 5.x systems and shouldn't hurt
other systems.
I'm also wondering, what's that strange IP packet:
(gdb) p/x *cache_elem
$3 = {primitives = {eth_dhost = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, eth_shost = {
0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, vlan_id = 0x0, src_ip = {family = 0x2,
address = {ipv4 = {s_addr = 0xff******}}}, dst_ip = {family = 0x2,
address = {ipv4 = {s_addr = 0xffffffff}}}, src_as = 0x0, dst_as = 0x0,
src_port = 0x0, dst_port = 0x0, tos = 0x0, proto = 0x8b, id = 0x0,
class = 0x0}, bytes_counter = 0x64, packet_counter = 0x2,
flows_counter = 0x0, tentatives = 0x0, basetime = 0x460c6cc8, valid = 0x1,
signature = 0x32a9ae34, chained = 0x0, prev = 0x0, next = 0x0,
start_tag = 0x460c6d77, lru_tag = 0x460c6d77, lru_prev = 0x0, lru_next = 0x0}
i.e. from A.B.C.255 to 255.255.255.255 proto (not port!) 139 (hex 0x8b)?
Patch:
Index: src/pmacct.h
===================================================================
RCS file: /home/repo/pmacct/src/pmacct.h,v
retrieving revision 1.3
diff -u -d -p -r1.3 pmacct.h
--- src/pmacct.h 25 Jan 2007 22:57:47 -0000 1.3
+++ src/pmacct.h 30 Mar 2007 03:30:51 -0000
@@ -55,6 +55,7 @@
#include <sys/select.h>
#include <signal.h>
#include <syslog.h>
+#include <pthread.h>
#include <sys/mman.h>
#if !defined (MAP_ANONYMOUS)
Index: src/sql_handlers.c
===================================================================
RCS file: /home/repo/pmacct/src/sql_handlers.c,v
retrieving revision 1.2
diff -u -d -p -r1.2 sql_handlers.c
--- src/sql_handlers.c 25 Jan 2007 22:57:47 -0000 1.2
+++ src/sql_handlers.c 30 Mar 2007 03:30:51 -0000
@@ -148,8 +148,10 @@ void MY_count_ip_proto_handler(const str
snprintf(*ptr_values, SPACELEFT(values_clause), values[num].string,
_protocols[cache_elem->primitives.proto].name);
}
else {
- snprintf(*ptr_where, SPACELEFT(where_clause), where[num].string,
cache_elem->primitives.proto);
- snprintf(*ptr_values, SPACELEFT(values_clause), values[num].string,
cache_elem->primitives.proto);
+ char proto_str[PROTO_LEN];
+ snprintf(proto_str, sizeof(proto_str), "%d", cache_elem->primitives.proto);
+ snprintf(*ptr_where, SPACELEFT(where_clause), where[num].string,
proto_str);
+ snprintf(*ptr_values, SPACELEFT(values_clause), values[num].string,
proto_str);
}
*ptr_where += strlen(*ptr_where);
*ptr_values += strlen(*ptr_values);
wbr&w, dmitry.
--
Dmitry Frolov <[EMAIL PROTECTED]>
RISS-Telecom Network, Novosibirsk, Russia
[EMAIL PROTECTED], +7 383 2278800, DVF-RIPE
_______________________________________________
pmacct-discussion mailing list
http://www.pmacct.net/#mailinglists