Add noexec Option to /dev/shm
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.
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