diff mbox series

[meta-security,v4,1/2] clamav: Add recipe for version 1.4.3

Message ID 20251114154052.3651845-1-hemant.jadhav@emerson.com
State New
Headers show
Series [meta-security,v4,1/2] clamav: Add recipe for version 1.4.3 | expand

Commit Message

Hemant Jadhav Nov. 14, 2025, 3:40 p.m. UTC
Major changes in 1.4.3:
- Upgraded core engine with improved threat detection capabilities
- Added Rust components requiring cross-compilation support
- Updated CMake build system replacing legacy autotools
- Modernized library dependencies (LLVM, JSON-C, PCre2)
- Added comprehensive license compliance for multi-component package
- Enhanced cross-compilation support for all target architectures

The recipe leverages cargo_common class for automatic Rust toolchain
configuration. ClamAV uses both CMake and Rust/Cargo build systems,
requiring special handling to ensure both configure properly.

Security rationale:
- ClamAV 0.104.4 reached end-of-life and is no longer maintained
- Upstream strongly recommends migration to 1.4.x for security updates

Signed-off-by: Hemant Jadhav <hemant.jadhav@emerson.com>
---
v4: Fix hybrid build system configuration
- Add custom do_configure() calling both cmake_do_configure and
  cargo_common_do_configure
- Enable network access during configure and compile for Cargo to fetch
  git dependencies (onenote_parser crate from Cisco-Talos/onenote.rs)
- Set CARGO_DISABLE_BITBAKE_VENDORING = "1" to disable BitBake vendoring
- Skip buildpaths QA check for main, libclamav, and staticdev packages
- Tested with clean build from scratch in OE-core master

v3: Remove S variable that was mistakenly left in v2

v2: Address review comments
- Remove S variable (auto-detected in master branch)
- Use cargo_common instead of rust-common (handles config.toml automatically)
- Remove manual Cargo configuration in do_configure:prepend()
- Change ${WORKDIR} to ${UNPACKDIR} for file path references

v1: Initial 1.4.3 upgrade
---
---
 recipes-scanners/clamav/clamav_1.4.3.bb       | 209 ++++++++++++++++++
 recipes-scanners/clamav/files/tmpfiles.clamav |   1 +
 .../clamav/files/volatiles.03_clamav          |   1 +
 3 files changed, 211 insertions(+)
 create mode 100644 recipes-scanners/clamav/clamav_1.4.3.bb

Comments

Scott Murray Nov. 14, 2025, 6:05 p.m. UTC | #1
On Fri, 14 Nov 2025, Hemant Jadhav via lists.yoctoproject.org wrote:

> Major changes in 1.4.3:
> - Upgraded core engine with improved threat detection capabilities
> - Added Rust components requiring cross-compilation support
> - Updated CMake build system replacing legacy autotools
> - Modernized library dependencies (LLVM, JSON-C, PCre2)
> - Added comprehensive license compliance for multi-component package
> - Enhanced cross-compilation support for all target architectures
>
> The recipe leverages cargo_common class for automatic Rust toolchain
> configuration. ClamAV uses both CMake and Rust/Cargo build systems,
> requiring special handling to ensure both configure properly.
>
> Security rationale:
> - ClamAV 0.104.4 reached end-of-life and is no longer maintained
> - Upstream strongly recommends migration to 1.4.x for security updates
>
> Signed-off-by: Hemant Jadhav <hemant.jadhav@emerson.com>
> ---
> v4: Fix hybrid build system configuration
> - Add custom do_configure() calling both cmake_do_configure and
>   cargo_common_do_configure
> - Enable network access during configure and compile for Cargo to fetch
>   git dependencies (onenote_parser crate from Cisco-Talos/onenote.rs)

This is a non-starter, as it:
- breaks build reproducibility, which is even more important for a
  security tool.
- opens the door to build breakage if any higher-order dependency
  crates increase their required Rust version (I've seen this happen
  multiple times in the past few years).

The recipe needs to use the regular cargo.bbclass and an include file
for the crates generated with cargo-update-recipe-crates.bbclass.

Scott

> - Set CARGO_DISABLE_BITBAKE_VENDORING = "1" to disable BitBake vendoring
> - Skip buildpaths QA check for main, libclamav, and staticdev packages
> - Tested with clean build from scratch in OE-core master
>
> v3: Remove S variable that was mistakenly left in v2
>
> v2: Address review comments
> - Remove S variable (auto-detected in master branch)
> - Use cargo_common instead of rust-common (handles config.toml automatically)
> - Remove manual Cargo configuration in do_configure:prepend()
> - Change ${WORKDIR} to ${UNPACKDIR} for file path references
>
> v1: Initial 1.4.3 upgrade
> ---
> ---
>  recipes-scanners/clamav/clamav_1.4.3.bb       | 209 ++++++++++++++++++
>  recipes-scanners/clamav/files/tmpfiles.clamav |   1 +
>  .../clamav/files/volatiles.03_clamav          |   1 +
>  3 files changed, 211 insertions(+)
>  create mode 100644 recipes-scanners/clamav/clamav_1.4.3.bb
>
> diff --git a/recipes-scanners/clamav/clamav_1.4.3.bb b/recipes-scanners/clamav/clamav_1.4.3.bb
> new file mode 100644
> index 0000000..0cbae53
> --- /dev/null
> +++ b/recipes-scanners/clamav/clamav_1.4.3.bb
> @@ -0,0 +1,209 @@
> +SUMMARY = "ClamAV anti-virus utilities and scanner tools"
> +DESCRIPTION = "ClamAV is an open source antivirus engine for detecting trojans, viruses, malware & other malicious threats."
> +HOMEPAGE = "http://www.clamav.net/index.html"
> +SECTION = "security"
> +LICENSE = "GPL-2.0-only & LGPL-2.1-only & BSD-2-Clause & Zlib & Apache-2.0-with-LLVM-exception"
> +LIC_FILES_CHKSUM = "file://COPYING.txt;md5=2c0b5770a62017a3121c69bb9f680b0c \
> +                    file://COPYING/COPYING.LGPL;md5=2d5025d4aa3495befef8f17206a5b0a1 \
> +                    file://COPYING/COPYING.bzip2;md5=ae8d555c34b656ff864ea9437a10d3a0 \
> +                    file://COPYING/COPYING.zlib;md5=3648a0b9713ab246e11536055165a41a \
> +                    file://COPYING/COPYING.llvm;md5=c82fc668ef1809acdd0684811df93bfc \
> +                    file://COPYING/COPYING.unrar;md5=6a741ba21afc8b71aeaee3b5f86a8111 \
> +                    file://COPYING/COPYING.file;md5=e63a61022c36cff2fdfbf02dd51674bd \
> +                    file://COPYING/COPYING.curl;md5=be5d9e1419c4363f4b32037a2d3b7ffa \
[snip]

To save me from digging into this myself, can you elaborate on why
upstream now has all these license files as opposed to the one the
previous version had?  Are they vendoring a bunch of code from all
those projects now?  If so, can we disable vendored libraries to use
system provided versions?

Thanks,

Scott
Hemant Jadhav Nov. 14, 2025, 7:16 p.m. UTC | #2
On Fri, Nov 14, 2025 at 12:05 PM, Scott Murray wrote:

> 
> To save me from digging into this myself, can you elaborate on why
> upstream now has all these license files as opposed to the one the
> previous version had? Are they vendoring a bunch of code from all
> those projects now? If so, can we disable vendored libraries to use
> system provided versions?

The multiple LICENSE files are present because the upstream project embeds modified portions of several third-party libraries directly within libclamav, rather than linking against system versions.
Actually, the same embedded code existed in 0.104.4 as well. The old 0.104.4 recipe only declared LICENSE = "LGPL-2.1-only", but it should have included all the embedded licenses too. I think this was missed/incomplete in the old recipe.

Answering to your next question: Unfortunately, NO - these are not optional external dependencies but embedded code that is integral to ClamAV's functionality. The recipe is already using system libraries where possible (bzip2, zlib, pcre2, openssl, libxml2, etc.) - the embedded code is only for components that must be vendored. (regex, YARA, inflate64 etc.)
I haven't explored lot, but I think system equivalents does not exist for YARA fork and specific LLVM bytecode components.
Scott Murray Nov. 14, 2025, 8:23 p.m. UTC | #3
On Fri, 14 Nov 2025, Hemant Jadhav via lists.yoctoproject.org wrote:

> On Fri, Nov 14, 2025 at 12:05 PM, Scott Murray wrote:
>
> >
> > To save me from digging into this myself, can you elaborate on why
> > upstream now has all these license files as opposed to the one the
> > previous version had? Are they vendoring a bunch of code from all
> > those projects now? If so, can we disable vendored libraries to use
> > system provided versions?
>
> The multiple LICENSE files are present because the upstream project
> embeds modified portions of several third-party libraries directly
> within libclamav, rather than linking against system versions.
> Actually, the same embedded code existed in 0.104.4 as well. The old
> 0.104.4 recipe only declared LICENSE = "LGPL-2.1-only", but it should
> have included all the embedded licenses too. I think this was
> missed/incomplete in the old recipe.

Okay.

> Answering to your next question: Unfortunately, NO - these are not
> optional external dependencies but embedded code that is integral to
> ClamAV's functionality. The recipe is already using system libraries
> where possible (bzip2, zlib, pcre2, openssl, libxml2, etc.) - the
> embedded code is only for components that must be vendored. (regex,
> YARA, inflate64 etc.)
> I haven't explored lot, but I think system equivalents does not exist
> for YARA fork and specific LLVM bytecode components.

Hmm, that's unfortunate.  I am curious what license compliance folks
would make of some of it, as there are differing schools of thought on
mixing GPL and Apache licensed code (FSF says no go, IIRC), and even
though they discuss it here:

https://github.com/Cisco-Talos/clamav?tab=readme-ov-file#3rd-party-code

I do see at least one source file on an initial skim that IMO would
probably need clarification if one were auditing.  Documenting all the
licenses in play is probably the best we can do to try to give folks an
idea that there's a bit more going on with it.

Thanks,

Scott
Hemant Jadhav Nov. 14, 2025, 8:30 p.m. UTC | #4
On Fri, Nov 14, 2025 at 12:05 PM, Scott Murray wrote:

> 
> This is a non-starter, as it:
> - breaks build reproducibility, which is even more important for a
> security tool.
> - opens the door to build breakage if any higher-order dependency
> crates increase their required Rust version (I've seen this happen
> multiple times in the past few years).
> 
> The recipe needs to use the regular cargo.bbclass and an include file
> for the crates generated with cargo-update-recipe-crates.bbclass.
> 
> Scott

Thank you, Scott, for pointing this out!

I didn't realize while implementing this that network access would be a non-starter for reproducibility.
I incorrectly borrowed the CARGO_DISABLE_BITBAKE_VENDORING approach from the Rust compiler recipe (meta/recipes-devtools/rust/rust_1.90.0.bb), which uses it because the Rust compiler comes with its own pre-vendored sources. This pattern is not appropriate for regular applications.

I am reworking the recipe to use the proper cargo vendoring approach. I've looked at the Suricata recipe in meta-security, which uses cargo + cargo-update-recipe-crates classes. I can rewrite the code.

Is this vendoring approach acceptable, or would you prefer a different solution for handling the Rust dependencies?
In case if this works, do you want me to start a new thread or continue with next version.
diff mbox series

Patch

diff --git a/recipes-scanners/clamav/clamav_1.4.3.bb b/recipes-scanners/clamav/clamav_1.4.3.bb
new file mode 100644
index 0000000..0cbae53
--- /dev/null
+++ b/recipes-scanners/clamav/clamav_1.4.3.bb
@@ -0,0 +1,209 @@ 
+SUMMARY = "ClamAV anti-virus utilities and scanner tools"
+DESCRIPTION = "ClamAV is an open source antivirus engine for detecting trojans, viruses, malware & other malicious threats."
+HOMEPAGE = "http://www.clamav.net/index.html"
+SECTION = "security"
+LICENSE = "GPL-2.0-only & LGPL-2.1-only & BSD-2-Clause & Zlib & Apache-2.0-with-LLVM-exception"
+LIC_FILES_CHKSUM = "file://COPYING.txt;md5=2c0b5770a62017a3121c69bb9f680b0c \
+                    file://COPYING/COPYING.LGPL;md5=2d5025d4aa3495befef8f17206a5b0a1 \
+                    file://COPYING/COPYING.bzip2;md5=ae8d555c34b656ff864ea9437a10d3a0 \
+                    file://COPYING/COPYING.zlib;md5=3648a0b9713ab246e11536055165a41a \
+                    file://COPYING/COPYING.llvm;md5=c82fc668ef1809acdd0684811df93bfc \
+                    file://COPYING/COPYING.unrar;md5=6a741ba21afc8b71aeaee3b5f86a8111 \
+                    file://COPYING/COPYING.file;md5=e63a61022c36cff2fdfbf02dd51674bd \
+                    file://COPYING/COPYING.curl;md5=be5d9e1419c4363f4b32037a2d3b7ffa \
+                    "
+
+DEPENDS = "glibc llvm libtool db openssl zlib curl libxml2 bison pcre2 json-c libcheck rust-native cargo-native libmspack"
+
+SRC_URI = "git://github.com/Cisco-Talos/clamav;branch=rel/1.4;protocol=https \
+           file://clamd.conf \
+           file://freshclam.conf \
+           file://volatiles.03_clamav \
+           file://tmpfiles.clamav \
+           "
+
+# ClamAV version 1.4.3
+SRCREV = "d8b053865fd5995f7af98bfbcd98c9a5644bfe2b"
+
+COMPATIBLE_HOST:libc-musl:class-target = "null"
+
+LEAD_SONAME = "libclamav.so"
+SO_VER = "12.0.0"
+BINCONFIG = "${bindir}/clamav-config"
+
+inherit cmake chrpath pkgconfig useradd systemd multilib_header multilib_script cargo_common
+
+# Allow network access for Cargo to fetch git dependencies (onenote_parser)
+# This is required because ClamAV's Cargo.toml has a direct git dependency
+do_compile[network] = "1"
+do_configure[network] = "1"
+
+# Disable cargo vendoring since we're using network access
+CARGO_DISABLE_BITBAKE_VENDORING = "1"
+
+UPSTREAM_CHECK_COMMITS = "1"
+
+CLAMAV_USER ?= "clamav"
+CLAMAV_GROUP ?= "clamav"
+
+PACKAGECONFIG ?= "clamonacc \
+                  ${@bb.utils.contains("DISTRO_FEATURES", "systemd", "systemd", "", d)}"
+PACKAGECONFIG[milter] = "-DENABLE_MILTER=ON ,-DENABLE_MILTER=OFF, curl, curl"
+PACKAGECONFIG[clamonacc] = "-DENABLE_CLAMONACC=ON ,-DENABLE_CLAMONACC=OFF,"
+PACKAGECONFIG[unrar] = "-DENABLE_UNRAR=ON ,-DENABLE_UNRAR=OFF,"
+PACKAGECONFIG[freshclamdnsfix] = "-DENABLE_FRESHCLAM_DNS_FIX=ON ,-DENABLE_FRESHCLAM_DNS_FIX=OFF,"
+PACKAGECONFIG[systemd] = "-DENABLE_SYSTEMD=ON -DSYSTEMD_UNIT_DIR=${systemd_system_unitdir}, -DENABLE_SYSTEMD=OFF, systemd"
+
+EXTRA_OECMAKE = "-DCMAKE_BUILD_TYPE=Release -DOPTIMIZE=ON -DENABLE_JSON_SHARED=OFF \
+                 -DCLAMAV_GROUP=${CLAMAV_GROUP} -DCLAMAV_USER=${CLAMAV_USER} \
+                 -DENABLE_TESTS=OFF -DBUILD_SHARED_LIBS=ON \
+                 -DDO_NOT_SET_RPATH=ON \
+                 -DCMAKE_INSTALL_PREFIX=${prefix} \
+                 -DCMAKE_INSTALL_SYSCONFDIR=${sysconfdir} \
+                 -DCMAKE_INSTALL_FULL_SYSCONFDIR=${sysconfdir} \
+                 -DSYSCONFDIR=${sysconfdir} \
+                 -DHAVE_SIGNED_RIGHT_SHIFT=1 \
+                 -DHAVE_UNAME_SYSCALL=1 \
+                 -DHAVE_FD_PASSING=1 \
+                 -Dtest_run_result=0 \
+                 -Dtest_run_result__TRYRUN_OUTPUT='' \
+                 -DCMAKE_C_FLAGS='${CFLAGS} -Wno-error=format-truncation -Wno-error=unused-function' \
+                 "
+
+MULTILIB_SCRIPTS = "${PN}-dev:${bindir}/clamav-config"
+
+# ClamAV uses both CMake and Rust/Cargo, so we need to configure both
+do_configure() {
+    cmake_do_configure
+    cargo_common_do_configure
+}
+
+do_compile:append() {
+    # Remove build path references from Rust static library
+    ${OBJCOPY} --remove-section .debug_line ${B}/libclamav_rust/target/${RUST_TARGET_SYS}/release/libclamav_rust.a || true
+}
+
+do_install:append() {
+    install -d ${D}/${sysconfdir}
+    install -d ${D}/${localstatedir}/lib/clamav
+    install -d ${D}${sysconfdir}/clamav ${D}${sysconfdir}/default/volatiles
+
+    install -m 644 ${UNPACKDIR}/clamd.conf ${D}${sysconfdir}
+    install -m 644 ${UNPACKDIR}/freshclam.conf ${D}${sysconfdir}
+    install -m 0644 ${UNPACKDIR}/volatiles.03_clamav  ${D}${sysconfdir}/default/volatiles/03_clamav
+
+    if [ -d ${D}${prefix}/etc ]; then
+        cp -r ${D}${prefix}/etc/* ${D}${sysconfdir}/ 2>/dev/null || true
+        rm -rf ${D}${prefix}/etc
+    fi
+
+    sed -i -e 's#${STAGING_DIR_HOST}##g' ${D}${libdir}/pkgconfig/libclamav.pc
+
+    # Remove build path references from binaries
+    chrpath -d ${D}${bindir}/clambc || true
+    chrpath -d ${D}${bindir}/sigtool || true
+    chrpath -d ${D}${libdir}/libclamav.so.${SO_VER} || true
+    chrpath -d ${D}${libdir}/libfreshclam.so.* || true
+
+    rm ${D}/${libdir}/libclamav.so
+    if [ "${INSTALL_CLAMAV_CVD}" = "1" ]; then
+        install -m 666 ${S}/clamav_db/* ${D}/${localstatedir}/lib/clamav/.
+    fi
+
+    rm ${D}/${libdir}/libfreshclam.so
+
+    if ${@bb.utils.contains('DISTRO_FEATURES','systemd','true','false',d)};then
+        install -d ${D}${sysconfdir}/tmpfiles.d
+        install -m 0644 ${UNPACKDIR}/tmpfiles.clamav ${D}${sysconfdir}/tmpfiles.d/clamav.conf
+    fi
+    oe_multilib_header clamav-types.h
+}
+
+pkg_postinst:${PN} () {
+    if [ -z "$D" ]; then
+        if command -v systemd-tmpfiles >/dev/null; then
+            systemd-tmpfiles --create ${sysconfdir}/tmpfiles.d/clamav.conf
+        elif [ -e ${sysconfdir}/init.d/populate-volatile.sh ]; then
+            ${sysconfdir}/init.d/populate-volatile.sh update
+        fi
+    fi
+}
+
+PACKAGES += "${PN}-daemon ${PN}-clamdscan ${PN}-freshclam ${PN}-libclamav ${PN}-libclammspack"
+
+FILES:${PN} = "${bindir}/clambc ${bindir}/clamscan ${bindir}/clamsubmit ${sbindir}/clamonacc \
+               ${bindir}/*sigtool ${mandir}/man1/clambc* ${mandir}/man1/clamscan* \
+               ${mandir}/man1/sigtool* ${mandir}/man1/clambsubmit* \
+               ${docdir}/clamav/*"
+
+FILES:${PN}-clamdscan = "${bindir}/clamdscan \
+                         ${docdir}/clamdscan/* \
+                         ${mandir}/man1/clamdscan* \
+                         "
+
+FILES:${PN}-daemon = "${bindir}/clamconf ${bindir}/clamdtop ${sbindir}/clamd \
+                      ${mandir}/man1/clamconf* ${mandir}/man1/clamdtop* \
+                      ${mandir}/man5/clamd* ${mandir}/man8/clamd* \
+                      ${sysconfdir}/clamd.conf* \
+                      ${systemd_system_unitdir}/clamav-daemon/* \
+                      ${docdir}/clamav-daemon/* ${sysconfdir}/clamav-daemon \
+                      ${sysconfdir}/logcheck/ignore.d.server/clamav-daemon \
+                      ${systemd_system_unitdir}/clamav-daemon.service \
+                      ${systemd_system_unitdir}/clamav-clamonacc.service \
+                      "
+
+FILES:${PN}-freshclam = "${bindir}/freshclam \
+                         ${sysconfdir}/freshclam.conf* \
+                         ${sysconfdir}/clamav ${sysconfdir}/default/volatiles \
+                         ${sysconfdir}/tmpfiles.d/*.conf \
+                         ${localstatedir}/lib/clamav \
+                         ${docdir}/${PN}-freshclam ${mandir}/man1/freshclam.* \
+                         ${mandir}/man5/freshclam.conf.* \
+                         ${systemd_system_unitdir}/clamav-freshclam.service"
+
+FILES:${PN}-libclamav = "${libdir}/libclamav.so* \
+                         ${libdir}/libfreshclam.so* ${docdir}/libclamav/* \
+                         "
+
+FILES:${PN}-libclammspack = "${libdir}/libclammspack.so* \
+                             ${libdir}/libmspack.so* \
+                             "
+
+FILES:${PN}-dev = "${bindir}/clamav-config ${libdir}/*.la \
+                   ${libdir}/pkgconfig/*.pc \
+                   ${mandir}/man1/clamav-config.* \
+                   ${includedir}/*.h ${docdir}/libclamav*"
+
+FILES:${PN}-staticdev = "${libdir}/*.a"
+
+FILES:${PN}-doc = "${mandir}/man/* \
+                   ${datadir}/man/* \
+                   ${docdir}/* \
+                   "
+
+RDEPENDS:${PN} = "openssl ncurses-libncurses libxml2 libbz2 ncurses-libtinfo curl libpcre2 clamav-libclamav"
+RDEPENDS:${PN}-daemon = "clamav clamav-freshclam"
+RDEPENDS:${PN}-freshclam = "clamav"
+RDEPENDS:${PN}-libclamav = "clamav-libclammspack"
+
+RRECOMMENDS:${PN} = "clamav-freshclam"
+
+RPROVIDES:${PN} += "${PN}-systemd"
+RREPLACES:${PN} += "${PN}-systemd"
+RCONFLICTS:${PN} += "${PN}-systemd"
+
+SYSTEMD_PACKAGES = "${PN}-daemon ${PN}-freshclam"
+SYSTEMD_SERVICE:${PN}-daemon = "clamav-daemon.service"
+SYSTEMD_SERVICE:${PN}-freshclam = "clamav-freshclam.service"
+
+USERADD_PACKAGES = "${PN}-freshclam"
+GROUPADD_PARAM:${PN}-freshclam = "--system ${CLAMAV_GROUP}"
+USERADD_PARAM:${PN}-freshclam = "--system -g ${CLAMAV_GROUP} --home-dir \
+                                 ${localstatedir}/lib/${BPN} \
+                                 --no-create-home --shell /sbin/nologin ${CLAMAV_USER}"
+
+INSANE_SKIP:${PN}-libclamav += "dev-so"
+INSANE_SKIP:${PN}-libclammspack += "dev-so"
+INSANE_SKIP:${PN} += "buildpaths"
+INSANE_SKIP:${PN}-libclamav += "buildpaths"
+INSANE_SKIP:${PN}-staticdev += "buildpaths"
diff --git a/recipes-scanners/clamav/files/tmpfiles.clamav b/recipes-scanners/clamav/files/tmpfiles.clamav
index fd5adfe..8e0849e 100644
--- a/recipes-scanners/clamav/files/tmpfiles.clamav
+++ b/recipes-scanners/clamav/files/tmpfiles.clamav
@@ -1,3 +1,4 @@ 
 #Type Path        Mode UID  GID  Age Argument
+d /var/lib/clamav 0755 clamav clamav -
 d /var/log/clamav 0755 clamav clamav -
 f /var/log/clamav/freshclam.log 0644 clamav clamav -
diff --git a/recipes-scanners/clamav/files/volatiles.03_clamav b/recipes-scanners/clamav/files/volatiles.03_clamav
index ee2153c..0561c4d 100644
--- a/recipes-scanners/clamav/files/volatiles.03_clamav
+++ b/recipes-scanners/clamav/files/volatiles.03_clamav
@@ -1,3 +1,4 @@ 
 # <type> <owner> <group> <mode> <path> <linksource>
+d clamav clamav 0755 /var/lib/clamav none
 d clamav clamav 0755 /var/log/clamav none
 f clamav clamav 0655 /var/log/clamav/freshclam.log none