summaryrefslogtreecommitdiff
path: root/app-antivirus/clamav/files/clamav-0.99.3-fix-fd-leaks-in-cli_scanscript.patch
blob: a457a71758c66cf916faff2dfcadd7bd37e02c2c (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
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
Author: Manuel Mausz <manuel-clamav@mausz.at>

http://lists.clamav.net/pipermail/clamav-users/2018-January/005687.html

--- clamav-0.99.3/libclamav/scanners.c.orig	2018-01-26 14:35:23.299386703 +0100
+++ clamav-0.99.3/libclamav/scanners.c	2018-01-26 14:47:44.422451335 +0100
@@ -1342,39 +1342,35 @@
 		return CL_CLEAN;
 	}
 
-	/* dump to disk only if explicitly asked to
-	 * or if necessary to check relative offsets,
-	 * otherwise we can process just in-memory */
-	if(ctx->engine->keeptmp || (troot && troot->ac_reloff_num > 0)) {
-		if((ret = cli_gentempfd(ctx->engine->tmpdir, &tmpname, &ofd))) {
-			cli_dbgmsg("cli_scanscript: Can't generate temporary file/descriptor\n");
-			return ret;
-		}
-		if (ctx->engine->keeptmp)
-			cli_dbgmsg("cli_scanscript: saving normalized file to %s\n", tmpname);
-	}
-
 	if(!(normalized = cli_malloc(SCANBUFF + maxpatlen))) {
 		cli_dbgmsg("cli_scanscript: Unable to malloc %u bytes\n", SCANBUFF);
-		free(tmpname);
 		return CL_EMEM;
 	}
-
 	text_normalize_init(&state, normalized, SCANBUFF + maxpatlen);
-	ret = CL_CLEAN;
-
 
 	if ((ret = cli_ac_initdata(&tmdata, troot?troot->ac_partsigs:0, troot?troot->ac_lsigs:0, troot?troot->ac_reloff_num:0, CLI_DEFAULT_AC_TRACKLEN))) {
-		free(tmpname);
+		free(normalized);
 		return ret;
 	}
 
 	if ((ret = cli_ac_initdata(&gmdata, groot->ac_partsigs, groot->ac_lsigs, groot->ac_reloff_num, CLI_DEFAULT_AC_TRACKLEN))) {
 		cli_ac_freedata(&tmdata);
-		free(tmpname);
+		free(normalized);
 		return ret;
 	}
 
+	/* dump to disk only if explicitly asked to
+	 * or if necessary to check relative offsets,
+	 * otherwise we can process just in-memory */
+	if(ctx->engine->keeptmp || (troot && troot->ac_reloff_num > 0)) {
+		if((ret = cli_gentempfd(ctx->engine->tmpdir, &tmpname, &ofd))) {
+			cli_dbgmsg("cli_scanscript: Can't generate temporary file/descriptor\n");
+			goto done;
+		}
+		if (ctx->engine->keeptmp)
+			cli_dbgmsg("cli_scanscript: saving normalized file to %s\n", tmpname);
+	}
+
 	mdata[0] = &tmdata;
 	mdata[1] = &gmdata; 
 
@@ -1388,9 +1384,8 @@
 
 			if  (write(ofd, state.out, state.out_pos) == -1) {
 				cli_errmsg("cli_scanscript: can't write to file %s\n",tmpname);
-				close(ofd);
-				free(tmpname);
-				return CL_EWRITE;
+				ret = CL_EWRITE;
+				goto done;
 			}
 			text_normalize_reset(&state);
 		}
@@ -1409,11 +1404,6 @@
 			funmap(*ctx->fmap);
 		}
 		*ctx->fmap = map;
-
-		/* If we aren't keeping temps, delete the normalized file after scan. */
-		if(!(ctx->engine->keeptmp))
-			if (cli_unlink(tmpname)) ret = CL_EUNLINK;
-
 	} else {
 		/* Since the above is moderately costly all in all,
 		 * do the old stuff if there's no relative offsets. */
@@ -1421,11 +1411,8 @@
 		if (troot) {
 			cli_targetinfo(&info, 7, map);
 			ret = cli_ac_caloff(troot, &tmdata, &info);
-			if (ret) {
-				cli_ac_freedata(&tmdata);
-				free(tmpname);
-				return ret;
-			}
+			if (ret)
+				goto done;
 		}
 
 		while(1) {
@@ -1466,13 +1453,6 @@
 
 	}
 
-	if(ctx->engine->keeptmp) {
-		free(tmpname);
-		if (ofd >= 0)
-			close(ofd);
-	}
-	free(normalized);
-
 	if(ret != CL_VIRUS || SCAN_ALL)  {
 		if ((ret = cli_exp_eval(ctx, troot, &tmdata, NULL, NULL)) == CL_VIRUS)
 			viruses_found++;
@@ -1481,9 +1461,19 @@
 				viruses_found++;
 	}
 
+done:
+	free(normalized);
 	cli_ac_freedata(&tmdata);
 	cli_ac_freedata(&gmdata);
 
+	if (ofd != -1)
+		close(ofd);
+	if (tmpname != NULL) {
+		if (!ctx->engine->keeptmp)
+			if (cli_unlink(tmpname)) ret = CL_EUNLINK;
+		free(tmpname);
+	}
+
 	if (SCAN_ALL && viruses_found)
 		return CL_VIRUS;