Browse code

clamonacc - fix fd leak when excluding file after self-check; cleanup signal handling and application exiting; fixup path for using unix fd passing with curl; normalize some log output; add suppression of noisy error cases when clamd lacks sufficient permissions to stat certain files"

Mickey Sola authored on 2019/05/31 06:44:03
Showing 8 changed files
... ...
@@ -24,6 +24,12 @@
24 24
 
25 25
 #include "libclamav/clamav.h"
26 26
 
27
+#ifndef ONAS_DEBUG
28
+#define ONAS_DEBUG
29
+#endif
30
+/* dev only switch for very noisy output */
31
+#undef ONAS_DEBUG
32
+
27 33
 #ifndef HAVE_ATTRIB_PACKED
28 34
 #define __attribute__(x)
29 35
 #endif
... ...
@@ -23,8 +23,6 @@
23 23
 #include "clamav-config.h"
24 24
 #endif
25 25
 
26
-//#define ONAS_DEBUG
27
-
28 26
 #include <stdio.h>
29 27
 #include <stdlib.h>
30 28
 #include <curl/curl.h>
... ...
@@ -169,64 +167,90 @@ CURLcode onas_curl_init(CURL **curl, const char *ipaddr, int64_t port, int64_t t
169 169
 		return CURLE_FAILED_INIT;
170 170
 	}
171 171
 
172
-        /* setup here, but caller needs to cleanup */
172
+	/* setup here, but caller needs to cleanup */
173 173
 	*curl = curl_easy_init();
174 174
 
175
-	curlcode = curl_easy_setopt(*curl, CURLOPT_PORT, port);
176
-        if (CURLE_OK != curlcode) {
177
-		logg("!ClamClient: could not setup curl with tcp port, %s\n", curl_easy_strerror(curlcode));
178
-		curl_easy_cleanup(*curl);
179
-		return curlcode;
180
-        }
175
+	if (!port) {
176
+
177
+		/* "ipaddr" is actually our unix socket path here */
178
+		curlcode = curl_easy_setopt(*curl, CURLOPT_UNIX_SOCKET_PATH, ipaddr);
179
+		if (CURLE_OK != curlcode) {
180
+			logg("!ClamClient: could not setup curl with local unix socket, %s\n", curl_easy_strerror(curlcode));
181
+			curl_easy_cleanup(*curl);
182
+			return curlcode;
183
+		}
181 184
 
182
-	curlcode = curl_easy_setopt(*curl, CURLOPT_URL, ipaddr);
183
-        if (CURLE_OK != curlcode) {
184
-		logg("!ClamClient: could not setup curl with tcp address, %s\n", curl_easy_strerror(curlcode));
185
-		curl_easy_cleanup(*curl);
186
-		return curlcode;
185
+		curlcode = curl_easy_setopt(*curl, CURLOPT_URL, "http://localhost/");
186
+		if (CURLE_OK != curlcode) {
187
+			logg("!ClamClient: could not setup curl with local address, %s\n", curl_easy_strerror(curlcode));
188
+			curl_easy_cleanup(*curl);
189
+			return curlcode;
190
+		}
191
+
192
+	} else {
193
+
194
+		curlcode = curl_easy_setopt(*curl, CURLOPT_PORT, port);
195
+		if (CURLE_OK != curlcode) {
196
+			logg("!ClamClient: could not setup curl with tcp port, %s\n", curl_easy_strerror(curlcode));
197
+			curl_easy_cleanup(*curl);
198
+			return curlcode;
199
+		}
200
+
201
+		curlcode = curl_easy_setopt(*curl, CURLOPT_URL, ipaddr);
202
+		if (CURLE_OK != curlcode) {
203
+			logg("!ClamClient: could not setup curl with tcp address, %s\n", curl_easy_strerror(curlcode));
204
+			curl_easy_cleanup(*curl);
205
+			return curlcode;
206
+		}
187 207
         }
188 208
 
189
-	/* we implement our own transfer protocol via send and recv, so we only need to connect */
190
-	curlcode = curl_easy_setopt(*curl, CURLOPT_CONNECT_ONLY, 1L);
191
-	if (CURLE_OK != curlcode) {
192
-		logg("!ClamClient: could not setup curl to connect only, %s\n", curl_easy_strerror(curlcode));
193
-		curl_easy_cleanup(*curl);
194
-		return curlcode;
195
-	}
209
+		curlcode = curl_easy_setopt(*curl, CURLOPT_NOSIGNAL, 1L);
210
+		if (CURLE_OK != curlcode) {
211
+			logg("!ClamClient: could not setup curl to not use signals, %s\n", curl_easy_strerror(curlcode));
212
+			curl_easy_cleanup(*curl);
213
+			return curlcode;
214
+		}
196 215
 
197
-	/* we implement our own transfer protocol via send and recv, so we only need to connect */
198
-	curlcode = curl_easy_setopt(*curl, CURLOPT_CONNECTTIMEOUT_MS, (long) timeout);
199
-	if (CURLE_OK != curlcode) {
200
-		logg("!ClamClient: could not setup curl with connect timeout, %s\n", curl_easy_strerror(curlcode));
201
-		curl_easy_cleanup(*curl);
202
-		return curlcode;
203
-	}
216
+		curlcode = curl_easy_setopt(*curl, CURLOPT_CONNECTTIMEOUT_MS, (long) timeout);
217
+		if (CURLE_OK != curlcode) {
218
+			logg("!ClamClient: could not setup curl with connect timeout, %s\n", curl_easy_strerror(curlcode));
219
+			curl_easy_cleanup(*curl);
220
+			return curlcode;
221
+		}
204 222
 
223
+		/* we implement our own transfer protocol via send and recv, so we only need to connect */
224
+		curlcode = curl_easy_setopt(*curl, CURLOPT_CONNECT_ONLY, 1L);
225
+		if (CURLE_OK != curlcode) {
226
+			logg("!ClamClient: could not setup curl to connect only, %s\n", curl_easy_strerror(curlcode));
227
+			curl_easy_cleanup(*curl);
228
+			return curlcode;
229
+		}
205 230
 
206 231
 
207 232
 #ifdef ONAS_DEBUG
208
-	curlcode = curl_easy_setopt(*curl, CURLOPT_VERBOSE, 1L);
209
-	if (CURLE_OK != curlcode) {
210
-		logg("!ClamClient: could not tell curl to be verbose, %s\n", curl_easy_strerror(curlcode));
211
-		curl_easy_cleanup(*curl);
212
-		return curlcode;
213
-	}
233
+		curlcode = curl_easy_setopt(*curl, CURLOPT_VERBOSE, 1L);
234
+		if (CURLE_OK != curlcode) {
235
+			logg("!ClamClient: could not tell curl to be verbose, %s\n", curl_easy_strerror(curlcode));
236
+			curl_easy_cleanup(*curl);
237
+			return curlcode;
238
+		}
214 239
 #endif
215 240
 
216
-        /* don't care about the body of the return message */
217
-        curlcode = curl_easy_setopt(*curl, CURLOPT_NOBODY, 1L);
218
-	if (CURLE_OK != curlcode) {
219
-		logg("!ClamClient: could not setup curl to send HEAD request, %s\n", curl_easy_strerror(curlcode));
220
-		curl_easy_cleanup(*curl);
221
-		return curlcode;
222
-	}
241
+		/* don't care about the body of the return message */
242
+		curlcode = curl_easy_setopt(*curl, CURLOPT_NOBODY, 1L);
243
+		if (CURLE_OK != curlcode) {
244
+			logg("!ClamClient: could not setup curl to send HEAD request, %s\n", curl_easy_strerror(curlcode));
245
+			curl_easy_cleanup(*curl);
246
+			return curlcode;
247
+		}
248
+
249
+		curlcode = curl_easy_setopt(*curl, CURLOPT_HEADER, 0L);
250
+		if (CURLE_OK != curlcode) {
251
+			logg("!ClamClient: could not setup curl to not send header, %s\n", curl_easy_strerror(curlcode));
252
+			curl_easy_cleanup(*curl);
253
+			return curlcode;
254
+		}
223 255
 
224
-        curlcode = curl_easy_setopt(*curl, CURLOPT_HEADER, 0L);
225
-	if (CURLE_OK != curlcode) {
226
-		logg("!ClamClient: could not setup curl to not send header, %s\n", curl_easy_strerror(curlcode));
227
-		curl_easy_cleanup(*curl);
228
-		return curlcode;
229
-	}
230 256
 
231 257
 	return curlcode;
232 258
 }
... ...
@@ -336,13 +360,7 @@ int onas_get_clamd_version(struct onas_context **ctx)
336 336
     }
337 337
 
338 338
     if (!b_remote) {
339
-	curl = curl_easy_init();
340
-        curlcode = curl_easy_setopt(curl, CURLOPT_UNIX_SOCKET_PATH, optget((*ctx)->clamdopts, "LocalSocket")->strarg);
341
-	if (CURLE_OK != curlcode) {
342
-		logg("!ClamClient: could not setup curl with local unix socket, %s\n", curl_easy_strerror(curlcode));
343
-		curl_easy_cleanup(curl);
344
-		return 2;
345
-	}
339
+	curlcode = onas_curl_init(&curl, optget((*ctx)->clamdopts, "LocalSocket")->strarg, (*ctx)->portnum, timeout);
346 340
     } else {
347 341
 	curlcode = onas_curl_init(&curl, optget((*ctx)->clamdopts, "TCPAddr")->strarg, (*ctx)->portnum, timeout);
348 342
 	if (CURLE_OK != curlcode) {
... ...
@@ -329,7 +329,32 @@ int onas_dsresult(CURL *curl, int scantype, uint64_t maxstream, const char *file
329 329
 				if (ret_code) {
330 330
 					*ret_code = CL_ESTAT;
331 331
 				}
332
+                        } else if(len > 41 && !memcmp(eol-42, " lstat() failed: Permission denied. ERROR", 41)) {
333
+				if(errors) {
334
+					(*errors)++;
335
+				}
336
+				*printok = 0;
337
+
338
+				if(filename) {
339
+					(scantype >= STREAM) ? logg("*%s%s\n", filename, colon) : logg("*%s\n", bol);
340
+				}
341
+
342
+				if (ret_code) {
343
+					*ret_code = CL_ESTAT;
344
+				}
345
+                        } else if(len > 21 && !memcmp(eol-22, " Access denied. ERROR", 21)) {
346
+				if(errors) {
347
+					(*errors)++;
348
+				}
349
+				*printok = 0;
332 350
 
351
+				if(filename) {
352
+					(scantype >= STREAM) ? logg("*%s%s\n", filename, colon) : logg("*%s\n", bol);
353
+				}
354
+
355
+				if (ret_code) {
356
+					*ret_code = CL_EACCES;
357
+				}
333 358
 			} else if(!memcmp(eol-7, " ERROR", 6)) {
334 359
 				if(errors) {
335 360
 					(*errors)++;
... ...
@@ -57,33 +57,38 @@
57 57
 
58 58
 extern pthread_t ddd_pid;
59 59
 extern pthread_t scque_pid;
60
+static int onas_fan_fd;
60 61
 
61
-/*static void onas_fan_exit(int sig)
62
+static void onas_fan_exit(int sig)
62 63
 {
63 64
 	logg("*ClamFanotif: onas_fan_exit(), signal %d\n", sig);
64 65
 
66
+        if(onas_fan_fd) {
65 67
     close(onas_fan_fd);
68
+        }
69
+        onas_fan_fd = 0;
66 70
 
67 71
     if (ddd_pid > 0) {
68 72
         pthread_kill(ddd_pid, SIGUSR1);
69 73
         pthread_join(ddd_pid, NULL);
70 74
     }
75
+        ddd_pid = 0;
71 76
 
72 77
         if (scque_pid > 0) {
73
-		pthread_kill(ddd_pid, SIGUSR1);
74
-		pthread_join(ddd_pid, NULL);
78
+		pthread_kill(scque_pid, SIGUSR2);
79
+		pthread_join(scque_pid, NULL);
75 80
     }
81
+        scque_pid = 0;
76 82
 
77
-	pthread_exit(NULL);
78 83
 	logg("ClamFanotif: stopped\n");
79
-}*/
84
+	pthread_exit(NULL);
85
+}
80 86
 
81 87
 cl_error_t onas_setup_fanotif(struct onas_context **ctx) {
82 88
 
83 89
     const struct optstruct *pt;
84 90
     short int scan;
85 91
     unsigned int sizelimit = 0, extinfo;
86
-	int onas_fan_fd;
87 92
 	uint64_t fan_mask = FAN_EVENT_ON_CHILD;
88 93
     char err[128];
89 94
 
... ...
@@ -152,9 +157,9 @@ cl_error_t onas_setup_fanotif(struct onas_context **ctx) {
152 152
     /* Load other options. */
153 153
 	(*ctx)->sizelimit = optget((*ctx)->clamdopts, "OnAccessMaxFileSize")->numarg;
154 154
 	if((*ctx)->sizelimit)
155
-		logg("*ClamFanotif: Max file size limited to %lu bytes\n", (*ctx)->sizelimit);
155
+		logg("*ClamFanotif: max file size limited to %lu bytes\n", (*ctx)->sizelimit);
156 156
     else
157
-		logg("*ClamFanotif: File size limit disabled\n");
157
+		logg("*ClamFanotif: file size limit disabled\n");
158 158
 
159 159
 	extinfo = optget((*ctx)->clamdopts, "ExtendedDetectionInfo")->enabled;
160 160
 
... ...
@@ -164,6 +169,8 @@ cl_error_t onas_setup_fanotif(struct onas_context **ctx) {
164 164
 int onas_fan_eloop(struct onas_context **ctx) {
165 165
 	int ret = 0;
166 166
         int err_cnt = 0;
167
+	sigset_t sigset;
168
+	struct sigaction act;
167 169
 	short int scan;
168 170
 	STATBUF sb;
169 171
 	fd_set rfds;
... ...
@@ -174,6 +181,26 @@ int onas_fan_eloop(struct onas_context **ctx) {
174 174
 	int len, check, fres;
175 175
 	char err[128];
176 176
 
177
+	/* ignore all signals except SIGUSR1 */
178
+	sigfillset(&sigset);
179
+	sigdelset(&sigset, SIGUSR1);
180
+	/* The behavior of a process is undefined after it ignores a
181
+	 * SIGFPE, SIGILL, SIGSEGV, or SIGBUS signal */
182
+	sigdelset(&sigset, SIGFPE);
183
+	sigdelset(&sigset, SIGILL);
184
+	sigdelset(&sigset, SIGSEGV);
185
+	sigdelset(&sigset, SIGINT);
186
+#ifdef SIGBUS
187
+	sigdelset(&sigset, SIGBUS);
188
+#endif
189
+	pthread_sigmask(SIG_SETMASK, &sigset, NULL);
190
+	memset(&act, 0, sizeof(struct sigaction));
191
+	act.sa_handler = onas_fan_exit;
192
+	sigfillset(&(act.sa_mask));
193
+	sigaction(SIGUSR1, &act, NULL);
194
+	sigaction(SIGSEGV, &act, NULL);
195
+	sigaction(SIGINT, &act, NULL);
196
+
177 197
     FD_ZERO(&rfds);
178 198
 	FD_SET((*ctx)->fan_fd, &rfds);
179 199
     do {
... ...
@@ -278,6 +305,7 @@ int onas_fan_eloop(struct onas_context **ctx) {
278 278
 						logg("!ClamFanotif: error occurred while excluding event\n");
279 279
                                                 return 2;
280 280
                                         }
281
+					}
281 282
 
282 283
                                         if (-1 == close(fmd->fd)) {
283 284
 						logg("!ClamFanotif: error occurred while closing metadata fd, %d\n", fmd->fd);
... ...
@@ -289,7 +317,6 @@ int onas_fan_eloop(struct onas_context **ctx) {
289 289
                                     }
290 290
                                 }
291 291
         }
292
-			}
293 292
         fmd = FAN_EVENT_NEXT(fmd, bread);
294 293
     }
295 294
     do {
... ...
@@ -348,7 +348,8 @@ void *onas_ddd_th(void *arg) {
348 348
 	 * SIGFPE, SIGILL, SIGSEGV, or SIGBUS signal */
349 349
     sigdelset(&sigset, SIGFPE);
350 350
     sigdelset(&sigset, SIGILL);
351
-	//sigdelset(&sigset, SIGSEGV);
351
+	sigdelset(&sigset, SIGSEGV);
352
+	sigdelset(&sigset, SIGINT);
352 353
 #ifdef SIGBUS
353 354
     sigdelset(&sigset, SIGBUS);
354 355
 #endif
... ...
@@ -359,22 +360,22 @@ void *onas_ddd_th(void *arg) {
359 359
     sigaction(SIGUSR1, &act, NULL);
360 360
     sigaction(SIGSEGV, &act, NULL);
361 361
 
362
-        logg("*ClamInotif: Starting inotify event thread\n");
362
+        logg("*ClamInotif: starting inotify event thread\n");
363 363
 
364 364
     onas_in_fd = inotify_init1(IN_NONBLOCK);
365 365
     if (onas_in_fd == -1) {
366
-		logg("!ClamInotif: Could not init inotify.");
366
+		logg("!ClamInotif: could not init inotify\n");
367 367
         return NULL;
368 368
     }
369 369
 
370 370
     ret = onas_ddd_init(0, ONAS_DEFAULT_HT_SIZE);
371 371
     if (ret) {
372
-		logg("!ClamInotif: Failed to initialize 3D. \n");
372
+		logg("!ClamInotif: failed to initialize DDD system\n");
373 373
         return NULL;
374 374
     }
375 375
 
376 376
 
377
-        logg("*ClamInotif: Dynamically determining directory hierarchy...\n");
377
+	logg("*ClamInotif: dynamically determining directory hierarchy...\n");
378 378
     /* Add provided paths recursively. */
379 379
 
380 380
 	if (!optget(ctx->opts, "watch-list")->enabled && !optget(ctx->clamdopts, "OnAccessIncludePath")->enabled) {
... ...
@@ -593,7 +594,7 @@ void *onas_ddd_th(void *arg) {
593 593
         }
594 594
     }
595 595
 
596
-        logg("*ClamInotif: Exiting inotify event thread\n");
596
+        logg("*ClamInotif: exiting inotify event thread\n");
597 597
     return NULL;
598 598
 }
599 599
 
... ...
@@ -605,7 +606,7 @@ static void onas_ddd_handle_in_delete(struct onas_context *ctx,
605 605
     if (stat(child_path, &s) == 0 && S_ISREG(s.st_mode)) return;
606 606
     if (!(event->mask & IN_ISDIR)) return;
607 607
 
608
-	logg("*ClamInotif: DELETE - Removing %s from %s with wd:%d\n", child_path, path, wd);
608
+	logg("*ClamInotif: DELETE - removing %s from %s with wd:%d\n", child_path, path, wd);
609 609
 	onas_ddd_unwatch(child_path, ctx->fan_fd, onas_in_fd);
610 610
     onas_ht_rm_hierarchy(ddd_ht, child_path, strlen(child_path), 0);
611 611
 
... ...
@@ -619,7 +620,7 @@ static void onas_ddd_handle_in_moved_from(struct onas_context *ctx,
619 619
     if (stat(child_path, &s) == 0 && S_ISREG(s.st_mode)) return;
620 620
     if (!(event->mask & IN_ISDIR)) return;
621 621
 
622
-	logg("*ClamInotif: MOVED_FROM - Removing %s from %s with wd:%d\n", child_path, path, wd);
622
+	logg("*ClamInotif: MOVED_FROM - removing %s from %s with wd:%d\n", child_path, path, wd);
623 623
 	onas_ddd_unwatch(child_path, ctx->fan_fd, onas_in_fd);
624 624
     onas_ht_rm_hierarchy(ddd_ht, child_path, strlen(child_path), 0);
625 625
 
... ...
@@ -636,7 +637,7 @@ static void onas_ddd_handle_in_create(struct onas_context *ctx,
636 636
 			onas_ddd_handle_extra_scanning(ctx, child_path, ONAS_SCTH_B_FILE);
637 637
 
638 638
 		} else if(event->mask & IN_ISDIR) {
639
-			logg("*ClamInotif: CREATE - Adding %s to %s with wd:%d\n", child_path, path, wd);
639
+			logg("*ClamInotif: CREATE - adding %s to %s with wd:%d\n", child_path, path, wd);
640 640
 			onas_ddd_handle_extra_scanning(ctx, child_path, ONAS_SCTH_B_DIR);
641 641
 
642 642
 			onas_ht_add_hierarchy(ddd_ht, child_path);
... ...
@@ -648,7 +649,7 @@ static void onas_ddd_handle_in_create(struct onas_context *ctx,
648 648
         if (stat(child_path, &s) == 0 && S_ISREG(s.st_mode)) return;
649 649
         if (!(event->mask & IN_ISDIR)) return;
650 650
 
651
-		logg("*ClamInotif: MOVED_TO - Adding %s to %s with wd:%d\n", child_path, path, wd);
651
+		logg("*ClamInotif: MOVED_TO - adding %s to %s with wd:%d\n", child_path, path, wd);
652 652
         onas_ht_add_hierarchy(ddd_ht, child_path);
653 653
 		onas_ddd_watch(child_path, ctx->fan_fd, ctx->fan_mask, onas_in_fd, in_mask);
654 654
     }
... ...
@@ -665,7 +666,7 @@ static void onas_ddd_handle_in_moved_to(struct onas_context *ctx,
665 665
 			onas_ddd_handle_extra_scanning(ctx, child_path, ONAS_SCTH_B_FILE);
666 666
 
667 667
 		} else if(event->mask & IN_ISDIR) {
668
-			logg("*ClamInotif: MOVED_TO - Adding %s to %s with wd:%d\n", child_path, path, wd);
668
+			logg("*ClamInotif: MOVED_TO - adding %s to %s with wd:%d\n", child_path, path, wd);
669 669
 			onas_ddd_handle_extra_scanning(ctx, child_path, ONAS_SCTH_B_DIR);
670 670
 
671 671
 			onas_ht_add_hierarchy(ddd_ht, child_path);
... ...
@@ -676,7 +677,7 @@ static void onas_ddd_handle_in_moved_to(struct onas_context *ctx,
676 676
         if (stat(child_path, &s) == 0 && S_ISREG(s.st_mode)) return;
677 677
         if (!(event->mask & IN_ISDIR)) return;
678 678
 
679
-		logg("*ClamInotif: MOVED_TO - Adding %s to %s with wd:%d\n", child_path, path, wd);
679
+		logg("*ClamInotif: MOVED_TO - adding %s to %s with wd:%d\n", child_path, path, wd);
680 680
         onas_ht_add_hierarchy(ddd_ht, child_path);
681 681
 		onas_ddd_watch(child_path, ctx->fan_fd, ctx->fan_mask, onas_in_fd, in_mask);
682 682
     }
... ...
@@ -717,12 +718,22 @@ static void onas_ddd_handle_extra_scanning(struct onas_context *ctx, const char
717 717
 static void onas_ddd_exit(int sig) {
718 718
 	logg("*ClamInotif: onas_ddd_exit(), signal %d\n", sig);
719 719
 
720
+        if (onas_in_fd) {
720 721
     close(onas_in_fd);
722
+        }
723
+        onas_in_fd = 0;
721 724
 
725
+	if (ddd_ht) {
722 726
     onas_free_ht(ddd_ht);
727
+        }
728
+        ddd_ht = NULL;
729
+
730
+        if (wdlt) {
723 731
     free(wdlt);
732
+        }
733
+        wdlt = NULL;
724 734
 
725
-    pthread_exit(NULL);
726 735
 	logg("ClamInotif: stopped\n");
736
+	pthread_exit(NULL);
727 737
 }
728 738
 #endif
... ...
@@ -148,12 +148,13 @@ void *onas_scanque_th(void *arg) {
148 148
 
149 149
 	/* ignore all signals except SIGUSR1 */
150 150
 	sigfillset(&sigset);
151
-	sigdelset(&sigset, SIGUSR1);
151
+	sigdelset(&sigset, SIGUSR2);
152 152
 	/* The behavior of a process is undefined after it ignores a
153 153
 	 * SIGFPE, SIGILL, SIGSEGV, or SIGBUS signal */
154 154
 	sigdelset(&sigset, SIGFPE);
155 155
 	sigdelset(&sigset, SIGILL);
156
-	//sigdelset(&sigset, SIGSEGV);
156
+	sigdelset(&sigset, SIGSEGV);
157
+	sigdelset(&sigset, SIGINT);
157 158
 #ifdef SIGBUS
158 159
 	sigdelset(&sigset, SIGBUS);
159 160
 #endif
... ...
@@ -161,16 +162,16 @@ void *onas_scanque_th(void *arg) {
161 161
 	memset(&act, 0, sizeof(struct sigaction));
162 162
 	act.sa_handler = onas_scanque_exit;
163 163
 	sigfillset(&(act.sa_mask));
164
-	sigaction(SIGUSR1, &act, NULL);
164
+	sigaction(SIGUSR2, &act, NULL);
165 165
 	sigaction(SIGSEGV, &act, NULL);
166 166
 
167
-	logg("*ClamQueue: initializing event queue consumer w/ (%d) threads in thread pool\n", ctx->maxthreads);
167
+	logg("*ClamQueue: initializing event queue consumer ... (%d) threads in thread pool\n", ctx->maxthreads);
168 168
         onas_init_event_queue();
169 169
         threadpool thpool = thpool_init(ctx->maxthreads);
170 170
 	g_thpool = thpool;
171 171
 
172 172
         /* loop w/ onas_consume_event until we die */
173
-	logg("*ClamQueue: waiting to cosume events ...\n");
173
+	logg("*ClamQueue: waiting to consume events ...\n");
174 174
 	do {
175 175
 		/* if there's no event to consume ... */
176 176
 		if (!onas_consume_event(thpool)) {
... ...
@@ -201,7 +202,10 @@ static int onas_consume_event(threadpool thpool) {
201 201
         return 1;
202 202
     }
203 203
 
204
+#ifdef ONAS_DEBUG
204 205
     logg("*ClamonQueue: consuming event!\n");
206
+#endif
207
+
205 208
     thpool_add_work(thpool, (void *) onas_scan_worker, (void *) popped_node->data);
206 209
 
207 210
     g_onas_event_queue_head->next = g_onas_event_queue_head->next->next;
... ...
@@ -222,7 +226,10 @@ cl_error_t onas_queue_event(struct onas_scan_event *event_data) {
222 222
 
223 223
     struct onas_event_queue_node *node = NULL;
224 224
 
225
+#ifdef ONAS_DEBUG
225 226
     logg("*ClamonQueue: queueing event!\n");
227
+#endif
228
+
226 229
     if (CL_EMEM == onas_new_event_queue_node(&node)) {
227 230
 	    return CL_EMEM;
228 231
     }
... ...
@@ -273,10 +280,13 @@ static void onas_scanque_exit(int sig) {
273 273
 	logg("*ClamScanque: onas_scanque_exit(), signal %d\n", sig);
274 274
 
275 275
 	onas_destroy_event_queue();
276
-	thpool_destroy(g_thpool);
276
+        if (g_thpool) {
277
+            thpool_destroy(g_thpool);
278
+        }
279
+        g_thpool = NULL;
277 280
 
278
-	pthread_exit(NULL);
279 281
 	logg("ClamScanque: stopped\n");
282
+	pthread_exit(NULL);
280 283
 }
281 284
 
282 285
 #endif
... ...
@@ -167,8 +167,6 @@ static cl_error_t onas_scth_scanfile(struct onas_scan_event *event_data, const c
167 167
 				res.response = FAN_DENY;
168 168
 			}
169 169
 		}
170
-	} else {
171
-            logg("DEBUG: NOT SCANNING\n");
172 170
 	}
173 171
 
174 172
 
... ...
@@ -178,7 +176,7 @@ static cl_error_t onas_scth_scanfile(struct onas_scan_event *event_data, const c
178 178
 			if(ret == -1) {
179 179
 				logg("!ClamWorker: internal error (can't write to fanotify)\n");
180 180
                                 if (errno == ENOENT) {
181
-                                    logg("ClamWorker: permission event has already been written ... recovering ...\n");
181
+                                    logg("*ClamWorker: permission event has already been written ... recovering ...\n");
182 182
                                 } else {
183 183
 				ret = CL_EWRITE;
184 184
 			}
... ...
@@ -187,10 +185,15 @@ static cl_error_t onas_scth_scanfile(struct onas_scan_event *event_data, const c
187 187
 	}
188 188
 
189 189
         if (b_fanotify) {
190
+
191
+#ifdef ONAS_DEBUG
192
+            logg("*ClamWorker: closing fd, %d)\n", event_data->fmd->fd);
193
+#endif
190 194
             if (-1 == close(event_data->fmd->fd) ) {
195
+
191 196
                 logg("!ClamWorker: internal error (can't close fanotify meta fd, %d)\n", event_data->fmd->fd);
192 197
                 if (errno == EBADF) {
193
-                    logg("ClamWorker: fd already closed ... recovering ...\n");
198
+                    logg("*ClamWorker: fd already closed ... recovering ...\n");
194 199
                 } else {
195 200
                 ret = CL_EUNLINK;
196 201
 		}
... ...
@@ -273,11 +276,17 @@ static cl_error_t onas_scth_handle_file(struct onas_scan_event *event_data, cons
273 273
 	}
274 274
 
275 275
 	ret = onas_scth_scanfile(event_data, pathname, sb, &infected, &err, &ret_code);
276
-	// probs need to error check here later, or at least log
277
-        if (event_data->bool_opts | ONAS_SCTH_B_INOTIFY) {
278
-            logg(">>>>>>DEBUG: ClamWorker: Inotify Scan Rsults ... ret = %d ; infected = %d ; err = %d ret_code = %d\n",
276
+
277
+#ifdef ONAS_DEBUG
278
+        /* very noisy, debug only */
279
+        if (event_data->bool_opts & ONAS_SCTH_B_INOTIFY) {
280
+            logg("*ClamWorker: Inotify Scan Results ...\n\tret = %d ...\n\tinfected = %d ...\n\terr = %d ...\n\tret_code = %d\n",
279 281
                     ret, infected, err, ret_code);
282
+        } else {
283
+            logg("*ClamWorker: Fanotify Scan Results ...\n\tret = %d ...\n\tinfected = %d ...\n\terr = %d ...\n\tret_code = %d\n\tfd = %d\n",
284
+                    ret, infected, err, ret_code, event_data->fmd->fd);
280 285
         }
286
+#endif
281 287
 
282 288
     return ret;
283 289
 }
... ...
@@ -365,8 +374,6 @@ cl_error_t onas_map_context_info_to_event_data(struct onas_context *ctx, struct
365 365
     (*event_data)->scantype = ctx->scantype;
366 366
     (*event_data)->timeout = ctx->timeout;
367 367
     (*event_data)->maxstream = ctx->maxstream;
368
-    (*event_data)->tcpaddr = optget(ctx->clamdopts, "TCPAddr")->strarg;
369
-    (*event_data)->portnum = ctx->portnum;
370 368
     (*event_data)->fan_fd = ctx->fan_fd;
371 369
     (*event_data)->sizelimit = ctx->sizelimit;
372 370
     (*event_data)->retry_attempts = ctx->retry_attempts;
... ...
@@ -379,6 +386,14 @@ cl_error_t onas_map_context_info_to_event_data(struct onas_context *ctx, struct
379 379
         (*event_data)->bool_opts |= ONAS_SCTH_B_DENY_ON_E;
380 380
     }
381 381
 
382
+    if (ctx->isremote) {
383
+        (*event_data)->bool_opts |= ONAS_SCTH_B_REMOTE;
384
+        (*event_data)->tcpaddr = optget(ctx->clamdopts, "TCPAddr")->strarg;
385
+        (*event_data)->portnum = ctx->portnum;
386
+    } else {
387
+        (*event_data)->tcpaddr = optget(ctx->clamdopts, "LocalSocket")->strarg;
388
+    }
389
+
382 390
     return CL_SUCCESS;
383 391
 }
384 392
 #endif
... ...
@@ -33,6 +33,17 @@
33 33
 #define ONAS_SCTH_B_SCAN        0x10
34 34
 #define ONAS_SCTH_B_RETRY_ON_E  0x20
35 35
 #define ONAS_SCTH_B_DENY_ON_E   0x40
36
+#define ONAS_SCTH_B_REMOTE      0x80
37
+
38
+#ifndef HAVE_ATTRIB_PACKED
39
+#define __attribute__(x)
40
+#endif
41
+#ifdef HAVE_PRAGMA_PACK
42
+#pragma pack(1)
43
+#endif
44
+#ifdef HAVE_PRAGMA_PACK_HPPA
45
+#pragma pack 1
46
+#endif
36 47
 
37 48
 struct onas_scan_event {
38 49
         const char *tcpaddr;
... ...
@@ -46,7 +57,14 @@ struct onas_scan_event {
46 46
         int64_t maxstream;
47 47
         int64_t timeout;
48 48
 	uint8_t bool_opts;
49
-};
49
+} __attribute((packed));
50
+
51
+#ifdef HAVE_PRAGMA_PACK
52
+#pragma pack()
53
+#endif
54
+#ifdef HAVE_PRAGMA_PACK_HPPA
55
+#pragma pack
56
+#endif
50 57
 
51 58
 void *onas_scan_th(void *arg);
52 59