bb12238 - Removing support for deprecated readdir_r() function. The readdir() function is thread safe so long as you don't share a dir object between threads. If you do, it requires a mutex.

pull/111/head
Micah Snyder (micasnyd) 6 years ago committed by Micah Snyder
parent bc56df8303
commit 1c996e8872
  1. 7
      clamd/scanner.c
  2. 2
      configure.ac
  3. 12
      libclamav/crypto.c
  4. 16
      libclamav/mbox.c
  5. 31
      libclamav/others.c
  6. 42
      libclamav/others_common.c
  7. 67
      libclamav/readdb.c
  8. 35
      libclamav/scanners.c
  9. 46
      m4/reorganization/code_checks/readdir.m4

@ -45,11 +45,6 @@
#endif
#include <pthread.h>
#if defined(HAVE_READDIR_R_3) || defined(HAVE_READDIR_R_2)
#include <limits.h>
#include <stddef.h>
#endif
#include "libclamav/clamav.h"
#include "libclamav/others.h"
#include "libclamav/scanners.h"
@ -144,7 +139,7 @@ int scan_callback(STATBUF *sb, char *filename, const char *msg, enum cli_ftw_rea
int type = scandata->type;
struct cb_context context;
/* detect disconnected socket,
/* detect disconnected socket,
* this should NOT detect half-shutdown sockets (SHUT_WR) */
if (send(scandata->conn->sd, &ret, 0, 0) == -1 && errno != EINTR) {
logg("$Client disconnected while command was active!\n");

@ -1,7 +1,6 @@
dnl Copyright (C) 2013-2019 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
dnl Copyright (C) 2007-2013 Sourcefire, Inc.
dnl Copyright (C) 2002-2007 Tomasz Kojm <tkojm@clamav.net>
dnl readdir_r checks (c) COPYRIGHT MIT 1995
dnl socklen_t check (c) Alexander V. Lukyanov <lav@yars.free.net>
dnl
dnl This program is free software; you can redistribute it and/or modify
@ -127,7 +126,6 @@ m4_include([m4/reorganization/code_checks/in_addr_t.m4])
m4_include([m4/reorganization/os_checks.m4])
m4_include([m4/reorganization/milter/check.m4])
m4_include([m4/reorganization/code_checks/pthread_02.m4])
m4_include([m4/reorganization/code_checks/readdir.m4])
m4_include([m4/reorganization/code_checks/ctime.m4])
m4_include([m4/reorganization/code_checks/socklen_t.m4])
m4_include([m4/reorganization/clamav_user.m4])

@ -842,24 +842,12 @@ int cl_validate_certificate_chain_ts_dir(char *tsdir, char *certpath)
int res;
DIR *dp;
struct dirent *dirent;
#if defined(HAVE_READDIR_R_3) || defined(HAVE_READDIR_R_2)
union {
struct dirent d;
char b[offsetof(struct dirent, d_name) + NAME_MAX + 1];
} result;
#endif
dp = opendir(tsdir);
if (!(dp))
return CL_EOPEN;
#if defined(HAVE_READDIR_R_3)
while (!readdir_r(dp, &result.d, &dirent) && dirent) {
#elif defined(HAVE_READDIR_R_2)
while ((dirent = (struct dirent *)readdir_r(dp, &result.d))) {
#else
while ((dirent = readdir(dp))) {
#endif
if (dirent->d_name[0] == '.')
continue;

@ -59,10 +59,6 @@
#include <unistd.h>
#endif
#if defined(HAVE_READDIR_R_3) || defined(HAVE_READDIR_R_2)
#include <stddef.h>
#endif
#ifdef CL_THREAD_SAFE
#include <pthread.h>
#endif
@ -3269,22 +3265,10 @@ rfc1341(message *m, const char *dir)
for (n = 1; n <= t; n++) {
char filename[NAME_MAX + 1];
struct dirent *dent;
#if defined(HAVE_READDIR_R_3) || defined(HAVE_READDIR_R_2)
union {
struct dirent d;
char b[offsetof(struct dirent, d_name) + NAME_MAX + 1];
} result;
#endif
snprintf(filename, sizeof(filename), "_%s-%u", md5_hex, n);
#ifdef HAVE_READDIR_R_3
while ((readdir_r(dd, &result.d, &dent) == 0) && dent) {
#elif defined(HAVE_READDIR_R_2)
while ((dent = (struct dirent *)readdir_r(dd, &result.d))) {
#else /*!HAVE_READDIR_R*/
while ((dent = readdir(dd))) {
#endif
FILE *fin;
char buffer[BUFSIZ], fullname[NAME_MAX + 1];
int nblanks;

@ -57,11 +57,6 @@
#include <pthread.h>
#endif
#if defined(HAVE_READDIR_R_3) || defined(HAVE_READDIR_R_2)
#include <limits.h>
#include <stddef.h>
#endif
#ifdef HAVE_LIBXML2
#include <libxml/parser.h>
#endif
@ -1081,7 +1076,7 @@ int cli_unlink(const char *pathname)
{
if (unlink(pathname) == -1) {
#ifdef _WIN32
/* Windows may fail to unlink a file if it is marked read-only,
/* Windows may fail to unlink a file if it is marked read-only,
* even if the user has permissions to delete the file. */
if (-1 == _chmod(pathname, _S_IWRITE)) {
char err[128];
@ -1226,12 +1221,6 @@ int cli_rmdirs(const char *name)
STATBUF statb;
DIR *dd;
struct dirent *dent;
#if defined(HAVE_READDIR_R_3) || defined(HAVE_READDIR_R_2)
union {
struct dirent d;
char b[offsetof(struct dirent, d_name) + NAME_MAX + 1];
} result;
#endif
char err[128];
if (CLAMSTAT(name, &statb) < 0) {
@ -1249,13 +1238,7 @@ int cli_rmdirs(const char *name)
rc = 0;
#ifdef HAVE_READDIR_R_3
while ((readdir_r(dd, &result.d, &dent) == 0) && dent) {
#elif defined(HAVE_READDIR_R_2)
while ((dent = (struct dirent *)readdir_r(dd, &result.d)) != NULL) {
#else
while ((dent = readdir(dd)) != NULL) {
#endif
char *path;
if (strcmp(dent->d_name, ".") == 0)
@ -1292,12 +1275,6 @@ int cli_rmdirs(const char *dirname)
{
DIR *dd;
struct dirent *dent;
#if defined(HAVE_READDIR_R_3) || defined(HAVE_READDIR_R_2)
union {
struct dirent d;
char b[offsetof(struct dirent, d_name) + NAME_MAX + 1];
} result;
#endif
STATBUF maind, statbuf;
char *path;
char err[128];
@ -1312,13 +1289,7 @@ int cli_rmdirs(const char *dirname)
return -1;
}
#ifdef HAVE_READDIR_R_3
while (!readdir_r(dd, &result.d, &dent) && dent) {
#elif defined(HAVE_READDIR_R_2)
while ((dent = (struct dirent *)readdir_r(dd, &result.d))) {
#else
while ((dent = readdir(dd))) {
#endif
if (dent->d_ino) {
if (strcmp(dent->d_name, ".") && strcmp(dent->d_name, "..")) {
path = cli_malloc(strlen(dirname) + strlen(dent->d_name) + 2);

@ -621,12 +621,6 @@ int cli_ftw(char *path, int flags, int maxdepth, cli_ftw_cb callback, struct cli
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)
union {
struct dirent d;
char b[offsetof(struct dirent, d_name) + NAME_MAX + 1];
} result;
#endif
struct dirent_data *entries = NULL;
size_t i, entries_cnt = 0;
int ret;
@ -639,16 +633,9 @@ static int cli_ftw_dir(const char *dirname, int flags, int maxdepth, cli_ftw_cb
if ((dd = opendir(dirname)) != NULL) {
struct dirent *dent;
int err;
errno = 0;
ret = CL_SUCCESS;
#ifdef HAVE_READDIR_R_3
while (!(err = readdir_r(dd, &result.d, &dent)) && dent) {
#elif defined(HAVE_READDIR_R_2)
while ((dent = (struct dirent *)readdir_r(dd, &result.d))) {
#else
while ((dent = readdir(dd))) {
#endif
int stated = 0;
enum filetype ft;
char *fname;
@ -752,29 +739,8 @@ static int cli_ftw_dir(const char *dirname, int flags, int maxdepth, cli_ftw_cb
}
errno = 0;
}
#ifndef HAVE_READDIR_R_3
err = errno;
#endif
closedir(dd);
ret = CL_SUCCESS;
if (err) {
char errs[128];
cli_errmsg("Unable to readdir() directory %s: %s\n", dirname,
cli_strerror(errno, errs, sizeof(errs)));
/* report error to callback using error_stat */
ret = callback(NULL, NULL, dirname, error_stat, data);
if (ret != CL_SUCCESS) {
if (entries) {
for (i = 0; i < entries_cnt; i++) {
struct dirent_data *entry = &entries[i];
free(entry->filename);
free(entry->statbuf);
}
free(entries);
}
return ret;
}
}
if (entries) {
cli_qsort(entries, entries_cnt, sizeof(*entries), ftw_compare);
@ -903,7 +869,7 @@ char *cli_sanitize_filepath(const char *filepath, size_t filepath_len)
depth--;
}
#ifdef _WIN32
/*
/*
* Windows' POSIX style API's accept both "/" and "\\" style path separators.
* The following checks using POSIX style path separators on Windows.
*/
@ -957,7 +923,7 @@ char *cli_sanitize_filepath(const char *filepath, size_t filepath_len)
depth++;
}
}
done:
if ((NULL != sanitized_filepath) && (0 == strlen(sanitized_filepath))) {
free(sanitized_filepath);
@ -1162,7 +1128,7 @@ cl_error_t cli_get_filepath_from_filedesc(int desc, char **filepath)
}
#elif _WIN32
DWORD dwRet = 0;
DWORD dwRet = 0;
intptr_t hFile = _get_osfhandle(desc);
dwRet = GetFinalPathNameByHandleA((HANDLE)hFile, NULL, 0, VOLUME_NAME_NT);
@ -1184,7 +1150,7 @@ cl_error_t cli_get_filepath_from_filedesc(int desc, char **filepath)
cli_errmsg("cli_get_filepath_from_filedesc: Failed to resolve filename for descriptor %d\n", desc);
free(*filepath);
*filepath = NULL;
status = CL_EOPEN;
status = CL_EOPEN;
goto done;
}

@ -69,11 +69,6 @@
#include "regex_list.h"
#include "hashtab.h"
#if defined(HAVE_READDIR_R_3) || defined(HAVE_READDIR_R_2)
#include <limits.h>
#include <stddef.h>
#endif
#include "mpool.h"
#include "bytecode.h"
#include "bytecode_api.h"
@ -129,7 +124,7 @@ int cli_sigopts_handler(struct cli_matcher *root, const char *virname, const cha
int ret = CL_SUCCESS;
/*
* cyclic loops with cli_parse_add are impossible now as cli_parse_add
* cyclic loops with cli_parse_add are impossible now as cli_parse_add
* no longer calls cli_sigopts_handler; leaving here for safety
*/
if (sigopts & ACPATT_OPTION_ONCE) {
@ -2923,7 +2918,7 @@ static int cli_loadcdb(FILE *fs, struct cl_engine *engine, unsigned int *signo,
return CL_SUCCESS;
}
/*
/*
* name;trusted;subject;serial;pubkey;exp;codesign;timesign;certsign;notbefore;comment[;minFL[;maxFL]]
* Name and comment are ignored. They're just for the end user.
* Exponent is ignored for now and hardcoded to \x01\x00\x01.
@ -3231,7 +3226,7 @@ static char *parse_yara_hex_string(YR_STRING *string, int *ret)
}
}
/* FIXME: removing this code because anchored bytes are not sufficiently
/* FIXME: removing this code because anchored bytes are not sufficiently
general for the purposes of yara rule to ClamAV sig conversions.
1. ClamAV imposes a maximum value for the upper range limit of 32:
#define AC_CH_MAXDIST 32
@ -3811,7 +3806,7 @@ static int load_oneyara(YR_RULE *rule, int chkpua, struct cl_engine *engine, uns
ytable_delete(&ytable);
return CL_EMEM;
}
if (rule->cl_flags & RULE_ALL && rule->cl_flags & RULE_THEM)
exp_op = "&";
else {
@ -3820,12 +3815,12 @@ static int load_oneyara(YR_RULE *rule, int chkpua, struct cl_engine *engine, uns
!(rule->cl_flags & RULE_EP && ytable.tbl_cnt == 1))
yara_complex++;
}
for (i=0; i<ytable.tbl_cnt; i++) {
size_t len=strlen(logic);
snprintf(logic+len, lsize-len, "%u%s", i, (i+1 == ytable.tbl_cnt) ? "" : exp_op);
}
}
/*** END CONDITIONAL HANDLING ***/
}
@ -4509,12 +4504,6 @@ static int cli_loaddbdir(const char *dirname, struct cl_engine *engine, unsigned
{
DIR *dd = NULL;
struct dirent *dent;
#if defined(HAVE_READDIR_R_3) || defined(HAVE_READDIR_R_2)
union {
struct dirent d;
char b[offsetof(struct dirent, d_name) + NAME_MAX + 1];
} result;
#endif
char *dbfile = NULL;
int ret = CL_EOPEN, have_daily_cld = 0, have_daily_cvd = 0, ends_with_sep = 0;
size_t dirname_len;
@ -4540,13 +4529,7 @@ static int cli_loaddbdir(const char *dirname, struct cl_engine *engine, unsigned
}
}
#ifdef HAVE_READDIR_R_3
while (!readdir_r(dd, &result.d, &dent) && dent) {
#elif defined(HAVE_READDIR_R_2)
while ((dent = (struct dirent *)readdir_r(dd, &result.d))) {
#else
while ((dent = readdir(dd))) {
#endif
struct db_ll_entry *entry;
unsigned int load_priority;
@ -4808,12 +4791,6 @@ int cl_statinidir(const char *dirname, struct cl_stat *dbstat)
{
DIR *dd;
struct dirent *dent;
#if defined(HAVE_READDIR_R_3) || defined(HAVE_READDIR_R_2)
union {
struct dirent d;
char b[offsetof(struct dirent, d_name) + NAME_MAX + 1];
} result;
#endif
char *fname;
if (dbstat) {
@ -4834,13 +4811,7 @@ int cl_statinidir(const char *dirname, struct cl_stat *dbstat)
cli_dbgmsg("Stat()ing files in %s\n", dirname);
#ifdef HAVE_READDIR_R_3
while (!readdir_r(dd, &result.d, &dent) && dent) {
#elif defined(HAVE_READDIR_R_2)
while ((dent = (struct dirent *)readdir_r(dd, &result.d))) {
#else
while ((dent = readdir(dd))) {
#endif
if (dent->d_ino) {
if (strcmp(dent->d_name, ".") && strcmp(dent->d_name, "..") && CLI_DBEXT(dent->d_name)) {
dbstat->entries++;
@ -4894,12 +4865,6 @@ int cl_statchkdir(const struct cl_stat *dbstat)
{
DIR *dd;
struct dirent *dent;
#if defined(HAVE_READDIR_R_3) || defined(HAVE_READDIR_R_2)
union {
struct dirent d;
char b[offsetof(struct dirent, d_name) + NAME_MAX + 1];
} result;
#endif
STATBUF sb;
unsigned int i, found;
char *fname;
@ -4916,13 +4881,7 @@ int cl_statchkdir(const struct cl_stat *dbstat)
cli_dbgmsg("Stat()ing files in %s\n", dbstat->dir);
#ifdef HAVE_READDIR_R_3
while (!readdir_r(dd, &result.d, &dent) && dent) {
#elif defined(HAVE_READDIR_R_2)
while ((dent = (struct dirent *)readdir_r(dd, &result.d))) {
#else
while ((dent = readdir(dd))) {
#endif
if (dent->d_ino) {
if (strcmp(dent->d_name, ".") && strcmp(dent->d_name, "..") && CLI_DBEXT(dent->d_name)) {
fname = cli_malloc(strlen(dbstat->dir) + strlen(dent->d_name) + 32);
@ -5402,12 +5361,6 @@ int cl_countsigs(const char *path, unsigned int countoptions, unsigned int *sigs
STATBUF sb;
char fname[1024];
struct dirent *dent;
#if defined(HAVE_READDIR_R_3) || defined(HAVE_READDIR_R_2)
union {
struct dirent d;
char b[offsetof(struct dirent, d_name) + NAME_MAX + 1];
} result;
#endif
DIR *dd;
int ret;
@ -5427,13 +5380,7 @@ int cl_countsigs(const char *path, unsigned int countoptions, unsigned int *sigs
cli_errmsg("cl_countsigs: Can't open directory %s\n", path);
return CL_EOPEN;
}
#ifdef HAVE_READDIR_R_3
while (!readdir_r(dd, &result.d, &dent) && dent) {
#elif defined(HAVE_READDIR_R_2)
while ((dent = (struct dirent *)readdir_r(dd, &result.d))) {
#else
while ((dent = readdir(dd))) {
#endif
if (dent->d_ino) {
if (strcmp(dent->d_name, ".") && strcmp(dent->d_name, "..") && CLI_DBEXT(dent->d_name)) {
snprintf(fname, sizeof(fname), "%s" PATHSEP "%s", path, dent->d_name);

@ -115,11 +115,6 @@
#include <bzlib.h>
#endif
#if defined(HAVE_READDIR_R_3) || defined(HAVE_READDIR_R_2)
#include <limits.h>
#include <stddef.h>
#endif
#include <fcntl.h>
#include <string.h>
@ -129,24 +124,12 @@ static int cli_scandir(const char *dirname, cli_ctx *ctx)
{
DIR *dd;
struct dirent *dent;
#if defined(HAVE_READDIR_R_3) || defined(HAVE_READDIR_R_2)
union {
struct dirent d;
char b[offsetof(struct dirent, d_name) + NAME_MAX + 1];
} result;
#endif
STATBUF statbuf;
char *fname;
unsigned int viruses_found = 0;
if ((dd = opendir(dirname)) != NULL) {
#ifdef HAVE_READDIR_R_3
while (!readdir_r(dd, &result.d, &dent) && dent) {
#elif defined(HAVE_READDIR_R_2)
while ((dent = (struct dirent *)readdir_r(dd, &result.d))) {
#else
while ((dent = readdir(dd))) {
#endif
if (dent->d_ino) {
if (strcmp(dent->d_name, ".") && strcmp(dent->d_name, "..")) {
/* build the full name */
@ -1149,12 +1132,6 @@ static int cli_vba_scandir(const char *dirname, cli_ctx *ctx, struct uniq *U)
vba_project_t *vba_project;
DIR *dd;
struct dirent *dent;
#if defined(HAVE_READDIR_R_3) || defined(HAVE_READDIR_R_2)
union {
struct dirent d;
char b[offsetof(struct dirent, d_name) + NAME_MAX + 1];
} result;
#endif
STATBUF statbuf;
char *fullname, vbaname[1024];
unsigned char *data;
@ -1384,13 +1361,7 @@ static int cli_vba_scandir(const char *dirname, cli_ctx *ctx, struct uniq *U)
* flattening the paths in ole2_walk_property_tree (case 1) */
if ((dd = opendir(dirname)) != NULL) {
#ifdef HAVE_READDIR_R_3
while (!readdir_r(dd, &result.d, &dent) && dent) {
#elif defined(HAVE_READDIR_R_2)
while ((dent = (struct dirent *)readdir_r(dd, &result.d))) {
#else
while ((dent = readdir(dd))) {
#endif
if (dent->d_ino) {
if (strcmp(dent->d_name, ".") && strcmp(dent->d_name, "..")) {
/* build the full name */
@ -3590,14 +3561,14 @@ static cl_error_t cli_base_scandesc(int desc, const char *filepath, cli_ctx *ctx
status = CL_ESTAT;
cli_dbgmsg("cli_magic_scandesc: returning %d %s (no post, no cache)\n", status, __AT__);
goto done;
goto done;
}
if (sb.st_size <= 5) {
cli_dbgmsg("Small data (%u bytes)\n", (unsigned int)sb.st_size);
status = CL_CLEAN;
cli_dbgmsg("cli_magic_scandesc: returning %d %s (no post, no cache)\n", status, __AT__);
goto done;
goto done;
}
ctx->fmap++;
@ -3609,7 +3580,7 @@ static cl_error_t cli_base_scandesc(int desc, const char *filepath, cli_ctx *ctx
status = CL_EMEM;
cli_dbgmsg("cli_magic_scandesc: returning %d %s (no post, no cache)\n", status, __AT__);
goto done;
goto done;
}
perf_stop(ctx, PERFT_MAP);

@ -1,46 +0,0 @@
dnl Check for readdir_r and number of its arguments
dnl Code from libwww/configure.in
AC_MSG_CHECKING([for readdir_r])
if test -z "$ac_cv_readdir_args"; then
AC_TRY_COMPILE(
[
#include <sys/types.h>
#include <dirent.h>
],
[
struct dirent dir, *dirp;
DIR *mydir;
dirp = readdir_r(mydir, &dir);
], ac_cv_readdir_args=2)
fi
if test -z "$ac_cv_readdir_args"; then
AC_TRY_COMPILE(
[
#include <sys/types.h>
#include <dirent.h>
],
[
struct dirent dir, *dirp;
DIR *mydir;
int rc;
rc = readdir_r(mydir, &dir, &dirp);
], ac_cv_readdir_args=3)
fi
AC_ARG_ENABLE([readdir_r],
[AS_HELP_STRING([--enable-readdir_r], [enable support for readdir_r])],
enable_readdir_r=$enableval, enable_readdir_r="no")
if test "$enable_readdir_r" = "no"; then
AC_MSG_RESULT(support disabled)
elif test -z "$ac_cv_readdir_args"; then
AC_MSG_RESULT(no)
else
if test "$ac_cv_readdir_args" = 2; then
AC_DEFINE([HAVE_READDIR_R_2],1,[readdir_r takes 2 arguments])
elif test "$ac_cv_readdir_args" = 3; then
AC_DEFINE([HAVE_READDIR_R_3],1,[readdir_r takes 3 arguments])
fi
AC_MSG_RESULT([yes, and it takes $ac_cv_readdir_args arguments])
fi
Loading…
Cancel
Save