Bug#989549: clamav-daemon: any local user can shut clamd down via control socket
FYI, bugzilla.clamav.net has been discontinued. New upstreams bugs: https://github.com/Cisco-Talos/clamav/issues/1169 (also https://github.com/Cisco-Talos/clamav/issues/347 https://github.com/Cisco-Talos/clamav/issues/922)
Bug#989549: clamav-daemon: any local user can shut clamd down via control socket
forwarded -1 https://bugzilla.clamav.net/show_bug.cgi?id=12782 Sebastian
Bug#989549: clamav-daemon: any local user can shut clamd down via control socket
Some additional notes, from discussion on the Ubuntu bugs: 1. dpkg-reconfigure dialogs say in the first dialog: "The ClamAV suite won't work if it isn't configured". However, that dialog is not displayed upon install, and except for https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=979077 clamd does work out of the box (after a reboot for instance to address 979077). 2. While via dpkg-reconfigure, we can restrict access to the socket and somewhat mitigate the vulnerability, it's not really an acceptable solution, as that socket is used both for the service and for daemon control, so by restricting access to the socket, we're preventing access to the service, and clients that need access to the service (MTAs, ftp, web servers...) are not the same as the ones that are meant to control the daemon (systemd, freshclam...). 3. The systemd service unit uses default Type=simple with clamd started in foreground. That means clamd is considered up and active before it is ready to accept requests. Using Type=forking (and remove the --foreground) would address that. (reinstating PidFile in clamd.conf would (according to systemd doc) make the MainPID detection more reliable and help with shutting down / reloading when access to the socket is restricted. See also https://github.com/extremeshok/clamav-unofficial-sigs/issues/392) 4. I'd expect a number of packages which depend on clamd or can be configured to do so currently rely on clamd being configured with the socket publicly accessible. Those would have to be taken into account in any fix to the issue. At the Ubuntu bug, I mention e2guardian or clamsmtp which depend on clamav-daemon though I've not looked at those in details. There's also amavis which is typically used with clamd for email filtering. To mitigate the issue on a deployment where clamd is used only by amavis, I changed the socket permissions to be rw--- clamav clamav, change the Type to forking as per above, and added an ACL to the socket file upon creation for amavis to be able to connect to it: --- /lib/systemd/system/clamav-daemon.service 2021-06-04 15:05:34.272466670 +0100 +++ /etc/systemd/system/clamav-daemon.service 2021-06-04 15:05:36.072489235 +0100 @@ -6,11 +6,11 @@ ConditionPathExistsGlob=/var/lib/clamav/daily.{c[vl]d,inc} [Service] -ExecStart=/usr/sbin/clamd --foreground=true +Type=forking +ExecStart=/usr/sbin/clamd # Reload the database ExecReload=/bin/kill -USR2 $MAINPID -StandardOutput=syslog -TimeoutStartSec=420 +TimeoutStartSec=5min [Install] WantedBy=multi-user.target --- /dev/null 2021-06-04 15:21:19.23200 +0100 +++ /etc/systemd/system/clamav-daemon.service.d/amavis.conf 2021-06-04 15:19:37.335686866 +0100 @@ -0,0 +1,10 @@ +[Unit] +Before=amavis.service + +[Service] +# clamd allows its clients to shut it down! So access to /run/clamav/clamd.ctl +# is restricted to a strict minimum. That's only members of the clamav group. +# The amavis process can only be in one group. It also doesn't need access to +# any of clamav's private resources. So we're only granting it access to the +# socket. +ExecStartPost=/usr/bin/setfacl -m u:amavis:rw /run/clamav/clamd.ctl (requires acl package. Could be improved by adding PidFile to clamd.conf and systemd service unit). -- Stephane
Bug#989549: clamav-daemon: any local user can shut clamd down via control socket
Package: clamav-daemon Version: 0.103.2+dfsg-2 Severity: important Hello, this is spawned off https://bugs.launchpad.net/ubuntu/+source/clamav/+bug/1930393 where I reported the same bug for Ubuntu. Also affects Debian. It's a (non-critical) security vulnerability but the issue has already made public above. After the default installation of clamav-daemon, as clamd's service access socket (which also double as a control socket) is world read+writeable: $ namei -l /run/clamav/clamd.ctl f: /run/clamav/clamd.ctl drwxr-xr-x root root / drwxr-xr-x root root run drwxr-xr-x clamav root clamav srw-rw-rw- clamav clamav clamd.ctl (and needs to be for users to be able to pass files to scan, to use the service) and clamd doesn't seem to be doing any access control itself either, any local user can shutdown clamd by sending the SHUTDOWN (aka QUIT) command there: $ printf 'zSHUTDOWN\0' | socat - unix-connect:/run/clamav/clamd.ctl or just $ echo QUIT | socat - unix:/run/clamav/clamd.ctl For instance. Which makes it a denial of service vulnerability. Other commands such as RELOAD (clamdscan --reload) or STATS may also need to be restricted. That's with the current Debian testing version, but I'd expect it applies to all versions of Debian and derivative. It should probably be addressed upstreams by clamd checking the credentials of the incoming connection, or as Seth suggested by separating out the admin commands to a different (restricted) socket. -- Package-specific info: --- configuration --- Checking configuration files in /etc/clamav Config file: clamd.conf --- AlertExceedsMax disabled PreludeEnable disabled PreludeAnalyzerName = "ClamAV" LogFile = "/var/log/clamav/clamav.log" LogFileUnlock disabled LogFileMaxSize = "4294967295" LogTime = "yes" LogClean disabled LogSyslog disabled LogFacility = "LOG_LOCAL6" LogVerbose disabled LogRotate = "yes" ExtendedDetectionInfo = "yes" PidFile disabled TemporaryDirectory disabled DatabaseDirectory = "/var/lib/clamav" OfficialDatabaseOnly disabled LocalSocket = "/var/run/clamav/clamd.ctl" LocalSocketGroup = "clamav" LocalSocketMode = "666" FixStaleSocket = "yes" TCPSocket disabled TCPAddr disabled MaxConnectionQueueLength = "15" StreamMaxLength = "26214400" StreamMinPort = "1024" StreamMaxPort = "2048" MaxThreads = "12" ReadTimeout = "180" CommandReadTimeout = "30" SendBufTimeout = "200" MaxQueue = "100" IdleTimeout = "30" ExcludePath disabled MaxDirectoryRecursion = "15" FollowDirectorySymlinks disabled FollowFileSymlinks disabled CrossFilesystems = "yes" SelfCheck = "3600" ConcurrentDatabaseReload = "yes" DisableCache disabled VirusEvent disabled ExitOnOOM disabled AllowAllMatchScan = "yes" Foreground disabled Debug disabled LeaveTemporaryFiles disabled User = "clamav" Bytecode = "yes" BytecodeSecurity = "Paranoid" BytecodeTimeout = "6" BytecodeUnsigned disabled BytecodeMode = "Auto" DetectPUA disabled ExcludePUA disabled IncludePUA disabled ScanPE = "yes" ScanELF = "yes" ScanMail = "yes" ScanPartialMessages disabled PhishingSignatures = "yes" PhishingScanURLs = "yes" HeuristicAlerts = "yes" HeuristicScanPrecedence disabled StructuredDataDetection disabled StructuredMinCreditCardCount = "3" StructuredMinSSNCount = "3" StructuredSSNFormatNormal = "yes" StructuredSSNFormatStripped disabled ScanHTML = "yes" ScanOLE2 = "yes" AlertBrokenExecutables disabled AlertBrokenMedia disabled AlertEncrypted disabled StructuredCCOnly disabled AlertEncryptedArchive disabled AlertEncryptedDoc disabled AlertOLE2Macros disabled AlertPhishingSSLMismatch disabled AlertPhishingCloak disabled AlertPartitionIntersection disabled ScanPDF = "yes" ScanSWF = "yes" ScanXMLDOCS = "yes" ScanHWP3 = "yes" ScanArchive = "yes" ForceToDisk disabled MaxScanTime = "12" MaxScanSize = "104857600" MaxFileSize = "262144000" MaxRecursion = "16" MaxFiles = "1" MaxEmbeddedPE = "10485760" MaxHTMLNormalize = "10485760" MaxHTMLNoTags = "2097152" MaxScriptNormalize = "5242880" MaxZipTypeRcg = "1048576" MaxPartitions = "50" MaxIconsPE = "100" MaxRecHWP3 = "16" PCREMatchLimit = "1" PCRERecMatchLimit = "5000" PCREMaxFileSize = "26214400" OnAccessMountPath disabled OnAccessIncludePath disabled OnAccessExcludePath disabled OnAccessExcludeRootUID disabled OnAccessExcludeUID disabled OnAccessExcludeUname disabled OnAccessMaxFileSize = "5242880" OnAccessDisableDDD disabled OnAccessPrevention disabled OnAccessExtraScanning disabled OnAccessCurlTimeout = "5000" OnAccessMaxThreads = "5" OnAccessRetryAttempts disabled OnAccessDenyOnError disabled DevACOnly disabled DevACDepth disabled DevPerformance disabled DevLiblog disabled DisableCertCheck disabled AlgorithmicDetection = "yes" BlockMax disabled PhishingAlwaysBlockSSLMismatch disabled PhishingAlwaysBlockCloak disabled PartitionIntersection disabled OLE2BlockMacros disabled ArchiveBlockEncrypted disabled Config file: freshclam.conf --- LogFileMaxSize = "4294967295" LogTime = "yes" LogSyslog disabled LogFacility