Browse code

0.100.x - bb11985 - adding initial refactor for thread-safe scan function for onas

Mickey Sola authored on 2017/12/21 02:53:57
Showing 7 changed files
... ...
@@ -47,6 +47,8 @@ clamd_SOURCES = \
47 47
     others.c \
48 48
     others.h \
49 49
     shared.h \
50
+    onaccess_others.c \
51
+    onaccess_others.h \
50 52
     onaccess_fan.c \
51 53
     onaccess_fan.h \
52 54
     onaccess_ddd.c \
... ...
@@ -173,8 +173,9 @@ am__clamd_SOURCES_DIST = $(top_srcdir)/shared/output.c \
173 173
 	$(top_srcdir)/shared/misc.h clamd.c tcpserver.c tcpserver.h \
174 174
 	localserver.c localserver.h session.c session.h thrmgr.c \
175 175
 	thrmgr.h server-th.c server.h scanner.c scanner.h others.c \
176
-	others.h shared.h onaccess_fan.c onaccess_fan.h onaccess_ddd.c \
177
-	onaccess_ddd.h onaccess_hash.c onaccess_hash.h onaccess_scth.c \
176
+	others.h shared.h onaccess_others.c onaccess_others.h \
177
+	onaccess_fan.c onaccess_fan.h onaccess_ddd.c onaccess_ddd.h \
178
+	onaccess_hash.c onaccess_hash.h onaccess_scth.c \
178 179
 	onaccess_scth.h priv_fts.h fts.c
179 180
 @BUILD_CLAMD_TRUE@@SYSTEM_LFS_FTS_FALSE@am__objects_1 = fts.$(OBJEXT)
180 181
 @BUILD_CLAMD_TRUE@am_clamd_OBJECTS = output.$(OBJEXT) \
... ...
@@ -184,6 +185,7 @@ am__clamd_SOURCES_DIST = $(top_srcdir)/shared/output.c \
184 184
 @BUILD_CLAMD_TRUE@	localserver.$(OBJEXT) session.$(OBJEXT) \
185 185
 @BUILD_CLAMD_TRUE@	thrmgr.$(OBJEXT) server-th.$(OBJEXT) \
186 186
 @BUILD_CLAMD_TRUE@	scanner.$(OBJEXT) others.$(OBJEXT) \
187
+@BUILD_CLAMD_TRUE@	onaccess_others.$(OBJEXT) \
187 188
 @BUILD_CLAMD_TRUE@	onaccess_fan.$(OBJEXT) \
188 189
 @BUILD_CLAMD_TRUE@	onaccess_ddd.$(OBJEXT) \
189 190
 @BUILD_CLAMD_TRUE@	onaccess_hash.$(OBJEXT) \
... ...
@@ -492,6 +494,7 @@ top_srcdir = @top_srcdir@
492 492
 @BUILD_CLAMD_TRUE@	localserver.h session.c session.h thrmgr.c \
493 493
 @BUILD_CLAMD_TRUE@	thrmgr.h server-th.c server.h scanner.c \
494 494
 @BUILD_CLAMD_TRUE@	scanner.h others.c others.h shared.h \
495
+@BUILD_CLAMD_TRUE@	onaccess_others.c onaccess_others.h \
495 496
 @BUILD_CLAMD_TRUE@	onaccess_fan.c onaccess_fan.h onaccess_ddd.c \
496 497
 @BUILD_CLAMD_TRUE@	onaccess_ddd.h onaccess_hash.c \
497 498
 @BUILD_CLAMD_TRUE@	onaccess_hash.h onaccess_scth.c \
... ...
@@ -623,6 +626,7 @@ distclean-compile:
623 623
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/onaccess_ddd.Po@am__quote@
624 624
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/onaccess_fan.Po@am__quote@
625 625
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/onaccess_hash.Po@am__quote@
626
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/onaccess_others.Po@am__quote@
626 627
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/onaccess_scth.Po@am__quote@
627 628
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/optparser.Po@am__quote@
628 629
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/others.Po@am__quote@
... ...
@@ -44,9 +44,8 @@
44 44
 #include "shared/optparser.h"
45 45
 #include "shared/output.h"
46 46
 
47
+#include "onaccess_others.h"
47 48
 #include "server.h"
48
-#include "others.h"
49
-#include "scanner.h"
50 49
 
51 50
 #include "onaccess_fan.h"
52 51
 #include "onaccess_hash.h"
... ...
@@ -73,23 +72,27 @@ static void onas_fan_exit(int sig)
73 73
 static int onas_fan_scanfile(int fan_fd, const char *fname, struct fanotify_event_metadata *fmd, int scan, int extinfo, struct thrarg *tharg)
74 74
 {
75 75
 	struct fanotify_response res;
76
-	struct cb_context context;
77 76
 	const char *virname;
78 77
 	int ret = 0;
79 78
 
80 79
     res.fd = fmd->fd;
81 80
     res.response = FAN_ALLOW;
82
-    context.filename = fname;
81
+    /*context.filename = fname;
83 82
     context.virsize = 0;
84
-    context.scandata = NULL;
85
-    if(scan && cl_scandesc_callback(fmd->fd, &virname, NULL, tharg->engine, tharg->options, &context) == CL_VIRUS) {
83
+    context.scandata = NULL;*/
84
+   /* if(scan && onas_scan(fmd->fd, &virname, NULL, tharg->engine, tharg->options, &context) == CL_VIRUS) {
86 85
 	if(extinfo && context.virsize)
87 86
 	    logg("ScanOnAccess: %s: %s(%s:%llu) FOUND\n", fname, virname, context.virhash, context.virsize);
88 87
 	else
89 88
 	    logg("ScanOnAccess: %s: %s FOUND\n", fname, virname);
90
-	virusaction(fname, virname, tharg->opts);
91
-
92
-	res.response = FAN_DENY;
89
+	virusaction(fname, virname, tharg->opts);*/
90
+    if (scan) {
91
+        if (onas_scan(fname, fmd->fd, &virname, tharg->engine, tharg->options, extinfo) == CL_VIRUS) {
92
+            /* TODO : FIXME? virusaction forks. This could be extraordinarily problematic, lead to deadlocks, 
93
+             * or at the very least lead to extreme memory consumption. Leaving disabled for now.*/ 
94
+            virusaction(fname, virname, tharg->opts);
95
+            res.response = FAN_DENY;
96
+        }
93 97
     }
94 98
 
95 99
     if(fmd->mask & FAN_ALL_PERM_EVENTS) {
... ...
@@ -292,6 +295,8 @@ void *onas_fan_th(void *arg)
292 292
     return NULL;
293 293
 }
294 294
 
295
+
296
+/* CLAMAUTH is deprecated */
295 297
 #elif defined(CLAMAUTH)
296 298
 
297 299
 #include <stdio.h>
298 300
new file mode 100644
... ...
@@ -0,0 +1,121 @@
0
+/*
1
+ *  Copyright (C) 2017 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
2
+ *
3
+ *  Authors: Mickey Sola
4
+ *
5
+ *  This program is free software; you can redistribute it and/or modify
6
+ *  it under the terms of the GNU General Public License version 2 as
7
+ *  published by the Free Software Foundation.
8
+ *
9
+ *  This program is distributed in the hope that it will be useful,
10
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
+ *  GNU General Public License for more details.
13
+ *
14
+ *  You should have received a copy of the GNU General Public License
15
+ *  along with this program; if not, write to the Free Software
16
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
17
+ *  MA 02110-1301, USA.
18
+ */
19
+
20
+#if HAVE_CONFIG_H
21
+#include "clamav-config.h"
22
+#endif
23
+
24
+#if defined(FANOTIFY)
25
+
26
+#include <stdio.h>
27
+#include <stdarg.h>
28
+#include <stdlib.h>
29
+#include <string.h>
30
+//#include <fcntl.h>
31
+#include <sys/stat.h>
32
+#include <errno.h>
33
+#include <pthread.h>
34
+//#include <limits.h>
35
+#include "libclamav/clamav.h"
36
+//#include "libclamav/scanners.h"
37
+#include "shared/optparser.h"
38
+#include "shared/output.h"
39
+//#include "shared/misc.h"
40
+//#include "libclamav/others.h"
41
+
42
+//#include "others.h"
43
+
44
+#include "onaccess_others.h"
45
+#include "scanner.h"
46
+
47
+static pthread_mutex_t onas_scan_lock = PTHREAD_MUTEX_INITIALIZER;
48
+
49
+int onas_fan_checkowner(int pid, const struct optstruct *opts)
50
+{
51
+    char path[32];
52
+    STATBUF sb;
53
+    const struct optstruct *opt = NULL;
54
+    const struct optstruct *opt_root = NULL;
55
+
56
+    /* always ignore ourselves */
57
+    if (pid == (int) getpid()) {
58
+        return 1;
59
+    }
60
+
61
+    /* look up options */
62
+    opt = optget (opts, "OnAccessExcludeUID");
63
+    opt_root = optget (opts, "OnAccessExcludeRootUID");
64
+
65
+    /* we can return immediately if no uid exclusions were requested */
66
+    if (!(opt->enabled || opt_root->enabled))
67
+        return 0;
68
+
69
+    /* perform exclusion checks if we can stat OK */
70
+    snprintf (path, sizeof (path), "/proc/%u", pid);
71
+    if (CLAMSTAT (path, &sb) == 0) {
72
+        /* check all our non-root UIDs first */
73
+        if (opt->enabled) {
74
+            while (opt)
75
+            {
76
+                if (opt->numarg == (long long) sb.st_uid)
77
+                    return 1;
78
+                opt = opt->nextarg;
79
+            }
80
+        }
81
+        /* finally check root UID */
82
+        if (opt_root->enabled) {
83
+            if (0 == (long long) sb.st_uid)
84
+                return 1;
85
+        }
86
+    } else if (errno == EACCES) {
87
+        logg("*Permission denied to stat /proc/%d to exclude UIDs... perhaps SELinux denial?\n", pid);
88
+    } else if (errno == ENOENT) {
89
+        /* FIXME: should this be configurable? */
90
+        logg("$/proc/%d vanished before UIDs could be excluded; scanning anyway\n", pid);
91
+    }
92
+
93
+    return 0;
94
+}
95
+
96
+int onas_scan(const char *fname, int fd, const char **virname, const struct cl_engine *engine, int options, int extinfo)
97
+{
98
+    int ret = 0;
99
+    struct cb_context context;
100
+
101
+    context.filename = fname;
102
+    context.virsize = 0;
103
+    context.scandata = NULL;
104
+
105
+    pthread_mutex_lock(&onas_scan_lock);
106
+    
107
+    ret = cl_scandesc_callback(fd, virname, NULL, engine, options, context);
108
+
109
+    pthread_mutex_unlock(&onas_scan_lock);
110
+
111
+    if (ret) {
112
+        if (extinfo && context.virsize)
113
+            logg("ScanOnAccess: %s: %s(%s:%llu) FOUND\n", fname, *virname, context.virhash, context.virsize);
114
+        else
115
+            logg("ScanOnAccess: %s: %s FOUND\n", fname, *virname);
116
+    }
117
+
118
+    return ret;
119
+}
120
+#endif
0 121
new file mode 100644
... ...
@@ -0,0 +1,29 @@
0
+/*
1
+ *  Copyright (C) 2017 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
2
+ *
3
+ *  Authors: Mickey Sola
4
+ *
5
+ *  This program is free software; you can redistribute it and/or modify
6
+ *  it under the terms of the GNU General Public License version 2 as
7
+ *  published by the Free Software Foundation.
8
+ *
9
+ *  This program is distributed in the hope that it will be useful,
10
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
+ *  GNU General Public License for more details.
13
+ *
14
+ *  You should have received a copy of the GNU General Public License
15
+ *  along with this program; if not, write to the Free Software
16
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
17
+ *  MA 02110-1301, USA.
18
+ */
19
+
20
+#ifndef __CLAMD_ONAS_OTHERS_H
21
+#define __CLAMD_ONAS_OTHERS_H
22
+
23
+#include "shared/optparser.h"
24
+
25
+int onas_fan_checkowner(int pid, const struct optstruct *opts);
26
+int onas_scan(const char *fname, int fd, const char **virname, const struct cl_engine *engine, int options, int extinfo);
27
+
28
+#endif
... ...
@@ -68,12 +68,12 @@
68 68
 
69 69
 #include <limits.h>
70 70
 #include "libclamav/clamav.h"
71
+#include "libclamav/scanners.h"
71 72
 #include "shared/optparser.h"
72 73
 #include "shared/output.h"
73 74
 #include "shared/misc.h"
74 75
 #include "libclamav/others.h"
75 76
 
76
-#include "session.h"
77 77
 #include "others.h"
78 78
 
79 79
 static pthread_mutex_t virusaction_lock = PTHREAD_MUTEX_INITIALIZER;
... ...
@@ -800,53 +800,3 @@ fds_free (struct fd_data *data)
800 800
     data->nfds = 0;
801 801
     fds_unlock (data);
802 802
 }
803
-
804
-#ifdef FANOTIFY
805
-int
806
-onas_fan_checkowner (int pid, const struct optstruct *opts)
807
-{
808
-    char path[32];
809
-    STATBUF sb;
810
-    const struct optstruct *opt = NULL;
811
-    const struct optstruct *opt_root = NULL;
812
-
813
-    /* always ignore ourselves */
814
-    if (pid == (int) getpid()) {
815
-        return 1;
816
-    }
817
-
818
-    /* look up options */
819
-    opt = optget (opts, "OnAccessExcludeUID");
820
-    opt_root = optget (opts, "OnAccessExcludeRootUID");
821
-
822
-    /* we can return immediately if no uid exclusions were requested */
823
-    if (!(opt->enabled || opt_root->enabled))
824
-        return 0;
825
-
826
-    /* perform exclusion checks if we can stat OK */
827
-    snprintf (path, sizeof (path), "/proc/%u", pid);
828
-    if (CLAMSTAT (path, &sb) == 0) {
829
-        /* check all our non-root UIDs first */
830
-        if (opt->enabled) {
831
-            while (opt)
832
-            {
833
-                if (opt->numarg == (long long) sb.st_uid)
834
-                    return 1;
835
-                opt = opt->nextarg;
836
-            }
837
-        }
838
-        /* finally check root UID */
839
-        if (opt_root->enabled) {
840
-            if (0 == (long long) sb.st_uid)
841
-                return 1;
842
-        }
843
-    } else if (errno == EACCES) {
844
-        logg("*Permission denied to stat /proc/%d to exclude UIDs... perhaps SELinux denial?\n", pid);
845
-    } else if (errno == ENOENT) {
846
-        /* FIXME: should this be configurable? */
847
-        logg("$/proc/%d vanished before UIDs could be excluded; scanning anyway\n", pid);
848
-    }
849
-
850
-    return 0;
851
-}
852
-#endif
... ...
@@ -83,8 +83,4 @@ void fds_cleanup(struct fd_data *data);
83 83
 int fds_poll_recv(struct fd_data *data, int timeout, int check_signals, void *event);
84 84
 void fds_free(struct fd_data *data);
85 85
 
86
-#ifdef FANOTIFY
87
-int onas_fan_checkowner(int pid, const struct optstruct *opts);
88
-#endif
89
-
90 86
 #endif