From 9c49cedf8e75046f8524728f5c06198b98c41512 Mon Sep 17 00:00:00 2001 From: Vincent Bernat Date: Mon, 11 Nov 2019 09:54:10 +0100 Subject: [PATCH] lib: fix memory leak when handling I/O The state data is used to ensure we don't interleave requests of the same kind (eg requesting data for eth0, then for eth1 while eth0 is running). The data was freed only when reaching `CONN_STATE_IDLE` again. Otherwise, there was a memory leak. To avoid the memory leak, we avoid use a static allocation instead. Fix #362. --- src/lib/atom.c | 11 ++++++----- src/lib/atom.h | 9 ++++----- src/lib/atoms/port.c | 2 +- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/lib/atom.c b/src/lib/atom.c index 955f4343..f81d3bbc 100644 --- a/src/lib/atom.c +++ b/src/lib/atom.c @@ -322,10 +322,12 @@ _lldpctl_do_something(lldpctl_conn_t *conn, return SET_ERROR(conn, LLDPCTL_ERR_SERIALIZATION); conn->state = state_send; if (state_data) - conn->state_data = strdup(state_data); + strlcpy(conn->state_data, state_data, sizeof(conn->state_data)); + else + conn->state_data[0] = 0; } if (conn->state == state_send && - (state_data == NULL || !strcmp(conn->state_data, state_data))) { + (state_data == NULL || !strncmp(conn->state_data, state_data, sizeof(conn->state_data)))) { /* We need to send the currently built message */ rc = lldpctl_send(conn); if (rc < 0) @@ -333,7 +335,7 @@ _lldpctl_do_something(lldpctl_conn_t *conn, conn->state = state_recv; } if (conn->state == state_recv && - (state_data == NULL || !strcmp(conn->state_data, state_data))) { + (state_data == NULL || !strncmp(conn->state_data, state_data, sizeof(conn->state_data)))) { /* We need to receive the answer */ while ((rc = ctl_msg_recv_unserialized(&conn->input_buffer, &conn->input_buffer_len, @@ -347,8 +349,7 @@ _lldpctl_do_something(lldpctl_conn_t *conn, return SET_ERROR(conn, LLDPCTL_ERR_SERIALIZATION); /* rc == 0 */ conn->state = CONN_STATE_IDLE; - free(conn->state_data); - conn->state_data = NULL; + conn->state_data[0] = 0; return 0; } else return SET_ERROR(conn, LLDPCTL_ERR_INVALID_STATE); diff --git a/src/lib/atom.h b/src/lib/atom.h index 615b315a..a818f7ac 100644 --- a/src/lib/atom.h +++ b/src/lib/atom.h @@ -55,11 +55,10 @@ struct lldpctl_conn_t { #define CONN_STATE_GET_DEFAULT_PORT_SEND 15 #define CONN_STATE_GET_DEFAULT_PORT_RECV 16 int state; /* Current state */ - char *state_data; /* Data attached to the state. It is used to - * check that we are using the same data as a - * previous call until the state machine goes to - * CONN_STATE_IDLE. */ - + /* Data attached to the state. It is used to check that we are using the + * same data as a previous call until the state machine goes to + * CONN_STATE_IDLE. */ + char state_data[IFNAMSIZ + 64]; /* Error handling */ lldpctl_error_t error; /* Last error */ diff --git a/src/lib/atoms/port.c b/src/lib/atoms/port.c index 5cce9131..2fa24959 100644 --- a/src/lib/atoms/port.c +++ b/src/lib/atoms/port.c @@ -329,7 +329,7 @@ _lldpctl_atom_set_atom_port(lldpctl_atom_t *atom, lldpctl_key_t key, lldpctl_ato struct lldpd_hardware *hardware = p->hardware; struct lldpd_port_set set = {}; int rc; - char *canary; + char *canary = NULL; #ifdef ENABLE_DOT3 struct _lldpctl_atom_dot3_power_t *dpow; -- 2.39.5