diff -Nru net-snmp-5.7.3+dfsg/debian/changelog net-snmp-5.7.3+dfsg/debian/changelog --- net-snmp-5.7.3+dfsg/debian/changelog 2022-07-25 18:23:32.000000000 +0000 +++ net-snmp-5.7.3+dfsg/debian/changelog 2022-12-15 07:48:12.000000000 +0000 @@ -1,3 +1,11 @@ +net-snmp (5.7.3+dfsg-1.8ubuntu3.8) bionic; urgency=medium + + * Fix snmptrapd reconnection issue after hitting MySQL wait_timeout + (LP: #1999711) + - d/p/snmptrapd-mysql-reconnection-after-hitting-wait_timeout.patch + + -- Chengen Du Thu, 15 Dec 2022 07:48:12 +0000 + net-snmp (5.7.3+dfsg-1.8ubuntu3.7) bionic-security; urgency=medium * SECURITY UPDATE: Multiple security issus diff -Nru net-snmp-5.7.3+dfsg/debian/patches/series net-snmp-5.7.3+dfsg/debian/patches/series --- net-snmp-5.7.3+dfsg/debian/patches/series 2022-07-25 18:23:06.000000000 +0000 +++ net-snmp-5.7.3+dfsg/debian/patches/series 2022-12-15 07:47:24.000000000 +0000 @@ -45,3 +45,4 @@ CVE-2020-15862-bug1893465.patch CVE-2022-248xx-1.patch CVE-2022-248xx-2.patch +snmptrapd-mysql-reconnection-after-hitting-wait_timeout.patch diff -Nru net-snmp-5.7.3+dfsg/debian/patches/snmptrapd-mysql-reconnection-after-hitting-wait_timeout.patch net-snmp-5.7.3+dfsg/debian/patches/snmptrapd-mysql-reconnection-after-hitting-wait_timeout.patch --- net-snmp-5.7.3+dfsg/debian/patches/snmptrapd-mysql-reconnection-after-hitting-wait_timeout.patch 1970-01-01 00:00:00.000000000 +0000 +++ net-snmp-5.7.3+dfsg/debian/patches/snmptrapd-mysql-reconnection-after-hitting-wait_timeout.patch 2022-12-15 07:47:54.000000000 +0000 @@ -0,0 +1,144 @@ +Description: snmptrap: Fix mysql reconnection after hitting wait_timeout + MySQL v8.0 supports ER_CLIENT_INTERACTION_TIMEOUT, which is not handled + in snmptrapd +Author: Chengen Du +Origin: backport, https://github.com/net-snmp/net-snmp/pull/484/files +Bug-Ubuntu: https://bugs.launchpad.net/bugs/1999711 +Last-Update: 2022-12-15 + +--- net-snmp-5.7.3+dfsg.orig/apps/snmptrapd_sql.c ++++ net-snmp-5.7.3+dfsg/apps/snmptrapd_sql.c +@@ -249,6 +249,13 @@ netsnmp_sql_disconnected(void) + } + } + ++static int ++netsnmp_sql_server_disconnected(int err) ++{ ++ // CR_SERVER_GONE_ERROR | CR_SERVER_LOST | ER_CLIENT_INTERACTION_TIMEOUT ++ return CR_SERVER_GONE_ERROR == err || CR_SERVER_LOST == err || 4031 == err; ++} ++ + /* + * convenience function to log mysql errors + */ +@@ -256,17 +263,20 @@ static void + netsnmp_sql_error(const char *message) + { + u_int err = mysql_errno(_sql.conn); +- snmp_log(LOG_ERR, "%s\n", message); +- if (_sql.conn != NULL) { ++ ++ if (0 == _sql.connected || 0 == netsnmp_sql_server_disconnected(err)) { ++ snmp_log(LOG_ERR, "%s\n", message); ++ if (_sql.conn != NULL) { + #if MYSQL_VERSION_ID >= 40101 +- snmp_log(LOG_ERR, "Error %u (%s): %s\n", +- err, mysql_sqlstate(_sql.conn), mysql_error(_sql.conn)); ++ snmp_log(LOG_ERR, "Error %u (%s): %s\n", ++ err, mysql_sqlstate(_sql.conn), mysql_error(_sql.conn)); + #else +- snmp(LOG_ERR, "Error %u: %s\n", +- mysql_errno(_sql.conn), mysql_error(_sql.conn)); ++ snmp(LOG_ERR, "Error %u: %s\n", ++ mysql_errno(_sql.conn), mysql_error(_sql.conn)); + #endif ++ } + } +- if (CR_SERVER_GONE_ERROR == err) ++ if (netsnmp_sql_server_disconnected(err)) + netsnmp_sql_disconnected(); + } + +@@ -278,14 +288,15 @@ netsnmp_sql_stmt_error (MYSQL_STMT *stmt + { + u_int err = mysql_errno(_sql.conn); + +- snmp_log(LOG_ERR, "%s\n", message); +- if (stmt) { +- snmp_log(LOG_ERR, "SQL Error %u (%s): %s\n", +- mysql_stmt_errno(stmt), mysql_stmt_sqlstate(stmt), +- mysql_stmt_error(stmt)); ++ if (0 == _sql.connected || !netsnmp_sql_server_disconnected(err)) { ++ snmp_log(LOG_ERR, "%s\n", message); ++ if (stmt) { ++ snmp_log(LOG_ERR, "SQL Error %u (%s): %s\n", ++ mysql_stmt_errno(stmt), mysql_stmt_sqlstate(stmt), ++ mysql_stmt_error(stmt)); ++ } + } +- +- if (CR_SERVER_GONE_ERROR == err) ++ if (netsnmp_sql_server_disconnected(err)) + netsnmp_sql_disconnected(); + } + +@@ -308,15 +319,6 @@ netsnmp_mysql_cleanup(void) + CONTAINER_FREE(_sql.queue); + _sql.queue = NULL; + +- if (_sql.trap_stmt) { +- mysql_stmt_close(_sql.trap_stmt); +- _sql.trap_stmt = NULL; +- } +- if (_sql.vb_stmt) { +- mysql_stmt_close(_sql.vb_stmt); +- _sql.vb_stmt = NULL; +- } +- + /** disconnect from server */ + netsnmp_sql_disconnected(); + +@@ -374,6 +376,17 @@ netsnmp_mysql_connect(void) + + DEBUGMSGTL(("sql:connection","connecting\n")); + ++ if (_sql.conn) { ++ mysql_close(_sql.conn); ++ _sql.conn = NULL; ++ } ++ ++ _sql.conn = mysql_init (NULL); ++ if (_sql.conn == NULL) { ++ netsnmp_sql_error("mysql_init() failed (out of memory?)"); ++ goto err; ++ } ++ + /** connect to server */ + if (mysql_real_connect (_sql.conn, _sql.host_name, _sql.user_name, + _sql.password, _sql.db_name, _sql.port_num, +@@ -536,12 +549,6 @@ netsnmp_mysql_init(void) + #endif + _vbind[VBIND_VAL].length = &_vbind[VBIND_VAL].buffer_length; + +- _sql.conn = mysql_init (NULL); +- if (_sql.conn == NULL) { +- netsnmp_sql_error("mysql_init() failed (out of memory?)"); +- return -1; +- } +- + /** try to connect; we'll try again later if we fail */ + (void) netsnmp_mysql_connect(); + +@@ -1098,6 +1105,8 @@ _sql_process_queue(u_int dontcare, void + (void) netsnmp_mysql_connect(); + } + ++ u_char sql_has_connected = _sql.connected; ++ + CONTAINER_FOR_EACH(_sql.queue, (netsnmp_container_obj_func*)_sql_save, + NULL); + +@@ -1111,8 +1120,10 @@ _sql_process_queue(u_int dontcare, void + } + } + +- CONTAINER_CLEAR(_sql.queue, (netsnmp_container_obj_func*)_sql_buf_free, +- NULL); ++ if (0 == sql_has_connected || _sql.connected) { ++ CONTAINER_CLEAR(_sql.queue, (netsnmp_container_obj_func*)_sql_buf_free, ++ NULL); ++ } + } + + #else