Cisco-Talos / clamav-docker

Dockerfiles for the ClamAV project
40 stars 21 forks source link

clamav user needs to be in tty UNIX group #58

Open nathanjrobertson opened 2 months ago

nathanjrobertson commented 2 months ago

This might be caused by a change in the upstream image, but if LogFile is set to output to stdout / stderr (standard for a container deployment), you now get an error:

Starting Freshclamd
Starting ClamAV
Socket for clamd not found yet, retrying (0/1800) ...ERROR: Failed to open log file /dev/fd/1: Symbolic link loop
ERROR: Can't initialize the internal logger

We get the same error if we set it to /dev/stdout. Those symlinks end up pointing to /dev/pts/0. When we set LogFile /dev/pts/0 in the config we get:

ERROR: Failed to open log file /dev/pts/0: Permission denied

The underlying cause is that the clamav user isn't a member of the tty group, which owns /dev/pts/0. Only users in the tty group can write to that file descriptor:

/ # ls -l /dev/pts
total 0
crw--w----    1 root     tty       136,   0 Sep  5 06:47 0
crw-rw-rw-    1 root     root        5,   2 Sep  5 06:47 ptmx
/ # groups clamav
clamav
/ #

I suggest that the adduser in the Dockerfile (https://github.com/Cisco-Talos/clamav-docker/blob/fdb02aa2c20f26faeec6a6c093a881cdfce93359/clamav/1.4/alpine/Dockerfile#L115) be modified to add the tty group to the clamav user so that people can set stdout / stderr to be the LogFile in the config.

micahsnyder commented 2 months ago

The change was a security fix in clamav to prevent following symlinks when opening the logfile. See CVE-2024-20506 in https://github.com/Cisco-Talos/clamav/blob/clamav-1.4.1/NEWS.md#141

I am a little confused though. ClamD already writes messages to stdout and stderr in addition to LogFile. Are you setting LogFile /dev.stdout as a means to redirect stderr to stdout? Would it also suffice to start ClamD like this?

clamd 2>&1
micahsnyder commented 2 months ago

Also considering this use case, I do wonder if we should change the logging symlink CVE fix to only use the O_NOFOLLOW optionn if currently running as root.

nathanjrobertson commented 2 months ago

Our configuration was years old, and follows some online HOWTO back then saying that LogFile /dev/stdout was the way to get clamd logging to Kubernetes in a way that got exported to your favourite third party logging tool. Are you saying that everything that is output to LogFile is already output to stderr, so in setting LogFile /dev/pts/0 I'd just end up with duplicate messages anyway?

In reading that CVE I don't think that is 100% of the problem. Yes, it causes it to refuse to follow the /dev/stdout symlink - however, if you try to log directly to where the symlink points in the resulting Docker image (/dev/pts/0), the clamav user isn't in the required group to be able to write to what /dev/stdout points at anyway.

nathanr@tezro:~$ docker run -it --rm clamav/clamav:latest /bin/sh
/ # su -l clamav -s /bin/sh -c 'echo test > /dev/pts/0'
-sh: can't create /dev/pts/0: Permission denied
/ # ls -l /dev/pts
total 0
crw--w----    1 root     tty       136,   0 Sep  6 05:29 0
crw-rw-rw-    1 root     root        5,   2 Sep  6 05:29 ptmx
/ # groups clamav
clamav
/ #

So, I'm suggesting that to retain the ability to log to stdout/stderr the clamav user should be in the tty group.