Hi,
We started to work on Bugzilla [1] about a problem in rules that check mount options for removable partitions. Currently, there are rules mount_option_noexec_removable_partitions, mount_option_nosuid_removable_partitions, mount_option_nodev_removable_partitions. These rules are templated. They use template mount_option_removable_partitions.
Overall, we have a confusion in these rules and their implementation. The checks doesn’t appear to properly recognize when partitions are configured with the proper nodev, nosuid, and noexec options.
Most importantly, we have found a discrepancy between the rule description in rule.yml files of the aforementioned rules and the actual OVAL checks used in the template (in /shared/templates/template_OVAL_mount_option_removable_partitions).
The rule description of rule mount_option_noexec_removable_partitions says that it prevents “direct execution of binaries from removable media (such as a USB key)”. Also, the rationale of this rule says: “Allowing users to execute binaries from removable media such as USB keys exposes the system to potential compromise.” The rule description of rule mount_option_nosuid_removable_partitions mentions removable media in general and doesn’t specify what is considered a removable media. On the other hand, the rule description of rule mount_option_nodev_removable_partitions says that legitimate character and block devices should exist only in the /dev directory on the root partition or within chroot jails built for system services. It’s interesting that all three rules share the same OVAL check from the template which differ only in the mount option parameter even though the rules contain different wording in XCCDF.
However, the OVAL check used by the template mount_option_removable_partitions tests only /dev/cdrom. The path is specified by XCCDF Value var_removable_partition, found in /linux_os/guide/system/permissions/partitions/var_removable_partition.var. This XCCDF Value has a single selector with value /dev/cdrom. Users can change this value in their tailoring files to check for a different block device, because But they can change this still only to a single path. Using this path is not in line in the rule descriptions. Obviously, using only /dev/cdrom doesn’t include USB keys that are used as an example in mount_option_noexec_removable_partitions. Also, it doesn’t cover removable media in general, because there can be other types of devices that we can imagine they’re removable. For example floppy disks, SATA disks or SD cards.
If we know the fact that the rules use /dev/cdrom we are confused by the OVAL check that checks multiple times if /dev/cdrom is equal to one of: /dev/cdrom, /dev/dvd, /dev/scd0, /dev/sr0. See constant_variable of id="variable_cd_dvd_drive_alternative_names_{{{ MOUNTOPTION }}}". This is normally true if the XCCDF Value var_removable_partition isn’t overridden by tailoring. This comparison is performed there multiple times. Also, the OVAL criteria tree contains branches that are effective when this isn’t true. We imagine that this might be some precaution for tailoring, but the use case isn’t clear at this moment. We welcome any information that would clear this up.
The aforementioned problem with the single block device isn’t the only problem of these rules, we have discovered multiple other issues.
The test scenario dvd_bad_opts.fail.sh for rule mount_option_noexec_removable_partitions is failing because scanner returns pass instead of expected result fail. The reason is the OVAL checks if path specified by var_removable_partition exists and if it doesn't exist the rule fail. As we already mentioned, this variable is always set to /dev/cdrom in all profiles, as the variable definition has only this value. But the test scenario doesn’t create /dev/cdrom, but /dev/dvd. Therefore, the check finds that /dev/cdrom doesn’t exist, and the rule passes trivially.
The test scenario dvd_good_opts.pass.sh (also for rule mount_option_noexec_removable_partitions) is broken as well. It returns the expected result, pass, but that’s again the trivial case. The test scenario creates /dev/dvd file at the beginning instead of /dev/cdrom. The OVAL check passed because /dev/cdrom didn't exist. Therefore the test scenario was not testing the actual regular expression matching in /etc/fstab.
A more serious problem than the faulty test scenarios is that the Bash and Ansible remediations in this template aren't functional. The remediation code works with a mount point which is in the second column of /etc/fstab. But they are passed values of the block device as a parameter which is in the first column of /etc/fstab. Actually, in all 3 rules we passed the device path (/dev/cdrom) as a mount point instead of block device. The remediation can’t work because in this case it looks for /dev/cdrom in the second column of /etc/fstab but it appears in the first column. People can mount the removable media to arbitrary directories. We think it makes sense to base the rules on the devices instead of the mount points.
Another finding that we made is the nature of the checks. The OVAL check isn't checking only /etc/fstab configuration, but is also checking run-time state. That doesn’t conform to the rule descriptions. Our understanding of the rule descriptions is that the rules are only about configuration, there is no mention of run-time.
Moreover, after internal discussion, it’s unclear which block devices should be considered removable in context of these rules. In theory, multiple devices can be removable. Considering the differences in rule descriptions we should Also, the removable device doesn't have to be mounted at the moment of system evaluation.
If the removable device isn’t configured in /etc/fstab, then automated mounting might happen. There are some default mount options which are used in this situation. We don’t know where they’re defined. We think that we should enforce presence of these entries in /etc/fstab. However, in the past we had a Bugzilla [2] which required us to let the rule pass if the entries aren’t mounted. If we review this Bugzilla [2] again, we are not sure if the reporter could be fully satisfied by the fix delivered at that time.
Some of the problems are already addressed in pull request [2]. Everyone can join the discussion. We have also added some test scenarios there.
We think the rule is expected to check for all types of removable devices. Probably, they could be defined as the pretty common ones, like floppy disks, CDs, DVDs or USB sticks. But we need to clarify all the requirements before completing the fix.
Best regards
[1] https://bugzilla.redhat.com/show_bug.cgi?id=1691579 [2] https://bugzilla.redhat.com/show_bug.cgi?id=1403905 [3] https://github.com/ComplianceAsCode/content/pull/5278
Originally, these rules were only written for cdrom with the guidance never changing to handle other devices even though it reads like they do handle other devices. You are correct in that the rules are to check for all types of removable devices. They were just never updated to fully address all the scenarios and have languished for sure. OVAL should always check runtime and static regardless of description; otherwise, you'd never know if you were truly compliant. Per the intro and how-to-use sections, a reboot is expected/required after configuration to ensure that the runtime meets the static.
In general, a better technical solution needs to be developed to handle all external media that requires multi-admin approval and guarding/blocking, but that's a solution that will take a while to develop and getting upstream approvals for.
On Thu, Mar 26, 2020 at 9:15 AM Jan Cerny jcerny@redhat.com wrote:
Hi,
We started to work on Bugzilla [1] about a problem in rules that check mount options for removable partitions. Currently, there are rules mount_option_noexec_removable_partitions, mount_option_nosuid_removable_partitions, mount_option_nodev_removable_partitions. These rules are templated. They use template mount_option_removable_partitions.
Overall, we have a confusion in these rules and their implementation. The checks doesn’t appear to properly recognize when partitions are configured with the proper nodev, nosuid, and noexec options.
Most importantly, we have found a discrepancy between the rule description in rule.yml files of the aforementioned rules and the actual OVAL checks used in the template (in /shared/templates/template_OVAL_mount_option_removable_partitions).
The rule description of rule mount_option_noexec_removable_partitions says that it prevents “direct execution of binaries from removable media (such as a USB key)”. Also, the rationale of this rule says: “Allowing users to execute binaries from removable media such as USB keys exposes the system to potential compromise.” The rule description of rule mount_option_nosuid_removable_partitions mentions removable media in general and doesn’t specify what is considered a removable media. On the other hand, the rule description of rule mount_option_nodev_removable_partitions says that legitimate character and block devices should exist only in the /dev directory on the root partition or within chroot jails built for system services. It’s interesting that all three rules share the same OVAL check from the template which differ only in the mount option parameter even though the rules contain different wording in XCCDF.
However, the OVAL check used by the template mount_option_removable_partitions tests only /dev/cdrom. The path is specified by XCCDF Value var_removable_partition, found in /linux_os/guide/system/permissions/partitions/var_removable_partition.var. This XCCDF Value has a single selector with value /dev/cdrom. Users can change this value in their tailoring files to check for a different block device, because But they can change this still only to a single path. Using this path is not in line in the rule descriptions. Obviously, using only /dev/cdrom doesn’t include USB keys that are used as an example in mount_option_noexec_removable_partitions. Also, it doesn’t cover removable media in general, because there can be other types of devices that we can imagine they’re removable. For example floppy disks, SATA disks or SD cards.
If we know the fact that the rules use /dev/cdrom we are confused by the OVAL check that checks multiple times if /dev/cdrom is equal to one of: /dev/cdrom, /dev/dvd, /dev/scd0, /dev/sr0. See constant_variable of id="variable_cd_dvd_drive_alternative_names_{{{ MOUNTOPTION }}}". This is normally true if the XCCDF Value var_removable_partition isn’t overridden by tailoring. This comparison is performed there multiple times. Also, the OVAL criteria tree contains branches that are effective when this isn’t true. We imagine that this might be some precaution for tailoring, but the use case isn’t clear at this moment. We welcome any information that would clear this up.
The aforementioned problem with the single block device isn’t the only problem of these rules, we have discovered multiple other issues.
The test scenario dvd_bad_opts.fail.sh for rule mount_option_noexec_removable_partitions is failing because scanner returns pass instead of expected result fail. The reason is the OVAL checks if path specified by var_removable_partition exists and if it doesn't exist the rule fail. As we already mentioned, this variable is always set to /dev/cdrom in all profiles, as the variable definition has only this value. But the test scenario doesn’t create /dev/cdrom, but /dev/dvd. Therefore, the check finds that /dev/cdrom doesn’t exist, and the rule passes trivially.
The test scenario dvd_good_opts.pass.sh (also for rule mount_option_noexec_removable_partitions) is broken as well. It returns the expected result, pass, but that’s again the trivial case. The test scenario creates /dev/dvd file at the beginning instead of /dev/cdrom. The OVAL check passed because /dev/cdrom didn't exist. Therefore the test scenario was not testing the actual regular expression matching in /etc/fstab.
A more serious problem than the faulty test scenarios is that the Bash and Ansible remediations in this template aren't functional. The remediation code works with a mount point which is in the second column of /etc/fstab. But they are passed values of the block device as a parameter which is in the first column of /etc/fstab. Actually, in all 3 rules we passed the device path (/dev/cdrom) as a mount point instead of block device. The remediation can’t work because in this case it looks for /dev/cdrom in the second column of /etc/fstab but it appears in the first column. People can mount the removable media to arbitrary directories. We think it makes sense to base the rules on the devices instead of the mount points.
Another finding that we made is the nature of the checks. The OVAL check isn't checking only /etc/fstab configuration, but is also checking run-time state. That doesn’t conform to the rule descriptions. Our understanding of the rule descriptions is that the rules are only about configuration, there is no mention of run-time.
Moreover, after internal discussion, it’s unclear which block devices should be considered removable in context of these rules. In theory, multiple devices can be removable. Considering the differences in rule descriptions we should Also, the removable device doesn't have to be mounted at the moment of system evaluation.
If the removable device isn’t configured in /etc/fstab, then automated mounting might happen. There are some default mount options which are used in this situation. We don’t know where they’re defined. We think that we should enforce presence of these entries in /etc/fstab. However, in the past we had a Bugzilla [2] which required us to let the rule pass if the entries aren’t mounted. If we review this Bugzilla [2] again, we are not sure if the reporter could be fully satisfied by the fix delivered at that time.
Some of the problems are already addressed in pull request [2]. Everyone can join the discussion. We have also added some test scenarios there.
We think the rule is expected to check for all types of removable devices. Probably, they could be defined as the pretty common ones, like floppy disks, CDs, DVDs or USB sticks. But we need to clarify all the requirements before completing the fix.
Best regards
[1] https://bugzilla.redhat.com/show_bug.cgi?id=1691579 [2] https://bugzilla.redhat.com/show_bug.cgi?id=1403905 [3] https://github.com/ComplianceAsCode/content/pull/5278
-- Jan Černý Security Technologies | Red Hat, Inc. _______________________________________________ scap-security-guide mailing list -- scap-security-guide@lists.fedorahosted.org To unsubscribe send an email to scap-security-guide-leave@lists.fedorahosted.org Fedora Code of Conduct: https://docs.fedoraproject.org/en-US/project/code-of-conduct/ List Guidelines: https://fedoraproject.org/wiki/Mailing_list_guidelines List Archives: https://lists.fedorahosted.org/archives/list/scap-security-guide@lists.fedor...
On 3/26/20 1:18 PM, Gabe Alford wrote:
We think the rule is expected to check for all types of removable devices. Probably, they could be defined as the pretty common ones, like floppy disks, CDs, DVDs or USB sticks. But we need to clarify all the requirements before completing the fix.
What specific questions / concerns can be clarified?
Here's a good starting point to read the requirements: https://nvd.nist.gov/800-53/Rev4/control/mp-7
On Čt, bře 26, 2020 at 13:30, Shawn Wells shawn@redhat.com wrote:
On 3/26/20 1:18 PM, Gabe Alford wrote:
We think the rule is expected to check for all types of removable devices. Probably, they could be defined as the pretty common ones, like floppy disks, CDs, DVDs or USB sticks. But we need to clarify all the requirements before completing the fix.
What specific questions / concerns can be clarified?
We definitely need to strike the right balance between difficulty of the task and its worth. Here are questions that I see in Jan's e-mail: What is a removable medium? The description of the rule is quite ambitious, if we aim for feasible implementation, we have to change it. Should we determine removable media by their mount points? Or by device names? Current status: We check only for the /dev/cdrom, so it is relatively easy to come with incremental improvements.How to make the rule tailorable? Should we use a blacklists, or rather a whitelists? Current status: The rule is formally tailorable, but the usefulness of tailoring is nearly zero.Remediations don't work. Although they can be fixed easily to work with /dev/cdrom, what about cases that are implied by the rule's description?Should we check the run-time status as well? Runtime checks are not implied by the rule description, and testing their correctness seems to be a quite expensive task to me.
AFAIK, removable media is best identified via the UDEV subsystem and queries should probably follow that path.
On Tue, Mar 31, 2020 at 5:41 AM Matěj Týč matyc@redhat.com wrote:
On Čt, bře 26, 2020 at 13:30, Shawn Wells shawn@redhat.com wrote:
On 3/26/20 1:18 PM, Gabe Alford wrote:
We think the rule is expected to check for all types of removable devices. Probably, they could be defined as the pretty common ones, like floppy disks, CDs, DVDs or USB sticks. But we need to clarify all the requirements before completing the fix.
What specific questions / concerns can be clarified?
We definitely need to strike the right balance between difficulty of the task and its worth. Here are questions that I see in Jan's e-mail:
- What is a removable medium? The description of the rule is quite
ambitious, if we aim for feasible implementation, we have to change it. Should we determine removable media by their mount points? Or by device names? Current status: We check only for the /dev/cdrom, so it is relatively easy to come with incremental improvements. 2. How to make the rule tailorable? Should we use a blacklists, or rather a whitelists? Current status: The rule is formally tailorable, but the usefulness of tailoring is nearly zero. 3. Remediations don't work. Although they can be fixed easily to work with /dev/cdrom, what about cases that are implied by the rule's description? 4. Should we check the run-time status as well? Runtime checks are not implied by the rule description, and testing their correctness seems to be a quite expensive task to me.
scap-security-guide mailing list -- scap-security-guide@lists.fedorahosted.org To unsubscribe send an email to scap-security-guide-leave@lists.fedorahosted.org Fedora Code of Conduct: https://docs.fedoraproject.org/en-US/project/code-of-conduct/ List Guidelines: https://fedoraproject.org/wiki/Mailing_list_guidelines List Archives: https://lists.fedorahosted.org/archives/list/scap-security-guide@lists.fedor...
The idea of the rule is to verify that all filesystems that are (or could be) mounted by means of regular user actions have (or would have) noexec, nosuid and nodev options.
The options are not really important because the rules are templated and template boils down to checking for a mount option for a particular mounted partition when it is mounted; and then checking for some mount option for a partition that might be mounted at an arbitray point of time.
The current state is pretty obvious. The rule has to go through /proc/self/mounts and verify that all /dev/* entries, that are not present in /etc/fstab (or present, but have noauto option there), are mounted with the mount option in question. Everything else is either a special filesystem or a non-removable device, which is expected to be present at the system boot time and would be waited for.
The configuration of the possible mount options for various filesystem that might be added by the user is a lot more complicated.
Let's get into various options for the user to add another filesystem (nothing here will require root access):
1) USB Mass Storage
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT sdc 8:32 0 931.5G 0 disk └─sdc1 8:33 0 931.5G 0 part /run/media/ekolesni/WD /dev/sdc1 on /run/media/ekolesni/WD type ext4 (rw,nosuid,nodev,relatime,seclabel,uhelper=udisks2)
sdd 8:48 1 59.8G 0 disk └─sdd1 8:49 1 59.8G 0 part /run/media/ekolesni/Samsung USB /dev/sdd1 on /run/media/ekolesni/Samsung USB type vfat (rw,nosuid,nodev,relatime,uid=1000,gid=1000,fmask=0022,dmask=0022,codepage=437,iocharset=ascii,shortname=mixed,showexec,utf8,flush,errors=remount-ro,uhelper=udisks2)
USB Mass Stoarge devices are combined removable media and devices. These are relevant parts of lsblk and mount. The first one is a USB HDD. Note how it is reported as non-removable in 3-rd column of lsblk — RM (which is essentially sys/block/sdc/removable), thus rendering this flag unreliable. The second one is a USB flash drive with correct removable flag. Both of them lacks noexec options, and, even further, vfat flash drive has showexec option which would mark all .exe, .cmd and .bat files as executable. These options are HARDCODED in udisks and there is NO sane WAY to OVERRIDE them [1,2,3]. One could try to mitigate this problem by adding an entry to /etc/fstab (which would require root access), but it will be onnly applicable for ONE particualr device, not for all USB mass storage, ergo not helpful at all. Huge problem here in both checking and fixing the issue.
2) CD(DVD)-ROM(RW)
sr0 11:0 1 548.8M 0 rom /run/media/ekolesni/Shopen /dev/sr0 on /run/media/ekolesni/Shopen type iso9660 (ro,nosuid,nodev,relatime,norock,check=r,map=n,blocksize=2048,uid=1000,gid=1000,dmode=500,fmode=400,uhelper=udisks2)
The template is already operating on these types of devices, but we also should be aware that is also could be USB drive, which would mean that /dev/sr0 drive might be absent in addidtion to the media itself. Udisks remark is also fully applicable here.
I think that ATM, we should fix the description of the rule to match what it is really trying to do (check CD-ROMs), and fix it to do it properly (best effort). Everytig else I would consider as an improvement of the rule (pretty time-cosuming one) that should not be implemented during a bug-fixing cycle.
3) Card Readers
sda 8:0 1 29.6G 0 disk └─sda1 8:1 1 29.6G 0 part /run/media/ekolesni/SDHC /dev/sda1 on /run/media/ekolesni/SDHC type fuseblk (rw,nosuid,nodev,relatime,user_id=0,group_id=0,default_permissions,allow_other,blksize=4096,uhelper=udisks2)
This particular card reader is physically non-removable, but it is connected via USB bus on the motherbords (regular situation) it is non-distinguishable from its USB-plugged siblings. Removable media makes it a bit like CD-ROM device, but in all other aspects it is more like USB Mass Storage devices. Udisks!
4) Virtual loop Devices
loop1 7:1 0 1.8G 1 loop ├─loop1p1 259:4 0 1.8G 1 part /run/media/ekolesni/Fedora-WS-Live-31-1-9 ├─loop1p2 259:5 0 10.6M 1 part └─loop1p3 259:6 0 22.2M 1 part /dev/loop1p1 on /run/media/ekolesni/Fedora-WS-Live-31-1-9 type iso9660 (ro,nosuid,nodev,relatime,nojoliet,check=s,map=n,blocksize=2048,uid=1000,gid=1000,dmode=500,fmode=400,uhelper=udisks2)
Loop devices are used to emulate block-based devices out of an image (usually a file). An .iso file is a good example of this, and could be activated by a user with help of gnome-disk-image-mounter (frontend for udisks and losetup).
5) Network Shares, PTP and MTP for Smartphones (gvfs); Flatpack
All gvfs filesystems will end there:
gvfsd-fuse on /run/user/1000/gvfs type fuse.gvfsd-fuse (rw,nosuid,nodev,relatime,user_id=1000,group_id=1000)
The /etc/fstab nas nothing to do with these mount and it is not clear wheither the rule should deal with them, but they are still filesystems and the lack noexec for example).
Flatpack, huh!
/dev/fuse on /run/user/1000/doc type fuse (rw,nosuid,nodev,relatime,user_id=1000,group_id=1000)
This filesystem is used for sharing contecnt between the host and Flatpack's sandbox. No noexec. It will throw a wrench in the run-time state validation as well by semantically being a device (/dev/fuse).
Appendix:
1) Non-removable system device (as an example)
nvme0n1 259:0 0 238.5G 0 disk ├─nvme0n1p1 259:1 0 200M 0 part /boot/efi ├─nvme0n1p2 259:2 0 1G 0 part /boot └─nvme0n1p3 259:3 0 237.3G 0 part └─luks-aec1b607-5b8c-42bf-c19d-4811515be435 253:0 0 237.3G 0 crypt ├─fedora_localhost--live-root 253:1 0 70G 0 lvm / ├─fedora_localhost--live-swap 253:2 0 7.9G 0 lvm [SWAP] └─fedora_localhost--live-home 253:3 0 159.4G 0 lvm /home /dev/nvme0n1p1 on /boot/efi type vfat (rw,relatime,fmask=0077,dmask=0077,codepage=437,iocharset=ascii,shortname=winnt,errors=remount-ro) /dev/nvme0n1p2 on /boot type ext4 (rw,relatime,seclabel) /dev/mapper/fedora_localhost--live-root on / type ext4 (rw,relatime,seclabel) /dev/mapper/fedora_localhost--live-home on /home type ext4 (rw,relatime,seclabel)
2) /etc/fstab
UUID=6b3513d4-d3cd-4cff-a8df-0a8b589c671f /boot ext4 defaults 1 2 UUID=4C38-AC88 /boot/efi vfat umask=0077,shortname=winnt 0 2 /dev/mapper/fedora_localhost--live-root / ext4 defaults,x-systemd.device-timeout=0 1 1 /dev/mapper/fedora_localhost--live-home /home ext4 defaults,x-systemd.device-timeout=0 1 2 /dev/mapper/fedora_localhost--live-swap none swap defaults,x-systemd.device-timeout=0 0 0
Links:
[1] - https://lists.freedesktop.org/archives/devkit-devel/2015-April/001668.html [2] - https://bugs.freedesktop.org/show_bug.cgi?id=33461 [3] - https://unix.stackexchange.com/questions/155567/mounting-removable-usb-disks...
scap-security-guide@lists.fedorahosted.org