summaryrefslogtreecommitdiff
path: root/libexec
diff options
context:
space:
mode:
authorpk <pk@NetBSD.org>1997-06-30 22:10:06 +0000
committerpk <pk@NetBSD.org>1997-06-30 22:10:06 +0000
commit72023de51f85949d7ca656698007b0dbf35f6943 (patch)
tree2da6844264c0d946cf1557e4e7054a137fc2c47c /libexec
parente0bb7d9370ce13f8b9b933358a02e3c4a96a8a7d (diff)
Do not free dlopen'ed map structures twice.
Plug memory leak when opening the same object mor than once.
Diffstat (limited to 'libexec')
-rw-r--r--libexec/ld.aout_so/rtld.c36
1 files changed, 24 insertions, 12 deletions
diff --git a/libexec/ld.aout_so/rtld.c b/libexec/ld.aout_so/rtld.c
index b915cc24217..5afc80155aa 100644
--- a/libexec/ld.aout_so/rtld.c
+++ b/libexec/ld.aout_so/rtld.c
@@ -1,4 +1,4 @@
-/* $NetBSD: rtld.c,v 1.50 1997/06/30 20:49:40 pk Exp $ */
+/* $NetBSD: rtld.c,v 1.51 1997/06/30 22:10:06 pk Exp $ */
/*
* Copyright (c) 1993 Paul Kranenburg
* All rights reserved.
@@ -581,6 +581,13 @@ free_link_map(smp)
struct so_map *smp;
{
+ if ((LM_PRIVATE(smp)->spd_flags & RTLD_DL) != 0) {
+ /* free synthetic sod structure allocated in __dlopen() */
+ free((char *)smp->som_sod->sod_name);
+ free(smp->som_sod);
+ }
+
+ /* free the link map structure. */
free(smp->som_spd);
if (smp->som_path != NULL)
free(smp->som_path);
@@ -729,9 +736,6 @@ unmap_object(smp)
/* unmap from address space */
(void)munmap(smp->som_addr, LM_PRIVATE(smp)->spd_size);
-
- /* free the link map structure. */
- free_link_map(smp);
}
void
@@ -1458,7 +1462,7 @@ static struct so_map dlmap = {
static int dlerrno;
/*
- * Populate sod struct for dlopen's call to map_obj
+ * Populate sod struct for dlopen's call to map_object
*/
void
build_sod(name, sodp)
@@ -1559,16 +1563,27 @@ __dlopen(name, mode)
xprintf("%s: %s\n", name, strerror(errno));
#endif
dlerrno = errno;
+ free((char *)sodp->sod_name);
+ free(sodp);
return NULL;
}
- if (LM_PRIVATE(smp)->spd_refcount++ > 0)
+ if (LM_PRIVATE(smp)->spd_refcount++ > 0) {
+ free((char *)sodp->sod_name);
+ free(sodp);
return smp;
+ }
- if (load_subs(smp) != 0)
+ LM_PRIVATE(smp)->spd_flags |= RTLD_DL;
+
+ if (load_subs(smp) != 0) {
+ if (--LM_PRIVATE(smp)->spd_refcount == 0) {
+ unmap_object(smp);
+ free_link_map(smp);
+ }
return NULL;
+ }
- LM_PRIVATE(smp)->spd_flags |= RTLD_DL;
init_maps(smp);
return smp;
}
@@ -1598,10 +1613,7 @@ xprintf("dlclose(%s): refcount = %d\n", smp->som_path, LM_PRIVATE(smp)->spd_refc
unload_subs(smp); /* XXX should unload implied objects */
#endif
unmap_object(smp);
- free((char *)smp->som_sod->sod_name);
- free(smp->som_sod);
- free(smp);
-
+ free_link_map(smp);
return 0;
}