I have a case when clamd doesn't respond to exiscan
query and exim hangs around forever on read() call.
That ends badly - thousands of hanging exim processes, eating resources,
new connections being dropped due to max limit reached.
This patch applies some default timeout to read
operations. Please apply.
diff -urN exim-4.62.org/src/malware.c exim-4.62/src/malware.c
--- exim-4.62.org/src/malware.c 2006-04-28 12:32:22.000000000 +0200
+++ exim-4.62/src/malware.c 2006-06-13 18:41:29.000000000 +0200
@@ -20,6 +20,8 @@
#define SHUT_WR 1
#endif
+#define MALWARE_TIMEOUT 120
+
#define DRWEBD_SCAN_CMD (1) /* scan file, buffer or diskfile */
#define DRWEBD_RETURN_VIRUSES (1<<0) /* ask daemon return to us viruses names from report */
#define DRWEBD_IS_MAIL (1<<19) /* say to daemon that format is "archive MAIL" */
@@ -557,7 +559,7 @@
return DEFER;
};
- bread = read(sock, av_buffer, sizeof(av_buffer));
+ bread = ip_recv(sock, av_buffer, sizeof(av_buffer), MALWARE_TIMEOUT);
if (bread >0) av_buffer[bread]='\0';
if (bread < 0) {
(void)close(sock);
@@ -591,7 +593,7 @@
i = 0;
memset(av_buffer, 0, sizeof(av_buffer));
do {
- bread=read(sock, &av_buffer[i], 1);
+ bread=ip_recv(sock, &av_buffer[i], 1, MALWARE_TIMEOUT);
if (bread < 0) {
(void)close(sock);
log_write(0, LOG_MAIN|LOG_PANIC,
@@ -976,7 +978,7 @@
/* wait for result */
memset(av_buffer, 0, sizeof(av_buffer));
- if ((!(bread = read(sock, av_buffer, sizeof(av_buffer))) > 0)) {
+ if ((!(bread = ip_recv(sock, av_buffer, sizeof(av_buffer), MALWARE_TIMEOUT)) > 0)) {
(void)close(sock);
log_write(0, LOG_MAIN|LOG_PANIC,
"malware acl condition: unable to read from sophie UNIX socket (%s)", sophie_options);
@@ -1098,7 +1100,7 @@
return DEFER;
}
memset(av_buffer2, 0, sizeof(av_buffer2));
- bread = read(sock, av_buffer2, sizeof(av_buffer2));
+ bread = ip_recv(sock, av_buffer2, sizeof(av_buffer2), MALWARE_TIMEOUT);
if (bread < 0) {
log_write(0, LOG_MAIN|LOG_PANIC,
@@ -1238,7 +1240,7 @@
/* Read the result */
memset(av_buffer, 0, sizeof(av_buffer));
- bread = read(sock, av_buffer, sizeof(av_buffer));
+ bread = ip_recv(sock, av_buffer, sizeof(av_buffer), MALWARE_TIMEOUT);
(void)close(sock);
if (!(bread > 0)) {
--
Arkadiusz Miśkiewicz PLD/Linux Team
arekm / maven.pl http://ftp.pld-linux.org/