Skip to content

Commit

Permalink
sql_cacher: Fix pkg memory leaks
Browse files Browse the repository at this point in the history
(cherry picked from commit e72fc5f)
  • Loading branch information
liviuchircu committed Mar 22, 2017
1 parent 9e4a897 commit bfd3411
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 19 deletions.
4 changes: 2 additions & 2 deletions cachedb/cachedb.h
Expand Up @@ -62,8 +62,8 @@ void cachedb_do_close(cachedb_con *con, void (*free_connection)(cachedb_pool_con
typedef cachedb_con* (cachedb_init_f)(str *url);
typedef void (cachedb_destroy_f)(cachedb_con *con);

/* NOTE: "val->s" must be allocated in PKG memory,
* and will be freed by the CacheDB layer! */
/* NOTE: "val->s" shall be allocated in PKG memory,
* and MUST be freed by the calling layer! */
typedef int (cachedb_get_f)(cachedb_con *con,str *attr,str *val);
typedef int (cachedb_getcounter_f)(cachedb_con *con,str *attr,int *val);
typedef int (cachedb_set_f)(cachedb_con *con,str *attr,str *val,int expires);
Expand Down
53 changes: 36 additions & 17 deletions modules/sql_cacher/sql_cacher.c
Expand Up @@ -612,6 +612,7 @@ static db_handlers_t *db_init_test_conn(cache_entry_t *c_entry)
db_res_t *sql_res;
str cachedb_res;
unsigned int i;
int rc;

new_db_hdls = pkg_malloc(sizeof(db_handlers_t));
if (!new_db_hdls) {
Expand Down Expand Up @@ -653,7 +654,9 @@ static db_handlers_t *db_init_test_conn(cache_entry_t *c_entry)
new_db_hdls->cdbcon = 0;
return NULL;
}
if (str_strcmp(&cachedb_res, &cdb_test_val) != 0) {
rc = str_strcmp(&cachedb_res, &cdb_test_val);
pkg_free(cachedb_res.s);
if (rc != 0) {
LM_ERR("Inconsistent test key for cachedb: %.*s\n",
c_entry->cachedb_url.len, c_entry->cachedb_url.s);
new_db_hdls->cdbf.destroy(new_db_hdls->cdbcon);
Expand Down Expand Up @@ -1206,7 +1209,7 @@ static int cdb_val_decode(pv_name_fix_t *pv_name, str *cdb_val, int reload_versi

if (pv_name->col_offset == -1) {
LM_WARN("Unknown column %.*s\n", pv_name->col.len, pv_name->col.s);
return -1;
return 2;
}

if (!pv_name->c_entry->on_demand) {
Expand All @@ -1217,7 +1220,7 @@ static int cdb_val_decode(pv_name_fix_t *pv_name, str *cdb_val, int reload_versi
memcpy(&int_val, int_buf, 4);

if (reload_version != int_val)
return -2;
return 3;
}

/* null integer value in db */
Expand Down Expand Up @@ -1263,7 +1266,7 @@ static int cdb_val_decode(pv_name_fix_t *pv_name, str *cdb_val, int reload_versi
return 0;
error:
LM_ERR("Failed to decode value: %.*s from cachedb\n", cdb_val->len, cdb_val->s);
return -1;
return 2;
}

static void optimize_cdb_decode(pv_name_fix_t *pv_name)
Expand Down Expand Up @@ -1557,6 +1560,7 @@ int pv_parse_name(pv_spec_p sp, str *in)
return 0;
}

static str valbuff;
int pv_get_sql_cached_value(struct sip_msg *msg, pv_param_t *param, pv_value_t *res)
{
pv_name_fix_t *pv_name;
Expand Down Expand Up @@ -1616,7 +1620,7 @@ int pv_get_sql_cached_value(struct sip_msg *msg, pv_param_t *param, pv_value_t
}

if (!pv_name->c_entry->on_demand) {
if (rc == -2) {
if (rc <= -2) {
LM_DBG("key %.*s not found in SQL db\n", pv_name->key.len, pv_name->key.s);
lock_stop_read(pv_name->c_entry->ref_lock);
return pv_get_null(msg, param, res);
Expand All @@ -1628,28 +1632,30 @@ int pv_get_sql_cached_value(struct sip_msg *msg, pv_param_t *param, pv_value_t

lock_stop_read(pv_name->c_entry->ref_lock);

if (rc2 == -1)
return pv_get_null(msg, param, res);
if (rc2 == -2) {
if (rc2 == 2)
goto out_free_null;
if (rc2 == 3) {
LM_DBG("key %.*s not found in SQL db\n", pv_name->key.len, pv_name->key.s);
return pv_get_null(msg, param, res);
goto out_free_null;
}
if (rc2 == 1) {
LM_DBG("NULL value in SQL db\n");
return pv_get_null(msg, param, res);
goto out_free_null;
}
}
} else {
if (rc == -2) {
if (rc <= -2) {
rc2 = on_demand_load(pv_name, &cdb_res, &str_res, &int_res);
if (rc2 == -1 || rc2 == -2)
return pv_get_null(msg, param, res);
if (rc2 == 2 || rc2 == 3)
goto out_free_null;
if (rc2 == 1) {
LM_DBG("NULL value in SQL db\n");
return pv_get_null(msg, param, res);
goto out_free_null;
}
} else {
if (!cdb_res.len || !cdb_res.s) {
if (cdb_res.len == 0 || !cdb_res.s) {
LM_DBG("key %.*s not found in SQL db\n", pv_name->key.len, pv_name->key.s);
return pv_get_null(msg, param, res);
}
Expand All @@ -1658,18 +1664,26 @@ int pv_get_sql_cached_value(struct sip_msg *msg, pv_param_t *param, pv_value_t
optimize_cdb_decode(pv_name);

rc2 = cdb_val_decode(pv_name, &cdb_res, 0, &str_res, &int_res);
if (rc2 == -1)
return pv_get_null(msg, param, res);
if (rc2 == 2)
goto out_free_null;
if (rc2 == 1) {
LM_DBG("NULL value in SQL db\n");
return pv_get_null(msg, param, res);
goto out_free_null;
}
}
}

if ((pv_name->c_entry->column_types & (one << pv_name->col_nr)) != 0) {
if (pkg_str_resize(&valbuff, str_res.len) != 0) {
LM_ERR("failed to alloc buffer\n");
goto out_free_null;
}

memcpy(valbuff.s, str_res.s, str_res.len);
valbuff.len = str_res.len;

res->flags = PV_VAL_STR;
res->rs.s = str_res.s;
res->rs.s = valbuff.s;
res->rs.len = str_res.len;
} else {
res->ri = int_res;
Expand All @@ -1679,7 +1693,12 @@ int pv_get_sql_cached_value(struct sip_msg *msg, pv_param_t *param, pv_value_t
res->flags = PV_VAL_STR|PV_VAL_INT|PV_TYPE_INT;
}

pkg_free(cdb_res.s);
return 0;

out_free_null:
pkg_free(cdb_res.s);
return pv_get_null(msg, param, res);
}

static void destroy(void)
Expand Down
19 changes: 19 additions & 0 deletions ut.h
Expand Up @@ -651,6 +651,25 @@ static inline char *pkg_strdup(const char *str)
return rval;
}

/* Extend the given buffer only if needed */
static inline int pkg_str_resize(str *in, int size)
{
char *p;

if (in->len < size) {
p = pkg_realloc(in->s, size);
if (!p) {
LM_ERR("oom\n");
return -1;
}

in->s = p;
in->len = size;
}

return 0;
}

/*
* compare two str's
*/
Expand Down

0 comments on commit bfd3411

Please sign in to comment.