ASA-2019-00009 – systemd: Stack overflow when calling syslog from a command with long cmdline


Allele Security Alert

ASA-2019-00009

Identifier(s)

ASA-2019-00009, CVE-2018-16864

Title

Stack overflow when calling syslog from a command with long cmdline

Vendor(s)

The systemd project

Product(s)

systemd

Affected version(s)

systemd since version v203 up to and including v240

Fixed version(s)

systemd version v241

systemd released with the following commit:

journald: do not store the iovec entry for process commandline on stack
https://github.com/systemd/systemd/pull/11374/commits/084eeb865ca63887098e0945fb4e93c852b91b0f

Proof of concept

Unknown

Description

An allocation of memory without limits, that could result in the stack clashing with another memory region, was discovered in systemd-journald when a program with long command line arguments calls syslog. A local attacker may use this flaw to crash systemd-journald or escalate his privileges.

Technical details

Passing pass several megabytes of command-line arguments to a program that calls syslog(), then journald crashes:

systemd-journal[472]: segfault at 7ffe9a077420 ip 00007f45f6174877 sp 00007ffe9a0773f0 error 6 in systemd-journald[7f45f6169000+3f000]
(gdb) disassemble 0x7f45f6174877 - 0x7f45f6169000
Dump of assembler code for function dispatch_message_real.4064:
...
0x000000000000b82c <+988>: callq 0x2bd10 
0x000000000000b831 <+993>: test %eax,%eax
0x000000000000b833 <+995>: js 0xb8ea <dispatch_message_real.4064+1178>
0x000000000000b839 <+1001>: mov -0x218(%rbp),%rbx
0x000000000000b840 <+1008>: test %rbx,%rbx
0x000000000000b843 <+1011>: je 0xd31b <dispatch_message_real.4064+7883>
0x000000000000b849 <+1017>: mov %rbx,%rdi
0x000000000000b84c <+1020>: callq 0x5360 <strlen@plt>
0x000000000000b851 <+1025>: add $0xa,%eax
0x000000000000b854 <+1028>: cltq
0x000000000000b856 <+1030>: add $0x1e,%rax
0x000000000000b85a <+1034>: and $0xfffffffffffffff0,%rax
0x000000000000b85e <+1038>: sub %rax,%rsp
0x000000000000b861 <+1041>: movabs $0x454e494c444d435f,%rax
0x000000000000b86b <+1051>: lea 0x37(%rsp),%r15
0x000000000000b870 <+1056>: and $0xfffffffffffffff0,%r15
0x000000000000b874 <+1060>: test %rbx,%rbx
0x000000000000b877 <+1063>: mov %rax,(%r15)
0x000000000000b87a <+1066>: mov $0x3d,%eax
0x000000000000b87f <+1071>: mov %ax,0x8(%r15)
0x000000000000b884 <+1076>: lea 0x9(%r15),%rax
0x000000000000b888 <+1080>: je 0xb895 <dispatch_message_real.4064+1093>
0x000000000000b88a <+1082>: mov %rbx,%rsi
0x000000000000b88d <+1085>: mov %rax,%rdi
0x000000000000b890 <+1088>: callq 0x5370 <stpcpy@plt>
File: v219/src/journal/journald-server.c
---
538 static void dispatch_message_real(
...
604 r = get_process_cmdline(ucred->pid, 0, false, &t);
605 if (r >= 0) {
606 x = strjoina("_CMDLINE=", t);
---
File: v219/src/shared/util.h
---
919 #define strjoina(a, ...) \
920 ({ \
921 const char *_appendees_[] = { a, __VA_ARGS__ }; \
922 char *_d_, *_p_; \
923 int _len_ = 0; \
924 unsigned _i_; \
925 for (_i_ = 0; _i_ < ELEMENTSOF(_appendees_) && _appendees_[_i_]; _i_++) \
926 _len_ += strlen(_appendees_[_i_]); \
927 _p_ = _d_ = alloca(_len_ + 1); \
928 for (_i_ = 0; _i_ < ELEMENTSOF(_appendees_) && _appendees_[_i_]; _i_++) \
929 _p_ = stpcpy(_p_, _appendees_[_i_]); \
930 *_p_ = 0; \
931 _d_; \
932 })
---

This vulnerability, an attacker-controlled alloca() at instruction 0xb85e and line 927, was introduced in systemd v203:

commit ae018d9bc900d6355dea4af05119b49c67945184
Date: Mon Apr 22 23:10:13 2013 -0300
...
r = get_process_cmdline(ucred->pid, 0, false, &t);
if (r >= 0) {
- cmdline = strappend("_CMDLINE=", t);
+ cmdline = strappenda("_CMDLINE=", t);

(strappenda() was renamed strjoina() in systemd v219) and became exploitable in systemd v230:

commit ac2e41f5103ce2c679089c4f8fb6be61d7caec07
Date: Fri Feb 12 04:59:57 2016 -0800
...
This adds a wait flag to journal_file_set_offline(), when false the offline is
performed asynchronously in a separate thread.

Credits

Qualys Research Labs

Reference(s)

System Down: A systemd-journald exploit
https://seclists.org/oss-sec/2019/q1/54

journald: do not store the iovec entry for process commandline on stack
https://github.com/systemd/systemd/pull/11374/commits/084eeb865ca63887098e0945fb4e93c852b91b0f

1653855 (CVE-2018-16864) – CVE-2018-16864 systemd: stack overflow when calling syslog from a command with long cmdline
https://bugzilla.redhat.com/show_bug.cgi?id=1653855

CVE-2018-16864 - Red Hat Customer Portal
https://access.redhat.com/security/cve/CVE-2018-16864

CVE-2018-16864 in Ubuntu
https://people.canonical.com/~ubuntu-security/cve/CVE-2018-16864.html

CVE-2018-16864
https://security-tracker.debian.org/tracker/CVE-2018-16864

CVE-2018-16864 | SUSE
https://www.suse.com/security/cve/CVE-2018-16864

CVE-2018-16864
https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-16864

CVE-2018-16864
https://nvd.nist.gov/vuln/detail/CVE-2018-16864

If there is any error in this alert or you wish a comprehensive analysis, let us know.

Last modified: September 4, 2019

We are not responsible for any data loss, device corruption or any other type of issue due to the use of any information mentioned in our security alerts.