How do I mitigate against NULL pointer dereference vulnerabilities?

Updated -

Release Found: Red Hat Enterprise Linux 3, 4, 5, 6, and Red Hat Enterprise MRG.

Introduction

NULL pointer dereference flaws in the Linux kernel can often be abused by a local, unprivileged user to gain root privileges by mapping attacker-controlled data to low memory pages. In the Linux kernel version 2.6.23, the /proc/sys/vm/mmap_min_addr tunable was introduced to prevent unprivileged users from creating new memory mappings below the minimum address.

This feature was backported in Red Hat Enterprise Linux 3, 4, and 5 via RHSA-2009:1550, RHSA-2009:1438, and RHBA-2008:0314 respectively. Prior kernel versions do not have support for disabling the mapping of low memory pages. This feature is enabled by default in Red Hat Enterprise Linux 5 (since RHBA-2008:0314) and in Red Hat Enterprise MRG (since RHSA-2009:1540), but was disabled in Red Hat Enterprise Linux 3 and 4 for backwards compatibility. This feature was always present and enabled in Red Hat Enterprise Linux 6.

In addition to the vm.mmap_min_addr kernel parameter, on Red Hat Enterprise Linux 5 (since RHSA-2009:1548), Red Hat Enterprise Linux 6 (since its initial release), and Red Hat Enterprise MRG (since RHSA-2009:1540), SELinux uses its own build time option (CONFIG_LSM_MMAP_MIN_ADDR) to prevent low memory pages being mapped with mmap(). If vm.mmap_min_addr is disabled, and SELinux is running in Enforcing mode, there will still be protection against mapping low memory pages.

Steps to mitigate

The mmap_min_addr setting can be changed to reduce the risk and mitigate against NULL pointer dereference vulnerabilities.

Red Hat Enterprise Linux 3 and 4

The mmap_min_addr protection is disabled by default in Red Hat Enterprise Linux 3 and 4. To enable it, add or amend the following entry in the /etc/sysctl.conf file:

vm.mmap_min_addr = 4096

To apply this setting, run the /sbin/sysctl -p command as the root user to reload the settings from /etc/sysctl.conf.

Verify that vm.mmap_min_addr is now set to 4096:

$ /sbin/sysctl vm.mmap_min_addr  
vm.mmap_min_addr = 4096

Red Hat Enterprise Linux 5 and Red Hat Enterprise MRG

Read the 17995 Knowledgebase article before proceeding. Note that for the following configuration to work, Red Hat Enterprise Linux 5 users must have the RHSA-2009:1548 update installed, and Red Hat Enterprise MRG users must have the RHSA-2009:1540 update installed.

On Red Hat Enterprise Linux 5 (since RHSA-2009:1548), when SELinux is running in Enforcing mode, its own protection (CONFIG_LSM_MMAP_MIN_ADDR) is used instead of the value specified with vm.mmap_min_addr. CONFIG_LSM_MMAP_MIN_ADDR is set to 4096 by default (meaning 4096 is the lowest address that can be mapped).

On Red Hat Enterprise MRG (since RHSA-2009:1540), CONFIG_LSM_MMAP_MIN_ADDR is set to 65536 by default.

The getenforce command returns the current SELinux mode. The below output demonstrates running getenforce when SELinux is in Enforcing mode:

$ getenforce
Enforcing

If SELinux is disabled or running in Permissive mode, the vm.mmap_min_addr kernel parameter is used to protect against mapping low pages. It is set to 4096 by default (the same as the SELinux CONFIG_LSM_MMAP_MIN_ADDR protection on Red Hat Enterprise Linux 5). Ensure that the value is not zero by running:

$ /sbin/sysctl vm.mmap_min_addr

If it is zero, it means the protection is disabled. In this case, you should edit the /etc/sysctl.conf file, and add or amend:

vm.mmap_min_addr = 4096

To apply this setting, run the /sbin/sysctl -p command as the root user to reload the settings from /etc/sysctl.conf.

Verify that vm.mmap_min_addr is now set to 4096:

$ /sbin/sysctl vm.mmap_min_addr  
vm.mmap_min_addr = 4096

Red Hat Enterprise Linux 6

On Red Hat Enterprise Linux 6 (since its initial release) when SELinux is running in Enforcing mode, its own protection (CONFIG_LSM_MMAP_MIN_ADDR) is used instead of the value specified with vm.mmap_min_addr. CONFIG_LSM_MMAP_MIN_ADDR is set to 65535 by default (meaning 65535 is the lowest address that can be mapped).

The getenforce command returns the current SELinux mode. The below output demonstrates running getenforce when SELinux is in Enforcing mode:

$ getenforce
Enforcing

If SELinux is disabled or running in Permissive mode, the vm.mmap_min_addr kernel parameter is used to protect against mapping low pages. It is set to 4096 by default. Ensure that the value is not zero by running:

$ /sbin/sysctl vm.mmap_min_addr

If it is zero, it means the protection is disabled. In this case, you should edit the /etc/sysctl.conf file, and add or amend:

vm.mmap_min_addr = 4096

To apply this setting, run the /sbin/sysctl -p command as the root user to reload the settings from /etc/sysctl.conf.

Verify that vm.mmap_min_addr is now set to 4096:

$ /sbin/sysctl vm.mmap_min_addr
vm.mmap_min_addr = 4096

Revision history

2012-05-01: Article updated to reflect the SELinux CONFIG_LSM_MMAP_MIN_ADDR protection, available in Red Hat Enterprise Linux 5 (since RHSA-2009:1548), Red Hat Enterprise Linux 6 (since its initial release), and Red Hat Enterprise MRG (since RHSA-2009:1540), that prevents low memory pages being mapped when vm.mmap_min_addr is disabled and SELinux is running in Enforcing mode.

Comments