lakitu: Backport a few systemd-resolved fixes for alloc size calculation

BUG=b:64222682
TEST=systemd-resolved doesn't crash with the patches
RELEASE_NOTE=Backported a few systemd-resolved fixes for alloc size
calculation

Change-Id: Icc0a9c2f1b5868a54fccb25868c191d03c936cf2
Reviewed-on: https://chromium-review.googlesource.com/598699
Reviewed-by: Aditya Kali <adityakali@google.com>
Commit-Queue: Daniel Wang <wonderfly@google.com>
Tested-by: Daniel Wang <wonderfly@google.com>
diff --git a/overlay-lakitu/sys-apps/systemd/files/232-0001-resolved-simplify-alloc-size-calculation.patch b/overlay-lakitu/sys-apps/systemd/files/232-0001-resolved-simplify-alloc-size-calculation.patch
new file mode 100644
index 0000000..ccd521b
--- /dev/null
+++ b/overlay-lakitu/sys-apps/systemd/files/232-0001-resolved-simplify-alloc-size-calculation.patch
@@ -0,0 +1,51 @@
+From db848813bae4d28c524b3b6a7dad135e426659ce Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
+Date: Sun, 18 Jun 2017 16:07:57 -0400
+Subject: [PATCH 1/3] resolved: simplify alloc size calculation
+
+The allocation size was calculated in a complicated way, and for values
+close to the page size we would actually allocate less than requested.
+
+Reported by Chris Coulson <chris.coulson@canonical.com>.
+
+CVE-2017-9445
+---
+ src/resolve/resolved-dns-packet.c | 8 +-------
+ src/resolve/resolved-dns-packet.h | 2 --
+ 2 files changed, 1 insertion(+), 9 deletions(-)
+
+diff --git a/src/resolve/resolved-dns-packet.c b/src/resolve/resolved-dns-packet.c
+index 240ee448f..821b66e26 100644
+--- a/src/resolve/resolved-dns-packet.c
++++ b/src/resolve/resolved-dns-packet.c
+@@ -47,13 +47,7 @@ int dns_packet_new(DnsPacket **ret, DnsProtocol protocol, size_t mtu) {
+ 
+         assert(ret);
+ 
+-        if (mtu <= UDP_PACKET_HEADER_SIZE)
+-                a = DNS_PACKET_SIZE_START;
+-        else
+-                a = mtu - UDP_PACKET_HEADER_SIZE;
+-
+-        if (a < DNS_PACKET_HEADER_SIZE)
+-                a = DNS_PACKET_HEADER_SIZE;
++        a = MAX(mtu, DNS_PACKET_HEADER_SIZE);
+ 
+         /* round up to next page size */
+         a = PAGE_ALIGN(ALIGN(sizeof(DnsPacket)) + a) - ALIGN(sizeof(DnsPacket));
+diff --git a/src/resolve/resolved-dns-packet.h b/src/resolve/resolved-dns-packet.h
+index 2c92392e4..3abcaf8cf 100644
+--- a/src/resolve/resolved-dns-packet.h
++++ b/src/resolve/resolved-dns-packet.h
+@@ -66,8 +66,6 @@ struct DnsPacketHeader {
+ /* With EDNS0 we can use larger packets, default to 4096, which is what is commonly used */
+ #define DNS_PACKET_UNICAST_SIZE_LARGE_MAX 4096
+ 
+-#define DNS_PACKET_SIZE_START 512
+-
+ struct DnsPacket {
+         int n_ref;
+         DnsProtocol protocol;
+-- 
+2.14.0.rc1.383.gd1ce394fe2-goog
+
diff --git a/overlay-lakitu/sys-apps/systemd/files/232-0002-resolved-do-not-allocate-packets-with-minimum-size.patch b/overlay-lakitu/sys-apps/systemd/files/232-0002-resolved-do-not-allocate-packets-with-minimum-size.patch
new file mode 100644
index 0000000..89200dd
--- /dev/null
+++ b/overlay-lakitu/sys-apps/systemd/files/232-0002-resolved-do-not-allocate-packets-with-minimum-size.patch
@@ -0,0 +1,48 @@
+From 88795538726a5bbfd9efc13d441cb05e1d7fc139 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
+Date: Tue, 27 Jun 2017 14:20:00 -0400
+Subject: [PATCH 2/3] resolved: do not allocate packets with minimum size
+
+dns_packet_new() is sometimes called with mtu == 0, and in that case we should
+allocate more than the absolute minimum (which is the dns packet header size),
+otherwise we have to resize immediately again after appending the first data to
+the packet.
+
+This partially reverts the previous commit.
+---
+ src/resolve/resolved-dns-packet.c | 12 +++++++++++-
+ 1 file changed, 11 insertions(+), 1 deletion(-)
+
+diff --git a/src/resolve/resolved-dns-packet.c b/src/resolve/resolved-dns-packet.c
+index 821b66e26..d1f0f760a 100644
+--- a/src/resolve/resolved-dns-packet.c
++++ b/src/resolve/resolved-dns-packet.c
+@@ -28,6 +28,9 @@
+ 
+ #define EDNS0_OPT_DO (1<<15)
+ 
++#define DNS_PACKET_SIZE_START 512
++assert_cc(DNS_PACKET_SIZE_START > UDP_PACKET_HEADER_SIZE)
++
+ typedef struct DnsPacketRewinder {
+         DnsPacket *packet;
+         size_t saved_rindex;
+@@ -47,7 +50,14 @@ int dns_packet_new(DnsPacket **ret, DnsProtocol protocol, size_t mtu) {
+ 
+         assert(ret);
+ 
+-        a = MAX(mtu, DNS_PACKET_HEADER_SIZE);
++        /* When dns_packet_new() is called with mtu == 0, allocate more than the
++         * absolute minimum (which is the dns packet header size), to avoid
++         * resizing immediately again after appending the first data to the packet.
++         */
++        if (mtu < UDP_PACKET_HEADER_SIZE)
++                a = DNS_PACKET_SIZE_START;
++        else
++                a = MAX(mtu, DNS_PACKET_HEADER_SIZE);
+ 
+         /* round up to next page size */
+         a = PAGE_ALIGN(ALIGN(sizeof(DnsPacket)) + a) - ALIGN(sizeof(DnsPacket));
+-- 
+2.14.0.rc1.383.gd1ce394fe2-goog
+
diff --git a/overlay-lakitu/sys-apps/systemd/files/232-0003-resolved-define-various-packet-sizes-as-unsigned.patch b/overlay-lakitu/sys-apps/systemd/files/232-0003-resolved-define-various-packet-sizes-as-unsigned.patch
new file mode 100644
index 0000000..0871025
--- /dev/null
+++ b/overlay-lakitu/sys-apps/systemd/files/232-0003-resolved-define-various-packet-sizes-as-unsigned.patch
@@ -0,0 +1,49 @@
+From 64a21fdaca7c93f1c30b21f6fdbd2261798b161a Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
+Date: Tue, 27 Jun 2017 16:59:06 -0400
+Subject: [PATCH 3/3] resolved: define various packet sizes as unsigned
+
+This seems like the right thing to do, and apparently at least some compilers
+warn about signed/unsigned comparisons with DNS_PACKET_SIZE_MAX.
+---
+ src/resolve/resolved-dns-packet.c | 2 +-
+ src/resolve/resolved-dns-packet.h | 6 +++---
+ 2 files changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/src/resolve/resolved-dns-packet.c b/src/resolve/resolved-dns-packet.c
+index d1f0f760a..a486216d6 100644
+--- a/src/resolve/resolved-dns-packet.c
++++ b/src/resolve/resolved-dns-packet.c
+@@ -28,7 +28,7 @@
+ 
+ #define EDNS0_OPT_DO (1<<15)
+ 
+-#define DNS_PACKET_SIZE_START 512
++#define DNS_PACKET_SIZE_START 512u
+ assert_cc(DNS_PACKET_SIZE_START > UDP_PACKET_HEADER_SIZE)
+ 
+ typedef struct DnsPacketRewinder {
+diff --git a/src/resolve/resolved-dns-packet.h b/src/resolve/resolved-dns-packet.h
+index 3abcaf8cf..5dff272fd 100644
+--- a/src/resolve/resolved-dns-packet.h
++++ b/src/resolve/resolved-dns-packet.h
+@@ -58,13 +58,13 @@ struct DnsPacketHeader {
+ /* The various DNS protocols deviate in how large a packet can grow,
+    but the TCP transport has a 16bit size field, hence that appears to
+    be the absolute maximum. */
+-#define DNS_PACKET_SIZE_MAX 0xFFFF
++#define DNS_PACKET_SIZE_MAX 0xFFFFu
+ 
+ /* RFC 1035 say 512 is the maximum, for classic unicast DNS */
+-#define DNS_PACKET_UNICAST_SIZE_MAX 512
++#define DNS_PACKET_UNICAST_SIZE_MAX 512u
+ 
+ /* With EDNS0 we can use larger packets, default to 4096, which is what is commonly used */
+-#define DNS_PACKET_UNICAST_SIZE_LARGE_MAX 4096
++#define DNS_PACKET_UNICAST_SIZE_LARGE_MAX 4096u
+ 
+ struct DnsPacket {
+         int n_ref;
+-- 
+2.14.0.rc1.383.gd1ce394fe2-goog
+
diff --git a/overlay-lakitu/sys-apps/systemd/systemd-232-r7.ebuild b/overlay-lakitu/sys-apps/systemd/systemd-232-r7.ebuild
new file mode 120000
index 0000000..f544380
--- /dev/null
+++ b/overlay-lakitu/sys-apps/systemd/systemd-232-r7.ebuild
@@ -0,0 +1 @@
+systemd-232.ebuild
\ No newline at end of file
diff --git a/overlay-lakitu/sys-apps/systemd/systemd-232.ebuild b/overlay-lakitu/sys-apps/systemd/systemd-232.ebuild
index 429a424..a9f22dd 100644
--- a/overlay-lakitu/sys-apps/systemd/systemd-232.ebuild
+++ b/overlay-lakitu/sys-apps/systemd/systemd-232.ebuild
@@ -182,6 +182,10 @@
 		"${FILESDIR}"/232-nspawn-sigchld.patch
 		# Lakitu: Add DHCP Search Domain List support. b/36192250
 		"${FILESDIR}"/232-dhcp-119.patch
+		# Lakitu: The following three are a set of fixes for CVE-2017-9445
+		"${FILESDIR}"/232-0001-resolved-simplify-alloc-size-calculation.patch
+		"${FILESDIR}"/232-0002-resolved-do-not-allocate-packets-with-minimum-size.patch
+		"${FILESDIR}"/232-0003-resolved-define-various-packet-sizes-as-unsigned.patch
 	)
 
 	[[ -d "${WORKDIR}"/patches ]] && PATCHES+=( "${WORKDIR}"/patches )