Bug 12676 - Segmentation fault with regex, multiscan and fdpass
Segmentation fault with regex, multiscan and fdpass
Status: RESOLVED FIXED
Product: ClamAV
Classification: ClamAV
Component: clamdscan
stable
x86_64 GNU/Linux
: P3 normal
: 0.101.0
Assigned To: Micah Snyder
:
Depends on:
Blocks:
  Show dependency treegraph
 
Reported: 2021-02-15 06:29 EST by Stephen Agate
Modified: 2021-03-30 22:41 EDT (History)
3 users (show)

See Also:
QA Contact:


Attachments
clamdscan crash patch (1.06 KB, patch)
2021-02-18 20:58 EST, Micah Snyder
no flags Details | Diff
clamdscan crash patch 2 (1.81 KB, patch)
2021-02-26 14:50 EST, Micah Snyder
no flags Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Stephen Agate 2021-02-15 06:29:52 EST
Steps to reproduce:

1. Add the following to clamd.conf:
        ExcludePath \.(c|h|txt)$
2. Restart the daemon
        sudo systemctl start clamav-daemon
3. Manually scan something using:
        sudo clamdscan --multiscan --fdpass /usr/bin

Removing either --multiscan or --fdpass avoids the seg fault.

$ clamconf -n
Checking configuration files in /etc/clamav

Config file: clamd.conf
-----------------------
LogFile = "/var/log/clamav/clamd.log"
LogFileMaxSize = "20971520"
LogTime = "yes"
PidFile = "/run/clamav/clamd.pid"
TemporaryDirectory = "/tmp"
LocalSocket = "/run/clamav/clamd.ctl"
ExcludePath = "\.(c|h|txt)$", "/\.(svn|git)/"
MaxDirectoryRecursion = "25"
User = "clamav"
ScanArchive disabled

Config file: freshclam.conf
---------------------------
PidFile = "/run/clamav/freshclam.pid"
UpdateLogFile = "/var/log/clamav/freshclam.log"
DatabaseMirror = "database.clamav.net"

Config file: clamav-milter.conf
-------------------------------
LogFile = "/var/log/clamav/clamav-milter.log"
LogTime = "yes"
PidFile = "/run/clamav/clamav-milter.pid"
TemporaryDirectory = "/tmp"
User = "clamav"

Software settings
-----------------
Version: 0.103.1
Optional features supported: MEMPOOL IPv6 AUTOIT_EA06 BZIP2 LIBXML2 PCRE2 ICONV JSON RAR 

Database information
--------------------
Database directory: /var/lib/clamav
main.cvd: version 59, sigs: 4564902, built on Mon Nov 25 13:56:15 2019
bytecode.cvd: version 331, sigs: 94, built on Thu Sep 19 17:12:33 2019
daily.cvd: version 26080, sigs: 4060834, built on Sun Feb 14 12:15:03 2021
Total number of signatures: 8625830

Platform information
--------------------
uname: Linux 5.10.16-arch1-1 #1 SMP PREEMPT Sat, 13 Feb 2021 20:50:18 +0000 x86_64
OS: linux-gnu, ARCH: x86_64, CPU: x86_64
Full OS version: "Arch Linux"
zlib version: 1.2.11 (1.2.11), compile flags: a9
platform id: 0x0a217a7a08000000000a0200

Build information
-----------------
GNU C: 10.2.0 (10.2.0)
CPPFLAGS: -D_FORTIFY_SOURCE=2
CFLAGS: -march=x86-64 -mtune=generic -O2 -pipe -fno-plt  -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64
CXXFLAGS: -march=x86-64 -mtune=generic -O2 -pipe -fno-plt
LDFLAGS: -Wl,-O1,--sort-common,--as-needed,-z,relro,-z,now
Configure: '--prefix=/usr' '--sbindir=/usr/bin' '--sysconfdir=/etc/clamav' '--with-dbdir=/var/lib/clamav' '--with-user=clamav' '--with-group=clamav' '--with-system-libmspack' '--disable-rpath' '--disable-clamav' '--disable-llvm' '--enable-zlib-vcheck' '--enable-milter' '--enable-clamdtop' 'CXXFLAGS=-march=x86-64 -mtune=generic -O2 -pipe -fno-plt' 'LDFLAGS=-Wl,-O1,--sort-common,--as-needed,-z,relro,-z,now' 'CPPFLAGS=-D_FORTIFY_SOURCE=2' 'CFLAGS=-march=x86-64 -mtune=generic -O2 -pipe -fno-plt'
sizeof(void*) = 8
Engine flevel: 122, dconf: 122

$ uname -mrsp
Linux 5.10.16-arch1-1 x86_64 unknown

Using host libthread_db library "/usr/lib/libthread_db.so.1".
Core was generated by `clamdscan --multiscan --fdpass /usr/bin'.
Program terminated with signal SIGSEGV, Segmentation fault.
#0  0x00007f9df437b05e in __strncpy_avx2 () from /usr/lib/libc.so.6
(gdb) bt
#0  0x00007f9df437b05e in __strncpy_avx2 () from /usr/lib/libc.so.6
#1  0x000055d6542ac7b7 in ?? ()
#2  0x000055d6542a8d3d in ?? ()
#3  0x000055d6542a8f52 in ?? ()
#4  0x00007f9df4575015 in cli_ftw () from /usr/lib/libclamav.so.9
#5  0x000055d6542a9f59 in ?? ()
#6  0x000055d6542aa127 in ?? ()
#7  0x000055d6542aac07 in ?? ()
#8  0x000055d6542a8408 in ?? ()
#9  0x00007f9df423fb25 in __libc_start_main () from /usr/lib/libc.so.6
#10 0x000055d6542a862e in ?? ()
Comment 1 Micah Snyder 2021-02-18 15:45:06 EST
Thanks for the report Stephen. I was able to reproduce the issue you describe, after adding the ExcludePath regex. 

I don't believe this is a security issue so I'm making the ticket public. This is definitely something we need to fix though. :) I'll spend a little more time on it this afternoon.
Comment 2 Micah Snyder 2021-02-18 20:58:30 EST
Created attachment 7736 [details]
clamdscan crash patch

From the backtrace for the clamdscan crash, looks like the filename is NULL and it proceeds for the regex matching w/out any NULL checks.

Program received signal SIGSEGV, Segmentation fault.
__strncpy_avx2 () at ../sysdeps/x86_64/multiarch/strcpy-avx2.S:301
301     ../sysdeps/x86_64/multiarch/strcpy-avx2.S: No such file or directory.
(gdb) bt
#0  __strncpy_avx2 () at ../sysdeps/x86_64/multiarch/strcpy-avx2.S:301
#1  0x00005555555656ac in match_regex (filename=0x0, pattern=0x55555559ec90 "\\.(c|h|txt)$")
    at ../shared/misc.c:453
#2  0x00005555555621be in chkpath (path=0x0) at ../clamdscan/proto.c:243
#3  0x000055555556317d in parallel_callback (sb=0x7fffffffe6f0, filename=0x0,
    path=0x55555559d2c0 "/usr/bin", reason=visit_directory_toplev, data=0x7fffffffe7d8)
    at ../clamdscan/proto.c:626
#4  0x00007ffff7cb966a in cli_ftw (path=0x55555559d2c0 "/usr/bin", flags=8, maxdepth=15,
    callback=0x555555563082 <parallel_callback>, data=0x7fffffffe7d8,
    pathchk=0x555555562207 <ftw_chkpath>) at ../libclamav/others_common.c:642
#5  0x000055555556376a in parallel_client_scan (file=0x55555559d2c0 "/usr/bin", scantype=3,
    infected=0x7fffffffe9ac, err=0x7fffffffe9b0, maxlevel=15, flags=8)
    at ../clamdscan/proto.c:748
#6  0x0000555555561200 in client_scan (file=0x555555598610 "/usr/bin", scantype=3,
    infected=0x7fffffffe9ac, err=0x7fffffffe9b0, maxlevel=15, session=1, flags=8)
    at ../clamdscan/client.c:318
#7  0x000055555556198e in client (opts=0x555555593eb0, infected=0x7fffffffe9ac,
    err=0x7fffffffe9b0) at ../clamdscan/client.c:442
#8  0x0000555555560365 in main (argc=4, argv=0x7fffffffec08) at ../clamdscan/clamdscan.c:169

I made a patch (attached) which provides the filepath for the regex match and also should resolve a possible minor memory leak in clamdscan if the scan returned something other than "success"/"clean". 

If you could please test out the patch, I'd appreciate it.
Comment 3 Stephen Agate 2021-02-19 16:55:05 EST
Thanks for looking at this. Your patch seems to fix the original problem, but it will still seg fault if a non-existent path is provided. For example:

sudo clamdscan --multiscan --fdpass /home/stephen/missing

Core was generated by `clamdscan --multiscan --fdpass /home/stephen/missing'.
Program terminated with signal SIGSEGV, Segmentation fault.
#0  0x00007f4fdf9f65f5 in __strncpy_sse2_unaligned () from /usr/lib/libc.so.6
(gdb) bt
#0  0x00007f4fdf9f65f5 in __strncpy_sse2_unaligned () from /usr/lib/libc.so.6
#1  0x000055f4588677b7 in strncpy (__len=513, __src=0x0, __dest=0x7ffd33434970 "\002")
    at /usr/include/bits/string_fortified.h:95
#2  match_regex (filename=filename@entry=0x0, pattern=0x55f45a49bc40 "\\.(c|h|txt)$") at misc.c:453
#3  0x000055f458863d3d in chkpath (path=0x0) at proto.c:243
#4  0x000055f458864003 in parallel_callback (sb=<optimized out>, filename=0x0, path=<optimized out>, 
    reason=error_stat, data=<optimized out>) at proto.c:626
#5  0x00007f4fdfcadee6 in handle_filetype (fname=0x55f45a49a2a0 "/home/stephen/missing", flags=8, 
    statbuf=0x7ffd33434db0, stated=0x7ffd33434dac, ft=0x7ffd33434da8, 
    callback=0x55f458863f10 <parallel_callback>, data=0x7ffd33434e98) at others_common.c:587
#6  0x00007f4fdfcaefd6 in cli_ftw (path=<optimized out>, path@entry=0x55f45a49a2a0 "/home/stephen/missing", 
    flags=flags@entry=8, maxdepth=maxdepth@entry=15, callback=callback@entry=0x55f458863f10 <parallel_callback>, 
    data=data@entry=0x7ffd33434e98, pathchk=pathchk@entry=0x55f458863d90 <ftw_chkpath>) at others_common.c:632
#7  0x000055f458864f59 in parallel_client_scan (file=file@entry=0x55f45a49a2a0 "/home/stephen/missing", 
    scantype=860049056, scantype@entry=3, infected=infected@entry=0x7ffd33435078, err=err@entry=0x7ffd3343507c, 
    maxlevel=maxlevel@entry=15, flags=flags@entry=8) at proto.c:748
#8  0x000055f458865127 in client_scan (file=0x55f45a495600 "/home/stephen/missing", scantype=scantype@entry=3, 
    infected=infected@entry=0x7ffd33435078, err=err@entry=0x7ffd3343507c, maxlevel=maxlevel@entry=15, 
    session=session@entry=1, flags=8) at client.c:318
#9  0x000055f458865c07 in client (opts=opts@entry=0x55f45a490eb0, infected=infected@entry=0x7ffd33435078, 
    err=err@entry=0x7ffd3343507c) at client.c:442
Comment 4 Micah Snyder 2021-02-22 18:00:33 EST
Thanks for testing it Stephen.  Nice catch!  I'll update you when I have a new patch.
Comment 5 Micah Snyder 2021-02-26 14:50:11 EST
Created attachment 7738 [details]
clamdscan crash patch 2

Here's a replacement patch that should also fix the scan of a path that doesn't exist. Please give it a try and let me know what you think.
Comment 6 Stephen Agate 2021-02-28 16:18:45 EST
I've tested the new patch and both crashes have now been fixed. Great job!

Thanks.

Stephen.
Comment 7 Shintaro Fujiwara 2021-03-22 12:28:43 EDT
Hi, I also encountered this bug just executing command below.

clamdscan --multiscan --fdpass /

Thank you.
Comment 8 Micah Snyder 2021-03-30 22:41:54 EDT
OK we just merged this in to the 0.104 development branch:
https://github.com/Cisco-Talos/clamav-devel/compare/5553a5e206ce...1cc8c2dce36c

Thanks for the bug report.