summaryrefslogtreecommitdiffstats
path: root/src/sss_client/nss_mc_passwd.c
diff options
context:
space:
mode:
authorLukas Slebodnik <lslebodn@redhat.com>2014-07-09 19:03:30 +0200
committerJakub Hrozek <jhrozek@redhat.com>2014-07-24 11:37:18 +0200
commitadd843f87b4da65e4cab7a888df8731cca306b6d (patch)
tree66278ca2d3ad4a73ea920e5eb5469f14753a2af2 /src/sss_client/nss_mc_passwd.c
parent0d25c8fded1653ec20914e5f093f025b6eb0f5d6 (diff)
downloadsssd-add843f87b4da65e4cab7a888df8731cca306b6d.tar.gz
sssd-add843f87b4da65e4cab7a888df8731cca306b6d.tar.xz
sssd-add843f87b4da65e4cab7a888df8731cca306b6d.zip
sss_client: Fix memory leak in nss_mc_{group,passwd}
Memory leak can happen with long living clients where there are records with colliding hashes; usually LDAP servers with many users or groups. Function sss_nss_mc_get_record allocates memory that is stored into "rec", with next iteration variable rec is overriden with new record and old one is lost and cannot be freed. Example code flow: src/sss_client/nss_mc_group.c:133: alloc_arg: "sss_nss_mc_get_record" allocates memory that is stored into "rec". src/sss_client/nss_mc_common.c:216:13: alloc_fn: Storage is returned from allocation function "malloc". src/sss_client/nss_mc_common.c:216:13: var_assign: Assigning: "copy_rec" = "malloc(rec_len)". src/sss_client/nss_mc_common.c:225:9: noescape: Resource "copy_rec" is not freed or pointed-to in function "memcpy". [Note: The source code implementation of the function has been overridden by a builtin model.] src/sss_client/nss_mc_common.c:239:5: var_assign: Assigning: "*_rec" = "copy_rec". src/sss_client/nss_mc_group.c:163: noescape: Resource "rec" is not freed or pointed-to in "sss_nss_mc_next_slot_with_hash". src/sss_client/nss_mc_common.c:294:60: noescape: "sss_nss_mc_next_slot_with_hash(struct sss_mc_rec *, uint32_t)" does not free or save its pointer parameter "rec". src/sss_client/nss_mc_group.c:133: overwrite_var: Overwriting "rec" in call to "sss_nss_mc_get_record" leaks the storage that "rec" points to. src/sss_client/nss_mc_common.c:239:5: write_notnull_to_parm: Assigning: "*_rec" = "copy_rec". Reviewed-by: Michal Židek <mzidek@redhat.com> Reviewed-by: Sumit Bose <sbose@redhat.com> (cherry picked from commit 9d876108620931e0941a115adf60bfd8d67459d9)
Diffstat (limited to 'src/sss_client/nss_mc_passwd.c')
-rw-r--r--src/sss_client/nss_mc_passwd.c8
1 files changed, 8 insertions, 0 deletions
diff --git a/src/sss_client/nss_mc_passwd.c b/src/sss_client/nss_mc_passwd.c
index a0a8d87f7..b952b3658 100644
--- a/src/sss_client/nss_mc_passwd.c
+++ b/src/sss_client/nss_mc_passwd.c
@@ -123,6 +123,10 @@ errno_t sss_nss_mc_getpwnam(const char *name, size_t name_len,
* it's value is not MC_INVALID_VAL, then the cache is
* probbably corrupted. */
while (MC_SLOT_WITHIN_BOUNDS(slot, pw_mc_ctx.dt_size)) {
+ /* free record from previous iteration */
+ free(rec);
+ rec = NULL;
+
ret = sss_nss_mc_get_record(&pw_mc_ctx, slot, &rec);
if (ret) {
goto done;
@@ -199,6 +203,10 @@ errno_t sss_nss_mc_getpwuid(uid_t uid,
* it's value is not MC_INVALID_VAL, then the cache is
* probbably corrupted. */
while (MC_SLOT_WITHIN_BOUNDS(slot, pw_mc_ctx.dt_size)) {
+ /* free record from previous iteration */
+ free(rec);
+ rec = NULL;
+
ret = sss_nss_mc_get_record(&pw_mc_ctx, slot, &rec);
if (ret) {
goto done;