Bug 1869195

Summary: probe_file traverses CIFS file systems even when rule applies to local file systems only
Product: Red Hat Enterprise Linux 7 Reporter: Renaud Métrich <rmetrich>
Component: openscapAssignee: Jan Černý <jcerny>
Status: CLOSED DEFERRED QA Contact: BaseOS QE Security Team <qe-baseos-security>
Severity: high Docs Contact:
Priority: high    
Version: 7.8CC: ekolesni, mhaicman
Target Milestone: rc   
Target Release: ---   
Hardware: All   
OS: Linux   
Whiteboard:
Fixed In Version: Doc Type: If docs needed, set a value
Doc Text:
Story Points: ---
Clone Of:
: 1870087 (view as bug list) Environment:
Last Closed: 2020-11-13 13:38:01 UTC Type: Bug
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:
Bug Depends On:    
Bug Blocks: 1870087    

Description Renaud Métrich 2020-08-17 09:10:19 UTC
Description of problem:

When a CIFS device is specified using Windows style URI ("\\server\directory") instead of Unix style URI ("//server/directory"), many rules executing probe_file internally execute on these remote file systems even when recurse_file_system:local is specified in the rule.

This happens because the code checking for locality is very weak.

src/OVAL/probes/fsdev.c: (from RHEL 8.2.0 code, RHEL 7.8 code is identical)
-------- 8< ---------------- 8< ---------------- 8< ---------------- 8< --------
 80 static int is_local_fs(struct mntent *ment)
 :
104         s = ment->mnt_fsname;
105         /* If the fsname begins with "//", it is probably CIFS. */
106         if (s[0] == '/' && s[1] == '/')
107                 return 0;
108 
109         /* If there's a ':' in the fsname and it occurs before any
110          * '/', then this is probably NFS and the file system is
111          * considered "remote".
112          */
113         s = strpbrk(s, "/:");
114         if (s && *s == ':')
115                 return 0;
116 
117         return 1;
-------- 8< ---------------- 8< ---------------- 8< ---------------- 8< --------

Instead of checking how the URI looks like, the code should rely on mnt_type field instead and do something similar to what systemd does:

src/shared/util.c: (from RHEL 8.2.0 code)
-------- 8< ---------------- 8< ---------------- 8< ---------------- 8< --------
596 bool fstype_is_network(const char *fstype) {
597         const char *x;
598 
599         x = startswith(fstype, "fuse.");
600         if (x)
601                 fstype = x;
602 
603         return STR_IN_SET(fstype,
604                           "afs",
605                           "cifs",
606                           "smb3",
607                           "smbfs",
608                           "sshfs",
609                           "ncpfs",
610                           "ncp",
611                           "nfs",
612                           "nfs4",
613                           "gfs",
614                           "gfs2",
615                           "glusterfs",
616                           "pvfs2", /* OrangeFS */
617                           "ocfs2",
618                           "lustre");
619 }
-------- 8< ---------------- 8< ---------------- 8< ---------------- 8< --------

This would also work for fuse filesystems.


Version-Release number of selected component (if applicable):

openscap-1.2.17-9 & later

How reproducible:

Always

Steps to Reproduce:
1. Set up a CIFS mount

  # mount -t cifs '\\vm-rhel7\export' /mnt/export

2. Execute probe_file under strace

  # strace -fttTvyy -o probe_file.strace -s 1024 -- /usr/libexec/openscap/probe_file

3. Send order to search for "shosts.equiv" by cat'ing to probe_file

  (#d8:seap.msg#d3::id#d0((#d11:file_object#d3::id#d48:oval:ssg-object_no_shosts_equiv_files_root:obj:1#d13::oval_version#d4:5.11)((#d4:path#d10::operation#d5#d10::var_check#d1)#d1:/)((#d8:filename#d10::operation#d11#d10::var_check#d1)#d14:shosts\\.equiv$)((#d9:behaviors#d10::max_depth#d2:-1#d8::recurse#d11:directories#d18::recurse_direction#d4:down#d20::recurse_file_system#d5:local))))

4. Grep for "/mnt/export" in the strace

  # grep -m 10 "/mnt/export" probe_file.strace

Actual results:

  ...
  3423  11:06:04.642979 lstat("/mnt/export/.bash_logout", {st_dev=makedev(0, 40), st_ino=33863760, st_mode=S_IFREG|0644, st_nlink=1, st_uid=0, st_gid=0, st_blksize=16384, st_blocks=8, st_size=4, st_atime=1596787476 /* 2020-08-07T10:04:36.737827500+0200 */, st_atime_nsec=737827500, st_mtime=1594218530 /* 2020-07-08T16:28:50.395275700+0200 */, st_mtime_nsec=395275700, st_ctime=1594218530 /* 2020-07-08T16:28:50.395275700+0200 */, st_ctime_nsec=395275700}) = 0 <0.000471>
  ...

Expected results:

  No browsing of files in /mnt/export


Additional info:

This is a well known issue (BZ #1694962 closed as WONTFIX) but there is no satisfying workaround, in particular when using Satellite's foreman functionality.
This can lead to extremely long oscap runs, hence should be fixed.

Comment 2 Jan Černý 2020-08-20 07:28:49 UTC
This issue has been fixed upstream in https://github.com/OpenSCAP/openscap/pull/1573

Comment 3 Marek Haicman 2020-11-13 13:38:01 UTC
Hello. Red Hat Enterprise Linux 7 has entered Maintenance Phase 2. This, as described here https://access.redhat.com/support/policy/updates/errata, means Critical and Important impact security advisories, and Urgent priority bugfix advisories are to be provided. As this bug is not of either criteria, I am closing it as CLOSED/DEFERRED, as it should be fixed in RHEL 8.3 release (see Bug 1870087).