Restrict Exposed Kernel Pointer Addresses Access

Esta página aún no está disponible en español. Estamos trabajando en su traducción.
Si tienes alguna pregunta o comentario sobre nuestro actual proyecto de traducción, no dudes en ponerte en contacto con nosotros.

Description

To set the runtime status of the kernel.kptr_restrict kernel parameter, run the following command:

$ sudo sysctl -w kernel.kptr_restrict=1
         

To make sure that the setting is persistent, add the following line to a file in the directory /etc/sysctl.d:

kernel.kptr_restrict = 1
         

Rationale

Exposing kernel pointers (through procfs or seq_printf()) exposes kernel writeable structures which may contain functions pointers. If a write vulnerability occurs in the kernel, allowing write access to any of this structure, the kernel can be compromised. This option disallow any program without the CAP_SYSLOG capability to get the addresses of kernel pointers by replacing them with 0.

Remediation

Shell script

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

#!/bin/bash

# Remediation is applicable only in certain platforms
if rpm --quiet -q kernel-core; then

# Comment out any occurrences of kernel.kptr_restrict from /etc/sysctl.d/*.conf files

for f in /etc/sysctl.d/*.conf /run/sysctl.d/*.conf /usr/local/lib/sysctl.d/*.conf; do


  # skip systemd-sysctl symlink (/etc/sysctl.d/99-sysctl.conf -> /etc/sysctl.conf)
  if [[ "$(readlink -f "$f")" == "/etc/sysctl.conf" ]]; then continue; fi

  matching_list=$(grep -P '^(?!#).*[\s]*kernel.kptr_restrict.*$' $f | uniq )
  if ! test -z "$matching_list"; then
    while IFS= read -r entry; do
      escaped_entry=$(sed -e 's|/|\\/|g' <<< "$entry")
      # comment out "kernel.kptr_restrict" matches to preserve user data
      sed -i --follow-symlinks "s/^${escaped_entry}$/# &/g" $f
    done <<< "$matching_list"
  fi
done

#
# Set sysctl config file which to save the desired value
#

SYSCONFIG_FILE="/etc/sysctl.conf"

sysctl_kernel_kptr_restrict_value='1'


#
# Set runtime for kernel.kptr_restrict
#
if ! { rpm --quiet -q kernel rpm-ostree bootc && ! rpm --quiet -q openshift-kubelet && { [ -f "/run/.containerenv" ] || [ -f "/.containerenv" ]; }; } ; then
    /sbin/sysctl -q -n -w kernel.kptr_restrict="$sysctl_kernel_kptr_restrict_value"
fi

#
# If kernel.kptr_restrict present in /etc/sysctl.conf, change value to appropriate value
#	else, add "kernel.kptr_restrict = value" to /etc/sysctl.conf
#

# Strip any search characters in the key arg so that the key can be replaced without
# adding any search characters to the config file.
stripped_key=$(sed 's/[\^=\$,;+]*//g' <<< "^kernel.kptr_restrict")

# shellcheck disable=SC2059
printf -v formatted_output "%s = %s" "$stripped_key" "$sysctl_kernel_kptr_restrict_value"

# If the key exists, change it. Otherwise, add it to the config_file.
# We search for the key string followed by a word boundary (matched by \>),
# so if we search for 'setting', 'setting2' won't match.
if LC_ALL=C grep -q -m 1 -i -e "^kernel.kptr_restrict\\>" "${SYSCONFIG_FILE}"; then
    escaped_formatted_output=$(sed -e 's|/|\\/|g' <<< "$formatted_output")
    LC_ALL=C sed -i --follow-symlinks "s/^kernel.kptr_restrict\\>.*/$escaped_formatted_output/gi" "${SYSCONFIG_FILE}"
else
    if [[ -s "${SYSCONFIG_FILE}" ]] && [[ -n "$(tail -c 1 -- "${SYSCONFIG_FILE}" || true)" ]]; then
        LC_ALL=C sed -i --follow-symlinks '$a'\\ "${SYSCONFIG_FILE}"
    fi
    cce="CCE-88686-1"
    printf '# Per %s: Set %s in %s\n' "${cce}" "${formatted_output}" "${SYSCONFIG_FILE}" >> "${SYSCONFIG_FILE}"
    printf '%s\n' "$formatted_output" >> "${SYSCONFIG_FILE}"
fi

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: Gather the package facts
  package_facts:
    manager: auto
  tags:
  - CCE-88686-1
  - NIST-800-53-CM-6(a)
  - NIST-800-53-SC-30
  - NIST-800-53-SC-30(2)
  - NIST-800-53-SC-30(5)
  - disable_strategy
  - low_complexity
  - medium_disruption
  - medium_severity
  - reboot_required
  - sysctl_kernel_kptr_restrict
- name: XCCDF Value sysctl_kernel_kptr_restrict_value # promote to variable
  set_fact:
    sysctl_kernel_kptr_restrict_value: !!str 1
  tags:
    - always

- name: Restrict Exposed Kernel Pointer Addresses Access - Set fact for sysctl paths
  ansible.builtin.set_fact:
    sysctl_paths:
    - /etc/sysctl.d/
    - /run/sysctl.d/
    - /usr/local/lib/sysctl.d/
  when: '"kernel-core" in ansible_facts.packages'
  tags:
  - CCE-88686-1
  - NIST-800-53-CM-6(a)
  - NIST-800-53-SC-30
  - NIST-800-53-SC-30(2)
  - NIST-800-53-SC-30(5)
  - disable_strategy
  - low_complexity
  - medium_disruption
  - medium_severity
  - reboot_required
  - sysctl_kernel_kptr_restrict

- name: Restrict Exposed Kernel Pointer Addresses Access - Find all files that contain
    kernel.kptr_restrict
  ansible.builtin.shell:
    cmd: find -L {{ sysctl_paths | join(" ") }} -type f -name '*.conf' | xargs grep
      -HP '^\s*kernel.kptr_restrict\s*=\s*.*$'
  register: find_all_values
  check_mode: false
  changed_when: false
  failed_when: false
  when: '"kernel-core" in ansible_facts.packages'
  tags:
  - CCE-88686-1
  - NIST-800-53-CM-6(a)
  - NIST-800-53-SC-30
  - NIST-800-53-SC-30(2)
  - NIST-800-53-SC-30(5)
  - disable_strategy
  - low_complexity
  - medium_disruption
  - medium_severity
  - reboot_required
  - sysctl_kernel_kptr_restrict

- name: Restrict Exposed Kernel Pointer Addresses Access - Find all files that set
    kernel.kptr_restrict to correct value
  ansible.builtin.shell:
    cmd: find -L {{ sysctl_paths | join(" ") }} -type f -name '*.conf' | xargs grep
      -HP '^\s*kernel.kptr_restrict\s*=\s*{{ sysctl_kernel_kptr_restrict_value }}$'
  register: find_correct_value
  check_mode: false
  changed_when: false
  failed_when: false
  when: '"kernel-core" in ansible_facts.packages'
  tags:
  - CCE-88686-1
  - NIST-800-53-CM-6(a)
  - NIST-800-53-SC-30
  - NIST-800-53-SC-30(2)
  - NIST-800-53-SC-30(5)
  - disable_strategy
  - low_complexity
  - medium_disruption
  - medium_severity
  - reboot_required
  - sysctl_kernel_kptr_restrict

- name: Restrict Exposed Kernel Pointer Addresses Access - Comment out any occurrences
    of kernel.kptr_restrict from config files
  ansible.builtin.replace:
    path: '{{ item | split(":") | first }}'
    regexp: ^[\s]*kernel.kptr_restrict
    replace: '#kernel.kptr_restrict'
  loop: '{{ find_all_values.stdout_lines }}'
  when:
  - '"kernel-core" in ansible_facts.packages'
  - find_correct_value.stdout_lines | length == 0 or find_all_values.stdout_lines
    | length > find_correct_value.stdout_lines | length
  tags:
  - CCE-88686-1
  - NIST-800-53-CM-6(a)
  - NIST-800-53-SC-30
  - NIST-800-53-SC-30(2)
  - NIST-800-53-SC-30(5)
  - disable_strategy
  - low_complexity
  - medium_disruption
  - medium_severity
  - reboot_required
  - sysctl_kernel_kptr_restrict

- name: Restrict Exposed Kernel Pointer Addresses Access - Ensure sysctl kernel.kptr_restrict
    is set
  ansible.posix.sysctl:
    name: kernel.kptr_restrict
    value: '{{ sysctl_kernel_kptr_restrict_value }}'
    sysctl_file: /etc/sysctl.conf
    state: present
    reload: true
  when: '"kernel-core" in ansible_facts.packages'
  tags:
  - CCE-88686-1
  - NIST-800-53-CM-6(a)
  - NIST-800-53-SC-30
  - NIST-800-53-SC-30(2)
  - NIST-800-53-SC-30(5)
  - disable_strategy
  - low_complexity
  - medium_disruption
  - medium_severity
  - reboot_required
  - sysctl_kernel_kptr_restrict