Out of bounds write in resolved with crafted TCP responses

Bug #1695546 reported by Chris Coulson
264
This bug affects 1 person
Affects Status Importance Assigned to Milestone
systemd (Ubuntu)
Fix Released
High
Dimitri John Ledkov
Xenial
Fix Released
Undecided
Unassigned
Yakkety
Fix Released
Undecided
Unassigned
Zesty
Fix Released
Undecided
Unassigned
Artful
Fix Released
High
Dimitri John Ledkov

Bug Description

[Impact]
Certain sizes passed to dns_packet_new can cause it to allocate a buffer that's too small. A page-aligned number - sizeof(DnsPacket) + sizeof(iphdr) + sizeof(udphdr) will do this - so, on x86 this will be a page-aligned number - 80. Eg, calling dns_packet_new with a size of 4016 will result in an allocation of 4096 bytes, but 108 bytes of this are for the DnsPacket struct.

A malicious DNS server can exploit this by responding with a specially crafted TCP payload to trick systemd-resolved in to allocating a buffer that's too small, and subsequently write arbitrary data beyond the end of it.

To demonstrate this you can run the attached python script. This is a mock DNS server that sends a response where the first two bytes of the TCP payload specify a size of 4016 (note, this size is picked to trigger an out of bounds write on x86 - you'll probably need to pick a different number for x86-64). You'll need to temporarily set your DNS server to 127.0.0.1.

[Testcase]
Launch the attached script on i386, point resolved at the started dns server, execute a dns query via resolved observe that it crashes.
Upgrade systemd package and observe that resolved no longer crashes.

[Regression Potential]
Low, resolved is not used by default in xenial. This is a bug fix to resolved, in case somebody does use resolved in xenial.

CVE References

Revision history for this message
Chris Coulson (chrisccoulson) wrote :
description: updated
Revision history for this message
Chris Coulson (chrisccoulson) wrote :
Download full text (4.2 KiB)

The test case results in traces like this.

#0 0xb7758cf9 in __kernel_vsyscall ()
No symbol table info available.
#1 0xb728b050 in __libc_signal_restore_set (set=0xbf8395e0) at ../sysdeps/unix/sysv/linux/nptl-signals.h:79
No locals.
#2 __GI_raise (sig=6) at ../sysdeps/unix/sysv/linux/raise.c:55
        set = {__val = {18946, 0, 808464438, 926376493, 808466485, 762454064, 807432237, 808464432, 540028976, 809119792, 540024880, 538976288, 538976288, 1987468064, 173896289, 892811106, 808464440, 926376493, 808476981, 762454064, 807432312, 808464432, 540028976, 809119792, 540024880, 538976288, 538976288, 1685478176, 173895539, 892811106, 808464481, 926376493}}
        pid = <optimised out>
        tid = <optimised out>
        ret = 0
#3 0xb728c577 in __GI_abort () at abort.c:89
        save_stage = 2
        act = {__sigaction_handler = {sa_handler = 0x30320a5d, sa_sigaction = 0x30320a5d}, sa_mask = {__val = {908996910, 892822026, 808465971, 929180976, 808923957, 1914712112, 544222509, 1664102448, 808464481, 979592736, 840970544, 859255606, 538976310, 1815027744, 1764713065, 758528051, 1970170220, 1852255608, 1768697717, 1919117154, 779382905, 841903987, 774975024, 929172022, 808923957, 1647128624, 1630745911, 540028976, 1882027890, 808464416, 0, 4096}}, sa_flags = -1222154106, sa_restorer = 0xbf839840}
        sigs = {__val = {32, 0 <repeats 31 times>}}
#4 0xb72c6f4f in __libc_message (do_abort=<optimised out>, fmt=<optimised out>) at ../sysdeps/posix/libc_fatal.c:175
        ap = <optimised out>
        fd = 2
        on_2 = <optimised out>
        list = <optimised out>
        nlist = <optimised out>
        cp = <optimised out>
        written = <optimised out>
#5 0xb72cdb47 in malloc_printerr (action=<optimised out>, str=0xb73c2d5c "double free or corruption (out)", ptr=<optimised out>, ar_ptr=0xb7415780 <main_arena>) at malloc.c:5046
        buf = "809d68b0"
        cp = <optimised out>
        ar_ptr = 0xb7415780 <main_arena>
        ptr = <optimised out>
        str = 0xb73c2d5c "double free or corruption (out)"
        action = <optimised out>
#6 0xb72ce406 in _int_free (av=0xb7415780 <main_arena>, p=0x809d68a8, have_lock=0) at malloc.c:3902
        size = <optimised out>
        fb = <optimised out>
        nextchunk = <optimised out>
        nextsize = <optimised out>
        nextinuse = <optimised out>
        prevsize = <optimised out>
        bck = <optimised out>
        fwd = <optimised out>
        errstr = <optimised out>
        locked = <optimised out>
        __func__ = "_int_free"
#7 0xb75a76fe in source_free.lto_priv.128 (s=<optimised out>) at ../src/libsystemd/sd-event/sd-event.c:887
No locals.
#8 0xb7602507 in sd_event_source_unref (s=<optimised out>) at ../src/libsystemd/sd-event/sd-event.c:1402
No locals.
#9 0x800523b6 in dns_stream_stop.lto_priv.71 (s=<optimised out>) at ../src/resolve/resolved-dns-stream.c:35
No locals.
#10 0x8005240b in dns_stream_complete (s=<optimised out>, error=<optimised out>) at ../src/resolve/resolved-dns-stream.c:55
No locals.
#11 0x80052689 in on_stream_io.lto_priv.64 (es=0x809d6640, fd=18, revents=1, userdata=0x809d6738) at ../src/resolve/resolved-dns-stream.c:321
        s = 0x80...

Read more...

description: updated
Revision history for this message
Chris Coulson (chrisccoulson) wrote :
Changed in systemd (Ubuntu):
assignee: nobody → Dimitri John Ledkov (xnox)
importance: Undecided → High
milestone: none → ubuntu-17.06
Revision history for this message
Dimitri John Ledkov (xnox) wrote :

I can reproduce the bug, using the python script, and setting DNS to 127.0.0.1 in /etc/systemd/resolved.conf, in an artful i386 lxd container.

The proposed patch seems to work around the problem. But i'm not sure if that is correct solution, that will work for all alignments on all architectures.

I guess we should be approaching upstream about this next?

Revision history for this message
Chris Coulson (chrisccoulson) wrote :

I've sent the details of this to Lennart now.

description: updated
Revision history for this message
Launchpad Janitor (janitor) wrote :

This bug was fixed in the package systemd - 232-21ubuntu5

---------------
systemd (232-21ubuntu5) zesty-security; urgency=medium

  * SECURITY UPDATE: Out-of-bounds write in systemd-resolved (LP: #1695546)
    - debian/patches/test-resolved-packet-add-a-simple-test-for-our-alloc.patch:
      Add a simple allocation test
    - debian/patches/resolved-simplify-alloc-size-calculation.patch: Simply
      allocation size calculation
    - CVE-2017-9445

 -- Chris Coulson <email address hidden> Wed, 21 Jun 2017 16:33:22 +0100

Changed in systemd (Ubuntu):
status: New → Fix Released
Revision history for this message
Launchpad Janitor (janitor) wrote :

This bug was fixed in the package systemd - 231-9ubuntu5

---------------
systemd (231-9ubuntu5) yakkety-security; urgency=medium

  * SECURITY UPDATE: Out-of-bounds write in systemd-resolved (LP: #1695546)
    - debian/patches/test-resolved-packet-add-a-simple-test-for-our-alloc.patch:
      Add a simple allocation test
    - debian/patches/resolved-simplify-alloc-size-calculation.patch: Simply
      allocation size calculation
    - CVE-2017-9445

 -- Chris Coulson <email address hidden> Wed, 21 Jun 2017 16:35:26 +0100

Changed in systemd (Ubuntu):
status: New → Fix Released
Steve Beattie (sbeattie)
information type: Private Security → Public Security
Changed in systemd (Ubuntu Xenial):
status: New → Confirmed
Changed in systemd (Ubuntu Yakkety):
status: New → Fix Released
Changed in systemd (Ubuntu Zesty):
status: New → Fix Released
description: updated
Revision history for this message
Łukasz Zemczak (sil2100) wrote : Please test proposed package

Hello Chris, or anyone else affected,

Accepted systemd into xenial-proposed. The package will build now and be available at https://launchpad.net/ubuntu/+source/systemd/229-4ubuntu18 in a few hours, and then in the -proposed repository.

Please help us by testing this new package. See https://wiki.ubuntu.com/Testing/EnableProposed for documentation on how to enable and use -proposed.Your feedback will aid us getting this update out to other Ubuntu users.

If this package fixes the bug for you, please add a comment to this bug, mentioning the version of the package you tested and change the tag from verification-needed-xenial to verification-done-xenial. If it does not fix the bug for you, please add a comment stating that, and change the tag to verification-failed-xenial. In either case, details of your testing will help us make a better decision.

Further information regarding the verification process can be found at https://wiki.ubuntu.com/QATeam/PerformingSRUVerification . Thank you in advance!

Changed in systemd (Ubuntu Xenial):
status: Confirmed → Fix Committed
tags: added: verification-needed verification-needed-xenial
Revision history for this message
Dimitri John Ledkov (xnox) wrote :

Instead of disconnect, I now get invalid reply response and the systemd-resolved service is not crashing.

Revision history for this message
Dimitri John Ledkov (xnox) wrote :

Crashes with 229-4ubuntu17, crash resiliant with 229-4ubuntu18.

tags: added: verification-done verification-done-xenial
removed: verification-needed verification-needed-xenial
Revision history for this message
Adam Conrad (adconrad) wrote :

Hello Chris, or anyone else affected,

Accepted systemd into xenial-proposed. The package will build now and be available at https://launchpad.net/ubuntu/+source/systemd/229-4ubuntu19 in a few hours, and then in the -proposed repository.

Please help us by testing this new package. See https://wiki.ubuntu.com/Testing/EnableProposed for documentation on how to enable and use -proposed.Your feedback will aid us getting this update out to other Ubuntu users.

If this package fixes the bug for you, please add a comment to this bug, mentioning the version of the package you tested and change the tag from verification-needed-xenial to verification-done-xenial. If it does not fix the bug for you, please add a comment stating that, and change the tag to verification-failed-xenial. In either case, details of your testing will help us make a better decision.

Further information regarding the verification process can be found at https://wiki.ubuntu.com/QATeam/PerformingSRUVerification . Thank you in advance!

tags: added: verification-needed verification-needed-xenial
removed: verification-done verification-done-xenial
Revision history for this message
Dimitri John Ledkov (xnox) wrote :

Starting with systemd 229-4ubuntu17, pointed systemd-resolve to the break-tcp DNS server and observed crash in the journal after calling systemd-resolve start.ubuntu.com.

Upgraded to 229-4ubuntu19, and now systemd-resolve start.ubuntu.com instead of disconnecting and crashing systemd-resolved daemon, keeps the systemd-resolved daemon running and an error is bubbled up back to the clinet received invalid reply.

tags: added: verification-done verification-done-xenial
removed: verification-needed verification-needed-xenial
Revision history for this message
Launchpad Janitor (janitor) wrote :

This bug was fixed in the package systemd - 229-4ubuntu19

---------------
systemd (229-4ubuntu19) xenial; urgency=medium

  * debian/extra/units/systemd-resolved.service.d/resolvconf.conf: partially
    revert, by removing ExecStart|StopPost lines, as these are not needed on
    xenial and generate warnings in the journal. (LP: #1704677)

systemd (229-4ubuntu18) xenial; urgency=medium

  * debian/extra/units/systemd-resolved.service.d/resolvconf.conf: if resolved
    is going to be started, make sure this blocks network-online.target.
    (LP: #1673860)
  * networkd: cherry-pick support for setting bridge port's priority
    (LP: #1668347)
  * Cherrypick upstream commit to enable system use kernel maximum limit for
    RLIMIT_NOFILE isntead of hard-coded (low) limit of 65536. (LP: #1686361)
  * Cherrypick upstream patch for platform predictable interface names.
    (LP: #1686784)
  * resolved: fix null pointer dereference crash (LP: #1621396)
  * Cherrypick core/timer downgrade message about random time addition
    (LP: #1692136)
  * SECURITY UPDATE: Out-of-bounds write in systemd-resolved (LP: #1695546)
    - CVE-2017-9445
  * Cherry-pick subset of patches to introduce infinity value in logind.conf
    for UserTasksMax (LP: #1651518)

 -- Dimitri John Ledkov <email address hidden> Mon, 17 Jul 2017 17:00:42 +0100

Changed in systemd (Ubuntu Xenial):
status: Fix Committed → Fix Released
Revision history for this message
Adam Conrad (adconrad) wrote : Update Released

The verification of the Stable Release Update for systemd has completed successfully and the package has now been released to -updates. Subsequently, the Ubuntu Stable Release Updates Team is being unsubscribed and will not receive messages about this bug report. In the event that you encounter a regression using the package from -updates please report a new bug using ubuntu-bug and tag the bug report regression-update so we can easily find any regressions.

To post a comment you must log in.
This report contains Public Security information  
Everyone can see this security related information.

Other bug subscribers

Bug attachments

Remote bug watches

Bug watches keep track of this bug in other bug trackers.