summaryrefslogtreecommitdiff
blob: 94dceac5d69c34793fe4ee45230c91555cd141cb (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
From 7989b3c6bdfdeb8770d17d8717b4a0cd48e79386 Mon Sep 17 00:00:00 2001
From: Robbie Harwood <rharwood@redhat.com>
Date: Wed, 24 Oct 2018 16:57:11 -0400
Subject: [PATCH] Fix rare leak of DSO in module_load

---
 src/module.c | 31 +++++++++++++++----------------
 1 file changed, 15 insertions(+), 16 deletions(-)

diff --git a/src/module.c b/src/module.c
index 1f1b7c9..0b59034 100644
--- a/src/module.c
+++ b/src/module.c
@@ -182,7 +182,7 @@ module_load(const char *filename, const char *symbname,
     intdll = dlopen(filename, RTLD_LAZY | RTLD_LOCAL);
 #endif /* WIN32 */
     if (!intdll)
-        return dllerror();
+        goto fail;
 
     /* Get the module symbol */
 #ifdef WIN32
@@ -190,16 +190,12 @@ module_load(const char *filename, const char *symbname,
 #else /* WIN32 */
     intsym = dlsym(intdll, symbname);
 #endif /* WIN32 */
-    if (!intsym) {
-        module_close(intdll);
-        return dllerror();
-    }
+    if (!intsym)
+        goto fail;
 
     /* Figure out whether or not to load this module */
-    if (!shouldload(intsym, misc, &interr)) {
-        module_close(intdll);
-        return interr;
-    }
+    if (!shouldload(intsym, misc, &interr))
+        goto fail;
 
     /* Re-open the module */
     module_close(intdll);
@@ -208,9 +204,8 @@ module_load(const char *filename, const char *symbname,
 #else  /* WIN32 */
     intdll = dlopen(filename, RTLD_NOW | RTLD_LOCAL);
 #endif /* WIN32 */
-    if (!intdll) {
-        return dllerror();
-    }
+    if (!intdll)
+        goto fail;
 
     /* Get the symbol again */
 #ifdef WIN32
@@ -218,14 +213,18 @@ module_load(const char *filename, const char *symbname,
 #else /* WIN32 */
     intsym = dlsym(intdll, symbname);
 #endif /* WIN32 */
-    if (!intsym) {
-        module_close(intdll);
-        return dllerror();
-    }
+    if (!intsym)
+        goto fail;
 
     if (dll)
         *dll = intdll;
     if (symb)
         *symb = intsym;
     return NULL;
+
+fail:
+    if (!interr)
+        interr = dllerror();
+    module_close(intdll);
+    return interr;
 }