Hello, not being maintainer for ntopng I tried to reproduce the issue by the steps below.
The crash happens because in MySQLDB.cpp this loop breaks only after 4 iterations instead of 2: const u_int16_t ipvers[2] = {4, 6}; for (u_int16_t i = 0; i < sizeof(ipvers); i++){ Attached are two patches: - 0001-Avoid-access-after-free.patch (Unrelated to this bug, just received the output from valgrind.) - 0002-Avoid-access-to-unintialized-memory.patch (With this applied ntopng is not crashing for me; similar change got applied upstream in https://github.com/ntop/ntopng/commit/2d2e735c99064e8f45c38199e810b121d2b5f4b1 ) Was tested just as far as starting and stopping the service is involved. Kind regards, Bernhard echo '-F="mysql;localhost;ntopng;flows;ntopng;simple"' >> /etc/ntopng.conf mysql -u root -p CREATE USER 'ntopng'@'localhost' IDENTIFIED BY 'simple'; create database ntopng; GRANT ALL PRIVILEGES ON ntopng.* To 'ntopng'@'localhost' IDENTIFIED BY 'simple'; exit systemctl start ntopng Job for ntopng.service failed because a fatal signal was delivered causing the control process to dump core. See "systemctl status ntopng.service" and "journalctl -xe" for details. journalctl -u ntopng Mai 06 15:52:42 debian systemd[1]: Starting ntopng - High-Speed Web-based Traffic Analysis and Flow Collection Tool... Mai 06 15:52:42 debian ntopng[9957]: 06/May/2017 15:52:42 [Prefs.cpp:919] Logging into /var/log/ntopng/ntopng.log Mai 06 15:52:42 debian ntopng[9957]: 06/May/2017 15:52:42 [Ntop.cpp:1121] Setting local networks to 127.0.0.0/8 Mai 06 15:52:42 debian ntopng[9957]: 06/May/2017 15:52:42 [Redis.cpp:92] Successfully connected to redis 127.0.0.1:6379@0 Mai 06 15:52:42 debian ntopng[9957]: [NDPI] ndpi_init_protocol_defaults(missing protoId=226) INTERNAL ERROR: not all protocols have been initialized Mai 06 15:52:42 debian ntopng[9957]: 06/May/2017 15:52:42 [MySQLDB.cpp:495] Attempting to connect to MySQL for interface dummy... Mai 06 15:52:42 debian ntopng[9957]: 06/May/2017 15:52:42 [MySQLDB.cpp:535] Succesfully connected to MySQL [localhost:ntopng] for interface dummy Mai 06 15:52:45 debian ntopng[9957]: 06/May/2017 15:52:45 [MySQLDB.cpp:297] MySQL schema update. Altering table flowsv4: renaming BYTES to IN_BYTES and adding OUT_BYTES Mai 06 15:52:46 debian ntopng[9957]: 06/May/2017 15:52:46 [MySQLDB.cpp:297] MySQL schema update. Altering table flowsv6: renaming BYTES to IN_BYTES and adding OUT_BYTES Mai 06 15:52:48 debian systemd[1]: ntopng.service: Control process exited, code=dumped status=11 Mai 06 15:52:48 debian systemd[1]: Failed to start ntopng - High-Speed Web-based Traffic Analysis and Flow Collection Tool. Mai 06 15:52:48 debian systemd[1]: ntopng.service: Unit entered failed state. Mai 06 15:52:48 debian systemd[1]: ntopng.service: Failed with result 'core-dump'. Mai 06 15:52:48 debian systemd[1]: ntopng.service: Service hold-off time over, scheduling restart. Mai 06 15:52:48 debian systemd[1]: Stopped ntopng - High-Speed Web-based Traffic Analysis and Flow Collection Tool. dmesg -T [Sa Mai 6 15:52:47 2017] ntopng[9957]: segfault at 7fffc2e90000 ip 000055bfbe6c0ffe sp 00007fffc2e8cee0 error 4 in ntopng[55bfbe6ac000+8a000] root@debian:/home/benutzer/debian/ntopng/ntopng/orig/ntopng-2.4+dfsg1/src# coredumpctl gdb 9957 ... Core was generated by `/usr/sbin/ntopng /etc/ntopng.conf'. Program terminated with signal SIGSEGV, Segmentation fault. #0 0x000055bfbe6c0ffe in MySQLDB::MySQLDB (this=0x55bfc0eec850, _iface=<optimized out>) at src/MySQLDB.cpp:307 307 exec_sql_query(&mysql, sql, true, true); (gdb) bt #0 0x000055bfbe6c0ffe in MySQLDB::MySQLDB (this=0x55bfc0eec850, _iface=<optimized out>) at src/MySQLDB.cpp:307 #1 0x000055bfbe6e35f0 in NetworkInterface::NetworkInterface (this=0x55bfbffa7fb0, name=0x55bfbe715310 "dummy") at src/NetworkInterface.cpp:133 #2 0x000055bfbe6c6042 in Prefs::add_default_interfaces (this=<optimized out>) at src/Prefs.cpp:1059 #3 0x000055bfbe6bc7d4 in main (argc=2, argv=0x7fffc2e8f298) at src/main.cpp:117 root@debian:/home/benutzer/debian/ntopng/ntopng/orig/ntopng-2.4+dfsg1/src# valgrind /usr/sbin/ntopng /etc/ntopng.conf ==10143== Memcheck, a memory error detector ==10143== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al. ==10143== Using Valgrind-3.12.0.SVN and LibVEX; rerun with -h for copyright info ==10143== Command: /usr/sbin/ntopng /etc/ntopng.conf ==10143== 06/May/2017 16:27:49 [Prefs.cpp:919] Logging into /var/log/ntopng/ntopng.log 06/May/2017 16:27:49 [Ntop.cpp:1121] Setting local networks to 127.0.0.0/8 06/May/2017 16:27:49 [Redis.cpp:92] Successfully connected to redis 127.0.0.1:6379@0 [NDPI] ndpi_init_protocol_defaults(missing protoId=226) INTERNAL ERROR: not all protocols have been initialized 06/May/2017 16:27:49 [MySQLDB.cpp:495] Attempting to connect to MySQL for interface dummy... 06/May/2017 16:27:50 [MySQLDB.cpp:535] Succesfully connected to MySQL [localhost:ntopng] for interface dummy ==10143== Invalid read of size 8 ==10143== at 0x616E301: mysql_num_rows (client.c:4561) ==10143== by 0x11C1AD: MySQLDB::exec_sql_query(st_mysql*, char*, bool, bool, bool) (MySQLDB.cpp:593) ==10143== by 0x11CF4F: MySQLDB::MySQLDB(NetworkInterface*) (MySQLDB.cpp:295) ==10143== by 0x13F5EF: NetworkInterface::NetworkInterface(char const*) (NetworkInterface.cpp:133) ==10143== by 0x122041: Prefs::add_default_interfaces() (Prefs.cpp:1059) ==10143== by 0x1187D3: main (main.cpp:117) ==10143== Address 0x144527a8 is 8 bytes inside a block of size 208 free'd ==10143== at 0x4C2CDDB: free (vg_replace_malloc.c:530) ==10143== by 0x11C1A5: MySQLDB::exec_sql_query(st_mysql*, char*, bool, bool, bool) (MySQLDB.cpp:592) ==10143== by 0x11CF4F: MySQLDB::MySQLDB(NetworkInterface*) (MySQLDB.cpp:295) ==10143== by 0x13F5EF: NetworkInterface::NetworkInterface(char const*) (NetworkInterface.cpp:133) ==10143== by 0x122041: Prefs::add_default_interfaces() (Prefs.cpp:1059) ==10143== by 0x1187D3: main (main.cpp:117) ==10143== Block was alloc'd at ==10143== at 0x4C2BBAF: malloc (vg_replace_malloc.c:299) ==10143== by 0x61A7D95: my_malloc (my_malloc.c:101) ==10143== by 0x616C1D5: mysql_store_result (client.c:4094) ==10143== by 0x11C190: MySQLDB::exec_sql_query(st_mysql*, char*, bool, bool, bool) (MySQLDB.cpp:589) ==10143== by 0x11CF4F: MySQLDB::MySQLDB(NetworkInterface*) (MySQLDB.cpp:295) ==10143== by 0x13F5EF: NetworkInterface::NetworkInterface(char const*) (NetworkInterface.cpp:133) ==10143== by 0x122041: Prefs::add_default_interfaces() (Prefs.cpp:1059) ==10143== by 0x1187D3: main (main.cpp:117) ==10143== ==10143== Use of uninitialised value of size 8 ==10143== at 0x7B0A16B: _itoa_word (_itoa.c:179) ==10143== by 0x7B0E869: vfprintf (vfprintf.c:1636) ==10143== by 0x7BBC8F5: __vsnprintf_chk (vsnprintf_chk.c:63) ==10143== by 0x7BBC857: __snprintf_chk (snprintf_chk.c:34) ==10143== by 0x11CF2A: snprintf (stdio2.h:65) ==10143== by 0x11CF2A: MySQLDB::MySQLDB(NetworkInterface*) (MySQLDB.cpp:294) ==10143== by 0x13F5EF: NetworkInterface::NetworkInterface(char const*) (NetworkInterface.cpp:133) ==10143== by 0x122041: Prefs::add_default_interfaces() (Prefs.cpp:1059) ==10143== by 0x1187D3: main (main.cpp:117) ==10143== ==10143== Conditional jump or move depends on uninitialised value(s) ==10143== at 0x7B0A175: _itoa_word (_itoa.c:179) ==10143== by 0x7B0E869: vfprintf (vfprintf.c:1636) ==10143== by 0x7BBC8F5: __vsnprintf_chk (vsnprintf_chk.c:63) ==10143== by 0x7BBC857: __snprintf_chk (snprintf_chk.c:34) ==10143== by 0x11CF2A: snprintf (stdio2.h:65) ==10143== by 0x11CF2A: MySQLDB::MySQLDB(NetworkInterface*) (MySQLDB.cpp:294) ==10143== by 0x13F5EF: NetworkInterface::NetworkInterface(char const*) (NetworkInterface.cpp:133) ==10143== by 0x122041: Prefs::add_default_interfaces() (Prefs.cpp:1059) ==10143== by 0x1187D3: main (main.cpp:117) ==10143== ==10143== Conditional jump or move depends on uninitialised value(s) ==10143== at 0x7B0E971: vfprintf (vfprintf.c:1636) ==10143== by 0x7BBC8F5: __vsnprintf_chk (vsnprintf_chk.c:63) ==10143== by 0x7BBC857: __snprintf_chk (snprintf_chk.c:34) ==10143== by 0x11CF2A: snprintf (stdio2.h:65) ==10143== by 0x11CF2A: MySQLDB::MySQLDB(NetworkInterface*) (MySQLDB.cpp:294) ==10143== by 0x13F5EF: NetworkInterface::NetworkInterface(char const*) (NetworkInterface.cpp:133) ==10143== by 0x122041: Prefs::add_default_interfaces() (Prefs.cpp:1059) ==10143== by 0x1187D3: main (main.cpp:117) ==10143== ==10143== Conditional jump or move depends on uninitialised value(s) ==10143== at 0x7B0D831: vfprintf (vfprintf.c:1636) ==10143== by 0x7BBC8F5: __vsnprintf_chk (vsnprintf_chk.c:63) ==10143== by 0x7BBC857: __snprintf_chk (snprintf_chk.c:34) ==10143== by 0x11CF2A: snprintf (stdio2.h:65) ==10143== by 0x11CF2A: MySQLDB::MySQLDB(NetworkInterface*) (MySQLDB.cpp:294) ==10143== by 0x13F5EF: NetworkInterface::NetworkInterface(char const*) (NetworkInterface.cpp:133) ==10143== by 0x122041: Prefs::add_default_interfaces() (Prefs.cpp:1059) ==10143== by 0x1187D3: main (main.cpp:117) ==10143== ==10143== Conditional jump or move depends on uninitialised value(s) ==10143== at 0x7B0D8B2: vfprintf (vfprintf.c:1636) ==10143== by 0x7BBC8F5: __vsnprintf_chk (vsnprintf_chk.c:63) ==10143== by 0x7BBC857: __snprintf_chk (snprintf_chk.c:34) ==10143== by 0x11CF2A: snprintf (stdio2.h:65) ==10143== by 0x11CF2A: MySQLDB::MySQLDB(NetworkInterface*) (MySQLDB.cpp:294) ==10143== by 0x13F5EF: NetworkInterface::NetworkInterface(char const*) (NetworkInterface.cpp:133) ==10143== by 0x122041: Prefs::add_default_interfaces() (Prefs.cpp:1059) ==10143== by 0x1187D3: main (main.cpp:117) ==10143== ==10143== Invalid read of size 2 ==10143== at 0x11CFFE: MySQLDB::MySQLDB(NetworkInterface*) (MySQLDB.cpp:307) ==10143== by 0x13F5EF: NetworkInterface::NetworkInterface(char const*) (NetworkInterface.cpp:133) ==10143== by 0x122041: Prefs::add_default_interfaces() (Prefs.cpp:1059) ==10143== by 0x1187D3: main (main.cpp:117) ==10143== Address 0xfff001000 is not stack'd, malloc'd or (recently) free'd ==10143== ==10143== ==10143== Process terminating with default action of signal 11 (SIGSEGV) ==10143== Access not within mapped region at address 0xFFF001000 ==10143== at 0x11CFFE: MySQLDB::MySQLDB(NetworkInterface*) (MySQLDB.cpp:307) ==10143== by 0x13F5EF: NetworkInterface::NetworkInterface(char const*) (NetworkInterface.cpp:133) ==10143== by 0x122041: Prefs::add_default_interfaces() (Prefs.cpp:1059) ==10143== by 0x1187D3: main (main.cpp:117) ==10143== If you believe this happened as a result of a stack ==10143== overflow in your program's main thread (unlikely but ==10143== possible), you can try to increase the size of the ==10143== main thread stack using the --main-stacksize= flag. ==10143== The main thread stack size used in this run was 8388608. ==10143== ==10143== HEAP SUMMARY: ==10143== in use at exit: 15,932,693 bytes in 95,935 blocks ==10143== total heap usage: 103,101 allocs, 7,166 frees, 22,180,739 bytes allocated ==10143== ==10143== LEAK SUMMARY: ==10143== definitely lost: 87 bytes in 3 blocks ==10143== indirectly lost: 0 bytes in 0 blocks ==10143== possibly lost: 1,544 bytes in 20 blocks ==10143== still reachable: 15,931,062 bytes in 95,912 blocks ==10143== of which reachable via heuristic: ==10143== length64 : 34,152 bytes in 17 blocks ==10143== newarray : 1,536 bytes in 16 blocks ==10143== suppressed: 0 bytes in 0 blocks ==10143== Rerun with --leak-check=full to see details of leaked memory ==10143== ==10143== For counts of detected and suppressed errors, rerun with: -v ==10143== Use --track-origins=yes to see where uninitialised values come from ==10143== ERROR SUMMARY: 28739 errors from 7 contexts (suppressed: 0 from 0) Speicherzugriffsfehler (Speicherabzug geschrieben)
From d105ca470feb89ac9ca4589600dd2a78df3e50cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bernhard=20=C3=9Cbelacker?= <bernha...@mailbox.org> Date: Sat, 6 May 2017 16:31:36 +0200 Subject: Avoid access after free. Found while investigating for https://bugs.debian.org/859653 ==10143== Invalid read of size 8 ==10143== at 0x616E301: mysql_num_rows (client.c:4561) ==10143== by 0x11C1AD: MySQLDB::exec_sql_query(st_mysql*, char*, bool, bool, bool) (MySQLDB.cpp:593) ==10143== by 0x11CF4F: MySQLDB::MySQLDB(NetworkInterface*) (MySQLDB.cpp:295) ==10143== by 0x13F5EF: NetworkInterface::NetworkInterface(char const*) (NetworkInterface.cpp:133) ==10143== by 0x122041: Prefs::add_default_interfaces() (Prefs.cpp:1059) ==10143== by 0x1187D3: main (main.cpp:117) ==10143== Address 0x144527a8 is 8 bytes inside a block of size 208 free'd ==10143== at 0x4C2CDDB: free (vg_replace_malloc.c:530) ==10143== by 0x11C1A5: MySQLDB::exec_sql_query(st_mysql*, char*, bool, bool, bool) (MySQLDB.cpp:592) ==10143== by 0x11CF4F: MySQLDB::MySQLDB(NetworkInterface*) (MySQLDB.cpp:295) ==10143== by 0x13F5EF: NetworkInterface::NetworkInterface(char const*) (NetworkInterface.cpp:133) ==10143== by 0x122041: Prefs::add_default_interfaces() (Prefs.cpp:1059) ==10143== by 0x1187D3: main (main.cpp:117) ==10143== Block was alloc'd at ==10143== at 0x4C2BBAF: malloc (vg_replace_malloc.c:299) ==10143== by 0x61A7D95: my_malloc (my_malloc.c:101) ==10143== by 0x616C1D5: mysql_store_result (client.c:4094) ==10143== by 0x11C190: MySQLDB::exec_sql_query(st_mysql*, char*, bool, bool, bool) (MySQLDB.cpp:589) ==10143== by 0x11CF4F: MySQLDB::MySQLDB(NetworkInterface*) (MySQLDB.cpp:295) ==10143== by 0x13F5EF: NetworkInterface::NetworkInterface(char const*) (NetworkInterface.cpp:133) ==10143== by 0x122041: Prefs::add_default_interfaces() (Prefs.cpp:1059) ==10143== by 0x1187D3: main (main.cpp:117) --- src/MySQLDB.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/MySQLDB.cpp b/src/MySQLDB.cpp index b9a1337..9148f25 100644 --- a/src/MySQLDB.cpp +++ b/src/MySQLDB.cpp @@ -589,8 +589,8 @@ int MySQLDB::exec_sql_query(MYSQL *conn, char *sql, if((result = mysql_store_result(&mysql)) == NULL) rc = 0; // unable to retrieve the result but still the query succeded else{ - mysql_free_result(result); rc = mysql_num_rows(result); + mysql_free_result(result); } } -- 2.11.0
From 3b8a1f8f11021bdd8319c175fd9743c6427c5541 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bernhard=20=C3=9Cbelacker?= <bernha...@mailbox.org> Date: Sat, 6 May 2017 16:36:18 +0200 Subject: Avoid access to unintialized memory. Found while investigating for https://bugs.debian.org/859653 ==14371== Use of uninitialised value of size 8 ==14371== at 0x7B0A16B: _itoa_word (_itoa.c:179) ==14371== by 0x7B0E869: vfprintf (vfprintf.c:1636) ==14371== by 0x7BBC8F5: __vsnprintf_chk (vsnprintf_chk.c:63) ==14371== by 0x7BBC857: __snprintf_chk (snprintf_chk.c:34) ==14371== by 0x11D2EA: snprintf (stdio2.h:65) ==14371== by 0x11D2EA: MySQLDB::MySQLDB(NetworkInterface*) (MySQLDB.cpp:294) ==14371== by 0x1496CF: NetworkInterface::NetworkInterface(char const*) (NetworkInterface.cpp:133) ==14371== by 0x122791: Prefs::add_default_interfaces() (Prefs.cpp:1059) ==14371== by 0x1188F3: main (main.cpp:117) ==19200== Use of uninitialised value of size 8 ==19200== at 0x7B0A16B: _itoa_word (_itoa.c:179) ==19200== by 0x7B0E869: vfprintf (vfprintf.c:1636) ==19200== by 0x7BBC8F5: __vsnprintf_chk (vsnprintf_chk.c:63) ==19200== by 0x7BBC857: __snprintf_chk (snprintf_chk.c:34) ==19200== by 0x11D474: snprintf (stdio2.h:65) ==19200== by 0x11D474: MySQLDB::MySQLDB(NetworkInterface*) (MySQLDB.cpp:321) ==19200== by 0x14980F: NetworkInterface::NetworkInterface(char const*) (NetworkInterface.cpp:133) ==19200== by 0x1228D1: Prefs::add_default_interfaces() (Prefs.cpp:1059) ==19200== by 0x1188F3: main (main.cpp:117) --- src/MySQLDB.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/MySQLDB.cpp b/src/MySQLDB.cpp index 9148f25..faf087a 100644 --- a/src/MySQLDB.cpp +++ b/src/MySQLDB.cpp @@ -289,7 +289,7 @@ MySQLDB::MySQLDB(NetworkInterface *_iface) : DB(_iface) { // Move column BYTES to BYTES_IN and add BYTES_OUT // note that this operation will arbitrarily move the old BYTES contents to BYTES_IN const u_int16_t ipvers[2] = {4, 6}; - for (u_int16_t i = 0; i < sizeof(ipvers); i++){ + for (u_int16_t i = 0; i < sizeof(ipvers)/sizeof(*ipvers); i++){ snprintf(sql, sizeof(sql), "SHOW COLUMNS FROM `%sv%hu` LIKE 'BYTES'", ntop->getPrefs()->get_mysql_tablename(), ipvers[i]); if(exec_sql_query(&mysql, sql, true, true) > 0){ @@ -309,7 +309,7 @@ MySQLDB::MySQLDB(NetworkInterface *_iface) : DB(_iface) { } // Modify database engine to MyISAM (that is much faster in non-transactional environments) - for (u_int16_t i = 0; i < sizeof(ipvers); i++){ + for (u_int16_t i = 0; i < sizeof(ipvers)/sizeof(*ipvers); i++){ snprintf(sql, sizeof(sql), "SELECT 1 " "FROM information_schema.TABLES " -- 2.11.0