Browse code

fix typo. add another stress test. Don't leak file descriptors. Fix IDSESSION delimiter handling.

git-svn: trunk@4800

Török Edvin authored on 2009/02/17 06:27:22
Showing 5 changed files
... ...
@@ -1,3 +1,9 @@
1
+Mon Feb 16 23:56:34 EET 2009 (edwin)
2
+------------------------------------
3
+ * clamd/clamd.c, clamd/server-th.c, unit_tests/check_clamd.c,
4
+ unit_tests/check_clamd.sh: fix typo.  add another stress test.
5
+ Don't leak file descriptors.  Fix IDSESSION delimiter handling.
6
+
1 7
 Mon Feb 16 20:53:45 EET 2009 (edwin)
2 8
 ------------------------------------
3 9
  * clamd/thrmgr.c: fix valgrind warning about locking order
... ...
@@ -289,7 +289,7 @@ int main(int argc, char **argv)
289 289
     min_port = optget(opts, "StreamMinPort")->numarg;
290 290
     max_port = optget(opts, "StreamMaxPort")->numarg;
291 291
     if (min_port < 1024 || min_port > max_port || max_port > 65535) {
292
-	logg("!Invalid StreaMinPort/StreamMaxPort: %d, %d\n", min_port, max_port);
292
+	logg("!Invalid StreamMinPort/StreamMaxPort: %d, %d\n", min_port, max_port);
293 293
 	ret = 1;
294 294
 	break;
295 295
     }
... ...
@@ -256,7 +256,7 @@ static const char *get_cmd(struct fd_buf *buf, size_t off, size_t *len, char *te
256 256
     }
257 257
 
258 258
     *term = '\n';
259
-    switch (buf->buffer[0]) {
259
+    switch (buf->buffer[off]) {
260 260
 	/* commands terminated by delimiters */
261 261
 	case 'z':
262 262
 	    *term = '\0';
... ...
@@ -953,6 +953,10 @@ int recvloop_th(int *socketds, unsigned nsockets, struct cl_engine *engine, unsi
953 953
 		    }
954 954
 		    conn.id++;
955 955
 		}
956
+		if (conn.scanfd != -1 && conn.scanfd != buf->dumpfd) {
957
+		    logg("*Unclaimed file descriptor received, closing: %d\n", conn.scanfd);
958
+		    close(conn.scanfd);
959
+		}
956 960
 		buf->mode = conn.mode;
957 961
 		buf->id = conn.id;
958 962
 		buf->group = conn.group;
... ...
@@ -95,6 +95,8 @@ static void commands_teardown(void)
95 95
     fail_unless_fmt(rc != -1, "Failed to unlink access denied testfile: %s\n", strerror(errno));
96 96
 }
97 97
 
98
+#define VERSION_REPLY "ClamAV "REPO_VERSION""VERSION_SUFFIX
99
+
98 100
 static struct basic_test {
99 101
     const char *command;
100 102
     const char *extra;
... ...
@@ -102,7 +104,7 @@ static struct basic_test {
102 102
 } basic_tests[] = {
103 103
     {"PING", NULL, "PONG"},
104 104
     {"RELOAD", NULL, "RELOADING"},
105
-    {"VERSION", NULL, "ClamAV "REPO_VERSION""VERSION_SUFFIX},
105
+    {"VERSION", NULL, VERSION_REPLY},
106 106
     {"SCAN "SCANFILE, NULL, FOUNDREPLY},
107 107
     {"SCAN "CLEANFILE, NULL, CLEANREPLY},
108 108
     {"CONTSCAN "SCANFILE, NULL, FOUNDREPLY},
... ...
@@ -130,7 +132,7 @@ static struct basic_test {
130 130
     {"FILDES", "X", "No file descriptor received. ERROR"}, /* FILDES w/o ancillary data */
131 131
 };
132 132
 
133
-static void *recvfull(int sd, size_t *len)
133
+static void *recvpartial(int sd, size_t *len, int partial)
134 134
 {
135 135
     char *buf = NULL;
136 136
     size_t off = 0;
... ...
@@ -147,12 +149,17 @@ static void *recvfull(int sd, size_t *len)
147 147
 	rc = recv(sd, buf + off, BUFSIZ, 0);
148 148
 	fail_unless_fmt(rc != -1, "recv() failed: %s\n", strerror(errno));
149 149
 	off += rc;
150
-    } while (rc);
150
+    } while (rc && (!partial || !memchr(buf, '\0', off)));
151 151
     *len = off;
152 152
     buf[*len] = '\0';
153 153
     return buf;
154 154
 }
155 155
 
156
+static void *recvfull(int sd, size_t *len)
157
+{
158
+    return recvpartial(sd, len, 0);
159
+}
160
+
156 161
 static void test_command(const char *cmd, size_t len, const char *extra, const char *expect, size_t expect_len)
157 162
 {
158 163
     void *recvdata;
... ...
@@ -464,6 +471,45 @@ START_TEST (test_fildes_many)
464 464
 }
465 465
 END_TEST
466 466
 
467
+START_TEST (test_fildes_unwanted)
468
+{
469
+    char buf[BUFSIZ];
470
+    size_t i;
471
+    int dummyfd;
472
+    char *data, *p;
473
+    size_t len;
474
+
475
+    conn_setup();
476
+    dummyfd = open(SCANFILE, O_RDONLY);
477
+
478
+    fail_unless_fmt(send(sockd, "zIDSESSION", sizeof("zIDSESSION"), 0) == sizeof("zIDSESSION"),
479
+		    "send() failed: %s\n", strerror(errno));
480
+    for (i=0;i < 1024; i++) {
481
+	snprintf(buf, sizeof(buf), "%u", i+1);
482
+	/* send a 'zVERSION\0' including the ancillary data.
483
+	 * The \0 is from the extra char needed when sending ancillary data */
484
+	fail_unless_fmt(sendmsg_fd(sockd, "zVERSION", sizeof("zVERSION")-1, dummyfd, 1) != -1,
485
+			"sendmsg (%u) failed: %s\n", i, strerror(errno));
486
+/*	fail_unless(send(sockd, "zVERSION", sizeof("zVERSION"), 0) == sizeof("zVERSION"),
487
+		    "send failed: %s\n",strerror(errno));*/
488
+	data = recvpartial(sockd, &len, 1);
489
+	p = strchr(data, ':');
490
+	fail_unless_fmt(!!p, "wrong VERSION reply (%u): %s\n", i, data);
491
+	*p++ = '\0';
492
+	fail_unless_fmt(*p == ' ', "wrong VERSION reply (%u): %s\n", i, p);
493
+	*p++  = '\0';
494
+
495
+	fail_unless_fmt(!strcmp(p, VERSION_REPLY), "wrong VERSION reply: %s\n", data);
496
+	fail_unless_fmt(!strcmp(data, buf), "wrong IDSESSION id: %s\n", data);
497
+
498
+	free(data);
499
+    }
500
+
501
+    close(dummyfd);
502
+    conn_teardown();
503
+}
504
+END_TEST
505
+
467 506
 static Suite *test_clamd_suite(void)
468 507
 {
469 508
     Suite *s = suite_create("clamd");
... ...
@@ -481,6 +527,7 @@ static Suite *test_clamd_suite(void)
481 481
     tc_stress = tcase_create("clamd stress test");
482 482
     suite_add_tcase(s, tc_stress);
483 483
     tcase_add_test(tc_stress, test_fildes_many);
484
+    tcase_add_test(tc_stress, test_fildes_unwanted);
484 485
 
485 486
     return s;
486 487
 }
... ...
@@ -52,6 +52,10 @@ scan_failed() {
52 52
 start_clamd()
53 53
 {
54 54
 	rm -f clamd-test.log
55
+	$LTEXEC $CLAMD_WRAPPER $TOP/clamd/clamd -c $1 --help >clamd-test.log || 
56
+		{ error "Failed to start clamd --help!"; die 1; }
57
+	grep "Clam AntiVirus Daemon" clamd-test.log >/dev/null ||
58
+		{ error "Wrong --help reply from clamd!"; die 1; }
55 59
 	$LTEXEC $CLAMD_WRAPPER $TOP/clamd/clamd -c $1 || 
56 60
 		{ error "Failed to start clamd!"; die 1; }
57 61
 }
... ...
@@ -159,13 +163,15 @@ EOF
159 159
 rm -rf clamdtest$CLAMD_TEST_UNIQ1 clamdtest$CLAMD_TEST_UNIQ2
160 160
 mkdir clamdtest$CLAMD_TEST_UNIQ1 clamdtest$CLAMD_TEST_UNIQ2 || 
161 161
 	{ echo "Unable to create temporary directories!"; exit 1; }
162
-	
162
+
163 163
 # Prepare configuration for clamd #1 and #2
164 164
 (prepare_clamd $CLAMD_TEST_UNIQ1)
165 165
 (prepare_clamd $CLAMD_TEST_UNIQ2)
166 166
 # Add clamd #2 specific configuration
167 167
 echo "VirusEvent $abs_srcdir/virusaction-test.sh `pwd`/clamdtest$CLAMD_TEST_UNIQ2 \"Virus found: %v\"" >>clamdtest$CLAMD_TEST_UNIQ2/test-clamd.conf
168 168
 echo "HeuristicScanPrecedence yes" >>clamdtest$CLAMD_TEST_UNIQ2/test-clamd.conf
169
+grep -v LogFile clamdtest$CLAMD_TEST_UNIQ2/test-clamd.conf >tmp__
170
+mv tmp__ clamdtest$CLAMD_TEST_UNIQ2/test-clamd.conf
169 171
 
170 172
 # Start clamd #1 tests
171 173
 (cd clamdtest$CLAMD_TEST_UNIQ1