Add noexec Option to /dev/shm

Classification:

compliance

Framework:

Control:

Description

The noexec mount option can be used to prevent binaries from being executed out of /dev/shm. It can be dangerous to allow the execution of binaries from world-writable temporary storage directories such as /dev/shm. Add the noexec option to the fourth column of /etc/fstab for the line which controls mounting of /dev/shm.

Rationale

Allowing users to execute binaries from world-writable directories such as /dev/shm can expose the system to potential compromise.

Remediation

Shell script

The following script can be run on the host to remediate the issue.

# Remediation is applicable only in certain platforms
if [ ! -f /.dockerenv ] && [ ! -f /run/.containerenv ]; then

function perform\_remediation {
 


 mount\_point\_match\_regexp="$(printf "[[:space:]]%s[[:space:]]" /dev/shm)"

 # If the mount point is not in /etc/fstab, get previous mount options from /etc/mtab
 if ! grep "$mount\_point\_match\_regexp" /etc/fstab; then
 # runtime opts without some automatic kernel/userspace-added defaults
 previous\_mount\_opts=$(grep "$mount\_point\_match\_regexp" /etc/mtab | head -1 | awk '{print $4}' \
 | sed -E "s/(rw|defaults|seclabel|noexec)(,|$)//g;s/,$//")
 [ "$previous\_mount\_opts" ] && previous\_mount\_opts+=","
 echo "tmpfs /dev/shm tmpfs defaults,${previous\_mount\_opts}noexec 0 0" >> /etc/fstab
 # If the mount\_opt option is not already in the mount point's /etc/fstab entry, add it
 elif ! grep "$mount\_point\_match\_regexp" /etc/fstab | grep "noexec"; then
 previous\_mount\_opts=$(grep "$mount\_point\_match\_regexp" /etc/fstab | awk '{print $4}')
 sed -i "s|\(${mount\_point\_match\_regexp}.\*${previous\_mount\_opts}\)|\1,noexec|" /etc/fstab
 fi


 if mkdir -p "/dev/shm"; then
 if mountpoint -q "/dev/shm"; then
 mount -o remount --target "/dev/shm"
 fi
 fi
}

perform\_remediation

else
 >&2 echo 'Remediation is not applicable, nothing was done'
fi

Ansible playbook

The following playbook can be run with Ansible to remediate the issue.

- name: 'Add noexec Option to /dev/shm: Check information associated to mountpoint'
 command: findmnt '/dev/shm'
 register: device\_name
 failed\_when: device\_name.rc > 1
 changed\_when: false
 when: ansible\_virtualization\_type not in ["docker", "lxc", "openvz", "podman", "container"]
 tags:
 - NIST-800-53-AC-6
 - NIST-800-53-AC-6(1)
 - NIST-800-53-CM-6(a)
 - NIST-800-53-CM-7(a)
 - NIST-800-53-CM-7(b)
 - NIST-800-53-MP-7
 - configure\_strategy
 - high\_disruption
 - low\_complexity
 - medium\_severity
 - mount\_option\_dev\_shm\_noexec
 - no\_reboot\_needed

- name: 'Add noexec Option to /dev/shm: Create mount\_info dictionary variable'
 set\_fact:
 mount\_info: '{{ mount\_info|default({})|combine({item.0: item.1}) }}'
 with\_together:
 - '{{ device\_name.stdout\_lines[0].split() | list | lower }}'
 - '{{ device\_name.stdout\_lines[1].split() | list }}'
 when:
 - ansible\_virtualization\_type not in ["docker", "lxc", "openvz", "podman", "container"]
 - device\_name.stdout is defined and device\_name.stdout\_lines is defined
 - (device\_name.stdout | length > 0)
 tags:
 - NIST-800-53-AC-6
 - NIST-800-53-AC-6(1)
 - NIST-800-53-CM-6(a)
 - NIST-800-53-CM-7(a)
 - NIST-800-53-CM-7(b)
 - NIST-800-53-MP-7
 - configure\_strategy
 - high\_disruption
 - low\_complexity
 - medium\_severity
 - mount\_option\_dev\_shm\_noexec
 - no\_reboot\_needed

- name: 'Add noexec Option to /dev/shm: If /dev/shm not mounted, craft mount\_info
 manually'
 set\_fact:
 mount\_info: '{{ mount\_info|default({})|combine({item.0: item.1}) }}'
 with\_together:
 - - target
 - source
 - fstype
 - options
 - - /dev/shm
 - tmpfs
 - tmpfs
 - defaults
 when:
 - ansible\_virtualization\_type not in ["docker", "lxc", "openvz", "podman", "container"]
 - ("" | length == 0)
 - (device\_name.stdout | length == 0)
 tags:
 - NIST-800-53-AC-6
 - NIST-800-53-AC-6(1)
 - NIST-800-53-CM-6(a)
 - NIST-800-53-CM-7(a)
 - NIST-800-53-CM-7(b)
 - NIST-800-53-MP-7
 - configure\_strategy
 - high\_disruption
 - low\_complexity
 - medium\_severity
 - mount\_option\_dev\_shm\_noexec
 - no\_reboot\_needed

- name: 'Add noexec Option to /dev/shm: Make sure noexec option is part of the to
 /dev/shm options'
 set\_fact:
 mount\_info: '{{ mount\_info | combine( {''options'':''''~mount\_info.options~'',noexec''
 }) }}'
 when:
 - ansible\_virtualization\_type not in ["docker", "lxc", "openvz", "podman", "container"]
 - mount\_info is defined and "noexec" not in mount\_info.options
 tags:
 - NIST-800-53-AC-6
 - NIST-800-53-AC-6(1)
 - NIST-800-53-CM-6(a)
 - NIST-800-53-CM-7(a)
 - NIST-800-53-CM-7(b)
 - NIST-800-53-MP-7
 - configure\_strategy
 - high\_disruption
 - low\_complexity
 - medium\_severity
 - mount\_option\_dev\_shm\_noexec
 - no\_reboot\_needed

- name: 'Add noexec Option to /dev/shm: Ensure /dev/shm is mounted with noexec option'
 mount:
 path: /dev/shm
 src: '{{ mount\_info.source }}'
 opts: '{{ mount\_info.options }}'
 state: mounted
 fstype: '{{ mount\_info.fstype }}'
 when:
 - ansible\_virtualization\_type not in ["docker", "lxc", "openvz", "podman", "container"]
 - (device\_name.stdout is defined and (device\_name.stdout | length > 0)) or ("" |
 length == 0)
 tags:
 - NIST-800-53-AC-6
 - NIST-800-53-AC-6(1)
 - NIST-800-53-CM-6(a)
 - NIST-800-53-CM-7(a)
 - NIST-800-53-CM-7(b)
 - NIST-800-53-MP-7
 - configure\_strategy
 - high\_disruption
 - low\_complexity
 - medium\_severity
 - mount\_option\_dev\_shm\_noexec
 - no\_reboot\_needed