<def-group>
  <definition class="compliance" id="mount_option_nosuid_removable_partitions" version="2">
    <metadata>
      <title>Add nosuid Option to Removable Media Partitions</title>
      <affected family="unix">
        <platform>Red Hat Enterprise Linux 6</platform>
      </affected>
      <description>The nosuid mount option prevents set-user-identifier (suid)
      and set-group-identifier (sgid) permissions from taking effect. These
      permissions allow users to execute binaries with the same permissions as
      the owner and group of the file respectively. Users should not be allowed
      to introduce suid and guid files into the system via partitions mounted
      from removeable media.</description>
      <reference source="JL" ref_id="RHEL6_20150305" ref_url="test_attestation"/>
    </metadata>
    <criteria operator="OR">
      <!-- First check if specified removable partition truly exists on the system. If not, don't check /etc/fstab & runtime configuration
           since there's no device to check against -->
      <criterion test_ref="test_removable_partition_doesnt_exist" comment="Check if removable partition really exists on the system" />
      <!-- Removable device exists. Check if it's CD/DVD drive. If so, verify that at least one from all of the possible its alternative
           names in /etc/fstab & runtime configuration are configured with 'nosuid' option -->
      <criteria operator="AND">
        <criterion test_ref="test_var_removable_partition_is_cd_dvd_drive" comment="Check if removable partition value represents CD/DVD drive" />
        <criterion test_ref="test_nosuid_etc_fstab_cd_dvd_drive" comment="Check if at least one from CD/DVD drive alternative names is using 'nosuid' mount option in /etc/fstab" />
        <criterion test_ref="test_nosuid_runtime_cd_dvd_drive" comment="Check if at least one from CD/DVD drive alternative names is using 'nosuid' mount option in runtime configuration" />
      </criteria>
      <!-- Removable device exists & isn't CD/DVD drive. Check the particular devices is configured with 'nosuid' mount option in both
           /etc/fstab & runtime configuration -->
      <criteria operator="AND">
        <criterion test_ref="test_nosuid_etc_fstab_not_cd_dvd_drive" comment="Check if removable partition is using 'nosuid' mount option in /etc/fstab" />
        <criterion test_ref="test_nosuid_runtime_not_cd_dvd_drive" comment="Check if removable partition is using 'nosuid' mount option in runtime configuration" />
      </criteria>
    </criteria>
  </definition>

  <!-- First check if specified removable partition really exists on the system.
       If not return PASS since there's nothing to check /etc/fstab & runtime settings against. -->
  <unix:file_test id="test_removable_partition_doesnt_exist" check="all" check_existence="none_exist" comment="Check if expected removable partitions truly exist on the system" version="1">
    <unix:object object_ref="object_removable_partition_doesnt_exist" />
  </unix:file_test>

  <unix:file_object id="object_removable_partition_doesnt_exist" version="1">
    <unix:filepath var_ref="var_removable_partition" var_check="at least one" />
  </unix:file_object>

  <!-- Specified removable partition exists on the system. Check if it represents a CD / DVD drive -->
  <ind:variable_test id="test_var_removable_partition_is_cd_dvd_drive" check="all" comment="Check if removable partition variable value represents CD/DVD drive" version="1">
    <ind:object object_ref="object_var_removable_partition_is_cd_dvd_drive" />
    <ind:state state_ref="state_var_removable_partition_is_cd_dvd_drive" />
  </ind:variable_test>

  <ind:variable_object id="object_var_removable_partition_is_cd_dvd_drive" version="1">
    <ind:var_ref>var_removable_partition</ind:var_ref>
  </ind:variable_object>

  <ind:variable_state id="state_var_removable_partition_is_cd_dvd_drive" version="1">
    <ind:value operation="equals">/dev/cdrom</ind:value>
  </ind:variable_state>

  <!-- If specified removable partition represents CD / DVD drive, create a variable
       holding also alternative names for CD / DVD block special device as used by udev -->
  <constant_variable id="variable_cd_dvd_drive_alternative_names" datatype="string" comment="CD/DVD drive alternative names whitelist" version="1">
    <value>/dev/cdrom</value>
    <value>/dev/dvd</value>
    <value>/dev/scd0</value>
    <value>/dev/sr0</value>
  </constant_variable>

  <!-- For each of the CD / DVD drive alternative names create regular expression pattern
       to be used in textfilecontent54_object below -->
  <local_variable id="variable_cd_dvd_drive_regex_pattern" datatype="string" comment="Regular expression pattern for CD / DVD drive alternative names" version="1">
    <concat>
      <literal_component>^[\s]*</literal_component>
      <variable_component var_ref="variable_cd_dvd_drive_alternative_names" />
      <!-- Capture the mount options field (4-th column of /etc/fstab) -->
      <literal_component>[\s]+[/\w]+[\s]+[\w]+[\s]+([^\s]+)(?:[\s]+[\d]+){2}$</literal_component>
    </concat>
  </local_variable>

  <!-- If specified removable partition represents CD / DVD drive, use all alternative
       names to check /etc/fstab & runtime settings -->
  <ind:textfilecontent54_test id="test_nosuid_etc_fstab_cd_dvd_drive" check="all" comment="'nosuid' mount option used for at least one CD / DVD drive alternative names in /etc/fstab" version="1">
    <ind:object object_ref="object_nosuid_etc_fstab_cd_dvd_drive" />
    <ind:state state_ref="state_nosuid_etc_fstab_cd_dvd_drive" />
  </ind:textfilecontent54_test>

  <ind:textfilecontent54_object id="object_nosuid_etc_fstab_cd_dvd_drive" version="1">
    <ind:filepath>/etc/fstab</ind:filepath>
    <ind:pattern operation="pattern match" datatype="string" var_ref="variable_cd_dvd_drive_regex_pattern" var_check="at least one" />
    <ind:instance datatype="int" operation="greater than or equal">1</ind:instance>
  </ind:textfilecontent54_object>

  <ind:textfilecontent54_state id="state_nosuid_etc_fstab_cd_dvd_drive" version="1">
    <ind:subexpression operation="pattern match" datatype="string">^.*,?nosuid,?.*$</ind:subexpression>
  </ind:textfilecontent54_state>

  <linux:partition_test id="test_nosuid_runtime_cd_dvd_drive" check="all" comment="'nosuid' mount option used for at least one CD / DVD drive alternative names in runtime configuration" version="1">
    <linux:object object_ref="object_nosuid_runtime_cd_dvd_drive" />
  </linux:partition_test>

  <linux:partition_object id="object_nosuid_runtime_cd_dvd_drive" version="1">
    <!-- CD / DVD drive can be mounted under any mount_point. We don't know ahead its exact name.
         => Capture all & filter out only the relevant ones via the corresponding state -->
    <linux:mount_point operation="pattern match">^.*$</linux:mount_point>
    <!-- Therefore from all the captured mount points select only those having
         device set to some CD / DVD drive alternative name and simultaneously
         having 'nosuid' mount option used -->
    <filter action="include">state_nosuid_runtime_cd_dvd_drive</filter>
  </linux:partition_object>

  <linux:partition_state id="state_nosuid_runtime_cd_dvd_drive" version="1">
    <linux:device datatype="string" operation="equals" var_ref="variable_cd_dvd_drive_alternative_names" var_check="at least one" />
    <linux:mount_options datatype="string" entity_check="at least one" operation="equals">nosuid</linux:mount_options>
  </linux:partition_state>

  <!-- Specified removable partition exists & doesn't represent a CD/DVD drive.
       Check if configured with 'nosuid' mount option in both /etc/fstab & runtime configuration -->
  <ind:textfilecontent54_test id="test_nosuid_etc_fstab_not_cd_dvd_drive" check="at least one" check_existence="all_exist" comment="Check if removable partition is configured with 'nosuid' mount option in /etc/fstab" version="1">
    <ind:object object_ref="object_nosuid_etc_fstab_not_cd_dvd_drive" />
    <ind:state state_ref="state_nosuid_etc_fstab_not_cd_dvd_drive" />
  </ind:textfilecontent54_test>

  <!-- Create regular expression pattern for the device to be used in the
       textfilecontent54_object below -->
  <local_variable id="variable_not_cd_dvd_drive_regex_pattern" datatype="string" comment="Regular expression pattern for removable block special device other than CD / DVD drive" version="1">
    <concat>
      <literal_component>^[\s]*</literal_component>
      <variable_component var_ref="var_removable_partition" />
      <!-- Capture the mount options field (4-th column of /etc/fstab) -->
      <literal_component>[\s]+[/\w]+[\s]+[\w]+[\s]+([^\s]+)(?:[\s]+[\d]+){2}$</literal_component>
    </concat>
  </local_variable>

  <ind:textfilecontent54_object id="object_nosuid_etc_fstab_not_cd_dvd_drive" version="1">
    <ind:filepath>/etc/fstab</ind:filepath>
    <ind:pattern operation="pattern match" datatype="string" var_ref="variable_not_cd_dvd_drive_regex_pattern" var_check="at least one" />
    <ind:instance datatype="int" operation="greater than or equal">1</ind:instance>
  </ind:textfilecontent54_object>

  <ind:textfilecontent54_state id="state_nosuid_etc_fstab_not_cd_dvd_drive" version="1">
    <ind:subexpression operation="pattern match" datatype="string">^.*,?nosuid,?.*</ind:subexpression>
  </ind:textfilecontent54_state>

  <linux:partition_test id="test_nosuid_runtime_not_cd_dvd_drive" check="all" check_existence="all_exist" comment="'nosuid' mount option used for removable partition in runtime configuration" version="1">
    <linux:object object_ref="object_nosuid_runtime_not_cd_dvd_drive" />
  </linux:partition_test>

  <linux:partition_object id="object_nosuid_runtime_not_cd_dvd_drive" version="1">
    <!-- Removable partition can be mounted under any mount point. We don't know it's
         exact name ahead => capture all & filter out only those relevant later via state -->
    <linux:mount_point operation="pattern match">^.*$</linux:mount_point>
    <!-- From all the captured mount points select only those having device equal
         to 'var_removable_partition' variable value and simultaneously having
         'nosuid' mount option set -->
    <filter action="include">state_nosuid_runtime_not_cd_dvd_drive</filter>
  </linux:partition_object>

  <linux:partition_state id="state_nosuid_runtime_not_cd_dvd_drive" version="1">
    <linux:device datatype="string" operation="equals" var_ref="var_removable_partition" var_check="at least one" />
    <linux:mount_options datatype="string" entity_check="at least one" operation="equals">nosuid</linux:mount_options>
  </linux:partition_state>

  <external_variable comment="removable partition" datatype="string" id="var_removable_partition" version="1" />

</def-group>
