Subject: [PATCH 1/2] Avoid possible memory leak in mcap_connect_mdl function

---
health/mcap.c | 25 +++++++++++++++++++++++--
1 files changed, 23 insertions(+), 2 deletions(-)

diff --git a/health/mcap.c b/health/mcap.c
index 6f1e565..30a1e6e 100644
--- a/health/mcap.c
+++ b/health/mcap.c
@@ -65,6 +65,7 @@ struct mcap_mdl_op_cb {
struct mcap_mdl *mdl; /* MDL for this operation */
mcap_cb_type cb; /* Operation callback */
gpointer user_data; /* Callback user data */
+ gboolean proc; /* If it was processed*/
};

/* MCAP finite state machine functions */
@@ -1573,7 +1574,7 @@ static void mcap_connect_mdl_cb(GIOChannel *chan, GError *conn_err,
mcap_mdl_operation_cb cb = con->cb.op;
gpointer user_data = con->user_data;

- g_free(con);
+ con->proc = TRUE;
DBG("mdl connect callback");

if (conn_err) {
@@ -1592,6 +1593,26 @@ static void mcap_connect_mdl_cb(GIOChannel *chan, GError *conn_err,
cb(mdl, conn_err, user_data);
}

+static void mdl_io_destroy(gpointer data)
+{
+ struct mcap_mdl_op_cb *con = data;
+ struct mcap_mdl *mdl = con->mdl;
+ mcap_mdl_operation_cb cb = con->cb.op;
+ gpointer user_data = con->user_data;
+ gboolean proc = con->proc;
+ GError *err = NULL;
+
+ g_free(con);
+
+ if (proc)
+ return;
+ g_set_error(&err, MCAP_ERROR, MCAP_ERROR_FAILED, "Connection error");
+ mdl->state = MDL_CLOSED;
+ g_io_channel_unref(mdl->dc);
+ mdl->dc = NULL;
+ cb(mdl, err, user_data);
+}
+
gboolean mcap_connect_mdl(struct mcap_mdl *mdl, BtIOType BtType,
uint16_t dcpsm,
mcap_mdl_operation_cb connect_cb,
@@ -1613,7 +1634,7 @@ gboolean mcap_connect_mdl(struct mcap_mdl *mdl, BtIOType BtType,
/* TODO: Check if BtIOType is ERTM or Streaming before continue */

mdl->dc = bt_io_connect(BtType, mcap_connect_mdl_cb, con,
- NULL, err,
+ mdl_io_destroy, err,
BT_IO_OPT_SOURCE_BDADDR, &mdl->mcl->ms->src,
BT_IO_OPT_DEST_BDADDR, &mdl->mcl->addr,
BT_IO_OPT_PSM, dcpsm,
--
1.7.0.4



2010-09-06 08:15:52

by Santiago Carot

[permalink] [raw]
Subject: [PATCH 2/2] Avoid possible memory leak in mcap_create_mcl function

---
health/mcap.c | 28 +++++++++++++++++++++++++---
1 files changed, 25 insertions(+), 3 deletions(-)

diff --git a/health/mcap.c b/health/mcap.c
index 30a1e6e..17e16d8 100644
--- a/health/mcap.c
+++ b/health/mcap.c
@@ -53,6 +53,7 @@ struct connect_mcl {
struct mcap_mcl *mcl; /* MCL for this operation */
mcap_mcl_connect_cb connect_cb; /* Connect callback */
gpointer user_data; /* Callback user data */
+ gboolean proc; /* If it is was proccessed */
};

typedef union {
@@ -1695,8 +1696,7 @@ static void mcap_connect_mcl_cb(GIOChannel *chan, GError *conn_err,
gpointer data = con->user_data;
GError *gerr = NULL;

- g_free(con);
-
+ con->proc = TRUE;
mcl->ctrl &= ~MCAP_CTRL_CONN;

if (conn_err) {
@@ -1760,6 +1760,28 @@ static void connect_dc_event_cb(GIOChannel *chan, GError *err,
mcl->cb->mdl_connected(mdl, mcl->cb->user_data);
}

+static void mcl_io_destroy(gpointer data)
+{
+ struct connect_mcl *con = data;
+ struct mcap_mcl *mcl = con->mcl;
+ mcap_mcl_connect_cb connect_cb = con->connect_cb;
+ gpointer user_data = con->user_data;
+ GError *err = NULL;
+
+ g_free(con);
+
+ if (con->proc)
+ return;
+
+ mcl->ctrl &= ~MCAP_CTRL_CONN;
+
+ if (mcl->ctrl & MCAP_CTRL_FREE)
+ mcl->ms->mcl_uncached_cb(mcl, mcl->ms->user_data);
+ mcap_mcl_check_del(mcl);
+ g_set_error(&err, MCAP_ERROR, MCAP_ERROR_FAILED, "Connection error");
+ connect_cb(NULL, err, user_data);
+}
+
gboolean mcap_create_mcl(struct mcap_instance *ms,
const bdaddr_t *addr,
uint16_t ccpsm,
@@ -1795,7 +1817,7 @@ gboolean mcap_create_mcl(struct mcap_instance *ms,
con->user_data = user_data;

mcl->cc = bt_io_connect(BT_IO_L2CAP, mcap_connect_mcl_cb, con,
- NULL, err,
+ mcl_io_destroy, err,
BT_IO_OPT_SOURCE_BDADDR, &ms->src,
BT_IO_OPT_DEST_BDADDR, addr,
BT_IO_OPT_PSM, ccpsm,
--
1.7.0.4