[Pkg-clamav-commits] [SCM] Debian repository for ClamAV branch, debian/unstable, updated. debian/0.95+dfsg-1-6156-g094ec9b

Tomasz Kojm tkojm at clamav.net
Sun Apr 4 00:59:21 UTC 2010


The following commit has been merged in the debian/unstable branch:
commit 51bbedb132409170d8eeb7cc602a887648236f22
Author: Tomasz Kojm <tkojm at clamav.net>
Date:   Fri Jul 31 21:28:55 2009 +0200

    libclamav, clamd: handle file exclusion in cli_ftw() (bb#1656)

diff --git a/ChangeLog b/ChangeLog
index 52bd38c..6f820eb 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+Fri Jul 31 21:28:18 CEST 2009 (tk)
+----------------------------------
+ * libclamav, clamd: handle file exclusion in cli_ftw() (bb#1656)
+
 Fri Jul 31 15:29:36 EEST 2009 (edwin)
 -------------------------------------
  * unit_tests/check_regex.c: fix unit-test failure on Solaris
diff --git a/clamd/scanner.c b/clamd/scanner.c
index deb2c0a..b886fec 100644
--- a/clamd/scanner.c
+++ b/clamd/scanner.c
@@ -143,20 +143,6 @@ int scan_callback(struct stat *sb, char *filename, const char *msg, enum cli_ftw
 	return CL_SUCCESS;
     }
 #endif
-    if((opt = optget(scandata->opts, "ExcludePath"))->enabled) {
-      while (opt) {
-	/* TODO: perhaps multiscan should skip this check? 
-	 * This should work unless the user is doing something stupid like
-	 * MULTISCAN / */
-	if(match_regex(filename, opt->strarg) == 1) {
-	    if (type != TYPE_MULTISCAN)
-		conn_reply_single(scandata->conn, filename, "Excluded");
-	    free(filename);
-	    return CL_SUCCESS;
-	}
-	opt = (const struct optstruct *) opt->nextarg;
-      }
-    }
 
     if(sb && sb->st_size == 0) { /* empty file */
 	if (msg == scandata->toplevel_path)
@@ -247,6 +233,24 @@ int scan_callback(struct stat *sb, char *filename, const char *msg, enum cli_ftw
     return CL_SUCCESS;
 }
 
+int scan_pathchk(const char *path, struct cli_ftw_cbdata *data)
+{
+	struct scan_cb_data *scandata = data->data;
+	const struct optstruct *opt;
+
+    if((opt = optget(scandata->opts, "ExcludePath"))->enabled) {
+	while(opt) {
+	    if(match_regex(path, opt->strarg) == 1) {
+		if(scandata->type != TYPE_MULTISCAN)
+		    conn_reply_single(scandata->conn, path, "Excluded");
+		    return 1;
+	    }
+	    opt = (const struct optstruct *) opt->nextarg;
+	}
+    }
+    return 0;
+}
+
 int scanfd(const int fd, const client_conn_t *conn, unsigned long int *scanned,
 	   const struct cl_engine *engine,
 	   unsigned int options, const struct optstruct *opts, int odesc, int stream)
diff --git a/clamd/scanner.h b/clamd/scanner.h
index e87a9c4..694d6e3 100644
--- a/clamd/scanner.h
+++ b/clamd/scanner.h
@@ -51,5 +51,6 @@ struct scan_cb_data {
 int scanfd(const int fd, const client_conn_t *conn, unsigned long int *scanned, const struct cl_engine *engine, unsigned int options, const struct optstruct *opts, int odesc, int stream);
 int scanstream(int odesc, unsigned long int *scanned, const struct cl_engine *engine, unsigned int options, const struct optstruct *opts, char term);
 int scan_callback(struct stat *sb, char *filename, const char *msg, enum cli_ftw_reason reason, struct cli_ftw_cbdata *data);
+int scan_pathchk(const char *path, struct cli_ftw_cbdata *data);
 
 #endif
diff --git a/clamd/session.c b/clamd/session.c
index 3e2d623..00ec1f6 100644
--- a/clamd/session.c
+++ b/clamd/session.c
@@ -316,7 +316,7 @@ int command(client_conn_t *conn, int *virus)
 	flags |= CLI_FTW_FOLLOW_DIR_SYMLINK;
     if (optget(opts, "FollowFileSymlinks")->enabled)
 	flags |= CLI_FTW_FOLLOW_FILE_SYMLINK;
-    ret = cli_ftw(conn->filename, flags,  maxdirrec ? maxdirrec : INT_MAX, scan_callback, &data);
+    ret = cli_ftw(conn->filename, flags,  maxdirrec ? maxdirrec : INT_MAX, scan_callback, &data, scan_pathchk);
     if (ret == CL_EMEM)
 	if(optget(opts, "ExitOnOOM")->enabled)
 	    return -1;
diff --git a/clamdscan/proto.c b/clamdscan/proto.c
index fac5887..4ea827f 100644
--- a/clamdscan/proto.c
+++ b/clamdscan/proto.c
@@ -379,7 +379,7 @@ int serial_client_scan(char *file, int scantype, int *infected, int maxlevel, in
     cdata.scantype = scantype;
     data.data = &cdata;
 
-    ftw = cli_ftw(file, flags, maxlevel ? maxlevel : INT_MAX, serial_callback, &data);
+    ftw = cli_ftw(file, flags, maxlevel ? maxlevel : INT_MAX, serial_callback, &data, NULL);
     *infected += cdata.infected;
 
     if(ftw == CL_SUCCESS || ftw == CL_BREAK) {
@@ -562,7 +562,7 @@ int parallel_client_scan(char *file, int scantype, int *infected, int maxlevel,
     cdata.printok = printinfected^1;
     data.data = &cdata;
 
-    ftw = cli_ftw(file, flags, maxlevel ? maxlevel : INT_MAX, parallel_callback, &data);
+    ftw = cli_ftw(file, flags, maxlevel ? maxlevel : INT_MAX, parallel_callback, &data, NULL);
 
     if(ftw != CL_SUCCESS) {
 	*infected += cdata.infected;
diff --git a/libclamav/others.h b/libclamav/others.h
index bfbdfc4..12d4aa6 100644
--- a/libclamav/others.h
+++ b/libclamav/others.h
@@ -374,11 +374,11 @@ void cli_dbgmsg_internal(const char *str, ...);
 #endif
 
 #if HAVE_SYSCONF_SC_PAGESIZE
-static inline int cli_getpagesize() { return sysconf(_SC_PAGESIZE); }
+static inline int cli_getpagesize(void) { return sysconf(_SC_PAGESIZE); }
 #define HAVE_CLI_GETPAGESIZE 1
 #else
 #if HAVE_GETPAGESIZE
-static inline int cli_getpagesize() { return getpagesize(); }
+static inline int cli_getpagesize(void) { return getpagesize(); }
 #define HAVE_CLI_GETPAGESIZE 1
 #endif
 #endif
@@ -448,6 +448,12 @@ struct cli_ftw_cbdata {
 typedef int (*cli_ftw_cb)(struct stat *stat_buf, char *filename, const char *path, enum cli_ftw_reason reason, struct cli_ftw_cbdata *data);
 
 /*
+ * returns 1 if the path should be skipped and 0 otherwise
+ * uses callback data
+ */
+typedef int (*cli_ftw_pathchk)(const char *path, struct cli_ftw_cbdata *data);
+
+/*
  * returns 
  *  CL_SUCCESS if it traversed all files and subdirs
  *  CL_BREAK if traversal has stopped at some point
@@ -461,7 +467,7 @@ typedef int (*cli_ftw_cb)(struct stat *stat_buf, char *filename, const char *pat
  * which one it is.
  * If it is a file, it simply calls the callback once, otherwise recurses.
  */
-int cli_ftw(char *base, int flags, int maxdepth, cli_ftw_cb callback, struct cli_ftw_cbdata *data);
+int cli_ftw(char *base, int flags, int maxdepth, cli_ftw_cb callback, struct cli_ftw_cbdata *data, cli_ftw_pathchk pathchk);
 
 const char *cli_strerror(int errnum, char* buf, size_t len);
 #endif
diff --git a/libclamav/others_common.c b/libclamav/others_common.c
index 01c6fbe..fde41b8 100644
--- a/libclamav/others_common.c
+++ b/libclamav/others_common.c
@@ -496,26 +496,25 @@ static int handle_filetype(const char *fname, int flags,
     return CL_SUCCESS;
 }
 
-static int cli_ftw_dir(const char *dirname, int flags, int maxdepth, cli_ftw_cb callback, struct cli_ftw_cbdata *data);
-static int handle_entry(struct dirent_data *entry, int flags, int maxdepth, cli_ftw_cb callback, struct cli_ftw_cbdata *data)
+static int cli_ftw_dir(const char *dirname, int flags, int maxdepth, cli_ftw_cb callback, struct cli_ftw_cbdata *data, cli_ftw_pathchk pathchk);
+static int handle_entry(struct dirent_data *entry, int flags, int maxdepth, cli_ftw_cb callback, struct cli_ftw_cbdata *data, cli_ftw_pathchk pathchk)
 {
     if (!entry->is_dir) {
 	return callback(entry->statbuf, entry->filename, entry->filename, visit_file, data);
     } else {
-	return cli_ftw_dir(entry->dirname, flags, maxdepth, callback, data);
+	return cli_ftw_dir(entry->dirname, flags, maxdepth, callback, data, pathchk);
     }
 }
 
-int cli_ftw(char *path, int flags, int maxdepth, cli_ftw_cb callback, struct cli_ftw_cbdata *data)
+int cli_ftw(char *path, int flags, int maxdepth, cli_ftw_cb callback, struct cli_ftw_cbdata *data, cli_ftw_pathchk pathchk)
 {
     struct stat statbuf;
     enum filetype ft = ft_unknown;
     struct dirent_data entry;
     int stated = 0;
-
     int ret;
 
-    if ((flags & CLI_FTW_TRIM_SLASHES) && path[0] && path[1]) {
+    if (((flags & CLI_FTW_TRIM_SLASHES) || pathchk) && path[0] && path[1]) {
 	char *pathend;
 	/* trim slashes so that dir and dir/ behave the same when
 	 * they are symlinks, and we are not following symlinks */
@@ -524,6 +523,8 @@ int cli_ftw(char *path, int flags, int maxdepth, cli_ftw_cb callback, struct cli
 	while (pathend > path && pathend[-1] == '/') --pathend;
 	*pathend = '\0';
     }
+    if(pathchk && pathchk(path, data) == 1)
+	return CL_SUCCESS;
     ret = handle_filetype(path, flags, &statbuf, &stated, &ft, callback, data);
     if (ret != CL_SUCCESS)
 	return ret;
@@ -538,10 +539,10 @@ int cli_ftw(char *path, int flags, int maxdepth, cli_ftw_cb callback, struct cli
 	if (ret != CL_SUCCESS)
 	    return ret;
     }
-    return handle_entry(&entry, flags, maxdepth, callback, data);
+    return handle_entry(&entry, flags, maxdepth, callback, data, pathchk);
 }
 
-static int cli_ftw_dir(const char *dirname, int flags, int maxdepth, cli_ftw_cb callback, struct cli_ftw_cbdata *data)
+static int cli_ftw_dir(const char *dirname, int flags, int maxdepth, cli_ftw_cb callback, struct cli_ftw_cbdata *data, cli_ftw_pathchk pathchk)
 {
     DIR *dd;
 #if defined(HAVE_READDIR_R_3) || defined(HAVE_READDIR_R_2)
@@ -617,6 +618,11 @@ static int cli_ftw_dir(const char *dirname, int flags, int maxdepth, cli_ftw_cb
 	    else
 		sprintf(fname, "%s/%s", dirname, dent->d_name);
 
+	    if(pathchk && pathchk(fname, data) == 1) {
+		free(fname);
+		continue;
+	    }
+
 	    ret = handle_filetype(fname, flags, &statbuf, &stated, &ft, callback, data);
 	    if (ret != CL_SUCCESS) {
 		free(fname);
@@ -674,7 +680,7 @@ static int cli_ftw_dir(const char *dirname, int flags, int maxdepth, cli_ftw_cb
 	    qsort(entries, entries_cnt, sizeof(*entries), ftw_compare);
 	    for (i = 0; i < entries_cnt; i++) {
 		struct dirent_data *entry = &entries[i];
-		ret = handle_entry(entry, flags, maxdepth-1, callback, data);
+		ret = handle_entry(entry, flags, maxdepth-1, callback, data, pathchk);
 		if (entry->is_dir)
 		    free(entry->filename);
 		if (entry->statbuf)

-- 
Debian repository for ClamAV



More information about the Pkg-clamav-commits mailing list