clamonacc - cleanup; add additional logging; fix issue where consumer queue would fall behind and burn through allowed open fds; update copyrights; cleanup error handling; re-enable extra scanning

pull/111/head
Mickey Sola 6 years ago committed by Micah Snyder
parent 3941428bbb
commit 7ad7211e1a
  1. 40
      clamonacc/client/onaccess_client.c
  2. 4
      clamonacc/client/onaccess_com.c
  3. 4
      clamonacc/client/onaccess_com.h
  4. 57
      clamonacc/client/onaccess_proto.c
  5. 18
      clamonacc/fanotif/onaccess_fan.c
  6. 11
      clamonacc/fanotif/onaccess_fan.h
  7. 116
      clamonacc/inotif/onaccess_ddd.c
  8. 33
      clamonacc/inotif/onaccess_hash.c
  9. 70
      clamonacc/misc/onaccess_others.c
  10. 4
      clamonacc/misc/onaccess_others.h
  11. 4
      clamonacc/scan/onaccess_scque.c
  12. 41
      clamonacc/scan/onaccess_scth.c

@ -23,7 +23,7 @@
#include "clamav-config.h"
#endif
#define ONAS_DEBUG
//#define ONAS_DEBUG
#include <stdio.h>
#include <stdlib.h>
@ -140,7 +140,7 @@ int onas_check_remote(struct onas_context **ctx, cl_error_t *err) {
}
#ifndef ONAS_DEBUG
if(onas_sendln(curl, "zPING", 5)) {
if(onas_sendln(curl, "zPING", 5, timeout)) {
logg("!ClamClient: could not ping clamd, %s\n", curl_easy_strerror(curlcode));
*err = CL_EARG;
curl_easy_cleanup(curl);
@ -316,37 +316,6 @@ cl_error_t onas_setup_client (struct onas_context **ctx) {
return CL_SUCCESS;
}
/* Turns a relative path into an absolute one
* Returns a pointer to the path (which must be
* freed by the caller) or NULL on error */
static char *onas_make_absolute(const char *basepath) {
int namelen;
char *ret;
if(!(ret = malloc(PATH_MAX + 1))) {
logg("^ClamClient: can't make room for fullpath\n");
return NULL;
}
if(!cli_is_abspath(basepath)) {
if(!getcwd(ret, PATH_MAX)) {
logg("^ClamClient: can't get absolute pathname of current working directory.\n");
free(ret);
return NULL;
}
if(*basepath == '\\') {
namelen = 2;
basepath++;
} else {
namelen = strlen(ret);
}
snprintf(&ret[namelen], PATH_MAX - namelen, PATHSEP"%s", basepath);
} else {
strncpy(ret, basepath, PATH_MAX);
}
ret[PATH_MAX] = '\0';
return ret;
}
int onas_get_clamd_version(struct onas_context **ctx)
{
char *buff;
@ -424,13 +393,10 @@ int onas_client_scan(const char *tcpaddr, int64_t portnum, int32_t scantype, uin
curlcode = onas_curl_init(&curl, tcpaddr, portnum, timeout);
if (CURLE_OK != curlcode) {
logg("!ClamClient: could not init curl for scanning, %s\n", curl_easy_strerror(curlcode));
logg("*DEBUG: addr : %s\tportnum : %d\n", tcpaddr, portnum);
/* curl cleanup done in onas_curl_init on error */
return CL_ECREAT;
}
/* logg here is noisy even for debug, enable only for dev work if something has gone very wrong. */
//logg("*ClamClient: connecting to daemon ...\n");
curlcode = curl_easy_perform(curl);
if (CURLE_OK != curlcode) {
logg("!ClamClient: could not establish connection, %s\n", curl_easy_strerror(curlcode));
@ -444,8 +410,6 @@ int onas_client_scan(const char *tcpaddr, int64_t portnum, int32_t scantype, uin
logg("*ClamClient: connection could not be established ... return code %d\n", *ret_code);
errors = 1;
}
/* logg here is noisy even for debug, enable only for dev work if something has gone very wrong. */
//logg("*ClamClient: done, closing connection ...\n");
curl_easy_cleanup(curl);
return *infected ? CL_VIRUS : (errors ? CL_ECREAT : CL_CLEAN);

@ -2,7 +2,7 @@
* Copyright (C) 2015 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
* Copyright (C) 2009-2010 Sourcefire, Inc.
*
* Author: aCaB
* Author: aCaB, Mickey Sola
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@ -208,7 +208,7 @@ int onas_recvln(struct RCVLN *rcv_data, char **ret_bol, char **ret_eol, int64_t
}
if (!eol) {
if(rcv_data->buf != rcv_data->lnstart) { /* old memmove sux */
if(rcv_data->buf != rcv_data->lnstart) {
memmove(rcv_data->buf, rcv_data->lnstart, rcv_data->retlen);
rcv_data->lnstart = rcv_data->buf;
}

@ -2,7 +2,7 @@
* Copyright (C) 2015 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
* Copyright (C) 2009-2010 Sourcefire, Inc.
*
* Author: aCaB
* Author: aCaB, Mickey Sola
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@ -33,7 +33,7 @@
#include "shared/misc.h"
struct RCVLN {
char buf[PATH_MAX+1024]; /* FIXME must match that in clamd - bb1349 */
char buf[PATH_MAX+1024];
CURL *curl;
CURLcode curlcode;
size_t retlen;

@ -2,7 +2,7 @@
* Copyright (C) 2015 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
* Copyright (C) 2009 Sourcefire, Inc.
*
* Authors: Tomasz Kojm, aCaB
* Authors: Tomasz Kojm, aCaB, Mickey Sola
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@ -54,7 +54,6 @@
#endif
#include "libclamav/clamav.h"
//#include "libclamav/others.h"
#include "shared/actions.h"
#include "shared/output.h"
#include "shared/misc.h"
@ -63,12 +62,6 @@
#include "onaccess_proto.h"
#include "onaccess_client.h"
//#include "../clamonacc.h"
#ifndef _WIN32
extern struct sockaddr_un nixsock;
#endif
static const char *scancmd[] = { "CONTSCAN", "MULTISCAN", "INSTREAM", "FILDES", "ALLMATCHSCAN" };
/* Issues an INSTREAM command to clamd and streams the given file
@ -77,6 +70,7 @@ static int onas_send_stream(CURL *curl, const char *filename, int fd, int64_t ti
uint32_t buf[BUFSIZ/sizeof(uint32_t)];
uint64_t len;
uint64_t todo = maxstream;
int ret = 1;
int close_flag = 0;
if (0 == fd) {
@ -85,27 +79,25 @@ static int onas_send_stream(CURL *curl, const char *filename, int fd, int64_t ti
logg("~%s: Access denied. ERROR\n", filename);
return 0;
}
//logg("DEBUG: >>>>> fd is %d\n", fd);
close_flag = 1;
} else {
fd = 0;
}
}
if(onas_sendln(curl, "zINSTREAM", 10, timeout)) {
if (close_flag) {
close(fd);
}
return -1;
ret = -1;
goto strm_out;
}
while((len = read(fd, &buf[1], sizeof(buf) - sizeof(uint32_t))) > 0) {
if((uint64_t)len > todo) len = todo;
buf[0] = htonl(len);
if (onas_sendln(curl, (const char *)buf, len+sizeof(uint32_t), timeout)) {
if (close_flag) {
close(fd);
}
return -1;
ret = -1;
goto strm_out;
}
todo -= len;
if(!todo) {
@ -113,16 +105,21 @@ static int onas_send_stream(CURL *curl, const char *filename, int fd, int64_t ti
break;
}
}
if (close_flag) {
close(fd);
}
if(len) {
logg("!Failed to read from %s.\n", filename ? filename : "STDIN");
return 0;
ret = 0;
goto strm_out;
}
*buf=0;
onas_sendln(curl, (const char *)buf, 4, timeout);
return 1;
strm_out:
if (close_flag) {
//logg("DEBUG: >>>>> closed fd %d\n", fd);
close(fd);
}
return ret;
}
#ifdef HAVE_FD_PASSING
@ -135,6 +132,7 @@ static int onas_send_fdpass(CURL *curl, const char *filename, int fd, int64_t ti
struct cmsghdr *cmsg;
unsigned char fdbuf[CMSG_SPACE(sizeof(int))];
char dummy[]="";
int ret = 1;
int close_flag = 0;
if (0 == fd) {
@ -150,10 +148,8 @@ static int onas_send_fdpass(CURL *curl, const char *filename, int fd, int64_t ti
}
if(result = onas_sendln(curl, "zFILDES", 8, timeout)) {
logg("*ClamProto: error sending w/ curl, %s\n", curl_easy_strerror(result));
if (close_flag) {
close(fd);
}
return -1;
ret = -1;
goto fd_out;
}
iov[0].iov_base = dummy;
@ -170,15 +166,14 @@ static int onas_send_fdpass(CURL *curl, const char *filename, int fd, int64_t ti
*(int *)CMSG_DATA(cmsg) = fd;
if(onas_sendln(curl, &msg, 0, timeout) == -1) {
logg("!FD send failed: %s\n", strerror(errno));
if (close_flag) {
close(fd);
}
return -1;
ret = -1;
goto fd_out;
}
fd_out:
if (close_flag) {
close(fd);
}
return 1;
return ret;
}
#endif
@ -328,7 +323,7 @@ int onas_dsresult(CURL *curl, int scantype, uint64_t maxstream, const char *file
*printok = 0;
if(filename) {
(scantype >= STREAM) ? logg("*%s%s\n", filename, colon) : logg("*burp %s\n", bol);
(scantype >= STREAM) ? logg("*%s%s\n", filename, colon) : logg("*%s\n", bol);
}
if (ret_code) {

@ -1,8 +1,7 @@
/*
* Copyright (C) 2013-2019 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
* Copyright (C) 2011-2013 Sourcefire, Inc.
* Copyright (C) 2019 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
*
* Authors: Tomasz Kojm, Mickey Sola
* Authors: Mickey Sola
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@ -85,7 +84,7 @@ cl_error_t onas_setup_fanotif(struct onas_context **ctx) {
short int scan;
unsigned int sizelimit = 0, extinfo;
int onas_fan_fd;
uint64_t fan_mask = FAN_EVENT_ON_CHILD | FAN_CLOSE;
uint64_t fan_mask = FAN_EVENT_ON_CHILD;
char err[128];
pthread_attr_t ddd_attr;
@ -182,7 +181,7 @@ int onas_fan_eloop(struct onas_context **ctx) {
} while((ret == -1 && errno == EINTR));
time_t start = time(NULL) - 30;
while(((bread = read((*ctx)->fan_fd, buf, sizeof(buf))) > 0) || errno == EOVERFLOW) {
while(((bread = read((*ctx)->fan_fd, buf, sizeof(buf))) > 0) || (errno == EOVERFLOW || errno == EMFILE)) {
if (errno == EOVERFLOW) {
if (time(NULL) - start >= 30) {
@ -195,6 +194,15 @@ int onas_fan_eloop(struct onas_context **ctx) {
continue;
}
if (errno == EMFILE) {
logg("*ClamFanotif: internal error (failed to read data) ... %s\n", strerror(errno));
logg("*ClamFanotif: waiting for consumer thread to catch up then retrying ...\n");
errno = 0;
sleep(3);
continue;
}
fmd = (struct fanotify_event_metadata *)buf;
while (FAN_EVENT_OK(fmd, bread)) {
scan = 1;

@ -1,8 +1,7 @@
/*
* Copyright (C) 2013-2019 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
* Copyright (C) 2011-2013 Sourcefire, Inc.
* Copyright (C) 2019 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
*
* Authors: Tomasz Kojm
* Authors: Mickey Sola
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@ -19,13 +18,13 @@
* MA 02110-1301, USA.
*/
#ifndef __FAN_H
#define __FAN_H
#ifndef __ONAS_FAN_H
#define __ONAS_FAN_H
#include "../clamonacc.h"
#include "libclamav/clamav.h"
void *onas_fan_th(void *arg);
//void *onas_fan_th(void *arg);
cl_error_t onas_setup_fanotif(struct onas_context **ctx);
int onas_fan_eloop(struct onas_context **ctx);

@ -1,5 +1,5 @@
/*
* Copyright (C) 2015-2019 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
* Copyright (C) 2019 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
*
* Authors: Mickey Sola
*
@ -44,6 +44,7 @@
#include "onaccess_hash.h"
#include "onaccess_ddd.h"
#include "../scan/onaccess_scth.h"
#include "../scan/onaccess_scque.h"
#include "../misc/onaccess_others.h"
#include "libclamav/clamav.h"
@ -56,6 +57,8 @@
#include "clamd/others.h"
#include "clamd/scanner.h"
static int onas_ddd_init_ht(uint32_t ht_size);
static int onas_ddd_init_wdlt(uint64_t nwatches);
static int onas_ddd_grow_wdlt();
@ -69,7 +72,7 @@ static void onas_ddd_handle_in_moved_to(struct onas_context *ctx, const char *pa
static void onas_ddd_handle_in_create(struct onas_context *ctx, const char *path, const char *child_path, const struct inotify_event *event, int wd, uint64_t in_mask);
static void onas_ddd_handle_in_moved_from(struct onas_context *ctx, const char *path, const char *child_path, const struct inotify_event *event, int wd);
static void onas_ddd_handle_in_delete(struct onas_context *ctx, const char *path, const char *child_path, const struct inotify_event *event, int wd);
/*static void onas_ddd_handle_extra_scanning(struct onas_context *ctx, const char *pathname, int extra_options);*/
static void onas_ddd_handle_extra_scanning(struct onas_context *ctx, const char *pathname, int extra_options);
static void onas_ddd_exit(int sig);
@ -425,7 +428,6 @@ void *onas_ddd_th(void *arg) {
idx++;
}
}
/* Remove provided paths recursively. */
@ -457,7 +459,7 @@ void *onas_ddd_th(void *arg) {
idx = 0;
while (exclude_list[idx] != NULL) {
if(onas_ht_get(ddd_ht, exclude_list[idx], strlen(exclude_list[idx]), NULL) != CL_SUCCESS) {
if(onas_ht_add_hierarchy(ddd_ht, exclude_list[idx])) {
if(onas_ht_rm_hierarchy(ddd_ht, exclude_list[idx], strlen(exclude_list[idx]), 0)){
logg("!ClamInotif: can't exclude '%s'\n", exclude_list[idx]);
return NULL;
} else {
@ -467,7 +469,6 @@ void *onas_ddd_th(void *arg) {
idx++;
}
}
/* Watch provided paths recursively */
@ -492,7 +493,8 @@ void *onas_ddd_th(void *arg) {
logg("*ClamInotif: you likely do not have enough inotify watchpoints available ... run the follow command to increase available watchpoints and try again ...\n");
logg("*\t $ echo fs.inotify.max_user_watches=524288 | sudo tee -a /etc/sysctl.conf && sudo sysctl -p\n");
kill(getpid(), SIGTERM); }
kill(getpid(), SIGTERM);
}
}
}
pt = (struct optstruct *)pt->nextarg;
@ -530,12 +532,9 @@ void *onas_ddd_th(void *arg) {
}
}
/* TODO: Re-enable OnAccessExtraScanning once the thread resource consumption issue is resolved. */
#if 0
if(optget(ctx->clamdopts, "OnAccessExtraScanning")->enabled) {
logg("ClamInotif: Extra scanning and notifications enabled.\n");
logg("ClamInotif: extra scanning on inotify events enabled\n");
}
#endif
FD_ZERO(&rfds);
FD_SET(onas_in_fd, &rfds);
@ -559,16 +558,24 @@ void *onas_ddd_th(void *arg) {
path = wdlt[wd];
child = event->name;
if (path == NULL) {
logg("*ClamInotif: watch descriptor not found in lookup table ... skipping\n");
continue;
}
len = strlen(path);
size_t size = strlen(child) + len + 2;
char *child_path = (char *)cli_malloc(size);
if (child_path == NULL)
if (child_path == NULL) {
logg("*ClamInotif: could not allocate space for child path ... aborting\n");
return NULL;
}
if (path[len - 1] == '/')
if (path[len-1] == '/') {
snprintf(child_path, --size, "%s%s", path, child);
else
} else {
snprintf(child_path, size, "%s/%s", path, child);
}
if (event->mask & IN_DELETE) {
onas_ddd_handle_in_delete(ctx, path, child_path, event, wd);
@ -624,22 +631,19 @@ static void onas_ddd_handle_in_create(struct onas_context *ctx,
struct stat s;
/* TODO: Re-enable OnAccessExtraScanning once the thread resource consumption issue is resolved. */
#if 0
if (optget(ctx->clamdopts, "OnAccessExtraScanning")->enabled) {
if(stat(child_path, &s) == 0 && S_ISREG(s.st_mode)) {
onas_ddd_handle_extra_scanning(ctx, child_path, ONAS_SCTH_ISFILE);
onas_ddd_handle_extra_scanning(ctx, child_path, ONAS_SCTH_B_FILE);
} else if(stat(child_path, &s) == 0 && S_ISDIR(s.st_mode)) {
} else if(event->mask & IN_ISDIR) {
logg("*ClamInotif: CREATE - Adding %s to %s with wd:%d\n", child_path, path, wd);
onas_ddd_handle_extra_scanning(ctx, child_path, ONAS_SCTH_B_DIR);
onas_ht_add_hierarchy(ddd_ht, child_path);
onas_ddd_watch(child_path, ctx->fan_fd, ctx->fan_mask, onas_in_fd, in_mask);
onas_ddd_handle_extra_scanning(ctx, child_path, ONAS_SCTH_ISDIR);
}
}
else
#endif
{
if (stat(child_path, &s) == 0 && S_ISREG(s.st_mode)) return;
if (!(event->mask & IN_ISDIR)) return;
@ -656,23 +660,19 @@ static void onas_ddd_handle_in_moved_to(struct onas_context *ctx,
const char *path, const char *child_path, const struct inotify_event *event, int wd, uint64_t in_mask) {
struct stat s;
/* TODO: Re-enable OnAccessExtraScanning once the thread resource consumption issue is resolved. */
#if 0
if (optget(ctx->clamdopts, "OnAccessExtraScanning")->enabled) {
if(stat(child_path, &s) == 0 && S_ISREG(s.st_mode)) {
onas_ddd_handle_extra_scanning(ctx, child_path, ONAS_SCTH_ISFILE);
onas_ddd_handle_extra_scanning(ctx, child_path, ONAS_SCTH_B_FILE);
} else if(stat(child_path, &s) == 0 && S_ISDIR(s.st_mode)) {
} else if(event->mask & IN_ISDIR) {
logg("*ClamInotif: MOVED_TO - Adding %s to %s with wd:%d\n", child_path, path, wd);
onas_ddd_handle_extra_scanning(ctx, child_path, ONAS_SCTH_B_DIR);
onas_ht_add_hierarchy(ddd_ht, child_path);
onas_ddd_watch(child_path, ctx->fan_fd, ctx->fan_mask, onas_in_fd, in_mask);
onas_ddd_handle_extra_scanning(ctx, child_path, ONAS_SCTH_ISDIR);
}
}
else
#endif
{
} else {
if (stat(child_path, &s) == 0 && S_ISREG(s.st_mode)) return;
if (!(event->mask & IN_ISDIR)) return;
@ -684,49 +684,35 @@ static void onas_ddd_handle_in_moved_to(struct onas_context *ctx,
return;
}
/* TODO: rework this to use consumer queue when making multithreading changes */
/*static void onas_ddd_handle_extra_scanning(struct onas_context *ctx, const char *pathname, int extra_options) {
int thread_started = 1;
struct scth_thrarg *scth_tharg = NULL;
pthread_attr_t scth_attr;
pthread_t scth_pid = 0;
do {
if (pthread_attr_init(&scth_attr)) break;
pthread_attr_setdetachstate(&scth_attr, PTHREAD_CREATE_JOINABLE);*/
static void onas_ddd_handle_extra_scanning(struct onas_context *ctx, const char *pathname, int extra_options) {
/* Allocate memory for arguments. Thread is responsible for freeing it. */
/* (!(scth_tharg = (struct scth_thrarg *) calloc(sizeof(struct scth_thrarg), 1))) break;
if (!(scth_tharg->options = (struct cl_scan_options *)calloc(sizeof(struct cl_scan_options), 1))) break;
struct onas_scan_event *event_data;
scth_tharg->extra_options = extra_options;
scth_tharg->opts = ctx->clamdopts;
scth_tharg->pathname = strdup(pathname);
thread_started = pthread_create(&scth_pid, &scth_attr, onas_scan_th, scth_tharg);
} while (0);
event_data = (struct onas_scan_event *) cli_calloc(1, sizeof(struct onas_scan_event));
if (NULL == event_data) {
logg("!ClamInotif: could not allocate memory for event data struct\n");
}
if (0 != thread_started) {*/
/* Failed to create thread. Free anything we may have allocated. */
/*logg("!ClamInotif: Unable to kick off extra scanning.\n");
if (NULL != scth_tharg) {
if (NULL != scth_tharg->pathname) {
free(scth_tharg->pathname);
scth_tharg->pathname = NULL;
}
if (NULL != scth_tharg->options) {
free(scth_tharg->options);
scth_tharg->options = NULL;
}
free(scth_tharg);
scth_tharg = NULL;
}
/* general mapping */
onas_map_context_info_to_event_data(ctx, &event_data);
event_data->pathname = cli_strdup(pathname);
event_data->bool_opts |= ONAS_SCTH_B_SCAN;
/* inotify specific stuffs */
event_data->bool_opts |= ONAS_SCTH_B_INOTIFY;
extra_options & ONAS_SCTH_B_FILE ? event_data->bool_opts |= ONAS_SCTH_B_FILE : extra_options;
extra_options & ONAS_SCTH_B_DIR ? event_data->bool_opts |= ONAS_SCTH_B_DIR : extra_options;
logg("*ClamInotif: attempting to feed consumer queue\n");
/* feed consumer queue */
if (CL_SUCCESS != onas_queue_event(event_data)) {
logg("!ClamInotif: error occurred while feeding consumer queue extra event ... continuing ...\n");
return;
}
return;
}*/
}
static void onas_ddd_exit(int sig) {
logg("*ClamInotif: onas_ddd_exit(), signal %d\n", sig);

@ -588,6 +588,7 @@ int onas_ht_add_hierarchy(struct onas_ht *ht, const char *pathname)
{
if (!ht || !pathname) return CL_ENULLARG;
int ret = 0;
FTS *ftsp = NULL;
int ftspopts = FTS_PHYSICAL | FTS_XDEV;
FTSENT *curr = NULL;
@ -601,7 +602,8 @@ int onas_ht_add_hierarchy(struct onas_ht *ht, const char *pathname)
char *const pathargv[] = {(char *)pathname, NULL};
if (!(ftsp = _priv_fts_open(pathargv, ftspopts, NULL))) {
logg("!ClamHash: could not open '%s'\n", pathname);
return CL_EARG;
ret = CL_EARG;
goto out;
}
while ((curr = _priv_fts_read(ftsp))) {
@ -612,7 +614,10 @@ int onas_ht_add_hierarchy(struct onas_ht *ht, const char *pathname)
switch (curr->fts_info) {
case FTS_D:
hnode = onas_hashnode_init();
if (!hnode) return CL_EMEM;
if (!hnode) {
ret = CL_EMEM;
goto out;
}
hnode->pathlen = curr->fts_pathlen;
hnode->pathname = cli_strndup(curr->fts_path, hnode->pathlen);
@ -631,8 +636,10 @@ int onas_ht_add_hierarchy(struct onas_ht *ht, const char *pathname)
do {
if (childlist->fts_info == FTS_D) {
if (CL_EMEM == onas_add_hashnode_child(hnode, childlist->fts_name)) {
onas_free_hashnode(hnode);
return CL_EMEM;
ret = CL_EMEM;
goto out;
}
}
}
@ -640,15 +647,27 @@ int onas_ht_add_hierarchy(struct onas_ht *ht, const char *pathname)
}
struct onas_element *elem = onas_element_init(hnode, hnode->pathname, hnode->pathlen);
if (!elem) return CL_EMEM;
if (!elem) {
ret = CL_EMEM;
goto out;
}
if (onas_ht_insert(ht, elem)) {
onas_free_element(elem);
return CL_EMEM;
ret = -1;
goto out;
}
}
out:
if (ftsp) {
_priv_fts_close(ftsp);
}
if (ret) {
return ret;
}
return CL_SUCCESS;
}

@ -1,5 +1,5 @@
/*
* Copyright (C) 2017-2019 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
* Copyright (C) 2019 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
*
* Authors: Mickey Sola
*
@ -28,19 +28,12 @@
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
//#include <fcntl.h>
#include <sys/stat.h>
#include <errno.h>
#include <pthread.h>
//#include <limits.h>
#include "libclamav/clamav.h"
//#include "libclamav/scanners.h"
#include "shared/optparser.h"
#include "shared/output.h"
//#include "shared/misc.h"
//#include "libclamav/others.h"
//#include "others.h"
#include "onaccess_others.h"
#include "clamd/scanner.h"
@ -86,7 +79,7 @@ int onas_fan_checkowner(int pid, const struct optstruct *opts)
} else if (errno == EACCES) {
logg("*Permission denied to stat /proc/%d to exclude UIDs... perhaps SELinux denial?\n", pid);
} else if (errno == ENOENT) {
/* FIXME: should this be configurable? */
/* TODO: should this be configurable? */
logg("$/proc/%d vanished before UIDs could be excluded; scanning anyway\n", pid);
}
@ -94,65 +87,6 @@ int onas_fan_checkowner(int pid, const struct optstruct *opts)
}
#endif
/**
* Thread-safe scan wrapper to ensure there's no processs contention over use of the socket.
*/
/* TODO: remove this
* int onas_scan(struct onas_context **ctx, const char *fname, STATBUF sb, int *infected, int *err, cl_error_t *ret_code)
{
int ret = 0;
int i = 0;
ret = onas_scan_safe(ctx, fname, sb, infected, err, ret_code);
if (*err) {
switch (*ret_code) {
case CL_EACCES:
case CL_ESTAT:
logg("*ClamMisc: internal issue (daemon could not access directory/file %s)\n", fname);
break;
case CL_EPARSE:
case CL_EREAD:
case CL_EWRITE:
case CL_EMEM:
case CL_ENULLARG:
default:
logg("~ClamMisc: internal issue (client failed to scan)\n");
}
if ((*ctx)->retry_on_error) {
logg("*ClamMisc: reattempting scan ... \n");
while (err) {
ret = onas_scan_safe(ctx, fname, sb, infected, err, ret_code);
i++;
if (*err && i == (*ctx)->retry_attempts) {
*err = 0;
}
}
}
}
return ret;
}*/
/**
* Thread-safe scan wrapper to ensure there's no processs contention over use of the socket.
*/
/* TODO: remove this
* int onas_scan_safe(struct onas_context **ctx, const char *fname, STATBUF sb, int *infected, int *err, cl_error_t *ret_code)
{
int ret = 0;
pthread_mutex_lock(&onas_scan_lock);
ret = onas_client_scan(ctx, fname, sb, infected, err, ret_code);
pthread_mutex_unlock(&onas_scan_lock);
return ret;
}*/
char **onas_get_opt_list(const char *fname, int *num_entries, cl_error_t *err)
{

@ -1,5 +1,5 @@
/*
* Copyright (C) 2017-2019 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
* Copyright (C) 2019 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
*
* Authors: Mickey Sola
*
@ -32,8 +32,6 @@ typedef enum {
} cli_check_t;
int onas_fan_checkowner(int pid, const struct optstruct *opts);
//int onas_scan(struct onas_context **ctx, const char *fname, STATBUF sb, int *infected, int *err, cl_error_t *ret_code);
//int onas_scan_safe(struct onas_context **ctx, const char *fname, STATBUF sb, int *infected, int *err, cl_error_t *ret_code);
char **onas_get_opt_list(const char *fname, int *num_entries, cl_error_t *err);
void free_opt_list(char** opt_list, int entries);

@ -175,7 +175,7 @@ void *onas_scanque_th(void *arg) {
/* if there's no event to consume ... */
if (!onas_consume_event(thpool)) {
/* sleep for a bit */
usleep(500);
usleep(1000);
}
} while(1);
@ -196,7 +196,6 @@ static int onas_consume_event(threadpool thpool) {
struct onas_event_queue_node *popped_node = g_onas_event_queue_head->next;
/* TODO: create scth arg using head event data, use get queue head here before lock*/
if (onas_queue_is_b_empty()) {
pthread_mutex_unlock(&onas_queue_lock);
return 1;
@ -273,7 +272,6 @@ static void onas_scanque_exit(int sig) {
logg("*ClamScanque: onas_scanque_exit(), signal %d\n", sig);
/* TODO: cleanup queue struct */
onas_destroy_event_queue();
thpool_destroy(g_thpool);

@ -142,7 +142,7 @@ static cl_error_t onas_scth_scanfile(struct onas_scan_event *event_data, const c
uint8_t b_deny_on_error;
if (NULL == event_data || NULL == fname || NULL == infected || NULL == err || NULL == ret_code) {
/* TODO: log */
logg("!ClamWorker: scan failed (NULL arg given)\n");
return CL_ENULLARG;
}
@ -162,12 +162,13 @@ static cl_error_t onas_scth_scanfile(struct onas_scan_event *event_data, const c
logg("*ClamWorker: scan failed with error code %d\n", *ret_code);
}
if (b_fanotify) {
if ((*err && *ret_code && b_deny_on_error) || *infected) {
res.response = FAN_DENY;
}
}
} else {
logg("DEBUG: NOT SCANNING\n");
}
@ -201,7 +202,7 @@ static cl_error_t onas_scth_scanfile(struct onas_scan_event *event_data, const c
static cl_error_t onas_scth_handle_dir(struct onas_scan_event *event_data, const char *pathname) {
FTS *ftsp = NULL;
int32_t ftspopts = FTS_PHYSICAL | FTS_XDEV;
int32_t ftspopts = FTS_NOCHDIR | FTS_PHYSICAL | FTS_XDEV;
FTSENT *curr = NULL;
int32_t infected = 0;
@ -215,9 +216,13 @@ static cl_error_t onas_scth_handle_dir(struct onas_scan_event *event_data, const
char *const pathargv[] = {(char *)pathname, NULL};
if (!(ftsp = _priv_fts_open(pathargv, ftspopts, NULL))) {
return CL_EOPEN;
ret = CL_EOPEN;
goto out;
}
logg("*ClamWorker: should never be here again!!!!!!!!!!!!\n");
while ((curr = _priv_fts_read(ftsp))) {
if (curr->fts_info != FTS_D) {
@ -227,16 +232,20 @@ static cl_error_t onas_scth_handle_dir(struct onas_scan_event *event_data, const
if (fres != 0 || sb.st_size > event_data->sizelimit) {
/* okay to skip w/o allow/deny since dir comes from inotify
* events and (probably) won't block w/ protection enabled */
// TODO: log here later ??
continue;
event_data->bool_opts &= ((uint16_t) ~ONAS_SCTH_B_SCAN);
logg("*ClamWorker: size limit surpassed while doing extra scanning ... skipping object ...\n");
}
}
ret = onas_scth_scanfile(event_data, curr->fts_path, sb, &infected, &err, &ret_code);
// TODO: probs need to error check here later, or at least log
}
}
out:
if(ftsp) {
_priv_fts_close(ftsp);
}
return ret;
}
@ -265,6 +274,10 @@ static cl_error_t onas_scth_handle_file(struct onas_scan_event *event_data, cons
ret = onas_scth_scanfile(event_data, pathname, sb, &infected, &err, &ret_code);
// probs need to error check here later, or at least log
if (event_data->bool_opts | ONAS_SCTH_B_INOTIFY) {
logg(">>>>>>DEBUG: ClamWorker: Inotify Scan Rsults ... ret = %d ; infected = %d ; err = %d ret_code = %d\n",
ret, infected, err, ret_code);
}
return ret;
}
@ -299,20 +312,26 @@ void *onas_scan_worker(void *arg) {
if (b_dir) {
logg("*ClamWorker: performing (extra) scanning on directory '%s'\n", event_data->pathname);
onas_scth_handle_dir(event_data, event_data->pathname);
} else if (b_file) {
logg("*ClamWorker: performing (extra) scanning on file '%s'\n", event_data->pathname);
onas_scth_handle_file(event_data, event_data->pathname);
}
} else if (b_fanotify) {
logg("*ClamWorker: performing scanning on file '%s'\n", event_data->pathname);
onas_scth_handle_file(event_data, event_data->pathname);
} else {
/* something went very wrong, so check if we have an open fd,
* try to close it to resolve any potential lingering permissions event,
* then move to cleanup */
if (event_data->fmd) {
if (event_data->fmd->fd) {
close(event_data->fmd->fd);
goto done;
}
}
}
/* TODO: else something went wrong and we should probably error out here, maybe try to recover somehow */
done:
/* our job to cleanup event data: worker queue just kicks us off in a thread pool, drops the event object
* from the queue and forgets about us */

Loading…
Cancel
Save