]> git.ipfire.org Git - thirdparty/lldpd.git/commitdiff
lib: fix memory leak when handling I/O
authorVincent Bernat <vincent@bernat.ch>
Mon, 11 Nov 2019 08:54:10 +0000 (09:54 +0100)
committerVincent Bernat <vincent@bernat.ch>
Mon, 11 Nov 2019 09:36:08 +0000 (10:36 +0100)
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
src/lib/atom.h
src/lib/atoms/port.c

index 955f434368bf8dcac3405c917910c98ab270c4f5..f81d3bbc207c02c8aaa9b49297b1bbc4a7a19272 100644 (file)
@@ -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);
index 615b315a9d7c769f19b95678b89a3dd31f72899e..a818f7ac967541349f1ad78bfdcad85b40be5c98 100644 (file)
@@ -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 */
 
index 5cce9131de4374986f6f56233e0e9fb152fafa95..2fa249594f26c049df09e9066997236004c95c50 100644 (file)
@@ -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;