#4428: Create security patch for systemd (CVE-2019-6454)
--------------------+----------------------
 Reporter:  renodr  |      Owner:  lfs-book
     Type:  task    |     Status:  new
 Priority:  high    |  Milestone:  8.4
Component:  Book    |    Version:  SVN
 Severity:  normal  |   Keywords:
--------------------+----------------------
 Create a security patch for CVE-2019-6454:

 {{{
 It was found that bus_process_object() in bus-objects.c allocates a buffer
 on the stack large enough to temporarily store the object path specified
 in the incoming message. A malicious unprivileged local user to send a
 message which results in the stack pointer moving outside of the bounds of
 the currently mapped stack region, jumping over the stack guard pages. A
 specifically crafted DBUS nessage could crash PID 1 and result in a
 subsequent kernel panic.
 }}}

 Remotely-exploitable PID1 crash via D-Bus and subsequent kernel panic.


 {{{
 Date: Mon, 18 Feb 2019 17:41:56 +0100
 From: Chris Coulson <chris.coul...@...onical.com>
 To: oss-secur...@...ts.openwall.com
 Subject: CVE-2019-6454: systemd (PID1) crash with specially crafted D-Bus
  message

 Hi,

 I recently discovered a way for an unprivileged user to crash PID1 by
 sending it a specially crafted D-Bus message on the system bus and causing
 the stack pointer to jump the stack guard pages, leaving it pointing to an
 unmapped page.

 Details of the issue follow:

 ----
 bus_process_object() in src/libsystemd/sd-bus/bus-objects.c allocates a
 buffer on the stack large enough to temporarily store the object path
 specified in the incoming message:

         assert(m->path);
         assert(m->member);

         pl = strlen(m->path);
         do {
 =>              char prefix[pl+1];

                 bus->nodes_modified = false;

                 r = object_find_and_run(bus, m, m->path, false,
 &found_object);

 As the length of this is attacker controlled, it is possible for a
 malicious unprivileged local user to send a message which results in the
 stack pointer moving outside of the bounds of the currently mapped stack
 region, jumping over the stack guard pages.

 According to the dbus specification, the path "may be of any length" (with
 the length being represented on the wire by a uint32), but systemd seems
 to limit the size of incoming messages to 128MB (BUS_MESSAGE_SIZE_MAX).
 From testing on Ubuntu 18.10, it seems that the
 real limit is actually much less than this - dbus-daemon drops the
 connection when I try to send a message with an object path greater than
 about 32MB. The effect of this is that the stack pointer always lands in
 an unmapped page and it doesn't seem to be possible to make it land in
 another mapped page.

 Running a simple script that sends a message with a long enough path to
 org.freedesktop.systemd1 on Ubuntu 18.10 (systemd v239) and CentOS 7.6
 (systemd v219) results in an easily reproducible crash (and subsequent
 kernel panic) on both x86 and x86-64, with a stack trace that looks like
 this:

 Program received signal SIGSEGV, Segmentation fault.
 bus_process_object (bus=0x56085041a6a0, m=0x5608504d4d00) at
 ../src/libsystemd/sd-bus/bus-objects.c:1378
 1378    ../src/libsystemd/sd-bus/bus-objects.c: No such file or directory.
 (gdb) bt
 #0  bus_process_object (bus=0x56085041a6a0, m=0x5608504d4d00) at
 ../src/libsystemd/sd-bus/bus-objects.c:1378
 #1  0x00007f4a4e373b37 in process_message (m=0x5608504d4d00,
 bus=0x56085041a6a0) at ../src/libsystemd/sd-bus/sd-bus.c:2663
 #2  process_running (ret=0x0, priority=0, hint_priority=false,
 bus=0x56085041a6a0) at ../src/libsystemd/sd-bus/sd-bus.c:2705
 #3  bus_process_internal (bus=b...@...ry=0x56085041a6a0,
 hint_priority=hint_prior...@...ry=false, priority=prior...@...ry=0,
 ret=r...@...ry=0x0) at ../src/libsystemd/sd-bus/sd-bus.c:2924
 #4  0x00007f4a4e373d9c in sd_bus_process (bus=b...@...ry=0x56085041a6a0,
 ret=r...@...ry=0x0) at ../src/libsystemd/sd-bus/sd-bus.c:2951
 #5  0x00007f4a4e373e68 in io_callback (s=<optimized out>, fd=<optimized
 out>, revents=<optimized out>, userdata=<optimized out>, s=<optimized
 out>, fd=<optimized out>, revents=<optimized out>, userdata=<optimized
 out>) at ../src/libsystemd/sd-bus/sd-bus.c:3304
 #6  0x00007f4a4e34fa10 in source_dispatch (s=s...@...ry=0x560850433590) at
 ../src/libsystemd/sd-event/sd-event.c:3103
 #7  0x00007f4a4e34fcff in sd_event_dispatch (e=e...@...ry=0x56085036a090) at
 ../src/libsystemd/sd-event/sd-event.c:3516
 #8  0x00007f4a4e34fec8 in sd_event_run (e=0x56085036a090,
 timeout=18446744073709551615) at ../src/libsystemd/sd-event/sd-
 event.c:3573
 #9  0x000056084e579453 in manager_loop (m=0x5608503675d0) at
 ../src/core/manager.c:2814
 #10 invoke_main_loop (m=0x5608503675d0, ret_reexecute=0x7fff92a0076a,
 ret_retval=0x7fff92a0076c, ret_shutdown_verb=<optimized out>,
 ret_fds=0x7fff92a00770, ret_switch_root_dir=0x7fff92a00798,
 ret_switch_root_init=0x7fff92a00790, ret_error_message=0x7fff92a00780) at
 ../src/core/main.c:1630
 #11 0x000056084e4da610 in main (argc=<optimized out>, argv=0x7fff92a00a48)
 at ../src/core/main.c:2415

 (gdb) p $_siginfo
 $1 = {si_signo = 11, si_errno = 0, si_code = 1, _sifields = {_pad =
 {-1867007032, 32767, 0 <repeats 26 times>}, _kill = {si_pid =
 -1867007032, si_uid = 32767}, _timer = {si_tid = -1867007032, si_overrun =
 32767, si_sigval = {sival_int = 0, sival_ptr = 0x0}}, _rt = {si_pid =
 -1867007032, si_uid = 32767, si_sigval = {sival_int = 0, sival_ptr =
 0x0}}, _sigchld = {si_pid = -1867007032, si_uid = 32767, si_status = 0,
 si_utime = 0, si_stime = 0}, _sigfault = {si_addr = 0x7fff90b7bbc8,
 _addr_lsb = 0, _addr_bnd = {_lower = 0x0, _upper = 0x0}}, _sigpoll =
 {si_band = 140735621348296, si_fd = 0}}}

 (gdb) disassemble
 Dump of assembler code for function bus_process_object:
 ......
    0x00007f4a4e387aae <+238>:   mov    %r13,%rsi
    0x00007f4a4e387ab1 <+241>:   mov    %r12,%rdi
    0x00007f4a4e387ab4 <+244>:   mov    %rsp,%rbx
 => 0x00007f4a4e387ab7 <+247>:   callq  0x7f4a4e386280
 <object_find_and_run>

 You can see that %rsp points to an unmapped page:

 (gdb) info
 registers

 rax            0x1e84810           32000016
 rbx            0x7fff90b7bbd0    140735621348304
 rcx            0x0                0
 rdx            0x7f4a48dbe028     139957026676776
 rsi            0x5608504d4d00     94593706970368
 rdi            0x56085041a6a0     94593706206880
 rbp            0x7fff92a00430     0x7fff92a00430
 rsp            0x7fff90b7bbd0      0x7fff90b7bbd0
 r8             0x7fff92a003f7      140735653348343
 r9             0x1                 1
 r10            0x1                 1
 r11            0x9690b4ffdb710482  -7597373560382749566
 r12            0x56085041a6a0      94593706206880
 r13            0x5608504d4d00      94593706970368
 r14            0x7fff92a003f7      140735653348343
 r15            0x7f4a4e465be0      139957117541344
 rip            0x7f4a4e387ab7      0x7f4a4e387ab7 <bus_process_object+247>
 eflags         0x10202             [ IF RF ]
 cs             0x33                51
 ss             0x2b                43
 ds             0x0                 0
 es             0x0                 0
 fs             0x0                 0
 gs             0x0                 0

 (gdb) info proc mappings
 process 1

 Mapped address spaces:

           Start Addr           End Addr       Size     Offset objfile
 ......
       0x7f4a4e76f000     0x7f4a4e770000     0x1000    0x29000 /lib/x86_64
 -linux-gnu/ld-2.28.so
       0x7f4a4e770000     0x7f4a4e771000     0x1000       0x0
       0x7fff929e0000     0x7fff92a01000    0x21000        0x0 [stack]
       0x7fff92ac8000     0x7fff92acb000     0x3000        0x0 [vvar]

 Given the constraint that it doesn't appear to be possible to make the
 stack pointer land in another mapped page, this bug is classified as
 denial-of-service.
 ----

 There are 3 patches required to resolve this, provided by Red Hat Product
 Security and attached to this message. The first patch enforces a sensible
 size limit on D-Bus object paths, dropping messages when the path is too
 long. The second patch removes usage of variable-size stack allocations
 for object paths. The third patch stops the system bus connection from
 being terminated when an invalid message is received.

 I would like to thank Riccardo Schirone, Lennart Poettering and Red Hat
 Product Security for their help with this issue.
 }}}

 I will craft the LFS and BLFS portions of this patch simultaneously and
 push them as such.
 
[https://github.com/systemd/systemd/commit/612b74d32f970c43c14ad087ad086424792981b1]
 [https://github.com/systemd/systemd/pull/11754]

--
Ticket URL: <http://wiki.linuxfromscratch.org/lfs/ticket/4428>
LFS Trac <http://wiki.linuxfromscratch.org/lfs/>
Linux From Scratch: Your Distro, Your Rules.
-- 
http://lists.linuxfromscratch.org/listinfo/lfs-book
FAQ: http://www.linuxfromscratch.org/blfs/faq.html
Unsubscribe: See the above information page

Reply via email to