How to set OnAccessPrevention true in clamonacc on Raspberry Pi 4 ?

Anti Virus
Reading Time: 3 minutes

I put clamonacc on Raspberry Pi 4 and using well.
But when I changed configuration of “OnAccessPrevention” as “true”, real-time scanning did not work at all😥
I will share how I resolved this issue.
If you have similar issue on your environment this article matches your needs.

What is clamonacc?

I guess you already know clamonacc.
However let me introduce quickly.
clamonacc is a program that realizes real-time scanning.
clamonacc is included clamav which is open source antivirus software for Linux.
clamonacc cannot realize real-time scanning only by itself, needs to co-work with clamd.

I will tuckle the problem which I declared in above post.

However, there are the following issues in my environment for now.
 – Raspberry Pi OS kernel is disabled by FANOTIFY
 – I tried with building FANOTIFY enabled kernel, installing.
 However it derived an communication error between clamonacc and clamdscan.

What happens when OnAccessPrevention is set as true?

I showed OnAccessPrevention explanation by man.
Interruption mechanism by FANOTIFY works.

OnAccessPrevention BOOL
       Enables fanotify blocking when malicious files are found.
       Default: disabled

However, OnAccessPrevention cannot be set true because CONFIG_FANOTIFY_ACCESS_PERMISSIONS in kernel of Raspberry Pi OS is not set which eventually equals as “false”.

sudo modprobe configs
zcat /proc/config.gz | grep FANOTIFY_ACCESS_PERMISSIONS
# CONFIG_FANOTIFY_ACCESS_PERMISSIONS is not set

Enabling CONFIG_FANOTIFY_ACCESS_PERMISSIONS

So I tried to build kernel to enable CONFIG_FANOTIFY_ACCESS_PERMISSION and put in the system. The official page explains how to build kernel, so follow it.

Raspberry Pi Documentation - The Linux kernel
The official documentation for Raspberry Pi computers and microcontrollers
sudo apt install git bc bison flex libssl-dev make
git clone --depth=1 https://github.com/raspberrypi/linux
cd linux
export KERNEL=kernel7l
make bcm2711_defconfig

I also changed CONFIG_LOCALVERSION in .config just in case.
– CONFIG_LOCALVERSION=”-v7l-MY_CUSTOM_KERNEL”

Let’s do from build to install in a row.
It takes about an hour on the Raspberry Pi 4.

make -j4 zImage modules dtbs
sudo make modules_install
sudo cp arch/arm/boot/dts/.dtb /boot/
sudo cp arch/arm/boot/dts/overlays/.dtb* /boot/overlays/
sudo cp arch/arm/boot/dts/overlays/README /boot/overlays/
sudo cp arch/arm/boot/zImage /boot/$KERNEL.img

I restarted Raspberry Pi 4 and CONFIG_FANOTIFY_ACCESS_PERMISSIONS was changed successfully.

sudo modprobe configs
zcat /proc/config.gz | grep FANOTIFY_ACCESS_PERMISSIONS
CONFIG_FANOTIFY_ACCESS_PERMISSIONS=y

Changing OnAccessPrevention true

CONFIG_FANOTIFY_ACCESS_PERMISSIONS was successfully activated, then I changed OnAccessPrevention true.
But real time scanning did not start with this error message…

ClamFanotif: attempting to feed consumer queue
ClamWorker: performing scanning on file '/var/www/html/nextcloud/index.html'
ERROR: ClamCom: TIMEOUT while waiting on socket (recv)
ClamClient: connection could not be established ... return code 12

As a conclusion I found “–fdpass” option for clamonacc is mandatory if we set OnAccessPrevention as true.

After passing –fdpass option clamonacc worked as expected!

–fdpass itself is explained follows.
clamd/clamonacc can communicate fine when both run on different users specified this option.
So we can guess if clamd/clamonacc run the same user we do not need this option…

--fdpass Pass filedescriptor to clamd (useful if clamd is running as a different user)

The code which uses –fdpass is here.
Does it use Unix Domain Socket?

clamonacc/client/client.c
cl_error_t onas_setup_client(struct onas_context **ctx)
{
(snip)
if (!remote && optget((*ctx)->clamdopts, "LocalSocket")->enabled && (optget(opts, "fdpass")->enabled)) {
     if (onas_set_sock_only_once(*ctx) == CL_EWRITE) {
(snip)
clamonacc/client/socket.c
cl_error_t onas_set_sock_only_once(struct onas_context *ctx)
{
(snip)
if (onas_sock.written != 1) {
     if (((opt =
               optget(ctx->clamdopts, "LocalSocket"))
              ->enabled) &&
         optget(ctx->opts, "fdpass")->enabled) {
         memset((void *)&onas_sock, 0, sizeof(onas_sock));
         onas_sock.sock.sun_family = AF_UNIX;
         strncpy(onas_sock.sock.sun_path, opt->strarg, sizeof(onas_sock.sock.sun_path));
         onas_sock.sock.sun_path[sizeof(onas_sock.sock.sun_path) - 1] = '\0';
          onas_sock.written                                            = 1;
          return CL_SUCCESS;
      }
  }

Now OnAccessPrevention itself works, however performance apparently decreased.
This is caused by real time scanning occurs even if only reading files.

I explained a little bit in this article.

If OnAccessPrevention is false, you can use the patch introduced in the above article, but if OnAccessPrevention is true, it can not be used because there is no corresponding mask.
So I gave up.

Chromebooks and modern PCs may be no problem because they are powerful, but Raspberry Pi 4 is not.
I decided to use OnAccessPrevention with false😅

Conclusion

How was it?

I could not clerified whether it is a specification or a bug that –fdpass is mandatory option to run when OnAccessPrevention is true, but my purpose to run clamonacc with OnAccessPrevention true is achieved.

Perhaps it wil be analyzed in my spare time😀

Comments

Copied title and URL