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

« back to all changes in this revision

Viewing changes to clamd/server-th.c

  • Committer: Bazaar Package Importer
  • Author(s): Stephen Gran
  • Date: 2008-09-05 17:25:34 UTC
  • mfrom: (0.35.1 lenny)
  • Revision ID: james.westby@ubuntu.com-20080905172534-yi3f8fkye1o7u1r3
* New upstream version (closes: #497662, #497773)
  - lots of new options for clamd.conf
  - fixes CVEs CVE-2008-3912, CVE-2008-3913, CVE-2008-3914, and
    CVE-2008-1389
* No longer supports --unzip option, so typo is gone (closes: #496276)
* Translations:
  - sv (thanks Martin Bagge <brother@bsnet.se>) (closes: #491760)

Show diffs side-by-side

added added

removed removed

Lines of Context:
35
35
#include <sys/types.h>
36
36
#ifndef C_WINDOWS
37
37
#include <sys/socket.h>
 
38
#include <sys/time.h>
 
39
#include <sys/resource.h>
38
40
#endif
39
41
#ifdef  HAVE_UNISTD_H
40
42
#include <unistd.h>
51
53
#include "others.h"
52
54
#include "shared.h"
53
55
#include "libclamav/others.h"
 
56
#include "libclamav/readdb.h"
54
57
 
55
58
#ifndef C_WINDOWS
56
59
#define closesocket(s)  close(s)
65
68
#endif
66
69
 
67
70
int progexit = 0;
68
 
pthread_mutex_t exit_mutex;
 
71
pthread_mutex_t exit_mutex = PTHREAD_MUTEX_INITIALIZER;
69
72
int reload = 0;
70
73
time_t reloaded_time = 0;
71
 
pthread_mutex_t reload_mutex;
 
74
pthread_mutex_t reload_mutex = PTHREAD_MUTEX_INITIALIZER;
72
75
int sighup = 0;
73
76
static struct cl_stat *dbstat = NULL;
74
77
 
191
194
{
192
195
        const char *dbdir;
193
196
        int retval;
194
 
        unsigned int sigs = 0, attempt = 1;
 
197
        unsigned int sigs = 0;
 
198
        char *pua_cats = NULL;
195
199
 
196
200
    *ret = 0;
197
201
    if(do_check) {
209
213
        }
210
214
    }
211
215
 
212
 
    /* release old structure */
213
 
    if(engine) {
214
 
        cl_free(engine);
215
 
        engine = NULL;
216
 
    }
217
 
 
218
216
    dbdir = cfgopt(copt, "DatabaseDirectory")->strarg;
219
217
    logg("Reading databases from %s\n", dbdir);
220
218
 
236
234
        return NULL;
237
235
    }
238
236
 
239
 
    while((retval = cl_load(dbdir, &engine, &sigs, dboptions)) == CL_ELOCKDB) {
240
 
        logg("!reload db failed: %s (attempt %u/3)\n", cl_strerror(retval), attempt);
241
 
        if(++attempt > 3)
242
 
            break;
 
237
    /* release old structure */
 
238
    if(engine) {
 
239
        if(engine->pua_cats)
 
240
            if(!(pua_cats = strdup(engine->pua_cats)))
 
241
                logg("^Can't make a copy of pua_cats\n");
 
242
 
 
243
        cl_free(engine);
 
244
        engine = NULL;
 
245
    }
 
246
 
 
247
    if(pua_cats) {
 
248
        if((retval = cli_initengine(&engine, dboptions))) {
 
249
            logg("!cli_initengine() failed: %s\n", cl_strerror(retval));
 
250
            *ret = 1;
 
251
            free(pua_cats);
 
252
            return NULL;
 
253
        }
 
254
        engine->pua_cats = pua_cats;
 
255
    }
 
256
 
 
257
    if((retval = cl_load(dbdir, &engine, &sigs, dboptions))) {
 
258
        logg("!reload db failed: %s\n", cl_strerror(retval));
 
259
        *ret = 1;
 
260
        return NULL;
243
261
    }
244
262
 
245
263
    if(retval) {
272
290
        char timestr[32];
273
291
#ifndef C_WINDOWS
274
292
        struct sigaction sigact;
 
293
        sigset_t sigset;
 
294
        struct rlimit rlim;
275
295
#endif
276
296
        mode_t old_umask;
277
297
        struct cl_limits limits;
278
 
#ifndef C_WINDOWS
279
 
        sigset_t sigset;
280
 
#endif
281
298
        client_conn_t *client_conn;
282
299
        const struct cfgstruct *cpt;
283
300
#ifdef HAVE_STRERROR_R
306
323
        if((fd = fopen(cpt->strarg, "w")) == NULL) {
307
324
            logg("!Can't save PID in file %s\n", cpt->strarg);
308
325
        } else {
309
 
            fprintf(fd, "%u", (unsigned int) mainpid);
 
326
            if (fprintf(fd, "%u", (unsigned int) mainpid)<0) {
 
327
                logg("!Can't save PID in file %s\n", cpt->strarg);
 
328
            }
310
329
            fclose(fd);
311
330
        }
312
331
        umask(old_umask);
330
349
        logg("^Limits: File size limit protection disabled.\n");
331
350
    }
332
351
 
 
352
#ifndef C_WINDOWS
 
353
    if(getrlimit(RLIMIT_FSIZE, &rlim) == 0) {
 
354
        if((rlim.rlim_max < limits.maxfilesize) || (rlim.rlim_max < limits.maxscansize))
 
355
            logg("^System limit for file size is lower than maxfilesize or maxscansize\n");
 
356
    } else {
 
357
        logg("^Cannot obtain resource limits for file size\n");
 
358
    }
 
359
#endif
 
360
 
333
361
    if((limits.maxreclevel = cfgopt(copt, "MaxRecursion")->numarg)) {
334
362
        logg("Limits: Recursion level limit set to %u.\n", limits.maxreclevel);
335
363
    } else {
400
428
            options |= CL_SCAN_MAILURL;
401
429
        }
402
430
 
 
431
        if(cfgopt(copt, "ScanPartialMessages")->enabled) {
 
432
            logg("Mail: RFC1341 handling enabled.\n");
 
433
            options |= CL_SCAN_PARTIAL_MESSAGE;
 
434
        }
 
435
 
403
436
    } else {
404
437
        logg("Mail files support disabled.\n");
405
438
    }
438
471
        }
439
472
    }
440
473
 
 
474
    if(cfgopt(copt,"HeuristicScanPrecedence")->enabled) {
 
475
            options |= CL_SCAN_HEURISTIC_PRECEDENCE;
 
476
            logg("Heuristic: precedence enabled\n");
 
477
    }
 
478
 
 
479
    if(cfgopt(copt, "StructuredDataDetection")->enabled) {
 
480
        options |= CL_SCAN_STRUCTURED;
 
481
 
 
482
        limits.min_cc_count = cfgopt(copt, "StructuredMinCreditCardCount")->numarg;
 
483
        logg("Structured: Minimum Credit Card Number Count set to %u\n", limits.min_cc_count);
 
484
 
 
485
        limits.min_ssn_count = cfgopt(copt, "StructuredMinSSNCount")->numarg;
 
486
        logg("Structured: Minimum Social Security Number Count set to %u\n", limits.min_ssn_count);
 
487
 
 
488
        if(cfgopt(copt, "StructuredSSNFormatNormal")->enabled)
 
489
            options |= CL_SCAN_STRUCTURED_SSN_NORMAL;
 
490
 
 
491
        if(cfgopt(copt, "StructuredSSNFormatStripped")->enabled)
 
492
            options |= CL_SCAN_STRUCTURED_SSN_STRIPPED;
 
493
    }
 
494
 
441
495
    selfchk = cfgopt(copt, "SelfCheck")->numarg;
442
496
    if(!selfchk) {
443
497
        logg("Self checking disabled.\n");
448
502
    if(cfgopt(copt, "ClamukoScanOnAccess")->enabled)
449
503
#ifdef CLAMUKO
450
504
    {
451
 
        pthread_attr_init(&clamuko_attr);
452
 
        pthread_attr_setdetachstate(&clamuko_attr, PTHREAD_CREATE_JOINABLE);
453
 
 
454
 
        tharg = (struct thrarg *) malloc(sizeof(struct thrarg));
455
 
        tharg->copt = copt;
456
 
        tharg->engine = engine;
457
 
        tharg->limits = &limits;
458
 
        tharg->options = options;
459
 
 
460
 
        pthread_create(&clamuko_pid, &clamuko_attr, clamukoth, tharg);
 
505
        do {
 
506
            if(!pthread_attr_init(&clamuko_attr)) break;
 
507
            pthread_attr_setdetachstate(&clamuko_attr, PTHREAD_CREATE_JOINABLE);
 
508
            if(!(tharg = (struct thrarg *) malloc(sizeof(struct thrarg)))) break;
 
509
            tharg->copt = copt;
 
510
            tharg->engine = engine;
 
511
            tharg->limits = &limits;
 
512
            tharg->options = options;
 
513
            if(pthread_create(&clamuko_pid, &clamuko_attr, clamukoth, tharg)) break;
 
514
            free(tharg);
 
515
            tharg=NULL;
 
516
        } while(0);
 
517
        if (!tharg) logg("!Unable to start Clamuko\n");
461
518
    }
462
519
#else
463
520
        logg("Clamuko is not available.\n");
497
554
    sigaction(SIGUSR2, &sigact, NULL);
498
555
#endif
499
556
 
500
 
    pthread_mutex_init(&exit_mutex, NULL);
501
 
    pthread_mutex_init(&reload_mutex, NULL);
502
 
 
503
557
    idletimeout = cfgopt(copt, "IdleTimeout")->numarg;
504
558
 
505
559
    if((thr_pool=thrmgr_new(max_threads, idletimeout, scanner_thread)) == NULL) {
564
618
 
565
619
        if (!progexit && new_sd >= 0) {
566
620
                client_conn = (client_conn_t *) malloc(sizeof(struct client_conn_tag));
567
 
                client_conn->sd = new_sd;
568
 
                client_conn->options = options;
569
 
                client_conn->copt = copt;
570
 
                client_conn->engine = cl_dup(engine);
571
 
                client_conn->engine_timestamp = reloaded_time;
572
 
                client_conn->limits = &limits;
573
 
                client_conn->socketds = socketds;
574
 
                client_conn->nsockets = nsockets;
575
 
                if (!thrmgr_dispatch(thr_pool, client_conn)) {
576
 
                    close(client_conn->sd);
577
 
                    free(client_conn);
578
 
                    logg("!thread dispatch failed\n");
 
621
                if(client_conn) {
 
622
                    client_conn->sd = new_sd;
 
623
                    client_conn->options = options;
 
624
                    client_conn->copt = copt;
 
625
                    client_conn->engine = cl_dup(engine);
 
626
                    client_conn->engine_timestamp = reloaded_time;
 
627
                    client_conn->limits = &limits;
 
628
                    client_conn->socketds = socketds;
 
629
                    client_conn->nsockets = nsockets;
 
630
                    if(!thrmgr_dispatch(thr_pool, client_conn)) {
 
631
                        closesocket(client_conn->sd);
 
632
                        free(client_conn);
 
633
                        logg("!thread dispatch failed\n");
 
634
                    }
 
635
                } else {
 
636
                    logg("!Can't allocate memory for client_conn\n");
 
637
                    closesocket(new_sd);
 
638
                    if(cfgopt(copt, "ExitOnOOM")->enabled) {
 
639
                        pthread_mutex_lock(&exit_mutex);
 
640
                        progexit = 1;
 
641
                        pthread_mutex_unlock(&exit_mutex);
 
642
                    }
579
643
                }
580
644
        }
581
645
 
582
646
        pthread_mutex_lock(&exit_mutex);
583
647
        if(progexit) {
584
 
            if (new_sd >= 0) {
 
648
#ifdef C_WINDOWS
 
649
            closesocket(new_sd);
 
650
#else
 
651
            if(new_sd >= 0)
585
652
                close(new_sd);
586
 
            }
 
653
#endif
587
654
            pthread_mutex_unlock(&exit_mutex);
588
655
            break;
589
656
        }
607
674
            engine = reload_db(engine, dboptions, copt, FALSE, &ret);
608
675
            if(ret) {
609
676
                logg("Terminating because of a fatal error.\n");
 
677
#ifdef C_WINDOWS
 
678
                closesocket(new_sd);
 
679
#else
610
680
                if(new_sd >= 0)
611
681
                    close(new_sd);
 
682
#endif
612
683
                break;
613
684
            }
 
685
 
614
686
            pthread_mutex_lock(&reload_mutex);
615
687
            reload = 0;
616
688
            time(&reloaded_time);
617
689
            pthread_mutex_unlock(&reload_mutex);
618
690
#ifdef CLAMUKO
619
 
            if(cfgopt(copt, "ClamukoScanOnAccess")->enabled) {
 
691
            if(cfgopt(copt, "ClamukoScanOnAccess")->enabled && tharg) {
620
692
                logg("Stopping and restarting Clamuko.\n");
621
693
                pthread_kill(clamuko_pid, SIGUSR1);
622
694
                pthread_join(clamuko_pid, NULL);