From 1990b367bbabe00dd44a83e5c177a098cdedfdfb Mon Sep 17 00:00:00 2001 From: Alejo Diaz Date: Sat, 6 Dec 2025 02:14:58 -0300 Subject: [PATCH 1/4] clamonacc: Enable prevention on OnAccessMountPath The root directory and non-mountpoints would be disabled. --- clamonacc/fanotif/fanotif.c | 40 +++++++++++++++++++++++++++++++++---- etc/clamd.conf.sample | 8 +++----- 2 files changed, 39 insertions(+), 9 deletions(-) diff --git a/clamonacc/fanotif/fanotif.c b/clamonacc/fanotif/fanotif.c index cb57a4ea67..791e01fcb5 100644 --- a/clamonacc/fanotif/fanotif.c +++ b/clamonacc/fanotif/fanotif.c @@ -33,6 +33,7 @@ #include #include #include +#include #include @@ -63,6 +64,28 @@ extern pthread_t ddd_pid; extern pthread_t scan_queue_pid; static int onas_fan_fd; +int is_mountpoint(const char *path) { + struct stat st_path, st_parent_path; + + if (strcmp(path, "/") == 0) { + return 1; + } + + if (stat(path, &st_path) == -1) { + logg(LOGG_DEBUG, "ClamFanotif: internal error: fail to stat path '%s'\n", path); + return 0; + } + + char * pathc = strdup(path); + char * parent_path = dirname(pathc); + if (stat(parent_path, &st_parent_path) == -1) { + logg(LOGG_DEBUG, "ClamFanotif: internal error: fail to stat parent path '%s'\n", parent_path); + return 0; + } + + return (st_path.st_dev != st_parent_path.st_dev); +} + cl_error_t onas_setup_fanotif(struct onas_context **ctx) { @@ -82,14 +105,11 @@ cl_error_t onas_setup_fanotif(struct onas_context **ctx) onas_fan_fd = (*ctx)->fan_fd; (*ctx)->fan_mask = fan_mask; - if (optget((*ctx)->clamdopts, "OnAccessPrevention")->enabled && !optget((*ctx)->clamdopts, "OnAccessMountPath")->enabled) { + if (optget((*ctx)->clamdopts, "OnAccessPrevention")->enabled { logg(LOGG_DEBUG, "ClamFanotif: kernel-level blocking feature enabled ... preventing malicious files access attempts\n"); (*ctx)->fan_mask |= FAN_ACCESS_PERM | FAN_OPEN_PERM; } else { logg(LOGG_DEBUG, "ClamFanotif: kernel-level blocking feature disabled ...\n"); - if (optget((*ctx)->clamdopts, "OnAccessPrevention")->enabled && optget((*ctx)->clamdopts, "OnAccessMountPath")->enabled) { - logg(LOGG_DEBUG, "ClamFanotif: feature not available when watching mounts ... \n"); - } (*ctx)->fan_mask |= FAN_ACCESS | FAN_OPEN; } @@ -102,6 +122,18 @@ cl_error_t onas_setup_fanotif(struct onas_context **ctx) if ((pt = optget((*ctx)->clamdopts, "OnAccessMountPath"))->enabled) { while (pt) { + if (optget((*ctx)->clamdopts, "OnAccessPrevention")->enabled) { + if ((pt->strarg == '/') || !is_mountpoint(pt->strarg)) { + logg(LOGG_DEBUG, "ClamFanotif: kernel-level blocking feature disabled for path '%s' ...\n", pt->strarg); + logg(LOGG_DEBUG, "ClamFanotif: prevention is only available if path is a mountpoint or not root directory\n"); + (*ctx)->fan_mask &= ~FAN_ACCESS_PERM & ~FAN_OPEN_PERM; + (*ctx)->fan_mask |= FAN_ACCESS | FAN_OPEN; + } else if ((*ctx)->fan_mask & (FAN_ACCESS | FAN_OPEN)) { + (*ctx)->fan_mask &= ~FAN_ACCESS & ~FAN_OPEN; + (*ctx)->fan_mask |= FAN_ACCESS_PERM | FAN_OPEN_PERM; + } + } + if (fanotify_mark(onas_fan_fd, FAN_MARK_ADD | FAN_MARK_MOUNT, (*ctx)->fan_mask, (*ctx)->fan_fd, pt->strarg) != 0) { logg(LOGG_ERROR, "ClamFanotif: can't include mountpoint '%s'\n", pt->strarg); return CL_EARG; diff --git a/etc/clamd.conf.sample b/etc/clamd.conf.sample index 73be60eae8..78d1060b97 100644 --- a/etc/clamd.conf.sample +++ b/etc/clamd.conf.sample @@ -812,13 +812,11 @@ Example # point containing the specified directory will be watched. If any directories # are specified, this option will preempt (disable and ignore all options # related to) the DDD system. This option will result in verdicts only. -# Note that prevention is explicitly disallowed to prevent common, fatal -# misconfigurations. (e.g. watching "/" with prevention on and no exclusions -# made on vital system directories) -# It can be used multiple times. +# Note that prevention is explicitly disallowed on the root directory to +# prevent common, fatal misconfigurations. It can be used multiple times. # Default: disabled -#OnAccessMountPath / #OnAccessMountPath /home/user +#OnAccessMountPath /media/user/drive # With this option you can exclude the root UID (0). Processes run under # root with be able to access all files without triggering scans or From 9dc59ba3951eabb17b9e91cc2e9a5aafc32728b9 Mon Sep 17 00:00:00 2001 From: Alejo Diaz Date: Sat, 6 Dec 2025 02:19:42 -0300 Subject: [PATCH 2/4] clamonacc: Change clamd.conf example to reflect new behavior --- etc/clamd.conf.sample | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/etc/clamd.conf.sample b/etc/clamd.conf.sample index 78d1060b97..a38b047d75 100644 --- a/etc/clamd.conf.sample +++ b/etc/clamd.conf.sample @@ -812,8 +812,9 @@ Example # point containing the specified directory will be watched. If any directories # are specified, this option will preempt (disable and ignore all options # related to) the DDD system. This option will result in verdicts only. -# Note that prevention is explicitly disallowed on the root directory to -# prevent common, fatal misconfigurations. It can be used multiple times. +# Note that prevention is explicitly disallowed on the root directory and +# non-mountpoints to prevent common, fatal misconfigurations. It can be used +# multiple times. # Default: disabled #OnAccessMountPath /home/user #OnAccessMountPath /media/user/drive From 8edd1e6046938d2faa2976eadf072dbe32194ba7 Mon Sep 17 00:00:00 2001 From: Alejo Diaz Date: Sat, 6 Dec 2025 02:26:50 -0300 Subject: [PATCH 3/4] clamonacc: Use strcmp for string comparation --- clamonacc/fanotif/fanotif.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/clamonacc/fanotif/fanotif.c b/clamonacc/fanotif/fanotif.c index 791e01fcb5..4dfc5c9b66 100644 --- a/clamonacc/fanotif/fanotif.c +++ b/clamonacc/fanotif/fanotif.c @@ -67,7 +67,7 @@ static int onas_fan_fd; int is_mountpoint(const char *path) { struct stat st_path, st_parent_path; - if (strcmp(path, "/") == 0) { + if (0 == strcmp(path, "/")) { return 1; } @@ -123,7 +123,7 @@ cl_error_t onas_setup_fanotif(struct onas_context **ctx) if ((pt = optget((*ctx)->clamdopts, "OnAccessMountPath"))->enabled) { while (pt) { if (optget((*ctx)->clamdopts, "OnAccessPrevention")->enabled) { - if ((pt->strarg == '/') || !is_mountpoint(pt->strarg)) { + if ((0 == strcmp("/", pt->strarg)) || !is_mountpoint(pt->strarg)) { logg(LOGG_DEBUG, "ClamFanotif: kernel-level blocking feature disabled for path '%s' ...\n", pt->strarg); logg(LOGG_DEBUG, "ClamFanotif: prevention is only available if path is a mountpoint or not root directory\n"); (*ctx)->fan_mask &= ~FAN_ACCESS_PERM & ~FAN_OPEN_PERM; From f265bf871b0fd5e5b17d8c7cd06fd611d0977ae2 Mon Sep 17 00:00:00 2001 From: Alejo Diaz Date: Sun, 7 Dec 2025 22:04:53 -0300 Subject: [PATCH 4/4] clamonacc: Fix typo --- clamonacc/fanotif/fanotif.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clamonacc/fanotif/fanotif.c b/clamonacc/fanotif/fanotif.c index 4dfc5c9b66..7600db1ab7 100644 --- a/clamonacc/fanotif/fanotif.c +++ b/clamonacc/fanotif/fanotif.c @@ -105,7 +105,7 @@ cl_error_t onas_setup_fanotif(struct onas_context **ctx) onas_fan_fd = (*ctx)->fan_fd; (*ctx)->fan_mask = fan_mask; - if (optget((*ctx)->clamdopts, "OnAccessPrevention")->enabled { + if (optget((*ctx)->clamdopts, "OnAccessPrevention")->enabled) { logg(LOGG_DEBUG, "ClamFanotif: kernel-level blocking feature enabled ... preventing malicious files access attempts\n"); (*ctx)->fan_mask |= FAN_ACCESS_PERM | FAN_OPEN_PERM; } else {