Bug 1624498 (CVE-2018-14634) - CVE-2018-14634 kernel: Integer overflow in Linux's create_elf_tables function
Summary: CVE-2018-14634 kernel: Integer overflow in Linux's create_elf_tables function
Keywords:
Status: CLOSED ERRATA
Alias: CVE-2018-14634
Product: Security Response
Classification: Other
Component: vulnerability
Version: unspecified
Hardware: All
OS: Linux
high
high
Target Milestone: ---
Assignee: Red Hat Product Security
QA Contact:
URL:
Whiteboard:
Depends On: 1625972 1625973 1625974 1625975 1625976 1625977 1625978 1625979 1625980 1625981 1625982 1625983 1625984 1625985 1625991 1625993
Blocks: 1624500 1635168
TreeView+ depends on / blocked
 
Reported: 2018-08-31 20:03 UTC by Laura Pardo
Modified: 2021-12-10 17:16 UTC (History)
51 users (show)

Fixed In Version:
Doc Type: If docs needed, set a value
Doc Text:
An integer overflow flaw was found in the Linux kernel's create_elf_tables() function. An unprivileged local user with access to SUID (or otherwise privileged) binary could use this flaw to escalate their privileges on the system.
Clone Of:
Environment:
Last Closed: 2018-12-18 05:53:44 UTC
Embargoed:


Attachments (Terms of Use)
extra mitigation - setrlimit race condition (357 bytes, text/plain)
2018-10-04 22:02 UTC, Frank Ch. Eigler
no flags Details


Links
System ID Private Priority Status Summary Last Updated
Red Hat Product Errata RHSA-2018:2748 0 None None None 2018-09-25 19:06:45 UTC
Red Hat Product Errata RHSA-2018:2763 0 None None None 2018-09-25 19:07:18 UTC
Red Hat Product Errata RHSA-2018:2846 0 None None None 2018-10-09 15:49:47 UTC
Red Hat Product Errata RHSA-2018:2924 0 None None None 2018-10-16 14:50:49 UTC
Red Hat Product Errata RHSA-2018:2925 0 None None None 2018-10-16 23:54:06 UTC
Red Hat Product Errata RHSA-2018:2933 0 None None None 2018-10-16 18:55:57 UTC
Red Hat Product Errata RHSA-2018:3540 0 None None None 2018-11-13 16:33:38 UTC
Red Hat Product Errata RHSA-2018:3586 0 None None None 2018-11-13 16:31:30 UTC
Red Hat Product Errata RHSA-2018:3590 0 None None None 2018-11-13 17:50:53 UTC
Red Hat Product Errata RHSA-2018:3591 0 None None None 2018-11-13 17:51:25 UTC
Red Hat Product Errata RHSA-2018:3643 0 None None None 2018-11-20 19:57:22 UTC

Description Laura Pardo 2018-08-31 20:03:19 UTC
A flaw was found in the Linux kernels with commit b6a2fea39318 ("mm: variable length argument support", from July 19, 2007) but without commit da029c11e6b1 ("exec:Limit arg stack to at most 75% of _STK_LIM", from July 7, 2017). An integer overflow in the Linux kernel's create_elf_tables() function. A local attacker can exploit this vulnerability via a SUID-root binary and obtain full root privileges.


Referenced commits:
b6a2fea39318 ("mm: variable length argument support", from July 19, 2007)
https://github.com/torvalds/linux/commit/b6a2fea39318e43fee84fa7b0b90d68bed92d2ba

da029c11e6b1 ("exec: Limit arg stack to at most 75% of _STK_LIM", from July 7, 2017) 
https://github.com/torvalds/linux/commit/da029c11e6b12f321f36dac8771e833b65cec962

Additional references:
https://www.qualys.com/2018/09/25/cve-2018-14634/mutagen-astronomy-integer-overflow-linux-create_elf_tables-cve-2018-14634.txt

Comment 1 Laura Pardo 2018-09-03 15:05:58 UTC
Acknowledgments:

Name: Qualys Research Labs

Comment 9 Petr Matousek 2018-09-25 15:24:07 UTC
Statement:

This issue does not affect 32-bit systems as they do not have a large enough address space to exploit this flaw.

Systems with less than 32GB of memory are very unlikely to be affected by this issue due to memory demands during exploitation.

This issue does not affect the versions of Linux kernel as shipped with Red Hat Enterprise Linux 5.

This issue affects the version of the kernel packages as shipped with Red Hat Enterprise Linux 6, 7 and Red Hat Enterprise MRG 2. Future kernel updates for Red Hat Enterprise Linux 6, 7 and Red Hat Enterprise MRG 2 will address this issue.

Comment 10 Petr Matousek 2018-09-25 15:27:52 UTC
Mitigation:

To mitigate the issue:

Enable and install kernel-debuginfo packages as per https://access.redhat.com/solutions/666123

1) On the host, save the following in a file with the ".stp" extension:

// CVE-2018-14634
//
// Theory of operations: adjust the thread's # rlimit-in-effect around
// calls to the vulnerable get_arg_page() function so as to encompass
// the newly required _STK_LIM / 4 * 3 maximum.

// Complication: the rlimit is stored in a current-> structure that
// is shared across the threads of the process.  They may concurrently
// invoke this operation.

function clamp_stack_rlim_cur:long ()
%{
  struct rlimit *rlim = current->signal->rlim;
  unsigned long rlim_cur = READ_ONCE(rlim[RLIMIT_STACK].rlim_cur);

  unsigned long limit = _STK_LIM / 4 * 3;
  limit *= 4; // multiply it back up, to the scale used by rlim_cur

  if (rlim_cur > limit) {
    WRITE_ONCE(rlim[RLIMIT_STACK].rlim_cur, limit);
    STAP_RETURN(limit);
  } else
    STAP_RETURN(0);
%}

probe kernel.function("copy_strings").call
{
  l = clamp_stack_rlim_cur()
   if (l)
     printf("lowered process %s(%d) STACK rlim_cur to %p\n",
            execname(), pid(), l)
}

probe begin {
	printf("CVE-2018-14634 mitigation loaded\n")

}

probe end {
	printf("CVE-2018-14634 mitigation unloaded\n")
}

2) Install the "systemtap" package and any required dependencies. Refer
to the "2. Using SystemTap" chapter in the Red Hat Enterprise Linux
"SystemTap Beginners Guide" document, available from docs.redhat.com,
for information on installing the required -debuginfo and matching kernel-devel packages

3) Run the "stap -g [filename-from-step-1].stp" command as root.

If the host is rebooted, the changes will be lost and the script must be
run again.


Alternatively, build the systemtap script on a development system with
"stap -g -p 4 [filename-from-step-1].stp", distribute the resulting
kernel module to all affected systems, and run "staprun -L <module>" on those.
When using this approach only systemtap-runtime package is required on
the affected systems. Please notice that the kernel version must be the same
across all systems.


This may not be a suitable workaround if your application uses massive amounts of stack space. Please consider this if there are any adverse affects when running this mitigation.

Comment 12 errata-xmlrpc 2018-09-25 19:06:30 UTC
This issue has been addressed in the following products:

  Red Hat Enterprise Linux 7

Via RHSA-2018:2748 https://access.redhat.com/errata/RHSA-2018:2748

Comment 13 errata-xmlrpc 2018-09-25 19:07:00 UTC
This issue has been addressed in the following products:

  Red Hat Enterprise Linux 7

Via RHSA-2018:2763 https://access.redhat.com/errata/RHSA-2018:2763

Comment 14 Alexander Peslyak 2018-09-26 12:05:43 UTC
Petr, am I correct that the systemtap mitigation is racy, and can be bypassed by a more elaborate exploit that would reset rlim[RLIMIT_STACK].rlim_cur back to a high enough value from another thread of the invoking process (perhaps it'd be doing that in a busy loop)? This came up in discussions of a similar kernel patch, resulting in patches to the patch, last year. I wonder if we can come up with a simple yet non-racy systemtap mitigation. Maybe also trap setrlimit() and impose a higher limit there that's enough to prevent the attack yet unlikely to break desirable uses.

Also, I'm curious - why exactly is RHEL5 unaffected? Thanks!

Comment 15 Kent Engström 2018-09-26 17:06:29 UTC
Trying the SystemTap mitigation script in our EL6 x86_64 environment, it seems to set the stack limit at shown by "ulimit -s" to 30720 regardless of the initial setting in /etc/security/limits.conf where we have "unlimited".

Setting a big number instead of unlimited in /etc/security/limits.conf for stack does not seem to matter; still set to 30720 by the SystemTap script.

Before applying:

# ssh n1 ulimit -s
unlimited

# ssh n1 staprun -L CVE-2018-14634-mitigation/2.6.32-754.3.5.el6.x86_64/stap_4d64dccb8f09ef10871f7b00522c1ff7_3076.ko

# ssh n1 ulimit -s
30720

Is it supposed to be like this?

Comment 16 Alexander Peslyak 2018-09-26 19:34:38 UTC
I can't speak about the intent, but the behavior Kent describes is consistent with my reading of the SystemTap mitigation script. The specific number 30720 is a result of what I think is a bug-turned-feature, in "limit *= 4; // multiply it back up, to the scale used by rlim_cur". This doesn't make sense to me in its current context (I guess this line is a leftover from prior edits of the script), but the multiplication results in the limit being not so low (would have been 3/4 of the default 10 MiB stack limit otherwise, which is more likely to break some applications and is unnecessarily strict to prevent exploitation of this specific issue). I think a forced limit of 30 MiB is sane, unless you have specific applications that require a higher limit (in which case you can edit the SystemTap script accordingly - a limit of a few hundred MiB would still mitigate the original issue).

Comment 18 Wade Mealing 2018-09-27 00:35:34 UTC
This will not modifiy the live limit shown by ulimit command.

Comment 20 Wade Mealing 2018-09-27 02:40:09 UTC
Gday Alexander,

I take responsibility for the systemtap script, Petr just made it public. 


> am I correct that the systemtap mitigation is racy, and can be bypassed by a more elaborate exploit that would reset rlim[RLIMIT_STACK].rlim_cur back to a high enough value from another thread of the invoking process (perhaps it'd be doing that in a busy loop)? 

You seem to be correct, I was not part of this discussion.  I had assumed that copy_strings would be the correct time, but much like most situations it is never as simple as it seems.


> This came up in discussions of a similar kernel patch, resulting in patches to
> the patch, last year. I wonder if we can come up with a simple yet non-racy 
> systemtap mitigation.

I had a few different angles, both of which appear to suffer the same race condition flaw that you've pointed out here.

I was pondering if it would be better to apply it directly to get_arg_page, but I think that will require additional investigation.    Feedback welcome on your behalf.  I think that working on this may have diminishing returns as the errata has already started shipping.


I had a reproducer that worked on el6 and el7, it did not reproduce on el5, but now you have me concerned I'm going to test it again.  Will post back with results.

Comment 21 Alexander Peslyak 2018-09-27 12:02:12 UTC
Thanks, Wade.

I don't understand what you mean by "This will not modifiy the live limit shown by ulimit command." If you're referring to the effect of the SystemTap mitigation, then it's actually expected to modify that, visibly I think due to bash calling getrlimit(), and it's been reported that way in a comment above.

In last year's discussions (and in the grsecurity patch much earlier), the only reason for the rlimit to be lowered on exec was to apply that selectively to SUID/SGID exec, rather than to all execs. Since you're doing it for all execs anyway, a simple workaround and end-user can use is to lower the hard limit in /etc/security/limits.conf with a line like this:

* hard stack 30720

This will apply to user logins (e.g., via SSH), but unfortunately not to various privsep child processes of services, etc., unless and until those services are manually restarted by someone logged in as root. It might or might not apply to various non-login ways that a user can invoke a command - e.g., via .forward files - depending on whether those services start PAM sessions for those command invocations or not. Thus, a more complete fix would (also) include adding "ulimit -Hs 30720" to an early system bootup script from where all other service startup scripts are invoked, but do we still have anything like that with systemd? I'm not familiar with systemd.

And this brings us back to a possible SystemTap, where I think you could lower both the hard and the soft limit. There's no point in allowing a higher hard limit if you'd be resetting the soft limit on each exec anyway. Not to be racy against a concurrent setrlimit(), which might be past its hard limit check already, you'd need to also intercept setrlimit() calls (is there a compat version of that syscall? if so, that as well) and impose the limit on its inputs. OTOH, if someone doesn't mind rebooting with the SystemTap loaded early on at bootup, then the race wouldn't matter anymore once we're setting both the hard and the soft limit on each exec - the hard limit would get inherited by all child processes, thereby preventing a concurrent setrlimit() attack on the already booted up system.

Yes, "working on this may have diminishing returns as the errata has already started shipping." Maybe it's more important to prepare better instructions for setup of SystemTap-based mitigations for next time one is needed. How can one have a SystemTap-based mitigation re-applied on system bootup early on? A hack I once used on a RHEL6'ish system is this:

# tail -4 /etc/sysconfig/sshd
MOD=/lib/modules/`uname -r`/extra/dirtycow.ko
if [ -e $MOD ]; then
	staprun -L $MOD
fi

Perhaps Red Hat should start recommending something like this, or come up with an official way for SystemTap-based mitigations to be loaded on system bootup (e.g., have a "service" that would do that, and would be guaranteed to start up before things such as sshd, crond, MTAs, etc. - those that may invoke user-supplied programs as part of their normal functionality).

Regarding RHEL5, I know why our OpenVZ/RHEL5-based kernels on Owl are unaffected since we migrated to those back in 2010 - I lowered MAX_ARG_STRINGS and introduced an extra check into get_arg_pages() back then (no, this isn't in OpenVZ upstream, it's Owl-specific unfortunately) - but I was surprised to hear yours are unaffected either. Maybe there's something else preventing the attack on those kernels (good) or on the specific system you tested on (bad; e.g., 32 GB could somehow not be allocated in the kernel when total RAM isn't a lot higher than that).

Thanks again for your replies.

Comment 28 Frank Ch. Eigler 2018-10-04 22:02:21 UTC
Created attachment 1490730 [details]
extra mitigation - setrlimit race condition

Alexander, thanks, good point regarding the race condition between a concurrent setrlimit(2).  This extra snippet of stap script aims to intercept those syscalls at a lower level worker function (do_prlimit), and to impose the same limiting value on RLIMIT_STACK calls.

Comment 29 errata-xmlrpc 2018-10-09 15:49:29 UTC
This issue has been addressed in the following products:

  Red Hat Enterprise Linux 6

Via RHSA-2018:2846 https://access.redhat.com/errata/RHSA-2018:2846

Comment 30 errata-xmlrpc 2018-10-16 14:50:24 UTC
This issue has been addressed in the following products:

  Red Hat Enterprise Linux 6.6 Advanced Update Support
  Red Hat Enterprise Linux 6.6 Telco Extended Update Support

Via RHSA-2018:2924 https://access.redhat.com/errata/RHSA-2018:2924

Comment 31 errata-xmlrpc 2018-10-16 18:55:38 UTC
This issue has been addressed in the following products:

  Red Hat Enterprise Linux 6.5 Advanced Update Support

Via RHSA-2018:2933 https://access.redhat.com/errata/RHSA-2018:2933

Comment 32 errata-xmlrpc 2018-10-16 23:53:46 UTC
This issue has been addressed in the following products:

  Red Hat Enterprise Linux 6.7 Extended Update Support

Via RHSA-2018:2925 https://access.redhat.com/errata/RHSA-2018:2925

Comment 41 errata-xmlrpc 2018-11-13 16:31:08 UTC
This issue has been addressed in the following products:

  Red Hat Enterprise MRG 2

Via RHSA-2018:3586 https://access.redhat.com/errata/RHSA-2018:3586

Comment 42 errata-xmlrpc 2018-11-13 16:33:15 UTC
This issue has been addressed in the following products:

  Red Hat Enterprise Linux 7.4 Extended Update Support

Via RHSA-2018:3540 https://access.redhat.com/errata/RHSA-2018:3540

Comment 43 errata-xmlrpc 2018-11-13 17:50:37 UTC
This issue has been addressed in the following products:

  Red Hat Enterprise Linux 7.2 Advanced Update Support
  Red Hat Enterprise Linux 7.2 Update Services for SAP Solutions
  Red Hat Enterprise Linux 7.2 Telco Extended Update Support

Via RHSA-2018:3590 https://access.redhat.com/errata/RHSA-2018:3590

Comment 44 errata-xmlrpc 2018-11-13 17:51:04 UTC
This issue has been addressed in the following products:

  Red Hat Enterprise Linux 7.3 Extended Update Support

Via RHSA-2018:3591 https://access.redhat.com/errata/RHSA-2018:3591

Comment 45 errata-xmlrpc 2018-11-20 19:56:59 UTC
This issue has been addressed in the following products:

  Red Hat Enterprise Linux 6.4 Advanced Update Support

Via RHSA-2018:3643 https://access.redhat.com/errata/RHSA-2018:3643


Note You need to log in before you can comment on or make changes to this bug.