CVE-2017-8779 - libtirpc, libntirpc: Memory leak when failing to parse XDR strings or bytearrays ("rpcbomb")
Environment
- Red Hat Enterprise Linux 6
- Red Hat Enterprise Linux 7
- Red Hat Gluster Storage 3
- Red Hat Ceph Storage 2 [ libntirpc tech preview ]
Issue
Issues in the interaction between rpcbind
, which provides a directory service for SunRPC-based services such as NFS
, and the low-level programming interfaces for SunRPC provided by libtirpc
, libntirpc
, and glibc
, could lead to memory being allocated and never freed. This could occur when malformed messages are sent to rpcbind
, and would be visible as an increase in the process' VmSize
as reported in /proc/$pid/status
or by top
.
Impact
Red Hat Product Security has rated this issue Important.
This flaw could be used to execute a remote Denial of Service (DoS) attack. In the default system configuration, with the sysctl
variable vm.overcommit_memory
set to either 0 or 1, an attack would take a not-insignificant amount of time to exhaust the system's memory. If vm.overcommit_memory
is set to a value of 2, the time required to exhaust system memory is sufficiently reduced. It was further noticed that, a 32-bit system would have its memory exhausted faster than a 64-bit system.
Detailed Description
SunRPC is an RPC (remote procedure call) mechanism originally designed by Sun Microsystems in the 1980s. Messages are encoded using XDR (external data representation: RFC4506, a binary format for serialising structured messages to disk or to send across the network).
XDR messages of particular types (such as "string", "bytes") include a 32-bit size field. When libtirpc
parses this field, it will malloc()
a corresponding amount of memory and then attempt to parse the rest of the message. If the message was truncated, parsing would return an error without freeing the allocated region. Client code such as rpcbind
is supposed to call a routine to free the reserved memory in this case - as it would after using the results of a successful parse - but in certain error cases it failed to do so. Potentially, up to 4GiB per message could be allocated.
Since the allocated regions were never actually used, the kernel would not allocate physical memory for these pages. Persistent attacks sending hundreds of thousands of packets could cause the allocator's page tables eventually to grow, causing the system to swap and rpcbind
to be terminated by the OOM (out-of-memory) Killer.
Depending on the setting of sysctl vm.overcommit_memory
, the process could map more virtual memory than was physically available on the system with very little impact. If vm.overcommit_memory=2
was set, other processes could potentially be impacted as the affected service rapidly consumed large amounts of available memory, causing the OOM Killer to be invoked. Details about Configuring System Memory can be found within the Red Hat Enterprise Linux Performance Tuning Guide.
Resolution
Mitigations are described below. Patches to all affected components will be made available in future updates.
Mitigation
- Close port
111
on machines which are on a public or untrusted network.111 (tcp/udp)
should be closed - A system having port
111
open should have firewall rules (iptables
orfirewalld
) to accept connections from trusted machines only - Use
vm.overcommit_memory=0
or1
only
Note: The above mitigations are present by default on default installations of Red Hat Enterprise Linux Server. These settings can be changed by a system administrator during or post installation time. The packages system-config-firewall
and firewalld
deny remote access to rpcbind
by default. vm.overcommit_memory
is normally set to 0. Additionally, we suggest that a simple cron
job can be setup which monitors VmSize
of rpcbind
and can trigger alerts.
If your environment has a particular need to set vm.overcommit_memory=2
, we strongly recommend setting per-process resource limits using systemd directives such as LimitAS
, or ulimit
hard limits.
Errata
This issue was resolved with the release of the following Security Errata.
NOTE: This Security Errata introduced a regression within the rpcbind package for a subset of our customers and resolved in subsequent Bugfix Errata which is listed below.
- Red Hat Enterprise Linux 6 libtirpc - RHSA-2017:1268
- Red Hat Enterprise Linux 6 rpcbind - RHSA-2017:1267
- Red Hat Enterprise Linux 6 rpcbind - RHBA-2017:1435
- Red Hat Enterprise Linux 7 libtirpc - RHSA-2017:1263
- Red Hat Enterprise Linux 7 rpcbind - RHSA-2017:1262
- Red Hat Enterprise Linux 7 rpcbind - RHBA-2017:1436
- Red Hat Gluster Storage 3.2 - RHSA-2017:1395
Root Cause
On one hand, libtirpc
's interface was too fragile in this case. Since it didn't actually use the allocated region, it should have released it immediately (or never allocated it in the first place). This would allow the exceptional case in rpcbind
to remain simple without risking a leak. On the other hand, client code -- especially in long-lived daemons -- should always be careful to deallocate resources under any circumstances, as any failure to do so may be an opportunity to attackers.
Patches for libtirpc
, libntirpc
, glibc
and rpcinfo
were all proposed in the security community and to upstream maintainers, with some of that activity occurring on Red Hat's Bugzilla. In cases like this, improving all of the involved software makes systems more robust into the future. Red Hat Product Security also undertook an analysis of other programs using XDR and the SunRPC interfaces in case the bug manifested elsewhere - particularly in important services such as krb5
and nfs-ganesha
. On examining the relevant code, we did not find any obvious instances of similar errors in other packages and are confident this particular flaw is confined to rpcbind
.
More information about this issue can be found on our CVE page: CVE-2017-8779
This solution is part of Red Hat’s fast-track publication program, providing a huge library of solutions that Red Hat engineers have created while supporting our customers. To give you the knowledge you need the instant it becomes available, these articles may be presented in a raw and unedited form.
Comments