~ubuntu-branches/ubuntu/wily/clamav/wily-proposed

« back to all changes in this revision

Viewing changes to .pc/0007-fix-ssize_t-size_t-off_t-printf-modifier.patch/clamd/server-th.c

  • Committer: Package Import Robot
  • Author(s): Scott Kitterman, Sebastian Andrzej Siewior, Andreas Cadhalpun, Scott Kitterman, Javier Fernández-Sanguino
  • Date: 2015-01-28 00:25:13 UTC
  • mfrom: (0.48.14 sid)
  • Revision ID: package-import@ubuntu.com-20150128002513-lil2oi74cooy4lzr
Tags: 0.98.6+dfsg-1
[ Sebastian Andrzej Siewior ]
* update "fix-ssize_t-size_t-off_t-printf-modifier", include of misc.h was
  missing but was pulled in via the systemd patch.
* Don't leak return codes from libmspack to clamav API. (Closes: #774686).

[ Andreas Cadhalpun ]
* Add patch to avoid emitting incremental progress messages when not
  outputting to a terminal. (Closes: #767350)
* Update lintian-overrides for unused-file-paragraph-in-dep5-copyright.
* clamav-base.postinst: always chown /var/log/clamav and /var/lib/clamav
  to clamav:clamav, not only on fresh installations. (Closes: #775400)
* Adapt the clamav-daemon and clamav-freshclam logrotate scripts,
  so that they correctly work under systemd.
* Move the PidFile variable from the clamd/freshclam configuration files
  to the init scripts. This makes the init scripts more robust against
  misconfiguration and avoids error messages with systemd. (Closes: #767353)
* debian/copyright: drop files from Files-Excluded only present in github
  tarballs
* Drop Workaround-a-bug-in-libc-on-Hurd.patch, because hurd got fixed.
  (see #752237)
* debian/rules: Remove useless --with-system-tommath --without-included-ltdl
  configure options.

[ Scott Kitterman ]
* Stop stripping llvm when repacking the tarball as the system llvm on some
  releases is too old to use
* New upstream bugfix release
  - Library shared object revisions.
  - Includes a patch from Sebastian Andrzej Siewior making ClamAV pid files
    compatible with systemd.
  - Fix a heap out of bounds condition with crafted Yoda's crypter files.
    This issue was discovered by Felix Groebert of the Google Security Team.
  - Fix a heap out of bounds condition with crafted mew packer files. This
    issue was discovered by Felix Groebert of the Google Security Team.
  - Fix a heap out of bounds condition with crafted upx packer files. This
    issue was discovered by Kevin Szkudlapski of Quarkslab.
  - Fix a heap out of bounds condition with crafted upack packer files. This
    issue was discovered by Sebastian Andrzej Siewior. CVE-2014-9328.
  - Compensate a crash due to incorrect compiler optimization when handling
    crafted petite packer files. This issue was discovered by Sebastian
    Andrzej Siewior.
* Update lintian override for embedded zlib to match new so version

[ Javier Fernández-Sanguino ]
* Updated Spanish Debconf template translation (Closes: #773563)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 *  Copyright (C) 2007-2009 Sourcefire, Inc.
 
3
 *
 
4
 *  Authors: Tomasz Kojm, Trog, Török Edvin
 
5
 *
 
6
 *  This program is free software; you can redistribute it and/or modify
 
7
 *  it under the terms of the GNU General Public License as published by
 
8
 *  the Free Software Foundation; either version 2 of the License, or
 
9
 *  (at your option) any later version.
 
10
 *
 
11
 *  This program is distributed in the hope that it will be useful,
 
12
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
13
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
14
 *  GNU General Public License for more details.
 
15
 *
 
16
 *  You should have received a copy of the GNU General Public License
 
17
 *  along with this program; if not, write to the Free Software
 
18
 *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
 
19
 *  MA 02110-1301, USA.
 
20
 */
 
21
 
 
22
#if HAVE_CONFIG_H
 
23
#include "clamav-config.h"
 
24
#endif
 
25
 
 
26
#include <pthread.h>
 
27
#include <errno.h>
 
28
#include <signal.h>
 
29
#include <stdio.h>
 
30
#include <string.h>
 
31
#include <time.h>
 
32
#include <sys/types.h>
 
33
#ifndef _WIN32
 
34
#include <sys/socket.h>
 
35
#include <sys/time.h>
 
36
#include <sys/resource.h>
 
37
#include <arpa/inet.h>
 
38
#endif
 
39
#ifdef  HAVE_UNISTD_H
 
40
#include <unistd.h>
 
41
#endif
 
42
 
 
43
#include <fcntl.h>
 
44
#ifdef C_SOLARIS
 
45
#include <stdio_ext.h>
 
46
#endif
 
47
#include "libclamav/clamav.h"
 
48
 
 
49
#include "shared/output.h"
 
50
#include "shared/optparser.h"
 
51
#include "shared/misc.h"
 
52
 
 
53
#include "fan.h"
 
54
#include "server.h"
 
55
#include "thrmgr.h"
 
56
#include "session.h"
 
57
#include "others.h"
 
58
#include "shared.h"
 
59
#include "libclamav/others.h"
 
60
#include "libclamav/readdb.h"
 
61
#include "libclamav/cltypes.h"
 
62
 
 
63
#define BUFFSIZE 1024
 
64
 
 
65
int progexit = 0;
 
66
pthread_mutex_t exit_mutex = PTHREAD_MUTEX_INITIALIZER;
 
67
int reload = 0;
 
68
time_t reloaded_time = 0;
 
69
pthread_mutex_t reload_mutex = PTHREAD_MUTEX_INITIALIZER;
 
70
int sighup = 0;
 
71
extern pthread_mutex_t logg_mutex;
 
72
static struct cl_stat dbstat;
 
73
 
 
74
void *event_wake_recv = NULL;
 
75
void *event_wake_accept = NULL;
 
76
 
 
77
static void scanner_thread(void *arg)
 
78
{
 
79
        client_conn_t *conn = (client_conn_t *) arg;
 
80
#ifndef _WIN32
 
81
        sigset_t sigset;
 
82
#endif
 
83
        int ret;
 
84
        int virus=0, errors = 0;
 
85
 
 
86
#ifndef _WIN32
 
87
    /* ignore all signals */
 
88
    sigfillset(&sigset);
 
89
    /* The behavior of a process is undefined after it ignores a 
 
90
     * SIGFPE, SIGILL, SIGSEGV, or SIGBUS signal */
 
91
    sigdelset(&sigset, SIGFPE);
 
92
    sigdelset(&sigset, SIGILL);
 
93
    sigdelset(&sigset, SIGSEGV);
 
94
#ifdef SIGBUS
 
95
    sigdelset(&sigset, SIGBUS);
 
96
#endif
 
97
    sigdelset(&sigset, SIGTSTP);
 
98
    sigdelset(&sigset, SIGCONT);
 
99
    pthread_sigmask(SIG_SETMASK, &sigset, NULL);
 
100
#endif
 
101
 
 
102
    ret = command(conn, &virus);
 
103
    if (ret == -1) {
 
104
        pthread_mutex_lock(&exit_mutex);
 
105
        progexit = 1;
 
106
        pthread_mutex_unlock(&exit_mutex);
 
107
        errors = 1;
 
108
    } else
 
109
        errors = ret;
 
110
 
 
111
    thrmgr_setactiveengine(NULL);
 
112
 
 
113
    if (conn->filename)
 
114
        free(conn->filename);
 
115
    logg("$Finished scanthread\n");
 
116
    if (thrmgr_group_finished(conn->group, virus ? EXIT_OTHER :
 
117
                              errors ? EXIT_ERROR : EXIT_OK)) {
 
118
        logg("$Scanthread: connection shut down (FD %d)\n", conn->sd);
 
119
        /* close connection if we were last in group */
 
120
        shutdown(conn->sd, 2);
 
121
        closesocket(conn->sd);
 
122
    }
 
123
    cl_engine_free(conn->engine);
 
124
    free(conn);
 
125
    return;
 
126
}
 
127
 
 
128
static int syncpipe_wake_recv_w = -1;
 
129
 
 
130
void sighandler_th(int sig)
 
131
{
 
132
    int action = 0;
 
133
    switch(sig) {
 
134
        case SIGINT:
 
135
        case SIGTERM:
 
136
            progexit = 1;
 
137
            action = 1;
 
138
            break;
 
139
 
 
140
#ifdef  SIGHUP
 
141
        case SIGHUP:
 
142
            sighup = 1;
 
143
            action = 1;
 
144
            break;
 
145
#endif
 
146
 
 
147
#ifdef  SIGUSR2
 
148
        case SIGUSR2:
 
149
            reload = 1;
 
150
            action = 1;
 
151
            break;
 
152
#endif
 
153
 
 
154
        default:
 
155
            break; /* Take no action on other signals - e.g. SIGPIPE */
 
156
    }
 
157
    /* a signal doesn't always wake poll(), for example on FreeBSD */
 
158
    if (action && syncpipe_wake_recv_w != -1)
 
159
        if (write(syncpipe_wake_recv_w, "", 1) != 1)
 
160
            logg("$Failed to write to syncpipe\n");
 
161
}
 
162
 
 
163
static struct cl_engine *reload_db(struct cl_engine *engine, unsigned int dboptions, const struct optstruct *opts, int do_check, int *ret)
 
164
{
 
165
        const char *dbdir;
 
166
        int retval;
 
167
        unsigned int sigs = 0;
 
168
        struct cl_settings *settings = NULL;
 
169
 
 
170
    *ret = 0;
 
171
    if(do_check) {
 
172
        if(!dbstat.entries) {
 
173
            logg("No stats for Database check - forcing reload\n");
 
174
            return engine;
 
175
        }
 
176
 
 
177
        if(cl_statchkdir(&dbstat) == 1) {
 
178
            logg("SelfCheck: Database modification detected. Forcing reload.\n");
 
179
            return engine;
 
180
        } else {
 
181
            logg("SelfCheck: Database status OK.\n");
 
182
            return NULL;
 
183
        }
 
184
    }
 
185
 
 
186
    /* release old structure */
 
187
    if(engine) {
 
188
        /* copy current settings */
 
189
        settings = cl_engine_settings_copy(engine);
 
190
        if(!settings)
 
191
            logg("^Can't make a copy of the current engine settings\n");
 
192
 
 
193
        thrmgr_setactiveengine(NULL);
 
194
        cl_engine_free(engine);
 
195
    }
 
196
 
 
197
    dbdir = optget(opts, "DatabaseDirectory")->strarg;
 
198
    logg("Reading databases from %s\n", dbdir);
 
199
 
 
200
    if(dbstat.entries)
 
201
        cl_statfree(&dbstat);
 
202
 
 
203
    memset(&dbstat, 0, sizeof(struct cl_stat));
 
204
    if((retval = cl_statinidir(dbdir, &dbstat))) {
 
205
        logg("!cl_statinidir() failed: %s\n", cl_strerror(retval));
 
206
        *ret = 1;
 
207
        if(settings)
 
208
            cl_engine_settings_free(settings);
 
209
        return NULL;
 
210
    }
 
211
 
 
212
    if(!(engine = cl_engine_new())) {
 
213
        logg("!Can't initialize antivirus engine\n");
 
214
        *ret = 1;
 
215
        if(settings)
 
216
            cl_engine_settings_free(settings);
 
217
        return NULL;
 
218
    }
 
219
 
 
220
    if(settings) {
 
221
        retval = cl_engine_settings_apply(engine, settings);
 
222
        if(retval != CL_SUCCESS) {
 
223
            logg("^Can't apply previous engine settings: %s\n", cl_strerror(retval));
 
224
            logg("^Using default engine settings\n");
 
225
        }
 
226
        cl_engine_settings_free(settings);
 
227
    }
 
228
 
 
229
    if((retval = cl_load(dbdir, engine, &sigs, dboptions))) {
 
230
        logg("!reload db failed: %s\n", cl_strerror(retval));
 
231
        cl_engine_free(engine);
 
232
        *ret = 1;
 
233
        return NULL;
 
234
    }
 
235
 
 
236
    if((retval = cl_engine_compile(engine)) != 0) {
 
237
        logg("!Database initialization error: can't compile engine: %s\n", cl_strerror(retval));
 
238
        cl_engine_free(engine);
 
239
        *ret = 1;
 
240
        return NULL;
 
241
    }
 
242
    logg("Database correctly reloaded (%u signatures)\n", sigs);
 
243
 
 
244
    thrmgr_setactiveengine(engine);
 
245
    return engine;
 
246
}
 
247
 
 
248
/*
 
249
 * zCOMMANDS are delimited by \0
 
250
 * nCOMMANDS are delimited by \n
 
251
 * Old-style non-prefixed commands are one packet, optionally delimited by \n,
 
252
 * with trailing \r|\n ignored
 
253
 */
 
254
static const char *get_cmd(struct fd_buf *buf, size_t off, size_t *len, char *term, int *oldstyle)
 
255
{
 
256
    char *pos;
 
257
    if (!buf->off || off >= buf->off) {
 
258
        *len = 0;
 
259
        return NULL;
 
260
    }
 
261
 
 
262
    *term = '\n';
 
263
    switch (buf->buffer[off]) {
 
264
        /* commands terminated by delimiters */
 
265
        case 'z':
 
266
            *term = '\0';
 
267
        case 'n':
 
268
            pos = memchr(buf->buffer + off, *term, buf->off - off);
 
269
            if (!pos) {
 
270
                /* we don't have another full command yet */
 
271
                *len = 0;
 
272
                return NULL;
 
273
            }
 
274
            *pos = '\0';
 
275
            if (*term) {
 
276
                *len = cli_chomp(buf->buffer + off);
 
277
            } else {
 
278
                *len = pos - buf->buffer - off;
 
279
            }
 
280
            *oldstyle = 0;
 
281
            return buf->buffer + off + 1;
 
282
        default:
 
283
            /* one packet = one command */
 
284
            if (off)
 
285
                return NULL;
 
286
            pos = memchr(buf->buffer, '\n', buf->off);
 
287
            if (pos) {
 
288
                *len = pos - buf->buffer;
 
289
                *pos = '\0';
 
290
            } else {
 
291
                *len = buf->off;
 
292
                buf->buffer[buf->off] = '\0';
 
293
            }
 
294
            cli_chomp(buf->buffer);
 
295
            *oldstyle = 1;
 
296
            return buf->buffer;
 
297
    }
 
298
}
 
299
 
 
300
struct acceptdata {
 
301
    struct fd_data fds;
 
302
    struct fd_data recv_fds;
 
303
    pthread_cond_t cond_nfds;
 
304
    int max_queue;
 
305
    int commandtimeout;
 
306
    int syncpipe_wake_recv[2];
 
307
    int syncpipe_wake_accept[2];
 
308
};
 
309
 
 
310
#define ACCEPTDATA_INIT(mutex1, mutex2) { FDS_INIT(mutex1), FDS_INIT(mutex2), PTHREAD_COND_INITIALIZER, 0, 0, {-1, -1}, {-1, -1}}
 
311
 
 
312
static void *acceptloop_th(void *arg)
 
313
{
 
314
    char buff[BUFFSIZE + 1];
 
315
    size_t i;
 
316
    struct acceptdata *data = (struct acceptdata*)arg;
 
317
    struct fd_data *fds = &data->fds;
 
318
    struct fd_data *recv_fds = &data->recv_fds;
 
319
    int max_queue = data->max_queue;
 
320
    int commandtimeout = data->commandtimeout;
 
321
 
 
322
    pthread_mutex_lock(fds->buf_mutex);
 
323
    for (;;) {
 
324
        /* Block waiting for data to become available for reading */
 
325
        int new_sd = fds_poll_recv(fds, -1, 0, event_wake_accept);
 
326
#ifdef _WIN32
 
327
        ResetEvent(event_wake_accept);
 
328
#endif
 
329
        /* TODO: what about sockets that get rm-ed? */
 
330
        if (!fds->nfds) {
 
331
            /* no more sockets to poll, all gave an error */
 
332
            logg("!Main socket gone: fatal\n");
 
333
            break;
 
334
        }
 
335
 
 
336
        if (new_sd == -1 && errno != EINTR) {
 
337
            logg("!Failed to poll sockets, fatal\n");
 
338
            pthread_mutex_lock(&exit_mutex);
 
339
            progexit = 1;
 
340
            pthread_mutex_unlock(&exit_mutex);
 
341
            break;
 
342
        }
 
343
 
 
344
        /* accept() loop */
 
345
        for (i=0;i < fds->nfds && new_sd >= 0; i++) {
 
346
            struct fd_buf *buf = &fds->buf[i];
 
347
            if (!buf->got_newdata)
 
348
                continue;
 
349
#ifndef _WIN32
 
350
            if (buf->fd == data->syncpipe_wake_accept[0]) {
 
351
                /* dummy sync pipe, just to wake us */
 
352
                if (read(buf->fd, buff, sizeof(buff)) < 0) {
 
353
                    logg("^Syncpipe read failed\n");
 
354
                }
 
355
                continue;
 
356
            }
 
357
#endif
 
358
            if (buf->got_newdata == -1) {
 
359
                logg("$Acceptloop closed FD: %d\n", buf->fd);
 
360
                shutdown(buf->fd, 2);
 
361
                closesocket(buf->fd);
 
362
                buf->fd = -1;
 
363
                continue;
 
364
            }
 
365
 
 
366
            /* don't accept unlimited number of connections, or
 
367
             * we'll run out of file descriptors */
 
368
            pthread_mutex_lock(recv_fds->buf_mutex);
 
369
            while (recv_fds->nfds > (unsigned)max_queue) {
 
370
                pthread_mutex_lock(&exit_mutex);
 
371
                if(progexit) {
 
372
                    pthread_mutex_unlock(&exit_mutex);
 
373
                    break;
 
374
                }
 
375
                pthread_mutex_unlock(&exit_mutex);
 
376
                pthread_cond_wait(&data->cond_nfds, recv_fds->buf_mutex);
 
377
            }
 
378
            pthread_mutex_unlock(recv_fds->buf_mutex);
 
379
 
 
380
            pthread_mutex_lock(&exit_mutex);
 
381
            if(progexit) {
 
382
                pthread_mutex_unlock(&exit_mutex);
 
383
                break;
 
384
            }
 
385
            pthread_mutex_unlock(&exit_mutex);
 
386
 
 
387
            /* listen only socket */
 
388
            new_sd = accept(fds->buf[i].fd, NULL, NULL);
 
389
 
 
390
            if (new_sd >= 0) {
 
391
                int ret, flags;
 
392
#ifdef F_GETFL
 
393
                flags = fcntl(new_sd, F_GETFL, 0);
 
394
                if (flags != -1) {
 
395
                    if (fcntl(new_sd, F_SETFL, flags | O_NONBLOCK) == -1) {
 
396
                        logg("^Can't set socket to nonblocking mode, errno %d\n",
 
397
                             errno);
 
398
                    }
 
399
                } else {
 
400
                        logg("^Can't get socket flags, errno %d\n", errno);
 
401
                }
 
402
#else
 
403
                logg("^Nonblocking sockets not available!\n");
 
404
#endif
 
405
                logg("$Got new connection, FD %d\n", new_sd);
 
406
                pthread_mutex_lock(recv_fds->buf_mutex);
 
407
                ret = fds_add(recv_fds, new_sd, 0, commandtimeout);
 
408
                pthread_mutex_unlock(recv_fds->buf_mutex);
 
409
 
 
410
                if (ret == -1) {
 
411
                    logg("!fds_add failed\n");
 
412
                    closesocket(new_sd);
 
413
                    continue;
 
414
                }
 
415
 
 
416
                /* notify recvloop */
 
417
#ifdef _WIN32
 
418
                SetEvent(event_wake_recv);
 
419
#else
 
420
                if (write(data->syncpipe_wake_recv[1], "", 1) == -1) {
 
421
                    logg("!write syncpipe failed\n");
 
422
                    continue;
 
423
                }
 
424
#endif
 
425
            } else if (errno != EINTR) {
 
426
                /* very bad - need to exit or restart */
 
427
#ifdef HAVE_STRERROR_R
 
428
                strerror_r(errno, buff, BUFFSIZE);
 
429
                logg("!accept() failed: %s\n", buff);
 
430
#else
 
431
                logg("!accept() failed\n");
 
432
#endif
 
433
                /* give the poll loop a chance to close disconnected FDs */
 
434
                break;
 
435
            }
 
436
 
 
437
        }
 
438
 
 
439
        /* handle progexit */
 
440
        pthread_mutex_lock(&exit_mutex);
 
441
        if (progexit) {
 
442
            pthread_mutex_unlock(&exit_mutex);
 
443
            break;
 
444
        }
 
445
        pthread_mutex_unlock(&exit_mutex);
 
446
    }
 
447
    pthread_mutex_unlock(fds->buf_mutex);
 
448
 
 
449
    if (sd_listen_fds(0) == 0)
 
450
    {
 
451
        /* only close the sockets, when not using systemd socket activation */
 
452
        for (i=0;i < fds->nfds; i++)
 
453
        {
 
454
            if (fds->buf[i].fd == -1)
 
455
                continue;
 
456
            logg("$Shutdown: closed fd %d\n", fds->buf[i].fd);
 
457
            shutdown(fds->buf[i].fd, 2);
 
458
            closesocket(fds->buf[i].fd);
 
459
        }
 
460
    }
 
461
 
 
462
    fds_free(fds);
 
463
    pthread_mutex_destroy(fds->buf_mutex);
 
464
    pthread_mutex_lock(&exit_mutex);
 
465
    progexit = 1;
 
466
    pthread_mutex_unlock(&exit_mutex);
 
467
#ifdef _WIN32
 
468
    SetEvent(event_wake_recv);
 
469
#else
 
470
    if (write(data->syncpipe_wake_recv[1], "", 1) < 0) {
 
471
        logg("$Syncpipe write failed\n");
 
472
    }
 
473
#endif
 
474
    return NULL;
 
475
}
 
476
 
 
477
static const char* parse_dispatch_cmd(client_conn_t *conn, struct fd_buf *buf, size_t *ppos, int *error, const struct optstruct *opts, int readtimeout)
 
478
{
 
479
    const char *cmd = NULL;
 
480
    int rc;
 
481
    size_t cmdlen;
 
482
    char term;
 
483
    int oldstyle;
 
484
    size_t pos = *ppos;
 
485
    /* Parse & dispatch commands */
 
486
    while ((conn->mode == MODE_COMMAND) &&
 
487
           (cmd = get_cmd(buf, pos, &cmdlen, &term, &oldstyle)) != NULL) {
 
488
        const char *argument;
 
489
        enum commands cmdtype;
 
490
        if (conn->group && oldstyle) {
 
491
            logg("$Received oldstyle command inside IDSESSION: %s\n", cmd);
 
492
            conn_reply_error(conn, "Only nCMDS\\n and zCMDS\\0 are accepted inside IDSESSION.");
 
493
            *error = 1;
 
494
            break;
 
495
        }
 
496
        cmdtype = parse_command(cmd, &argument, oldstyle);
 
497
        logg("$got command %s (%u, %u), argument: %s\n",
 
498
             cmd, (unsigned)cmdlen, (unsigned)cmdtype, argument ? argument : "");
 
499
        if (cmdtype == COMMAND_FILDES) {
 
500
            if (buf->buffer + buf->off <= cmd + strlen("FILDES\n")) {
 
501
                /* we need the extra byte from recvmsg */
 
502
                conn->mode = MODE_WAITANCILL;
 
503
                buf->mode = MODE_WAITANCILL;
 
504
                /* put term back */
 
505
                buf->buffer[pos + cmdlen] = term;
 
506
                cmdlen = 0;
 
507
                logg("$RECVTH: mode -> MODE_WAITANCILL\n");
 
508
                break;
 
509
            }
 
510
            /* eat extra \0 for controlmsg */
 
511
            cmdlen++;
 
512
            logg("$RECVTH: FILDES command complete\n");
 
513
        }
 
514
        conn->term = term;
 
515
        buf->term = term;
 
516
 
 
517
        if ((rc = execute_or_dispatch_command(conn, cmdtype, argument)) < 0) {
 
518
            logg("!Command dispatch failed\n");
 
519
            if(rc == -1 && optget(opts, "ExitOnOOM")->enabled) {
 
520
                pthread_mutex_lock(&exit_mutex);
 
521
                progexit = 1;
 
522
                pthread_mutex_unlock(&exit_mutex);
 
523
            }
 
524
            *error = 1;
 
525
        }
 
526
        if (thrmgr_group_need_terminate(conn->group)) {
 
527
            logg("$Receive thread: have to terminate group\n");
 
528
            *error = CL_ETIMEOUT;
 
529
            break;
 
530
        }
 
531
        if (*error || !conn->group || rc) {
 
532
            if (rc && thrmgr_group_finished(conn->group, EXIT_OK)) {
 
533
                logg("$Receive thread: closing conn (FD %d), group finished\n", conn->sd);
 
534
                /* if there are no more active jobs */
 
535
                shutdown(conn->sd, 2);
 
536
                closesocket(conn->sd);
 
537
                buf->fd = -1;
 
538
                conn->group = NULL;
 
539
            } else if (conn->mode != MODE_STREAM) {
 
540
                logg("$mode -> MODE_WAITREPLY\n");
 
541
                /* no more commands are accepted */
 
542
                conn->mode = MODE_WAITREPLY;
 
543
                /* Stop monitoring this FD, it will be closed either
 
544
                 * by us, or by the scanner thread. 
 
545
                 * Never close a file descriptor that is being
 
546
                 * monitored by poll()/select() from another thread,
 
547
                 * because this can lead to subtle bugs such as:
 
548
                 * Other thread closes file descriptor -> POLLHUP is
 
549
                 * set, but the poller thread doesn't wake up yet.
 
550
                 * Another client opens a connection and sends some
 
551
                 * data. If the socket reuses the previous file descriptor,
 
552
                 * then POLLIN is set on the file descriptor too.
 
553
                 * When poll() wakes up it sees POLLIN | POLLHUP
 
554
                 * and thinks that the client has sent some data,
 
555
                 * and closed the connection, so clamd closes the
 
556
                 * connection in turn resulting in a bug.
 
557
                 *
 
558
                 * If we wouldn't have poll()-ed the file descriptor
 
559
                 * we closed in another thread, but rather made sure
 
560
                 * that we don't put a FD that we're about to close
 
561
                 * into poll()'s list of watched fds; then POLLHUP
 
562
                 * would be set, but the file descriptor would stay
 
563
                 * open, until we wake up from poll() and close it.
 
564
                 * Thus a new connection won't be able to reuse the
 
565
                 * same FD, and there is no bug.
 
566
                 * */
 
567
                buf->fd = -1;
 
568
            }
 
569
        }
 
570
        /* we received a command, set readtimeout */
 
571
        time(&buf->timeout_at);
 
572
        buf->timeout_at += readtimeout;
 
573
        pos += cmdlen+1;
 
574
        if (conn->mode == MODE_STREAM) {
 
575
            /* TODO: this doesn't belong here */
 
576
            buf->dumpname = conn->filename;
 
577
            buf->dumpfd = conn->scanfd;
 
578
            logg("$Receive thread: INSTREAM: %s fd %u\n", buf->dumpname, buf->dumpfd);
 
579
        }
 
580
        if (conn->mode != MODE_COMMAND) {
 
581
            logg("$Breaking command loop, mode is no longer MODE_COMMAND\n");
 
582
            break;
 
583
        }
 
584
        conn->id++;
 
585
    }
 
586
    *ppos = pos;
 
587
    buf->mode = conn->mode;
 
588
    buf->id = conn->id;
 
589
    buf->group = conn->group;
 
590
    buf->quota = conn->quota;
 
591
    if (conn->scanfd != -1 && conn->scanfd != buf->dumpfd) {
 
592
        logg("$Unclaimed file descriptor received, closing: %d\n", conn->scanfd);
 
593
        close(conn->scanfd);
 
594
        /* protocol error */
 
595
        conn_reply_error(conn, "PROTOCOL ERROR: ancillary data sent without FILDES.");
 
596
        *error = 1;
 
597
        return NULL;
 
598
    }
 
599
    if (!*error) {
 
600
        /* move partial command to beginning of buffer */
 
601
        if (pos < buf->off) {
 
602
            memmove (buf->buffer, &buf->buffer[pos], buf->off - pos);
 
603
            buf->off -= pos;
 
604
        } else
 
605
            buf->off = 0;
 
606
        if (buf->off)
 
607
            logg("$Moved partial command: %lu\n", (unsigned long)buf->off);
 
608
        else
 
609
            logg("$Consumed entire command\n");
 
610
        /* adjust pos to account for the buffer shuffle */
 
611
        pos = 0;
 
612
    }
 
613
    *ppos = pos;
 
614
    return cmd;
 
615
}
 
616
 
 
617
/* static const unsigned char* parse_dispatch_cmd(client_conn_t *conn, struct fd_buf *buf, size_t *ppos, int *error, const struct optstruct *opts, int readtimeout) */
 
618
static int handle_stream(client_conn_t *conn, struct fd_buf *buf, const struct optstruct *opts, int *error, size_t *ppos, int readtimeout)
 
619
{
 
620
    int rc;
 
621
    size_t pos = *ppos;
 
622
    size_t cmdlen;
 
623
    
 
624
    logg("$mode == MODE_STREAM\n");
 
625
    /* we received some data, set readtimeout */
 
626
    time(&buf->timeout_at);
 
627
    buf->timeout_at += readtimeout;
 
628
    while (pos <= buf->off) {
 
629
        if (!buf->chunksize) {
 
630
            /* read chunksize */
 
631
            if (buf->off-pos >= 4) {
 
632
                uint32_t cs;
 
633
                memmove(&cs, buf->buffer + pos, 4);
 
634
                pos += 4;
 
635
                buf->chunksize = ntohl(cs);
 
636
                logg("$Got chunksize: %u\n", buf->chunksize);
 
637
                if (!buf->chunksize) {
 
638
                    /* chunksize 0 marks end of stream */
 
639
                    conn->scanfd = buf->dumpfd;
 
640
                    conn->term = buf->term;
 
641
                    buf->dumpfd = -1;
 
642
                    buf->mode = buf->group ? MODE_COMMAND : MODE_WAITREPLY;
 
643
                    if (buf->mode == MODE_WAITREPLY)
 
644
                        buf->fd = -1;
 
645
                    logg("$Chunks complete\n");
 
646
                    buf->dumpname = NULL;
 
647
                    if ((rc = execute_or_dispatch_command(conn, COMMAND_INSTREAMSCAN, NULL)) < 0) {
 
648
                        logg("!Command dispatch failed\n");
 
649
                        if(rc == -1 && optget(opts, "ExitOnOOM")->enabled) {
 
650
                            pthread_mutex_lock(&exit_mutex);
 
651
                            progexit = 1;
 
652
                            pthread_mutex_unlock(&exit_mutex);
 
653
                        }
 
654
                        *error = 1;
 
655
                    } else {
 
656
                        memmove (buf->buffer, &buf->buffer[pos], buf->off - pos);
 
657
                        buf->off -= pos;
 
658
                        *ppos = 0;
 
659
                        buf->id++;
 
660
                        return 0;
 
661
                    }
 
662
                }
 
663
                if (buf->chunksize > buf->quota) {
 
664
                    logg("^INSTREAM: Size limit reached, (requested: %lu, max: %lu)\n",
 
665
                         (unsigned long)buf->chunksize, (unsigned long)buf->quota);
 
666
                    conn_reply_error(conn, "INSTREAM size limit exceeded.");
 
667
                    *error = 1;
 
668
                    *ppos = pos;
 
669
                    return -1;
 
670
                } else {
 
671
                    buf->quota -= buf->chunksize;
 
672
                }
 
673
                logg("$Quota Remaining: %lu\n", buf->quota);
 
674
            } else {
 
675
                /* need more data, so return and wait for some */
 
676
                memmove (buf->buffer, &buf->buffer[pos], buf->off - pos);
 
677
                buf->off -= pos;
 
678
                *ppos = 0;
 
679
                return -1;
 
680
            }
 
681
        }
 
682
        if (pos + buf->chunksize < buf->off)
 
683
            cmdlen = buf->chunksize;
 
684
        else
 
685
            cmdlen = buf->off - pos;
 
686
        buf->chunksize -= cmdlen;
 
687
        if (cli_writen(buf->dumpfd, buf->buffer + pos, cmdlen) < 0) {
 
688
            conn_reply_error(conn, "Error writing to temporary file");
 
689
            logg("!INSTREAM: Can't write to temporary file.\n");
 
690
            *error = 1;
 
691
        }
 
692
        logg("$Processed %lu bytes of chunkdata, pos %lu\n", cmdlen, pos);
 
693
        pos += cmdlen;
 
694
        if (pos == buf->off) {
 
695
            buf->off = 0;
 
696
            pos = 0;
 
697
            /* need more data, so return and wait for some */
 
698
            *ppos = pos;
 
699
            return -1;
 
700
        }
 
701
    }
 
702
    *ppos = pos;
 
703
    return 0;
 
704
}
 
705
 
 
706
int recvloop_th(int *socketds, unsigned nsockets, struct cl_engine *engine, unsigned int dboptions, const struct optstruct *opts)
 
707
{
 
708
        int max_threads, max_queue, readtimeout, ret = 0;
 
709
        unsigned int options = 0;
 
710
        char timestr[32];
 
711
#ifndef _WIN32
 
712
        struct sigaction sigact;
 
713
        sigset_t sigset;
 
714
        struct rlimit rlim;
 
715
#endif
 
716
        mode_t old_umask;
 
717
        const struct optstruct *opt;
 
718
        char buff[BUFFSIZE + 1];
 
719
        pid_t mainpid;
 
720
        int idletimeout;
 
721
        unsigned long long val;
 
722
        size_t i, j, rr_last = 0;
 
723
        pthread_t accept_th;
 
724
        pthread_mutex_t fds_mutex = PTHREAD_MUTEX_INITIALIZER;
 
725
        pthread_mutex_t recvfds_mutex = PTHREAD_MUTEX_INITIALIZER;
 
726
        struct acceptdata acceptdata = ACCEPTDATA_INIT(&fds_mutex, &recvfds_mutex);
 
727
        struct fd_data *fds = &acceptdata.recv_fds;
 
728
        time_t start_time, current_time;
 
729
        unsigned int selfchk;
 
730
        threadpool_t *thr_pool;
 
731
 
 
732
#if defined(FANOTIFY) || defined(CLAMAUTH)
 
733
        pthread_t fan_pid;
 
734
        pthread_attr_t fan_attr;
 
735
        struct thrarg *tharg = NULL; /* shut up gcc */
 
736
#endif
 
737
 
 
738
#ifndef _WIN32
 
739
        memset(&sigact, 0, sizeof(struct sigaction));
 
740
#endif
 
741
 
 
742
    /* set up limits */
 
743
    if((opt = optget(opts, "MaxScanSize"))->active) {
 
744
        if((ret = cl_engine_set_num(engine, CL_ENGINE_MAX_SCANSIZE, opt->numarg))) {
 
745
            logg("!cl_engine_set_num(CL_ENGINE_MAX_SCANSIZE) failed: %s\n", cl_strerror(ret));
 
746
            cl_engine_free(engine);
 
747
            return 1;
 
748
        }
 
749
    }
 
750
    val = cl_engine_get_num(engine, CL_ENGINE_MAX_SCANSIZE, NULL);
 
751
    if(val)
 
752
        logg("Limits: Global size limit set to %llu bytes.\n", val);
 
753
    else
 
754
        logg("^Limits: Global size limit protection disabled.\n");
 
755
 
 
756
    if((opt = optget(opts, "MaxFileSize"))->active) {
 
757
        if((ret = cl_engine_set_num(engine, CL_ENGINE_MAX_FILESIZE, opt->numarg))) {
 
758
            logg("!cl_engine_set_num(CL_ENGINE_MAX_FILESIZE) failed: %s\n", cl_strerror(ret));
 
759
            cl_engine_free(engine);
 
760
            return 1;
 
761
        }
 
762
    }
 
763
    val = cl_engine_get_num(engine, CL_ENGINE_MAX_FILESIZE, NULL);
 
764
    if(val)
 
765
        logg("Limits: File size limit set to %llu bytes.\n", val);
 
766
    else
 
767
        logg("^Limits: File size limit protection disabled.\n");
 
768
 
 
769
#ifndef _WIN32
 
770
    if(getrlimit(RLIMIT_FSIZE, &rlim) == 0) {
 
771
        if(rlim.rlim_cur < (rlim_t) cl_engine_get_num(engine, CL_ENGINE_MAX_FILESIZE, NULL))
 
772
            logg("^System limit for file size is lower than engine->maxfilesize\n");
 
773
        if(rlim.rlim_cur < (rlim_t) cl_engine_get_num(engine, CL_ENGINE_MAX_SCANSIZE, NULL))
 
774
            logg("^System limit for file size is lower than engine->maxscansize\n");
 
775
    } else {
 
776
        logg("^Cannot obtain resource limits for file size\n");
 
777
    }
 
778
#endif
 
779
 
 
780
    if((opt = optget(opts, "MaxRecursion"))->active) {
 
781
        if((ret = cl_engine_set_num(engine, CL_ENGINE_MAX_RECURSION, opt->numarg))) {
 
782
            logg("!cl_engine_set_num(CL_ENGINE_MAX_RECURSION) failed: %s\n", cl_strerror(ret));
 
783
            cl_engine_free(engine);
 
784
            return 1;
 
785
        }
 
786
    }
 
787
    val = cl_engine_get_num(engine, CL_ENGINE_MAX_RECURSION, NULL);
 
788
    if(val)
 
789
        logg("Limits: Recursion level limit set to %u.\n", (unsigned int) val);
 
790
    else
 
791
        logg("^Limits: Recursion level limit protection disabled.\n");
 
792
 
 
793
    if((opt = optget(opts, "MaxFiles"))->active) {
 
794
        if((ret = cl_engine_set_num(engine, CL_ENGINE_MAX_FILES, opt->numarg))) {
 
795
            logg("!cl_engine_set_num(CL_ENGINE_MAX_FILES) failed: %s\n", cl_strerror(ret));
 
796
            cl_engine_free(engine);
 
797
            return 1;
 
798
        }
 
799
    }
 
800
    val = cl_engine_get_num(engine, CL_ENGINE_MAX_FILES, NULL);
 
801
    if(val)
 
802
        logg("Limits: Files limit set to %u.\n", (unsigned int) val);
 
803
    else
 
804
        logg("^Limits: Files limit protection disabled.\n");
 
805
 
 
806
#ifndef _WIN32
 
807
    if (getrlimit(RLIMIT_CORE, &rlim) == 0) {
 
808
        logg("*Limits: Core-dump limit is %lu.\n", (unsigned long)rlim.rlim_cur);
 
809
    }
 
810
#endif
 
811
 
 
812
    /* Engine max sizes */
 
813
 
 
814
    if((opt = optget(opts, "MaxEmbeddedPE"))->active) {
 
815
        if((ret = cl_engine_set_num(engine, CL_ENGINE_MAX_EMBEDDEDPE, opt->numarg))) {
 
816
            logg("!cli_engine_set_num(CL_ENGINE_MAX_EMBEDDEDPE) failed: %s\n", cl_strerror(ret));
 
817
            cl_engine_free(engine);
 
818
            return 1;
 
819
        }
 
820
    }
 
821
    val = cl_engine_get_num(engine, CL_ENGINE_MAX_EMBEDDEDPE, NULL);
 
822
    logg("Limits: MaxEmbeddedPE limit set to %llu bytes.\n", val);
 
823
 
 
824
    if((opt = optget(opts, "MaxHTMLNormalize"))->active) {
 
825
        if((ret = cl_engine_set_num(engine, CL_ENGINE_MAX_HTMLNORMALIZE, opt->numarg))) {
 
826
            logg("!cli_engine_set_num(CL_ENGINE_MAX_HTMLNORMALIZE) failed: %s\n", cl_strerror(ret));
 
827
            cl_engine_free(engine);
 
828
            return 1;
 
829
        }
 
830
    }
 
831
    val = cl_engine_get_num(engine, CL_ENGINE_MAX_HTMLNORMALIZE, NULL);
 
832
    logg("Limits: MaxHTMLNormalize limit set to %llu bytes.\n", val);
 
833
 
 
834
    if((opt = optget(opts, "MaxHTMLNoTags"))->active) {
 
835
        if((ret = cl_engine_set_num(engine, CL_ENGINE_MAX_HTMLNOTAGS, opt->numarg))) {
 
836
            logg("!cli_engine_set_num(CL_ENGINE_MAX_HTMLNOTAGS) failed: %s\n", cl_strerror(ret));
 
837
            cl_engine_free(engine);
 
838
            return 1;
 
839
        }
 
840
    }
 
841
    val = cl_engine_get_num(engine, CL_ENGINE_MAX_HTMLNOTAGS, NULL);
 
842
    logg("Limits: MaxHTMLNoTags limit set to %llu bytes.\n", val);
 
843
 
 
844
    if((opt = optget(opts, "MaxScriptNormalize"))->active) {
 
845
        if((ret = cl_engine_set_num(engine, CL_ENGINE_MAX_SCRIPTNORMALIZE, opt->numarg))) {
 
846
            logg("!cli_engine_set_num(CL_ENGINE_MAX_SCRIPTNORMALIZE) failed: %s\n", cl_strerror(ret));
 
847
            cl_engine_free(engine);
 
848
            return 1;
 
849
        }
 
850
    }
 
851
    val = cl_engine_get_num(engine, CL_ENGINE_MAX_SCRIPTNORMALIZE, NULL);
 
852
    logg("Limits: MaxScriptNormalize limit set to %llu bytes.\n", val);
 
853
 
 
854
    if((opt = optget(opts, "MaxZipTypeRcg"))->active) {
 
855
        if((ret = cl_engine_set_num(engine, CL_ENGINE_MAX_ZIPTYPERCG, opt->numarg))) {
 
856
            logg("!cli_engine_set_num(CL_ENGINE_MAX_ZIPTYPERCG) failed: %s\n", cl_strerror(ret));
 
857
            cl_engine_free(engine);
 
858
            return 1;
 
859
        }
 
860
    }
 
861
    val = cl_engine_get_num(engine, CL_ENGINE_MAX_ZIPTYPERCG, NULL);
 
862
    logg("Limits: MaxZipTypeRcg limit set to %llu bytes.\n", val);
 
863
 
 
864
    if((opt = optget(opts, "MaxPartitions"))->active) {
 
865
        if((ret = cl_engine_set_num(engine, CL_ENGINE_MAX_PARTITIONS, opt->numarg))) {
 
866
            logg("!cli_engine_set_num(MaxPartitions) failed: %s\n", cl_strerror(ret));
 
867
            cl_engine_free(engine);
 
868
            return 1;
 
869
        }
 
870
    }
 
871
    val = cl_engine_get_num(engine, CL_ENGINE_MAX_PARTITIONS, NULL);
 
872
    logg("Limits: MaxPartitions limit set to %llu.\n", val);
 
873
 
 
874
    if((opt = optget(opts, "MaxIconsPE"))->active) {
 
875
        if((ret = cl_engine_set_num(engine, CL_ENGINE_MAX_ICONSPE, opt->numarg))) {
 
876
            logg("!cli_engine_set_num(MaxIconsPE) failed: %s\n", cl_strerror(ret));
 
877
            cl_engine_free(engine);
 
878
            return 1;
 
879
        }
 
880
    }
 
881
    val = cl_engine_get_num(engine, CL_ENGINE_MAX_ICONSPE, NULL);
 
882
    logg("Limits: MaxIconsPE limit set to %llu.\n", val);
 
883
 
 
884
    if(optget(opts, "ScanArchive")->enabled) {
 
885
        logg("Archive support enabled.\n");
 
886
        options |= CL_SCAN_ARCHIVE;
 
887
 
 
888
        if(optget(opts, "ArchiveBlockEncrypted")->enabled) {
 
889
            logg("Archive: Blocking encrypted archives.\n");
 
890
            options |= CL_SCAN_BLOCKENCRYPTED;
 
891
        }
 
892
 
 
893
    } else {
 
894
        logg("Archive support disabled.\n");
 
895
    }
 
896
 
 
897
    if(optget(opts, "AlgorithmicDetection")->enabled) {
 
898
        logg("Algorithmic detection enabled.\n");
 
899
        options |= CL_SCAN_ALGORITHMIC;
 
900
    } else {
 
901
        logg("Algorithmic detection disabled.\n");
 
902
    }
 
903
 
 
904
    if(optget(opts, "ScanPE")->enabled) {
 
905
        logg("Portable Executable support enabled.\n");
 
906
        options |= CL_SCAN_PE;
 
907
    } else {
 
908
        logg("Portable Executable support disabled.\n");
 
909
    }
 
910
 
 
911
    if(optget(opts, "ScanELF")->enabled) {
 
912
        logg("ELF support enabled.\n");
 
913
        options |= CL_SCAN_ELF;
 
914
    } else {
 
915
        logg("ELF support disabled.\n");
 
916
    }
 
917
 
 
918
    if(optget(opts, "ScanPE")->enabled || optget(opts, "ScanELF")->enabled) {
 
919
        if(optget(opts, "DetectBrokenExecutables")->enabled) {
 
920
            logg("Detection of broken executables enabled.\n");
 
921
            options |= CL_SCAN_BLOCKBROKEN;
 
922
        }
 
923
    }
 
924
 
 
925
    if(optget(opts, "ScanMail")->enabled) {
 
926
        logg("Mail files support enabled.\n");
 
927
        options |= CL_SCAN_MAIL;
 
928
 
 
929
        if(optget(opts, "ScanPartialMessages")->enabled) {
 
930
            logg("Mail: RFC1341 handling enabled.\n");
 
931
            options |= CL_SCAN_PARTIAL_MESSAGE;
 
932
        }
 
933
 
 
934
    } else {
 
935
        logg("Mail files support disabled.\n");
 
936
    }
 
937
 
 
938
    if(optget(opts, "ScanOLE2")->enabled) {
 
939
        logg("OLE2 support enabled.\n");
 
940
        options |= CL_SCAN_OLE2;
 
941
        if(optget(opts, "OLE2BlockMacros")->enabled) {
 
942
            logg("OLE2: Blocking all VBA macros.\n");
 
943
            options |= CL_SCAN_BLOCKMACROS;
 
944
        }
 
945
    } else {
 
946
        logg("OLE2 support disabled.\n");
 
947
    }
 
948
 
 
949
    if(optget(opts, "ScanPDF")->enabled) {
 
950
        logg("PDF support enabled.\n");
 
951
        options |= CL_SCAN_PDF;
 
952
    } else {
 
953
        logg("PDF support disabled.\n");
 
954
    }
 
955
 
 
956
    if(optget(opts, "ScanSWF")->enabled) {
 
957
        logg("SWF support enabled.\n");
 
958
        options |= CL_SCAN_SWF;
 
959
    } else {
 
960
        logg("SWF support disabled.\n");
 
961
    }
 
962
 
 
963
    if(optget(opts, "ScanHTML")->enabled) {
 
964
        logg("HTML support enabled.\n");
 
965
        options |= CL_SCAN_HTML;
 
966
    } else {
 
967
        logg("HTML support disabled.\n");
 
968
    }
 
969
 
 
970
    if(optget(opts,"PhishingScanURLs")->enabled) {
 
971
 
 
972
        if(optget(opts,"PhishingAlwaysBlockCloak")->enabled) {
 
973
            options |= CL_SCAN_PHISHING_BLOCKCLOAK; 
 
974
            logg("Phishing: Always checking for cloaked urls\n");
 
975
        }
 
976
 
 
977
        if(optget(opts,"PhishingAlwaysBlockSSLMismatch")->enabled) {
 
978
            options |= CL_SCAN_PHISHING_BLOCKSSL;
 
979
            logg("Phishing: Always checking for ssl mismatches\n");
 
980
        }
 
981
    }
 
982
 
 
983
    if(optget(opts,"PartitionIntersection")->enabled) {
 
984
        options |= CL_SCAN_PARTITION_INTXN;
 
985
        logg("Raw DMG: Always checking for partitons intersections\n");
 
986
    }
 
987
 
 
988
    if(optget(opts,"HeuristicScanPrecedence")->enabled) {
 
989
            options |= CL_SCAN_HEURISTIC_PRECEDENCE;
 
990
            logg("Heuristic: precedence enabled\n");
 
991
    }
 
992
 
 
993
    if(optget(opts, "StructuredDataDetection")->enabled) {
 
994
        options |= CL_SCAN_STRUCTURED;
 
995
 
 
996
        if((opt = optget(opts, "StructuredMinCreditCardCount"))->enabled) {
 
997
            if((ret = cl_engine_set_num(engine, CL_ENGINE_MIN_CC_COUNT, opt->numarg))) {
 
998
                logg("!cl_engine_set_num(CL_ENGINE_MIN_CC_COUNT) failed: %s\n", cl_strerror(ret));
 
999
                cl_engine_free(engine);
 
1000
                return 1;
 
1001
            }
 
1002
        }
 
1003
        val = cl_engine_get_num(engine, CL_ENGINE_MIN_CC_COUNT, NULL);
 
1004
        logg("Structured: Minimum Credit Card Number Count set to %u\n", (unsigned int) val);
 
1005
 
 
1006
        if((opt = optget(opts, "StructuredMinSSNCount"))->enabled) {
 
1007
            if((ret = cl_engine_set_num(engine, CL_ENGINE_MIN_SSN_COUNT, opt->numarg))) {
 
1008
                logg("!cl_engine_set_num(CL_ENGINE_MIN_SSN_COUNT) failed: %s\n", cl_strerror(ret));
 
1009
                cl_engine_free(engine);
 
1010
                return 1;
 
1011
            }
 
1012
        }
 
1013
        val = cl_engine_get_num(engine, CL_ENGINE_MIN_SSN_COUNT, NULL);
 
1014
        logg("Structured: Minimum Social Security Number Count set to %u\n", (unsigned int) val);
 
1015
 
 
1016
        if(optget(opts, "StructuredSSNFormatNormal")->enabled)
 
1017
            options |= CL_SCAN_STRUCTURED_SSN_NORMAL;
 
1018
 
 
1019
        if(optget(opts, "StructuredSSNFormatStripped")->enabled)
 
1020
            options |= CL_SCAN_STRUCTURED_SSN_STRIPPED;
 
1021
    }
 
1022
 
 
1023
#ifdef HAVE__INTERNAL__SHA_COLLECT
 
1024
    if(optget(opts, "DevCollectHashes")->enabled)
 
1025
        options |= CL_SCAN_INTERNAL_COLLECT_SHA;
 
1026
#endif
 
1027
 
 
1028
    selfchk = optget(opts, "SelfCheck")->numarg;
 
1029
    if(!selfchk) {
 
1030
        logg("Self checking disabled.\n");
 
1031
    } else {
 
1032
        logg("Self checking every %u seconds.\n", selfchk);
 
1033
    }
 
1034
    memset(&dbstat, 0, sizeof(dbstat));
 
1035
 
 
1036
    /* save the PID */
 
1037
    mainpid = getpid();
 
1038
    if((opt = optget(opts, "PidFile"))->enabled) {
 
1039
            FILE *fd;
 
1040
        old_umask = umask(0002);
 
1041
        if((fd = fopen(opt->strarg, "w")) == NULL) {
 
1042
            logg("!Can't save PID in file %s\n", opt->strarg);
 
1043
        } else {
 
1044
            if (fprintf(fd, "%u\n", (unsigned int) mainpid)<0) {
 
1045
                logg("!Can't save PID in file %s\n", opt->strarg);
 
1046
            }
 
1047
            fclose(fd);
 
1048
        }
 
1049
        umask(old_umask);
 
1050
    }
 
1051
 
 
1052
    logg("*Listening daemon: PID: %u\n", (unsigned int) mainpid);
 
1053
    max_threads = optget(opts, "MaxThreads")->numarg;
 
1054
    max_queue = optget(opts, "MaxQueue")->numarg;
 
1055
    acceptdata.commandtimeout = optget(opts, "CommandReadTimeout")->numarg;
 
1056
    readtimeout = optget(opts, "ReadTimeout")->numarg;
 
1057
 
 
1058
#if !defined(_WIN32) && defined(RLIMIT_NOFILE)
 
1059
    if (getrlimit(RLIMIT_NOFILE, &rlim) == 0) {
 
1060
        /* don't warn if default value is too high, silently fix it */
 
1061
        unsigned maxrec;
 
1062
        int max_max_queue;
 
1063
        unsigned warn = optget(opts, "MaxQueue")->active;
 
1064
        const unsigned clamdfiles = 6;
 
1065
        /* Condition to not run out of file descriptors:
 
1066
         * MaxThreads * MaxRecursion + (MaxQueue - MaxThreads) + CLAMDFILES < RLIMIT_NOFILE 
 
1067
         * CLAMDFILES is 6: 3 standard FD + logfile + 2 FD for reloading the DB
 
1068
         * */
 
1069
#ifdef C_SOLARIS
 
1070
#ifdef HAVE_ENABLE_EXTENDED_FILE_STDIO
 
1071
        if (enable_extended_FILE_stdio(-1, -1) == -1) {
 
1072
            logg("^Unable to set extended FILE stdio, clamd will be limited to max 256 open files\n");
 
1073
            rlim.rlim_cur = rlim.rlim_cur > 255 ? 255 : rlim.rlim_cur;
 
1074
        }
 
1075
#elif !defined(_LP64)
 
1076
        if (rlim.rlim_cur > 255) {
 
1077
            rlim.rlim_cur = 255;
 
1078
            logg("^Solaris only supports 256 open files for 32-bit processes, you need at least Solaris 10u4, or compile as 64-bit to support more!\n");
 
1079
        }
 
1080
#endif
 
1081
#endif
 
1082
        opt = optget(opts,"MaxRecursion");
 
1083
        maxrec = opt->numarg;
 
1084
        max_max_queue = rlim.rlim_cur - maxrec * max_threads - clamdfiles + max_threads;
 
1085
        if (max_queue < max_threads) {
 
1086
            max_queue = max_threads;
 
1087
            if (warn)
 
1088
                logg("^MaxQueue value too low, increasing to: %d\n", max_queue);
 
1089
        }
 
1090
        if (max_max_queue < max_threads) {
 
1091
            logg("^MaxThreads * MaxRecursion is too high: %d, open file descriptor limit is: %lu\n",
 
1092
                 maxrec*max_threads, (unsigned long)rlim.rlim_cur);
 
1093
            max_max_queue = max_threads;
 
1094
        }
 
1095
        if (max_queue > max_max_queue) {
 
1096
            max_queue = max_max_queue;
 
1097
            if (warn)
 
1098
                logg("^MaxQueue value too high, lowering to: %d\n", max_queue);
 
1099
        } else if (max_queue < 2*max_threads && max_queue < max_max_queue) {
 
1100
            max_queue = 2*max_threads;
 
1101
            if (max_queue > max_max_queue)
 
1102
                max_queue = max_max_queue;
 
1103
            /* always warn here */
 
1104
            logg("^MaxQueue is lower than twice MaxThreads, increasing to: %d\n", max_queue);
 
1105
        }
 
1106
    }
 
1107
#endif
 
1108
    logg("*MaxQueue set to: %d\n", max_queue);
 
1109
    acceptdata.max_queue = max_queue;
 
1110
 
 
1111
    if(optget(opts, "ScanOnAccess")->enabled)
 
1112
#if defined(FANOTIFY) || defined(CLAMAUTH)
 
1113
    {
 
1114
        do {
 
1115
            if(pthread_attr_init(&fan_attr)) break;
 
1116
            pthread_attr_setdetachstate(&fan_attr, PTHREAD_CREATE_JOINABLE);
 
1117
            if(!(tharg = (struct thrarg *) malloc(sizeof(struct thrarg)))) break;
 
1118
            tharg->opts = opts;
 
1119
            tharg->engine = engine;
 
1120
            tharg->options = options;
 
1121
            if(!pthread_create(&fan_pid, &fan_attr, fan_th, tharg)) break;
 
1122
            free(tharg);
 
1123
            tharg=NULL;
 
1124
        } while(0);
 
1125
        if (!tharg) logg("!Unable to start on-access scan\n");
 
1126
    }
 
1127
#else
 
1128
        logg("!On-access scan is not available\n");
 
1129
#endif
 
1130
 
 
1131
#ifndef _WIN32
 
1132
    /* set up signal handling */
 
1133
    sigfillset(&sigset);
 
1134
    sigdelset(&sigset, SIGINT);
 
1135
    sigdelset(&sigset, SIGTERM);
 
1136
    sigdelset(&sigset, SIGSEGV);
 
1137
    sigdelset(&sigset, SIGHUP);
 
1138
    sigdelset(&sigset, SIGPIPE);
 
1139
    sigdelset(&sigset, SIGUSR2);
 
1140
    /* The behavior of a process is undefined after it ignores a 
 
1141
     * SIGFPE, SIGILL, SIGSEGV, or SIGBUS signal */
 
1142
    sigdelset(&sigset, SIGFPE);
 
1143
    sigdelset(&sigset, SIGILL);
 
1144
    sigdelset(&sigset, SIGSEGV);
 
1145
#ifdef SIGBUS    
 
1146
    sigdelset(&sigset, SIGBUS);
 
1147
#endif
 
1148
    sigdelset(&sigset, SIGTSTP);
 
1149
    sigdelset(&sigset, SIGCONT);
 
1150
    sigprocmask(SIG_SETMASK, &sigset, NULL);
 
1151
 
 
1152
    /* SIGINT, SIGTERM, SIGSEGV */
 
1153
    sigact.sa_handler = sighandler_th;
 
1154
    sigemptyset(&sigact.sa_mask);
 
1155
    sigaddset(&sigact.sa_mask, SIGINT);
 
1156
    sigaddset(&sigact.sa_mask, SIGTERM);
 
1157
    sigaddset(&sigact.sa_mask, SIGHUP);
 
1158
    sigaddset(&sigact.sa_mask, SIGPIPE);
 
1159
    sigaddset(&sigact.sa_mask, SIGUSR2);
 
1160
    sigaction(SIGINT, &sigact, NULL);
 
1161
    sigaction(SIGTERM, &sigact, NULL);
 
1162
    sigaction(SIGHUP, &sigact, NULL);
 
1163
    sigaction(SIGPIPE, &sigact, NULL);
 
1164
    sigaction(SIGUSR2, &sigact, NULL);
 
1165
#endif
 
1166
 
 
1167
    idletimeout = optget(opts, "IdleTimeout")->numarg;
 
1168
 
 
1169
    for (i=0;i < nsockets;i++)
 
1170
        if (fds_add(&acceptdata.fds, socketds[i], 1, 0) == -1) {
 
1171
            logg("!fds_add failed\n");
 
1172
            cl_engine_free(engine);
 
1173
            return 1;
 
1174
        }
 
1175
#ifdef _WIN32
 
1176
        event_wake_accept = CreateEvent(NULL, TRUE, FALSE, NULL);
 
1177
        event_wake_recv = CreateEvent(NULL, TRUE, FALSE, NULL);
 
1178
#else
 
1179
    if (pipe(acceptdata.syncpipe_wake_recv) == -1 ||
 
1180
        (pipe(acceptdata.syncpipe_wake_accept) == -1)) {
 
1181
 
 
1182
        logg("!pipe failed\n");
 
1183
        exit(-1);
 
1184
    }
 
1185
    syncpipe_wake_recv_w = acceptdata.syncpipe_wake_recv[1];
 
1186
 
 
1187
    if (fds_add(fds, acceptdata.syncpipe_wake_recv[0], 1, 0) == -1 ||
 
1188
        fds_add(&acceptdata.fds, acceptdata.syncpipe_wake_accept[0], 1, 0)) {
 
1189
        logg("!failed to add pipe fd\n");
 
1190
        exit(-1);
 
1191
    }
 
1192
#endif
 
1193
 
 
1194
    if ((thr_pool = thrmgr_new(max_threads, idletimeout, max_queue, scanner_thread)) == NULL) {
 
1195
        logg("!thrmgr_new failed\n");
 
1196
        exit(-1);
 
1197
    }
 
1198
 
 
1199
    if (pthread_create(&accept_th, NULL, acceptloop_th, &acceptdata)) {
 
1200
        logg("!pthread_create failed\n");
 
1201
        exit(-1);
 
1202
    }
 
1203
 
 
1204
    time(&start_time);
 
1205
    for(;;) {
 
1206
        int new_sd;
 
1207
 
 
1208
        /* Block waiting for connection on any of the sockets */
 
1209
        pthread_mutex_lock(fds->buf_mutex);
 
1210
        fds_cleanup(fds);
 
1211
        /* signal that we can accept more connections */
 
1212
        if (fds->nfds <= (unsigned)max_queue)
 
1213
            pthread_cond_signal(&acceptdata.cond_nfds);
 
1214
        new_sd = fds_poll_recv(fds, selfchk ? (int)selfchk : -1, 1, event_wake_recv);
 
1215
#ifdef _WIN32
 
1216
        ResetEvent(event_wake_recv);
 
1217
#else
 
1218
        if (!fds->nfds) {
 
1219
            /* at least the dummy/sync pipe should have remained */
 
1220
            logg("!All recv() descriptors gone: fatal\n");
 
1221
            pthread_mutex_lock(&exit_mutex);
 
1222
            progexit = 1;
 
1223
            pthread_mutex_unlock(&exit_mutex);
 
1224
            pthread_mutex_unlock(fds->buf_mutex);
 
1225
            break;
 
1226
        }
 
1227
#endif
 
1228
        if (new_sd == -1 && errno != EINTR) {
 
1229
            logg("!Failed to poll sockets, fatal\n");
 
1230
            pthread_mutex_lock(&exit_mutex);
 
1231
            progexit = 1;
 
1232
            pthread_mutex_unlock(&exit_mutex);
 
1233
        }
 
1234
 
 
1235
 
 
1236
        if(fds->nfds) i = (rr_last + 1) % fds->nfds;
 
1237
        for (j = 0;  j < fds->nfds && new_sd >= 0; j++, i = (i+1) % fds->nfds) {
 
1238
            size_t pos = 0;
 
1239
            int error = 0;
 
1240
            struct fd_buf *buf = &fds->buf[i];
 
1241
            if (!buf->got_newdata)
 
1242
                continue;
 
1243
 
 
1244
#ifndef _WIN32
 
1245
            if (buf->fd == acceptdata.syncpipe_wake_recv[0]) {
 
1246
                /* dummy sync pipe, just to wake us */
 
1247
                if (read(buf->fd, buff, sizeof(buff)) < 0) {
 
1248
                    logg("^Syncpipe read failed\n");
 
1249
                }
 
1250
                continue;
 
1251
            }
 
1252
#endif
 
1253
            if (buf->got_newdata == -1) {
 
1254
                if (buf->mode == MODE_WAITREPLY) {
 
1255
                    logg("$mode WAIT_REPLY -> closed\n");
 
1256
                    buf->fd = -1;
 
1257
                    thrmgr_group_terminate(buf->group);
 
1258
                    thrmgr_group_finished(buf->group, EXIT_ERROR);
 
1259
                    continue;
 
1260
                } else {
 
1261
                    logg("$client read error or EOF on read\n");
 
1262
                    error = 1;
 
1263
                }
 
1264
            }
 
1265
 
 
1266
            if (buf->fd != -1 && buf->got_newdata == -2) {
 
1267
                logg("$Client read timed out\n");
 
1268
                mdprintf(buf->fd, "COMMAND READ TIMED OUT\n");
 
1269
                error = 1;
 
1270
            }
 
1271
 
 
1272
            rr_last = i;
 
1273
            if (buf->mode == MODE_WAITANCILL) {
 
1274
                buf->mode = MODE_COMMAND;
 
1275
                logg("$mode -> MODE_COMMAND\n");
 
1276
            }
 
1277
            while (!error && buf->fd != -1 && buf->buffer && pos < buf->off &&
 
1278
                   buf->mode != MODE_WAITANCILL) {
 
1279
                client_conn_t conn;
 
1280
                const char *cmd = NULL;
 
1281
                int rc;
 
1282
                /* New data available to read on socket. */
 
1283
 
 
1284
                memset(&conn, 0, sizeof(conn));
 
1285
                conn.scanfd = buf->recvfd;
 
1286
                buf->recvfd = -1;
 
1287
                conn.sd = buf->fd;
 
1288
                conn.options = options;
 
1289
                conn.opts = opts;
 
1290
                conn.thrpool = thr_pool;
 
1291
                conn.engine = engine;
 
1292
                conn.group = buf->group;
 
1293
                conn.id = buf->id;
 
1294
                conn.quota = buf->quota;
 
1295
                conn.filename = buf->dumpname;
 
1296
                conn.mode = buf->mode;
 
1297
                conn.term = buf->term;
 
1298
 
 
1299
                /* Parse & dispatch command */
 
1300
                cmd = parse_dispatch_cmd(&conn, buf, &pos, &error, opts, readtimeout);
 
1301
 
 
1302
                if (conn.mode == MODE_COMMAND && !cmd)
 
1303
                    break;
 
1304
                if (!error) {
 
1305
                    if (buf->mode == MODE_WAITREPLY && buf->off) {
 
1306
                        /* Client is not supposed to send anything more */
 
1307
                        logg("^Client sent garbage after last command: %lu bytes\n", (unsigned long)buf->off);
 
1308
                        buf->buffer[buf->off] = '\0';
 
1309
                        logg("$Garbage: %s\n", buf->buffer);
 
1310
                        error = 1;
 
1311
                    } else if (buf->mode == MODE_STREAM) {
 
1312
                        rc = handle_stream(&conn, buf, opts, &error, &pos, readtimeout);
 
1313
                        if (rc == -1)
 
1314
                            break;
 
1315
                        else
 
1316
                            continue;
 
1317
                    }
 
1318
                }
 
1319
                if (error && error != CL_ETIMEOUT) {
 
1320
                    conn_reply_error(&conn, "Error processing command.");
 
1321
                }
 
1322
            }
 
1323
            if (error) {
 
1324
                if (buf->dumpfd != -1) {
 
1325
                    close(buf->dumpfd);
 
1326
                    if (buf->dumpname) {
 
1327
                        cli_unlink(buf->dumpname);
 
1328
                        free(buf->dumpname);
 
1329
                    }
 
1330
                    buf->dumpfd = -1;
 
1331
                }
 
1332
                thrmgr_group_terminate(buf->group);
 
1333
                if (thrmgr_group_finished(buf->group, EXIT_ERROR)) {
 
1334
                    if (buf->fd < 0) {
 
1335
                        logg("$Skipping shutdown of bad socket after error (FD %d)\n", buf->fd);
 
1336
                    }
 
1337
                    else {
 
1338
                        logg("$Shutting down socket after error (FD %d)\n", buf->fd);
 
1339
                        shutdown(buf->fd, 2);
 
1340
                        closesocket(buf->fd);
 
1341
                    }
 
1342
                } else
 
1343
                    logg("$Socket not shut down due to active tasks\n");
 
1344
                buf->fd = -1;
 
1345
            }
 
1346
        }
 
1347
        pthread_mutex_unlock(fds->buf_mutex);
 
1348
 
 
1349
        /* handle progexit */
 
1350
        pthread_mutex_lock(&exit_mutex);
 
1351
        if (progexit) {
 
1352
            pthread_mutex_unlock(&exit_mutex);
 
1353
            pthread_mutex_lock(fds->buf_mutex);
 
1354
        if (sd_listen_fds(0) == 0)
 
1355
        {
 
1356
            /* only close the sockets, when not using systemd socket activation */
 
1357
            for (i=0;i < fds->nfds; i++)
 
1358
            {
 
1359
                if (fds->buf[i].fd == -1)
 
1360
                    continue;
 
1361
                thrmgr_group_terminate(fds->buf[i].group);
 
1362
                if (thrmgr_group_finished(fds->buf[i].group, EXIT_ERROR))
 
1363
                {
 
1364
                    logg("$Shutdown closed fd %d\n", fds->buf[i].fd);
 
1365
                    shutdown(fds->buf[i].fd, 2);
 
1366
                    closesocket(fds->buf[i].fd);
 
1367
                    fds->buf[i].fd = -1;
 
1368
                }
 
1369
            }
 
1370
            }
 
1371
            pthread_mutex_unlock(fds->buf_mutex);
 
1372
            break;
 
1373
        }
 
1374
        pthread_mutex_unlock(&exit_mutex);
 
1375
 
 
1376
        /* SIGHUP */
 
1377
        if (sighup) {
 
1378
            logg("SIGHUP caught: re-opening log file.\n");
 
1379
            logg_close();
 
1380
            sighup = 0;
 
1381
            if(!logg_file && (opt = optget(opts, "LogFile"))->enabled)
 
1382
                logg_file = opt->strarg;
 
1383
        }
 
1384
 
 
1385
        /* SelfCheck */
 
1386
        if(selfchk) {
 
1387
            time(&current_time);
 
1388
            if((current_time - start_time) >= (time_t)selfchk) {
 
1389
                if(reload_db(engine, dboptions, opts, TRUE, &ret)) {
 
1390
                    pthread_mutex_lock(&reload_mutex);
 
1391
                    reload = 1;
 
1392
                    pthread_mutex_unlock(&reload_mutex);
 
1393
                }
 
1394
                time(&start_time);
 
1395
            }
 
1396
        }
 
1397
 
 
1398
        /* DB reload */
 
1399
        pthread_mutex_lock(&reload_mutex);
 
1400
        if(reload) {
 
1401
            pthread_mutex_unlock(&reload_mutex);
 
1402
#if defined(FANOTIFY) || defined(CLAMAUTH)
 
1403
            if(optget(opts, "ScanOnAccess")->enabled && tharg) {
 
1404
                logg("Restarting on-access scan\n");
 
1405
                pthread_mutex_lock(&logg_mutex);
 
1406
                pthread_kill(fan_pid, SIGUSR1);
 
1407
                pthread_mutex_unlock(&logg_mutex);
 
1408
                pthread_join(fan_pid, NULL);
 
1409
            }
 
1410
#endif
 
1411
            engine = reload_db(engine, dboptions, opts, FALSE, &ret);
 
1412
            if(ret) {
 
1413
                logg("Terminating because of a fatal error.\n");
 
1414
                if(new_sd >= 0)
 
1415
                    closesocket(new_sd);
 
1416
                break;
 
1417
            }
 
1418
 
 
1419
            pthread_mutex_lock(&reload_mutex);
 
1420
            reload = 0;
 
1421
            time(&reloaded_time);
 
1422
            pthread_mutex_unlock(&reload_mutex);
 
1423
#if defined(FANOTIFY) || defined(CLAMAUTH)
 
1424
            if(optget(opts, "ScanOnAccess")->enabled && tharg) {
 
1425
                tharg->engine = engine;
 
1426
                pthread_create(&fan_pid, &fan_attr, fan_th, tharg);
 
1427
            }
 
1428
#endif
 
1429
            time(&start_time);
 
1430
        } else {
 
1431
            pthread_mutex_unlock(&reload_mutex);
 
1432
        }
 
1433
    }
 
1434
 
 
1435
    pthread_mutex_lock(&exit_mutex);
 
1436
    progexit = 1;
 
1437
    pthread_mutex_unlock(&exit_mutex);
 
1438
#ifdef _WIN32
 
1439
    SetEvent(event_wake_accept);
 
1440
#else
 
1441
    if (write(acceptdata.syncpipe_wake_accept[1], "", 1) < 0) {
 
1442
        logg("^Write to syncpipe failed\n");
 
1443
    }
 
1444
#endif
 
1445
    /* Destroy the thread manager.
 
1446
     * This waits for all current tasks to end
 
1447
     */
 
1448
    logg("*Waiting for all threads to finish\n");
 
1449
    thrmgr_destroy(thr_pool);
 
1450
#if defined(FANOTIFY) || defined(CLAMAUTH)
 
1451
    if(optget(opts, "ScanOnAccess")->enabled && tharg) {
 
1452
        logg("Stopping on-access scan\n");
 
1453
        pthread_mutex_lock(&logg_mutex);
 
1454
        pthread_kill(fan_pid, SIGUSR1);
 
1455
        pthread_mutex_unlock(&logg_mutex);
 
1456
        pthread_join(fan_pid, NULL);
 
1457
    free(tharg);
 
1458
    }
 
1459
#endif
 
1460
    if(engine) {
 
1461
        thrmgr_setactiveengine(NULL);
 
1462
        cl_engine_free(engine);
 
1463
    }
 
1464
 
 
1465
    pthread_join(accept_th, NULL);
 
1466
    fds_free(fds);
 
1467
    pthread_mutex_destroy(fds->buf_mutex);
 
1468
    pthread_cond_destroy(&acceptdata.cond_nfds);
 
1469
#ifdef _WIN32
 
1470
    CloseHandle(event_wake_accept);
 
1471
    CloseHandle(event_wake_recv);
 
1472
#else
 
1473
    close(acceptdata.syncpipe_wake_accept[1]);
 
1474
    close(acceptdata.syncpipe_wake_recv[1]);
 
1475
#endif
 
1476
    if(dbstat.entries)
 
1477
        cl_statfree(&dbstat);
 
1478
    if (sd_listen_fds(0) == 0)
 
1479
    {
 
1480
        /* only close the sockets, when not using systemd socket activation */
 
1481
        logg("*Shutting down the main socket%s.\n", (nsockets > 1) ? "s" : "");
 
1482
        for (i = 0; i < nsockets; i++)
 
1483
            shutdown(socketds[i], 2);
 
1484
    }
 
1485
 
 
1486
    if((opt = optget(opts, "PidFile"))->enabled) {
 
1487
        if(unlink(opt->strarg) == -1)
 
1488
            logg("!Can't unlink the pid file %s\n", opt->strarg);
 
1489
        else
 
1490
            logg("Pid file removed.\n");
 
1491
    }
 
1492
 
 
1493
    time(&current_time);
 
1494
    logg("--- Stopped at %s", cli_ctime(&current_time, timestr, sizeof(timestr)));
 
1495
 
 
1496
    return ret;
 
1497
}