diff options
| author | Martin Borg <martin.borg@enea.com> | 2018-02-28 09:33:50 +0100 |
|---|---|---|
| committer | Martin Borg <martin.borg@enea.com> | 2018-02-28 09:33:50 +0100 |
| commit | 495b231e8e0da5046b6b1803d372fe33d0b14be9 (patch) | |
| tree | 63a15b7f1e71be9c3ab4f2ee829e9b59e2f0515f | |
| parent | 75578eccbe6c1de6b437e1599fe674e6b7ee2db1 (diff) | |
| download | meta-el-common-495b231e8e0da5046b6b1803d372fe33d0b14be9.tar.gz | |
Drop CVE patches that have been fixed in upstream poky/rocko
Signed-off-by: Martin Borg <martin.borg@enea.com>
22 files changed, 0 insertions, 2475 deletions
diff --git a/recipes-connectivity/bind/bind/0001-fix-back-port-issue.patch b/recipes-connectivity/bind/bind/0001-fix-back-port-issue.patch deleted file mode 100644 index a874469..0000000 --- a/recipes-connectivity/bind/bind/0001-fix-back-port-issue.patch +++ /dev/null | |||
| @@ -1,29 +0,0 @@ | |||
| 1 | From 6bed6ea11b1880e0a078bd02c1d31d21f0540583 Mon Sep 17 00:00:00 2001 | ||
| 2 | From: Mark Andrews <marka@isc.org> | ||
| 3 | Date: Thu, 29 Dec 2016 10:48:46 +1100 | ||
| 4 | Subject: [PATCH] fix back port issue | ||
| 5 | |||
| 6 | This patch is needed for CVE-2016-9444 fix. | ||
| 7 | Upstream-Status: Backport [backport from v9_10_6_patch: https://source.isc.org/cgi-bin/gitweb.cgi?p=bind9.git;a=patch;h=6bed6ea11b1880e0a078bd02c1d31d21f0540583] | ||
| 8 | |||
| 9 | Signed-off-by: Sona Sarmadi <sona.sarmadi@enea.com> | ||
| 10 | --- | ||
| 11 | lib/dns/message.c | 2 +- | ||
| 12 | 1 file changed, 1 insertion(+), 1 deletion(-) | ||
| 13 | |||
| 14 | diff --git a/lib/dns/message.c b/lib/dns/message.c | ||
| 15 | index fe8e5d0..5b8166a 100644 | ||
| 16 | --- a/lib/dns/message.c | ||
| 17 | +++ b/lib/dns/message.c | ||
| 18 | @@ -1639,7 +1639,7 @@ getsection(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx, | ||
| 19 | ((msg->flags & DNS_MESSAGEFLAG_TC) == 0) && | ||
| 20 | !preserve_order && | ||
| 21 | !auth_signed(section)) | ||
| 22 | - DO_ERROR(DNS_R_FORMERR); | ||
| 23 | + DO_FORMERR; | ||
| 24 | |||
| 25 | if (seen_problem) | ||
| 26 | return (DNS_R_RECOVERABLE); | ||
| 27 | -- | ||
| 28 | 1.9.1 | ||
| 29 | |||
diff --git a/recipes-connectivity/bind/bind/CVE-2016-9444.patch b/recipes-connectivity/bind/bind/CVE-2016-9444.patch deleted file mode 100644 index 2c1e125..0000000 --- a/recipes-connectivity/bind/bind/CVE-2016-9444.patch +++ /dev/null | |||
| @@ -1,186 +0,0 @@ | |||
| 1 | From 254d55749ccb1129e7d021a51d0c3b7d3da26ee1 Mon Sep 17 00:00:00 2001 | ||
| 2 | From: Sona Sarmadi <sona.sarmadi@enea.com> | ||
| 3 | Date: Tue, 12 Sep 2017 14:13:28 +0200 | ||
| 4 | Subject: [PATCH] CVE-2016-9444 | ||
| 5 | |||
| 6 | An unusually-formed DS record response could cause an assertion failure | ||
| 7 | |||
| 8 | CVE: CVE-2016-9444 | ||
| 9 | Upstream-Status: Backport [backport from remotes/origin/v9_10_6_patch | ||
| 10 | https://source.isc.org/cgi-bin/gitweb.cgi?p=bind9.git;a=commit;h=04c7ee66b1eda851737cc7582a2a88193a0b4118] | ||
| 11 | |||
| 12 | Signed-off-by: Sona Sarmadi <sona.sarmadi@enea.com> | ||
| 13 | --- | ||
| 14 | CHANGES | 4 +++ | ||
| 15 | lib/dns/message.c | 76 +++++++++++++++++++++++++++++++++++++++++++++++++++--- | ||
| 16 | lib/dns/resolver.c | 21 ++++++--------- | ||
| 17 | 3 files changed, 85 insertions(+), 16 deletions(-) | ||
| 18 | |||
| 19 | diff --git a/CHANGES b/CHANGES | ||
| 20 | index 97d2e60..5760ca5 100644 | ||
| 21 | --- a/CHANGES | ||
| 22 | +++ b/CHANGES | ||
| 23 | @@ -1,3 +1,7 @@ | ||
| 24 | +4517. [security] Named could mishandle authority sections that were | ||
| 25 | + missing RRSIGs triggering an assertion failure. | ||
| 26 | + (CVE-2016-9444) [RT # 43632] | ||
| 27 | + | ||
| 28 | 4504. [security] Allow the maximum number of records in a zone to | ||
| 29 | be specified. This provides a control for issues | ||
| 30 | raised in CVE-2016-6170. [RT #42143] | ||
| 31 | diff --git a/lib/dns/message.c b/lib/dns/message.c | ||
| 32 | index 0dd4c77..2e37dac 100644 | ||
| 33 | --- a/lib/dns/message.c | ||
| 34 | +++ b/lib/dns/message.c | ||
| 35 | @@ -1171,6 +1171,63 @@ update(dns_section_t section, dns_rdataclass_t rdclass) { | ||
| 36 | return (ISC_FALSE); | ||
| 37 | } | ||
| 38 | |||
| 39 | +/* | ||
| 40 | + * Check to confirm that all DNSSEC records (DS, NSEC, NSEC3) have | ||
| 41 | + * covering RRSIGs. | ||
| 42 | + */ | ||
| 43 | +static isc_boolean_t | ||
| 44 | +auth_signed(dns_namelist_t *section) { | ||
| 45 | + dns_name_t *name; | ||
| 46 | + | ||
| 47 | + for (name = ISC_LIST_HEAD(*section); | ||
| 48 | + name != NULL; | ||
| 49 | + name = ISC_LIST_NEXT(name, link)) | ||
| 50 | + { | ||
| 51 | + int auth_dnssec = 0, auth_rrsig = 0; | ||
| 52 | + dns_rdataset_t *rds; | ||
| 53 | + | ||
| 54 | + for (rds = ISC_LIST_HEAD(name->list); | ||
| 55 | + rds != NULL; | ||
| 56 | + rds = ISC_LIST_NEXT(rds, link)) | ||
| 57 | + { | ||
| 58 | + switch (rds->type) { | ||
| 59 | + case dns_rdatatype_ds: | ||
| 60 | + auth_dnssec |= 0x1; | ||
| 61 | + break; | ||
| 62 | + case dns_rdatatype_nsec: | ||
| 63 | + auth_dnssec |= 0x2; | ||
| 64 | + break; | ||
| 65 | + case dns_rdatatype_nsec3: | ||
| 66 | + auth_dnssec |= 0x4; | ||
| 67 | + break; | ||
| 68 | + case dns_rdatatype_rrsig: | ||
| 69 | + break; | ||
| 70 | + default: | ||
| 71 | + continue; | ||
| 72 | + } | ||
| 73 | + | ||
| 74 | + switch (rds->covers) { | ||
| 75 | + case dns_rdatatype_ds: | ||
| 76 | + auth_rrsig |= 0x1; | ||
| 77 | + break; | ||
| 78 | + case dns_rdatatype_nsec: | ||
| 79 | + auth_rrsig |= 0x2; | ||
| 80 | + break; | ||
| 81 | + case dns_rdatatype_nsec3: | ||
| 82 | + auth_rrsig |= 0x4; | ||
| 83 | + break; | ||
| 84 | + default: | ||
| 85 | + break; | ||
| 86 | + } | ||
| 87 | + } | ||
| 88 | + | ||
| 89 | + if (auth_dnssec != auth_rrsig) | ||
| 90 | + return (ISC_FALSE); | ||
| 91 | + } | ||
| 92 | + | ||
| 93 | + return (ISC_TRUE); | ||
| 94 | +} | ||
| 95 | + | ||
| 96 | static isc_result_t | ||
| 97 | getsection(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx, | ||
| 98 | dns_section_t sectionid, unsigned int options) | ||
| 99 | @@ -1196,12 +1253,12 @@ getsection(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx, | ||
| 100 | best_effort = ISC_TF(options & DNS_MESSAGEPARSE_BESTEFFORT); | ||
| 101 | seen_problem = ISC_FALSE; | ||
| 102 | |||
| 103 | + section = &msg->sections[sectionid]; | ||
| 104 | + | ||
| 105 | for (count = 0; count < msg->counts[sectionid]; count++) { | ||
| 106 | int recstart = source->current; | ||
| 107 | isc_boolean_t skip_name_search, skip_type_search; | ||
| 108 | |||
| 109 | - section = &msg->sections[sectionid]; | ||
| 110 | - | ||
| 111 | skip_name_search = ISC_FALSE; | ||
| 112 | skip_type_search = ISC_FALSE; | ||
| 113 | free_rdataset = ISC_FALSE; | ||
| 114 | @@ -1364,7 +1421,7 @@ getsection(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx, | ||
| 115 | goto cleanup; | ||
| 116 | rdata->rdclass = rdclass; | ||
| 117 | issigzero = ISC_FALSE; | ||
| 118 | - if (rdtype == dns_rdatatype_rrsig && | ||
| 119 | + if (rdtype == dns_rdatatype_rrsig && | ||
| 120 | rdata->flags == 0) { | ||
| 121 | covers = dns_rdata_covers(rdata); | ||
| 122 | if (covers == 0) | ||
| 123 | @@ -1575,6 +1632,19 @@ getsection(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx, | ||
| 124 | INSIST(free_rdataset == ISC_FALSE); | ||
| 125 | } | ||
| 126 | |||
| 127 | + /* | ||
| 128 | + * If any of DS, NSEC or NSEC3 appeared in the | ||
| 129 | + * authority section of a query response without | ||
| 130 | + * a covering RRSIG, FORMERR | ||
| 131 | + */ | ||
| 132 | + if (sectionid == DNS_SECTION_AUTHORITY && | ||
| 133 | + msg->opcode == dns_opcode_query && | ||
| 134 | + ((msg->flags & DNS_MESSAGEFLAG_QR) != 0) && | ||
| 135 | + ((msg->flags & DNS_MESSAGEFLAG_TC) == 0) && | ||
| 136 | + !preserve_order && | ||
| 137 | + !auth_signed(section)) | ||
| 138 | + DO_ERROR(DNS_R_FORMERR); | ||
| 139 | + | ||
| 140 | if (seen_problem) | ||
| 141 | return (DNS_R_RECOVERABLE); | ||
| 142 | return (ISC_R_SUCCESS); | ||
| 143 | diff --git a/lib/dns/resolver.c b/lib/dns/resolver.c | ||
| 144 | index b8fa6b3..017b4ba 100644 | ||
| 145 | --- a/lib/dns/resolver.c | ||
| 146 | +++ b/lib/dns/resolver.c | ||
| 147 | @@ -5435,16 +5435,13 @@ cache_name(fetchctx_t *fctx, dns_name_t *name, dns_adbaddrinfo_t *addrinfo, | ||
| 148 | rdataset->type, | ||
| 149 | &noqname); | ||
| 150 | if (tresult == ISC_R_SUCCESS && | ||
| 151 | - noqname != NULL) { | ||
| 152 | - tresult = | ||
| 153 | - dns_rdataset_addnoqname( | ||
| 154 | + noqname != NULL) | ||
| 155 | + (void) dns_rdataset_addnoqname( | ||
| 156 | rdataset, noqname); | ||
| 157 | - RUNTIME_CHECK(tresult == | ||
| 158 | - ISC_R_SUCCESS); | ||
| 159 | - } | ||
| 160 | } | ||
| 161 | - if ((fctx->options & DNS_FETCHOPT_PREFETCH) != 0) | ||
| 162 | - options = DNS_DBADD_PREFETCH; | ||
| 163 | + if ((fctx->options & | ||
| 164 | + DNS_FETCHOPT_PREFETCH) != 0) | ||
| 165 | + options = DNS_DBADD_PREFETCH; | ||
| 166 | addedrdataset = ardataset; | ||
| 167 | result = dns_db_addrdataset(fctx->cache, node, | ||
| 168 | NULL, now, rdataset, | ||
| 169 | @@ -5584,11 +5581,9 @@ cache_name(fetchctx_t *fctx, dns_name_t *name, dns_adbaddrinfo_t *addrinfo, | ||
| 170 | tresult = findnoqname(fctx, name, | ||
| 171 | rdataset->type, &noqname); | ||
| 172 | if (tresult == ISC_R_SUCCESS && | ||
| 173 | - noqname != NULL) { | ||
| 174 | - tresult = dns_rdataset_addnoqname( | ||
| 175 | - rdataset, noqname); | ||
| 176 | - RUNTIME_CHECK(tresult == ISC_R_SUCCESS); | ||
| 177 | - } | ||
| 178 | + noqname != NULL) | ||
| 179 | + (void) dns_rdataset_addnoqname( | ||
| 180 | + rdataset, noqname); | ||
| 181 | } | ||
| 182 | |||
| 183 | /* | ||
| 184 | -- | ||
| 185 | 1.9.1 | ||
| 186 | |||
diff --git a/recipes-connectivity/bind/bind/CVE-2017-3135.patch b/recipes-connectivity/bind/bind/CVE-2017-3135.patch deleted file mode 100644 index 8cb2340..0000000 --- a/recipes-connectivity/bind/bind/CVE-2017-3135.patch +++ /dev/null | |||
| @@ -1,30 +0,0 @@ | |||
| 1 | From 6106ed6841b253c78c6120be24c8722d6310a9b9 Mon Sep 17 00:00:00 2001 | ||
| 2 | From: Mark Andrews <marka@isc.org> | ||
| 3 | Date: Tue, 31 Jan 2017 11:20:03 +1100 | ||
| 4 | Subject: [PATCH] add a REQUIRE to catch the NULL pointer dereference that | ||
| 5 | triggered CVE-2017-3135 | ||
| 6 | |||
| 7 | CVE: CVE-2017-3135 | ||
| 8 | Upstream-Status: Backport [backport from remotes/origin/v9_10] | ||
| 9 | |||
| 10 | (cherry picked from commit 1d8995d226d8bca96b8ba286316018be4b7835f2) | ||
| 11 | Signed-off-by: Sona Sarmadi <sona.sarmadi@enea.com> | ||
| 12 | --- | ||
| 13 | lib/dns/rdataset.c | 1 + | ||
| 14 | 1 file changed, 1 insertion(+) | ||
| 15 | |||
| 16 | diff --git a/lib/dns/rdataset.c b/lib/dns/rdataset.c | ||
| 17 | index 1870394..79bcecb 100644 | ||
| 18 | --- a/lib/dns/rdataset.c | ||
| 19 | +++ b/lib/dns/rdataset.c | ||
| 20 | @@ -338,6 +338,7 @@ towiresorted(dns_rdataset_t *rdataset, const dns_name_t *owner_name, | ||
| 21 | */ | ||
| 22 | |||
| 23 | REQUIRE(DNS_RDATASET_VALID(rdataset)); | ||
| 24 | + REQUIRE(rdataset->methods != NULL); | ||
| 25 | REQUIRE(countp != NULL); | ||
| 26 | REQUIRE((order == NULL) == (order_arg == NULL)); | ||
| 27 | REQUIRE(cctx != NULL && cctx->mctx != NULL); | ||
| 28 | -- | ||
| 29 | 1.9.1 | ||
| 30 | |||
diff --git a/recipes-connectivity/bind/bind/CVE-2017-3136.patch b/recipes-connectivity/bind/bind/CVE-2017-3136.patch deleted file mode 100644 index c47a6f7..0000000 --- a/recipes-connectivity/bind/bind/CVE-2017-3136.patch +++ /dev/null | |||
| @@ -1,47 +0,0 @@ | |||
| 1 | From cdb44bbabefa96fceb9bca540f5112493756d593 Mon Sep 17 00:00:00 2001 | ||
| 2 | From: Sona Sarmadi <sona.sarmadi@enea.com> | ||
| 3 | Date: Wed, 27 Sep 2017 09:45:10 +0200 | ||
| 4 | Subject: [PATCH] Dns64 with break-dnssec yes; can result in a assertion | ||
| 5 | failure. | ||
| 6 | |||
| 7 | From 764240ca07ab1b796226d5402ccd9fbfa77ec32a Mon Sep 17 00:00:00 2001 | ||
| 8 | From: Mark Andrews <marka@isc.org> | ||
| 9 | Date: Wed, 15 Feb 2017 12:18:51 +1100 | ||
| 10 | |||
| 11 | (cherry picked from commit 3bce12e4b6d37f570ffc7747b499f8b90e8521ac) | ||
| 12 | |||
| 13 | CVE: CVE-2017-3136 | ||
| 14 | Upstream-Status: Backport [backport from remotes/origin/v9_10] | ||
| 15 | |||
| 16 | Signed-off-by: Sona Sarmadi <sona.sarmadi@enea.com> | ||
| 17 | --- | ||
| 18 | CHANGES | 3 +++ | ||
| 19 | bin/named/query.c | 1 + | ||
| 20 | 2 files changed, 4 insertions(+) | ||
| 21 | |||
| 22 | diff --git a/CHANGES b/CHANGES | ||
| 23 | index ec11967..ba27df0 100644 | ||
| 24 | --- a/CHANGES | ||
| 25 | +++ b/CHANGES | ||
| 26 | @@ -1,3 +1,6 @@ | ||
| 27 | +4575. [security] Dns64 with break-dnssec yes; can result in a | ||
| 28 | + assertion failure. (CVE-2017-3136) [RT #44653] | ||
| 29 | + | ||
| 30 | 4517. [security] Named could mishandle authority sections that were | ||
| 31 | missing RRSIGs triggering an assertion failure. | ||
| 32 | (CVE-2016-9444) [RT # 43632] | ||
| 33 | diff --git a/bin/named/query.c b/bin/named/query.c | ||
| 34 | index 1398776..48822ff 100644 | ||
| 35 | --- a/bin/named/query.c | ||
| 36 | +++ b/bin/named/query.c | ||
| 37 | @@ -8149,6 +8149,7 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype) | ||
| 38 | result = query_dns64(client, &fname, rdataset, | ||
| 39 | sigrdataset, dbuf, | ||
| 40 | DNS_SECTION_ANSWER); | ||
| 41 | + noqname = NULL; | ||
| 42 | dns_rdataset_disassociate(rdataset); | ||
| 43 | dns_message_puttemprdataset(client->message, &rdataset); | ||
| 44 | if (result == ISC_R_NOMORE) { | ||
| 45 | -- | ||
| 46 | 1.9.1 | ||
| 47 | |||
diff --git a/recipes-connectivity/bind/bind_%.bbappend b/recipes-connectivity/bind/bind_%.bbappend deleted file mode 100644 index 0461313..0000000 --- a/recipes-connectivity/bind/bind_%.bbappend +++ /dev/null | |||
| @@ -1,7 +0,0 @@ | |||
| 1 | FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:" | ||
| 2 | |||
| 3 | SRC_URI += "file://CVE-2016-9444.patch \ | ||
| 4 | file://0001-fix-back-port-issue.patch \ | ||
| 5 | file://CVE-2017-3135.patch \ | ||
| 6 | file://CVE-2017-3136.patch \ | ||
| 7 | " | ||
diff --git a/recipes-core/glibc/glibc/CVE-2017-1000366.patch b/recipes-core/glibc/glibc/CVE-2017-1000366.patch deleted file mode 100644 index 8ba9c5c..0000000 --- a/recipes-core/glibc/glibc/CVE-2017-1000366.patch +++ /dev/null | |||
| @@ -1,53 +0,0 @@ | |||
| 1 | From f6110a8fee2ca36f8e2d2abecf3cba9fa7b8ea7d Mon Sep 17 00:00:00 2001 | ||
| 2 | From: Florian Weimer <fweimer@redhat.com> | ||
| 3 | Date: Mon, 19 Jun 2017 17:09:55 +0200 | ||
| 4 | Subject: [PATCH] CVE-2017-1000366: Ignore LD_LIBRARY_PATH for AT_SECURE=1 | ||
| 5 | programs [BZ #21624] | ||
| 6 | |||
| 7 | LD_LIBRARY_PATH can only be used to reorder system search paths, which | ||
| 8 | is not useful functionality. | ||
| 9 | |||
| 10 | This makes an exploitable unbounded alloca in _dl_init_paths unreachable | ||
| 11 | for AT_SECURE=1 programs. | ||
| 12 | |||
| 13 | CVE: CVE-2017-1000366 | ||
| 14 | Upstream-Status: Backport [https://sourceware.org/git/?p=glibc.git;a=commit;h=3c7cd21290cabdadd72984fb69bc51e64ff1002d] | ||
| 15 | |||
| 16 | Signed-off-by: Sona Sarmadi <sona.sarmadi@enea.com> | ||
| 17 | --- | ||
| 18 | ChangeLog | 7 +++++++ | ||
| 19 | elf/rtld.c | 3 ++- | ||
| 20 | 2 files changed, 9 insertions(+), 1 deletion(-) | ||
| 21 | |||
| 22 | diff --git a/ChangeLog b/ChangeLog | ||
| 23 | index f140ee6..7bfdf45 100644 | ||
| 24 | --- a/ChangeLog | ||
| 25 | +++ b/ChangeLog | ||
| 26 | @@ -1,3 +1,10 @@ | ||
| 27 | +2017-06-19 Florian Weimer <fweimer@redhat.com> | ||
| 28 | + | ||
| 29 | + [BZ #21624] | ||
| 30 | + CVE-2017-1000366 | ||
| 31 | + * elf/rtld.c (process_envvars): Ignore LD_LIBRARY_PATH for | ||
| 32 | + __libc_enable_secure. | ||
| 33 | + | ||
| 34 | 2017-02-05 Siddhesh Poyarekar <siddhesh@sourceware.org> | ||
| 35 | |||
| 36 | * version.h (RELEASE): Set to "stable" | ||
| 37 | diff --git a/elf/rtld.c b/elf/rtld.c | ||
| 38 | index a036ece..2fc33a6 100644 | ||
| 39 | --- a/elf/rtld.c | ||
| 40 | +++ b/elf/rtld.c | ||
| 41 | @@ -2418,7 +2418,8 @@ process_envvars (enum mode *modep) | ||
| 42 | |||
| 43 | case 12: | ||
| 44 | /* The library search path. */ | ||
| 45 | - if (memcmp (envline, "LIBRARY_PATH", 12) == 0) | ||
| 46 | + if (!__libc_enable_secure | ||
| 47 | + && memcmp (envline, "LIBRARY_PATH", 12) == 0) | ||
| 48 | { | ||
| 49 | library_path = &envline[13]; | ||
| 50 | break; | ||
| 51 | -- | ||
| 52 | 1.9.1 | ||
| 53 | |||
diff --git a/recipes-core/glibc/glibc/CVE-2017-12132.patch b/recipes-core/glibc/glibc/CVE-2017-12132.patch deleted file mode 100644 index dc184db..0000000 --- a/recipes-core/glibc/glibc/CVE-2017-12132.patch +++ /dev/null | |||
| @@ -1,866 +0,0 @@ | |||
| 1 | From 44cf81c6c008316876cfcc8208ae982621949e0e Mon Sep 17 00:00:00 2001 | ||
| 2 | From: Sona Sarmadi <sona.sarmadi@enea.com> | ||
| 3 | Date: Mon, 11 Sep 2017 10:55:45 +0200 | ||
| 4 | Subject: [PATCH] glibc: CVE-2017-12132 | ||
| 5 | |||
| 6 | From e14a27723cc3a154d67f3f26e719d08c0ba9ad25 Mon Sep 17 00:00:00 2001 | ||
| 7 | From: Florian Weimer <fweimer@redhat.com> | ||
| 8 | Date: Thu, 13 Apr 2017 13:09:38 +0200 | ||
| 9 | Subject: [PATCH] resolv: Reduce EDNS payload size to 1200 bytes [BZ #21361] | ||
| 10 | |||
| 11 | This hardens the stub resolver against fragmentation-based attacks. | ||
| 12 | |||
| 13 | CVE: CVE-2017-12132 | ||
| 14 | Upstream-Status: Backport [https://sourceware.org/git/gitweb.cgi?p=glibc.git;a=patch;h=e14a27723cc3a154d67f3f26e719d08c0ba9ad25] | ||
| 15 | |||
| 16 | Signed-off-by: Sona Sarmadi <sona.sarmadi@enea.com> | ||
| 17 | --- | ||
| 18 | ChangeLog | 21 ++ | ||
| 19 | include/resolv.h | 3 - | ||
| 20 | resolv/Makefile | 2 + | ||
| 21 | resolv/res_mkquery.c | 28 ++- | ||
| 22 | resolv/res_query.c | 23 ++- | ||
| 23 | resolv/resolv-internal.h | 18 ++ | ||
| 24 | resolv/tst-resolv-edns.c | 501 +++++++++++++++++++++++++++++++++++++++++++++++ | ||
| 25 | support/resolv_test.c | 56 +++++- | ||
| 26 | support/resolv_test.h | 11 ++ | ||
| 27 | 9 files changed, 650 insertions(+), 13 deletions(-) | ||
| 28 | create mode 100644 resolv/tst-resolv-edns.c | ||
| 29 | |||
| 30 | diff --git a/ChangeLog b/ChangeLog | ||
| 31 | index 7bfdf45..a0c2f51 100644 | ||
| 32 | --- a/ChangeLog | ||
| 33 | +++ b/ChangeLog | ||
| 34 | @@ -1,3 +1,24 @@ | ||
| 35 | +2017-04-13 Florian Weimer <fweimer@redhat.com> | ||
| 36 | + | ||
| 37 | + [BZ #21361] | ||
| 38 | + Limit EDNS buffer size to 1200 bytes. | ||
| 39 | + * include/resolv.h (__res_nopt): Remove declaration. | ||
| 40 | + * resolv/Makefile (tests): tst-resolv-edns. | ||
| 41 | + (tst-resolv-edns): Link with -lresolv, -lpthread. | ||
| 42 | + * resolv/res_mkquery.c (__res_ntop): Limit EDNS buffer size to the | ||
| 43 | + interval [512, 1200]. | ||
| 44 | + * resolv/res_query.c (__libc_res_nquery): Use 1200 buffer size if | ||
| 45 | + we can resize the buffer. | ||
| 46 | + * resolv/resolv-internal.h (RESOLV_EDNS_BUFFER_SIZE): Define. | ||
| 47 | + (__res_nopt): Declare. | ||
| 48 | + * resolv/tst-resolv-edns.c: New file. | ||
| 49 | + * resolv/resolv_test.h (struct resolv_edns_info): Define. | ||
| 50 | + (struct resolv_response_context): Add edns member. | ||
| 51 | + * resolv/resolv_test.c (struct query_info): Add edns member. | ||
| 52 | + (parse_query): Extract EDNS information from the query. | ||
| 53 | + (server_thread_udp_process_one): Propagate EDNS data. | ||
| 54 | + (server_thread_tcp_client): Likewise. | ||
| 55 | + | ||
| 56 | 2017-06-19 Florian Weimer <fweimer@redhat.com> | ||
| 57 | |||
| 58 | [BZ #21624] | ||
| 59 | diff --git a/include/resolv.h b/include/resolv.h | ||
| 60 | index 95dcd3c..e8f477c 100644 | ||
| 61 | --- a/include/resolv.h | ||
| 62 | +++ b/include/resolv.h | ||
| 63 | @@ -37,8 +37,6 @@ extern void res_pquery (const res_state __statp, const unsigned char *__msg, | ||
| 64 | extern int res_ourserver_p (const res_state __statp, | ||
| 65 | const struct sockaddr_in6 *__inp); | ||
| 66 | extern void __res_iclose (res_state statp, bool free_addr); | ||
| 67 | -extern int __res_nopt(res_state statp, int n0, unsigned char *buf, int buflen, | ||
| 68 | - int anslen); | ||
| 69 | libc_hidden_proto (__res_ninit) | ||
| 70 | libc_hidden_proto (__res_maybe_init) | ||
| 71 | libc_hidden_proto (__res_nclose) | ||
| 72 | @@ -91,7 +89,6 @@ libresolv_hidden_proto (__res_nameinquery) | ||
| 73 | libresolv_hidden_proto (__res_queriesmatch) | ||
| 74 | libresolv_hidden_proto (__res_nsend) | ||
| 75 | libresolv_hidden_proto (__b64_ntop) | ||
| 76 | -libresolv_hidden_proto (__res_nopt) | ||
| 77 | libresolv_hidden_proto (__dn_count_labels) | ||
| 78 | libresolv_hidden_proto (__p_secstodate) | ||
| 79 | |||
| 80 | diff --git a/resolv/Makefile b/resolv/Makefile | ||
| 81 | index fdc37ed..01086d5 100644 | ||
| 82 | --- a/resolv/Makefile | ||
| 83 | +++ b/resolv/Makefile | ||
| 84 | @@ -46,6 +46,7 @@ tests += \ | ||
| 85 | tst-res_hconf_reorder \ | ||
| 86 | tst-res_use_inet6 \ | ||
| 87 | tst-resolv-basic \ | ||
| 88 | + tst-resolv-edns \ | ||
| 89 | tst-resolv-network \ | ||
| 90 | tst-resolv-search \ | ||
| 91 | |||
| 92 | @@ -124,6 +125,7 @@ $(objpfx)tst-bug18665-tcp: $(objpfx)libresolv.so $(shared-thread-library) | ||
| 93 | $(objpfx)tst-bug18665: $(objpfx)libresolv.so $(shared-thread-library) | ||
| 94 | $(objpfx)tst-res_use_inet6: $(objpfx)libresolv.so $(shared-thread-library) | ||
| 95 | $(objpfx)tst-resolv-basic: $(objpfx)libresolv.so $(shared-thread-library) | ||
| 96 | +$(objpfx)tst-resolv-edns: $(objpfx)libresolv.so $(shared-thread-library) | ||
| 97 | $(objpfx)tst-resolv-network: $(objpfx)libresolv.so $(shared-thread-library) | ||
| 98 | $(objpfx)tst-resolv-qtypes: $(objpfx)libresolv.so $(shared-thread-library) | ||
| 99 | $(objpfx)tst-resolv-search: $(objpfx)libresolv.so $(shared-thread-library) | ||
| 100 | diff --git a/resolv/res_mkquery.c b/resolv/res_mkquery.c | ||
| 101 | index d80b531..5a0bb10 100644 | ||
| 102 | --- a/resolv/res_mkquery.c | ||
| 103 | +++ b/resolv/res_mkquery.c | ||
| 104 | @@ -69,7 +69,7 @@ | ||
| 105 | #include <netinet/in.h> | ||
| 106 | #include <arpa/nameser.h> | ||
| 107 | #include <netdb.h> | ||
| 108 | -#include <resolv.h> | ||
| 109 | +#include <resolv/resolv-internal.h> | ||
| 110 | #include <stdio.h> | ||
| 111 | #include <string.h> | ||
| 112 | #include <sys/time.h> | ||
| 113 | @@ -243,7 +243,30 @@ __res_nopt(res_state statp, | ||
| 114 | *cp++ = 0; /* "." */ | ||
| 115 | |||
| 116 | NS_PUT16(T_OPT, cp); /* TYPE */ | ||
| 117 | - NS_PUT16(MIN(anslen, 0xffff), cp); /* CLASS = UDP payload size */ | ||
| 118 | + | ||
| 119 | + /* Lowering the advertised buffer size based on the actual | ||
| 120 | + answer buffer size is desirable because the server will | ||
| 121 | + minimize the reply to fit into the UDP packet (and A | ||
| 122 | + non-minimal response might not fit the buffer). | ||
| 123 | + | ||
| 124 | + The RESOLV_EDNS_BUFFER_SIZE limit could still result in TCP | ||
| 125 | + fallback and a non-minimal response which has to be | ||
| 126 | + hard-truncated in the stub resolver, but this is price to | ||
| 127 | + pay for avoiding fragmentation. (This issue does not | ||
| 128 | + affect the nss_dns functions because they use the stub | ||
| 129 | + resolver in such a way that it allocates a properly sized | ||
| 130 | + response buffer.) */ | ||
| 131 | + { | ||
| 132 | + uint16_t buffer_size; | ||
| 133 | + if (anslen < 512) | ||
| 134 | + buffer_size = 512; | ||
| 135 | + else if (anslen > RESOLV_EDNS_BUFFER_SIZE) | ||
| 136 | + buffer_size = RESOLV_EDNS_BUFFER_SIZE; | ||
| 137 | + else | ||
| 138 | + buffer_size = anslen; | ||
| 139 | + NS_PUT16 (buffer_size, cp); | ||
| 140 | + } | ||
| 141 | + | ||
| 142 | *cp++ = NOERROR; /* extended RCODE */ | ||
| 143 | *cp++ = 0; /* EDNS version */ | ||
| 144 | |||
| 145 | @@ -261,4 +284,3 @@ __res_nopt(res_state statp, | ||
| 146 | |||
| 147 | return cp - buf; | ||
| 148 | } | ||
| 149 | -libresolv_hidden_def (__res_nopt) | ||
| 150 | diff --git a/resolv/res_query.c b/resolv/res_query.c | ||
| 151 | index 07dc6f6..57156d0 100644 | ||
| 152 | --- a/resolv/res_query.c | ||
| 153 | +++ b/resolv/res_query.c | ||
| 154 | @@ -77,6 +77,7 @@ | ||
| 155 | #include <stdio.h> | ||
| 156 | #include <stdlib.h> | ||
| 157 | #include <string.h> | ||
| 158 | +#include <resolv/resolv-internal.h> | ||
| 159 | |||
| 160 | /* Options. Leave them on. */ | ||
| 161 | /* #undef DEBUG */ | ||
| 162 | @@ -146,7 +147,10 @@ __libc_res_nquery(res_state statp, | ||
| 163 | if ((oflags & RES_F_EDNS0ERR) == 0 | ||
| 164 | && (statp->options & (RES_USE_EDNS0|RES_USE_DNSSEC)) != 0) | ||
| 165 | { | ||
| 166 | - n = __res_nopt(statp, n, query1, bufsize, anslen / 2); | ||
| 167 | + /* Use RESOLV_EDNS_BUFFER_SIZE because the receive | ||
| 168 | + buffer can be reallocated. */ | ||
| 169 | + n = __res_nopt (statp, n, query1, bufsize, | ||
| 170 | + RESOLV_EDNS_BUFFER_SIZE); | ||
| 171 | if (n < 0) | ||
| 172 | goto unspec_nomem; | ||
| 173 | } | ||
| 174 | @@ -167,8 +171,10 @@ __libc_res_nquery(res_state statp, | ||
| 175 | if (n > 0 | ||
| 176 | && (oflags & RES_F_EDNS0ERR) == 0 | ||
| 177 | && (statp->options & (RES_USE_EDNS0|RES_USE_DNSSEC)) != 0) | ||
| 178 | - n = __res_nopt(statp, n, query2, bufsize - nused - n, | ||
| 179 | - anslen / 2); | ||
| 180 | + /* Use RESOLV_EDNS_BUFFER_SIZE because the receive | ||
| 181 | + buffer can be reallocated. */ | ||
| 182 | + n = __res_nopt (statp, n, query2, bufsize, | ||
| 183 | + RESOLV_EDNS_BUFFER_SIZE); | ||
| 184 | nquery2 = n; | ||
| 185 | } | ||
| 186 | |||
| 187 | @@ -182,7 +188,16 @@ __libc_res_nquery(res_state statp, | ||
| 188 | if (n > 0 | ||
| 189 | && (oflags & RES_F_EDNS0ERR) == 0 | ||
| 190 | && (statp->options & (RES_USE_EDNS0|RES_USE_DNSSEC)) != 0) | ||
| 191 | - n = __res_nopt(statp, n, query1, bufsize, anslen); | ||
| 192 | + { | ||
| 193 | + /* Use RESOLV_EDNS_BUFFER_SIZE if the receive buffer | ||
| 194 | + can be reallocated. */ | ||
| 195 | + size_t advertise; | ||
| 196 | + if (answerp == NULL) | ||
| 197 | + advertise = anslen; | ||
| 198 | + else | ||
| 199 | + advertise = RESOLV_EDNS_BUFFER_SIZE; | ||
| 200 | + n = __res_nopt (statp, n, query1, bufsize, advertise); | ||
| 201 | + } | ||
| 202 | |||
| 203 | nquery1 = n; | ||
| 204 | } | ||
| 205 | diff --git a/resolv/resolv-internal.h b/resolv/resolv-internal.h | ||
| 206 | index 99fc17c..76fbe2f 100644 | ||
| 207 | --- a/resolv/resolv-internal.h | ||
| 208 | +++ b/resolv/resolv-internal.h | ||
| 209 | @@ -32,4 +32,22 @@ res_use_inet6 (void) | ||
| 210 | return _res.options & DEPRECATED_RES_USE_INET6; | ||
| 211 | } | ||
| 212 | |||
| 213 | +enum | ||
| 214 | + { | ||
| 215 | + /* The advertized EDNS buffer size. The value 1200 is derived | ||
| 216 | + from the IPv6 minimum MTU (1280 bytes) minus some arbitrary | ||
| 217 | + space for tunneling overhead. If the DNS server does not react | ||
| 218 | + to ICMP Fragmentation Needed But DF Set messages, this should | ||
| 219 | + avoid all UDP fragments on current networks. Avoiding UDP | ||
| 220 | + fragments is desirable because it prevents fragmentation-based | ||
| 221 | + spoofing attacks because the randomness in a DNS packet is | ||
| 222 | + concentrated in the first fragment (with the headers) and does | ||
| 223 | + not protect subsequent fragments. */ | ||
| 224 | + RESOLV_EDNS_BUFFER_SIZE = 1200, | ||
| 225 | + }; | ||
| 226 | + | ||
| 227 | +/* Add an OPT record to a DNS query. */ | ||
| 228 | +int __res_nopt (res_state, int n0, unsigned char *buf, int buflen, | ||
| 229 | + int anslen) attribute_hidden; | ||
| 230 | + | ||
| 231 | #endif /* _RESOLV_INTERNAL_H */ | ||
| 232 | diff --git a/resolv/tst-resolv-edns.c b/resolv/tst-resolv-edns.c | ||
| 233 | new file mode 100644 | ||
| 234 | index 0000000..f17dbc3 | ||
| 235 | --- /dev/null | ||
| 236 | +++ b/resolv/tst-resolv-edns.c | ||
| 237 | @@ -0,0 +1,501 @@ | ||
| 238 | +/* Test EDNS handling in the stub resolver. | ||
| 239 | + Copyright (C) 2016-2017 Free Software Foundation, Inc. | ||
| 240 | + This file is part of the GNU C Library. | ||
| 241 | + | ||
| 242 | + The GNU C Library is free software; you can redistribute it and/or | ||
| 243 | + modify it under the terms of the GNU Lesser General Public | ||
| 244 | + License as published by the Free Software Foundation; either | ||
| 245 | + version 2.1 of the License, or (at your option) any later version. | ||
| 246 | + | ||
| 247 | + The GNU C Library is distributed in the hope that it will be useful, | ||
| 248 | + but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 249 | + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| 250 | + Lesser General Public License for more details. | ||
| 251 | + | ||
| 252 | + You should have received a copy of the GNU Lesser General Public | ||
| 253 | + License along with the GNU C Library; if not, see | ||
| 254 | + <http://www.gnu.org/licenses/>. */ | ||
| 255 | + | ||
| 256 | +#include <errno.h> | ||
| 257 | +#include <netdb.h> | ||
| 258 | +#include <stdio.h> | ||
| 259 | +#include <stdlib.h> | ||
| 260 | +#include <string.h> | ||
| 261 | +#include <support/check.h> | ||
| 262 | +#include <support/resolv_test.h> | ||
| 263 | +#include <support/support.h> | ||
| 264 | +#include <support/test-driver.h> | ||
| 265 | +#include <support/xthread.h> | ||
| 266 | + | ||
| 267 | +/* Data produced by a test query. */ | ||
| 268 | +struct response_data | ||
| 269 | +{ | ||
| 270 | + char *qname; | ||
| 271 | + uint16_t qtype; | ||
| 272 | + struct resolv_edns_info edns; | ||
| 273 | +}; | ||
| 274 | + | ||
| 275 | +/* Global array used by put_response and get_response to record | ||
| 276 | + response data. The test DNS server returns the index of the array | ||
| 277 | + element which contains the actual response data. This enables the | ||
| 278 | + test case to return arbitrary amounts of data with the limited | ||
| 279 | + number of bits which fit into an IP addres. | ||
| 280 | + | ||
| 281 | + The volatile specifier is needed because the test case accesses | ||
| 282 | + these variables from a callback function called from a function | ||
| 283 | + which is marked as __THROW (i.e., a leaf function which actually is | ||
| 284 | + not). */ | ||
| 285 | +static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; | ||
| 286 | +static struct response_data ** volatile response_data_array; | ||
| 287 | +volatile static size_t response_data_count; | ||
| 288 | + | ||
| 289 | +/* Extract information from the query, store it in a struct | ||
| 290 | + response_data object, and return its index in the | ||
| 291 | + response_data_array. */ | ||
| 292 | +static unsigned int | ||
| 293 | +put_response (const struct resolv_response_context *ctx, | ||
| 294 | + const char *qname, uint16_t qtype) | ||
| 295 | +{ | ||
| 296 | + xpthread_mutex_lock (&mutex); | ||
| 297 | + ++response_data_count; | ||
| 298 | + /* We only can represent 2**24 indexes in 10.0.0.0/8. */ | ||
| 299 | + TEST_VERIFY (response_data_count < (1 << 24)); | ||
| 300 | + response_data_array = xrealloc | ||
| 301 | + (response_data_array, sizeof (*response_data_array) * response_data_count); | ||
| 302 | + unsigned int index = response_data_count - 1; | ||
| 303 | + struct response_data *data = xmalloc (sizeof (*data)); | ||
| 304 | + *data = (struct response_data) | ||
| 305 | + { | ||
| 306 | + .qname = xstrdup (qname), | ||
| 307 | + .qtype = qtype, | ||
| 308 | + .edns = ctx->edns, | ||
| 309 | + }; | ||
| 310 | + response_data_array[index] = data; | ||
| 311 | + xpthread_mutex_unlock (&mutex); | ||
| 312 | + return index; | ||
| 313 | +} | ||
| 314 | + | ||
| 315 | +/* Verify the index into the response_data array and return the data | ||
| 316 | + at it. */ | ||
| 317 | +static struct response_data * | ||
| 318 | +get_response (unsigned int index) | ||
| 319 | +{ | ||
| 320 | + xpthread_mutex_lock (&mutex); | ||
| 321 | + TEST_VERIFY_EXIT (index < response_data_count); | ||
| 322 | + struct response_data *result = response_data_array[index]; | ||
| 323 | + xpthread_mutex_unlock (&mutex); | ||
| 324 | + return result; | ||
| 325 | +} | ||
| 326 | + | ||
| 327 | +/* Deallocate all response data. */ | ||
| 328 | +static void | ||
| 329 | +free_response_data (void) | ||
| 330 | +{ | ||
| 331 | + xpthread_mutex_lock (&mutex); | ||
| 332 | + size_t count = response_data_count; | ||
| 333 | + struct response_data **array = response_data_array; | ||
| 334 | + for (unsigned int i = 0; i < count; ++i) | ||
| 335 | + { | ||
| 336 | + struct response_data *data = array[i]; | ||
| 337 | + free (data->qname); | ||
| 338 | + free (data); | ||
| 339 | + } | ||
| 340 | + free (array); | ||
| 341 | + response_data_array = NULL; | ||
| 342 | + response_data_count = 0; | ||
| 343 | + xpthread_mutex_unlock (&mutex); | ||
| 344 | +} | ||
| 345 | + | ||
| 346 | +#define EDNS_PROBE_EXAMPLE "edns-probe.example" | ||
| 347 | + | ||
| 348 | +static void | ||
| 349 | +response (const struct resolv_response_context *ctx, | ||
| 350 | + struct resolv_response_builder *b, | ||
| 351 | + const char *qname, uint16_t qclass, uint16_t qtype) | ||
| 352 | +{ | ||
| 353 | + TEST_VERIFY_EXIT (qname != NULL); | ||
| 354 | + | ||
| 355 | + /* The "tcp." prefix can be used to request TCP fallback. */ | ||
| 356 | + const char *qname_compare = qname; | ||
| 357 | + bool force_tcp; | ||
| 358 | + if (strncmp ("tcp.", qname_compare, strlen ("tcp.")) == 0) | ||
| 359 | + { | ||
| 360 | + force_tcp = true; | ||
| 361 | + qname_compare += strlen ("tcp."); | ||
| 362 | + } | ||
| 363 | + else | ||
| 364 | + force_tcp = false; | ||
| 365 | + | ||
| 366 | + enum {edns_probe} requested_qname; | ||
| 367 | + if (strcmp (qname_compare, EDNS_PROBE_EXAMPLE) == 0) | ||
| 368 | + requested_qname = edns_probe; | ||
| 369 | + else | ||
| 370 | + { | ||
| 371 | + support_record_failure (); | ||
| 372 | + printf ("error: unexpected QNAME: %s\n", qname); | ||
| 373 | + return; | ||
| 374 | + } | ||
| 375 | + TEST_VERIFY_EXIT (qclass == C_IN); | ||
| 376 | + struct resolv_response_flags flags = {.tc = force_tcp && !ctx->tcp}; | ||
| 377 | + resolv_response_init (b, flags); | ||
| 378 | + resolv_response_add_question (b, qname, qclass, qtype); | ||
| 379 | + if (flags.tc) | ||
| 380 | + return; | ||
| 381 | + | ||
| 382 | + if (test_verbose) | ||
| 383 | + printf ("info: edns=%d payload_size=%d\n", | ||
| 384 | + ctx->edns.active, ctx->edns.payload_size); | ||
| 385 | + | ||
| 386 | + /* Encode the response_data object in multiple address records. | ||
| 387 | + Each record carries two bytes of payload data, and an index. */ | ||
| 388 | + resolv_response_section (b, ns_s_an); | ||
| 389 | + switch (requested_qname) | ||
| 390 | + { | ||
| 391 | + case edns_probe: | ||
| 392 | + { | ||
| 393 | + unsigned int index = put_response (ctx, qname, qtype); | ||
| 394 | + switch (qtype) | ||
| 395 | + { | ||
| 396 | + case T_A: | ||
| 397 | + { | ||
| 398 | + uint32_t addr = htonl (0x0a000000 | index); | ||
| 399 | + resolv_response_open_record (b, qname, qclass, qtype, 0); | ||
| 400 | + resolv_response_add_data (b, &addr, sizeof (addr)); | ||
| 401 | + resolv_response_close_record (b); | ||
| 402 | + } | ||
| 403 | + break; | ||
| 404 | + case T_AAAA: | ||
| 405 | + { | ||
| 406 | + char addr[16] | ||
| 407 | + = {0x20, 0x01, 0xd, 0xb8, 0, 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 408 | + index >> 16, index >> 8, index}; | ||
| 409 | + resolv_response_open_record (b, qname, qclass, qtype, 0); | ||
| 410 | + resolv_response_add_data (b, &addr, sizeof (addr)); | ||
| 411 | + resolv_response_close_record (b); | ||
| 412 | + } | ||
| 413 | + } | ||
| 414 | + } | ||
| 415 | + break; | ||
| 416 | + } | ||
| 417 | +} | ||
| 418 | + | ||
| 419 | +/* Update *DATA with data from ADDRESS of SIZE. Set the corresponding | ||
| 420 | + flag in SHADOW for each byte written. */ | ||
| 421 | +static struct response_data * | ||
| 422 | +decode_address (const void *address, size_t size) | ||
| 423 | +{ | ||
| 424 | + switch (size) | ||
| 425 | + { | ||
| 426 | + case 4: | ||
| 427 | + TEST_VERIFY (memcmp (address, "\x0a", 1) == 0); | ||
| 428 | + break; | ||
| 429 | + case 16: | ||
| 430 | + TEST_VERIFY (memcmp (address, "\x20\x01\x0d\xb8", 4) == 0); | ||
| 431 | + break; | ||
| 432 | + default: | ||
| 433 | + FAIL_EXIT1 ("unexpected address size %zu", size); | ||
| 434 | + } | ||
| 435 | + const unsigned char *addr = address; | ||
| 436 | + unsigned int index = addr[size - 3] * 256 * 256 | ||
| 437 | + + addr[size - 2] * 256 | ||
| 438 | + + addr[size - 1]; | ||
| 439 | + return get_response (index); | ||
| 440 | +} | ||
| 441 | + | ||
| 442 | +static struct response_data * | ||
| 443 | +decode_hostent (struct hostent *e) | ||
| 444 | +{ | ||
| 445 | + TEST_VERIFY_EXIT (e != NULL); | ||
| 446 | + TEST_VERIFY_EXIT (e->h_addr_list[0] != NULL); | ||
| 447 | + TEST_VERIFY (e->h_addr_list[1] == NULL); | ||
| 448 | + return decode_address (e->h_addr_list[0], e->h_length); | ||
| 449 | +} | ||
| 450 | + | ||
| 451 | +static struct response_data * | ||
| 452 | +decode_addrinfo (struct addrinfo *ai, int family) | ||
| 453 | +{ | ||
| 454 | + struct response_data *data = NULL; | ||
| 455 | + while (ai != NULL) | ||
| 456 | + { | ||
| 457 | + if (ai->ai_family == family) | ||
| 458 | + { | ||
| 459 | + struct response_data *new_data; | ||
| 460 | + switch (family) | ||
| 461 | + { | ||
| 462 | + case AF_INET: | ||
| 463 | + { | ||
| 464 | + struct sockaddr_in *pin = (struct sockaddr_in *) ai->ai_addr; | ||
| 465 | + new_data = decode_address (&pin->sin_addr.s_addr, 4); | ||
| 466 | + } | ||
| 467 | + break; | ||
| 468 | + case AF_INET6: | ||
| 469 | + { | ||
| 470 | + struct sockaddr_in6 *pin = (struct sockaddr_in6 *) ai->ai_addr; | ||
| 471 | + new_data = decode_address (&pin->sin6_addr.s6_addr, 16); | ||
| 472 | + } | ||
| 473 | + break; | ||
| 474 | + default: | ||
| 475 | + FAIL_EXIT1 ("invalid address family %d", ai->ai_family); | ||
| 476 | + } | ||
| 477 | + if (data == NULL) | ||
| 478 | + data = new_data; | ||
| 479 | + else | ||
| 480 | + /* Check pointer equality because this should be the same | ||
| 481 | + response (same index). */ | ||
| 482 | + TEST_VERIFY (data == new_data); | ||
| 483 | + } | ||
| 484 | + ai = ai->ai_next; | ||
| 485 | + } | ||
| 486 | + TEST_VERIFY_EXIT (data != NULL); | ||
| 487 | + return data; | ||
| 488 | +} | ||
| 489 | + | ||
| 490 | +/* Updated by the main test loop in accordance with what is set in | ||
| 491 | + _res.options. */ | ||
| 492 | +static bool use_edns; | ||
| 493 | +static bool use_dnssec; | ||
| 494 | + | ||
| 495 | +/* Verify the decoded response data against the flags above. */ | ||
| 496 | +static void | ||
| 497 | +verify_response_data_payload (struct response_data *data, | ||
| 498 | + size_t expected_payload) | ||
| 499 | +{ | ||
| 500 | + bool edns = use_edns || use_dnssec; | ||
| 501 | + TEST_VERIFY (data->edns.active == edns); | ||
| 502 | + if (!edns) | ||
| 503 | + expected_payload = 0; | ||
| 504 | + if (data->edns.payload_size != expected_payload) | ||
| 505 | + { | ||
| 506 | + support_record_failure (); | ||
| 507 | + printf ("error: unexpected payload size %d (edns=%d)\n", | ||
| 508 | + (int) data->edns.payload_size, edns); | ||
| 509 | + } | ||
| 510 | + uint16_t expected_flags = 0; | ||
| 511 | + if (use_dnssec) | ||
| 512 | + expected_flags |= 0x8000; /* DO flag. */ | ||
| 513 | + if (data->edns.flags != expected_flags) | ||
| 514 | + { | ||
| 515 | + support_record_failure (); | ||
| 516 | + printf ("error: unexpected EDNS flags 0x%04x (edns=%d)\n", | ||
| 517 | + (int) data->edns.flags, edns); | ||
| 518 | + } | ||
| 519 | +} | ||
| 520 | + | ||
| 521 | +/* Same as verify_response_data_payload, but use the default | ||
| 522 | + payload. */ | ||
| 523 | +static void | ||
| 524 | +verify_response_data (struct response_data *data) | ||
| 525 | +{ | ||
| 526 | + verify_response_data_payload (data, 1200); | ||
| 527 | +} | ||
| 528 | + | ||
| 529 | +static void | ||
| 530 | +check_hostent (struct hostent *e) | ||
| 531 | +{ | ||
| 532 | + TEST_VERIFY_EXIT (e != NULL); | ||
| 533 | + verify_response_data (decode_hostent (e)); | ||
| 534 | +} | ||
| 535 | + | ||
| 536 | +static void | ||
| 537 | +do_ai (int family) | ||
| 538 | +{ | ||
| 539 | + struct addrinfo hints = { .ai_family = family }; | ||
| 540 | + struct addrinfo *ai; | ||
| 541 | + int ret = getaddrinfo (EDNS_PROBE_EXAMPLE, "80", &hints, &ai); | ||
| 542 | + TEST_VERIFY_EXIT (ret == 0); | ||
| 543 | + switch (family) | ||
| 544 | + { | ||
| 545 | + case AF_INET: | ||
| 546 | + case AF_INET6: | ||
| 547 | + verify_response_data (decode_addrinfo (ai, family)); | ||
| 548 | + break; | ||
| 549 | + case AF_UNSPEC: | ||
| 550 | + verify_response_data (decode_addrinfo (ai, AF_INET)); | ||
| 551 | + verify_response_data (decode_addrinfo (ai, AF_INET6)); | ||
| 552 | + break; | ||
| 553 | + default: | ||
| 554 | + FAIL_EXIT1 ("invalid address family %d", family); | ||
| 555 | + } | ||
| 556 | + freeaddrinfo (ai); | ||
| 557 | +} | ||
| 558 | + | ||
| 559 | +enum res_op | ||
| 560 | +{ | ||
| 561 | + res_op_search, | ||
| 562 | + res_op_query, | ||
| 563 | + res_op_querydomain, | ||
| 564 | + res_op_nsearch, | ||
| 565 | + res_op_nquery, | ||
| 566 | + res_op_nquerydomain, | ||
| 567 | + | ||
| 568 | + res_op_last = res_op_nquerydomain, | ||
| 569 | +}; | ||
| 570 | + | ||
| 571 | +static const char * | ||
| 572 | +res_op_string (enum res_op op) | ||
| 573 | +{ | ||
| 574 | + switch (op) | ||
| 575 | + { | ||
| 576 | + case res_op_search: | ||
| 577 | + return "res_search"; | ||
| 578 | + case res_op_query: | ||
| 579 | + return "res_query"; | ||
| 580 | + case res_op_querydomain: | ||
| 581 | + return "res_querydomain"; | ||
| 582 | + case res_op_nsearch: | ||
| 583 | + return "res_nsearch"; | ||
| 584 | + case res_op_nquery: | ||
| 585 | + return "res_nquery"; | ||
| 586 | + case res_op_nquerydomain: | ||
| 587 | + return "res_nquerydomain"; | ||
| 588 | + } | ||
| 589 | + FAIL_EXIT1 ("invalid res_op value %d", (int) op); | ||
| 590 | +} | ||
| 591 | + | ||
| 592 | +/* Call libresolv function OP to look up PROBE_NAME, with an answer | ||
| 593 | + buffer of SIZE bytes. Check that the advertised UDP buffer size is | ||
| 594 | + in fact EXPECTED_BUFFER_SIZE. */ | ||
| 595 | +static void | ||
| 596 | +do_res_search (const char *probe_name, enum res_op op, size_t size, | ||
| 597 | + size_t expected_buffer_size) | ||
| 598 | +{ | ||
| 599 | + if (test_verbose) | ||
| 600 | + printf ("info: testing %s with buffer size %zu\n", | ||
| 601 | + res_op_string (op), size); | ||
| 602 | + unsigned char *buffer = xmalloc (size); | ||
| 603 | + int ret = -1; | ||
| 604 | + switch (op) | ||
| 605 | + { | ||
| 606 | + case res_op_search: | ||
| 607 | + ret = res_search (probe_name, C_IN, T_A, buffer, size); | ||
| 608 | + break; | ||
| 609 | + case res_op_query: | ||
| 610 | + ret = res_query (probe_name, C_IN, T_A, buffer, size); | ||
| 611 | + break; | ||
| 612 | + case res_op_nsearch: | ||
| 613 | + ret = res_nsearch (&_res, probe_name, C_IN, T_A, buffer, size); | ||
| 614 | + break; | ||
| 615 | + case res_op_nquery: | ||
| 616 | + ret = res_nquery (&_res, probe_name, C_IN, T_A, buffer, size); | ||
| 617 | + break; | ||
| 618 | + case res_op_querydomain: | ||
| 619 | + case res_op_nquerydomain: | ||
| 620 | + { | ||
| 621 | + char *example_stripped = xstrdup (probe_name); | ||
| 622 | + char *dot_example = strstr (example_stripped, ".example"); | ||
| 623 | + if (dot_example != NULL && strcmp (dot_example, ".example") == 0) | ||
| 624 | + { | ||
| 625 | + /* Truncate the domain name. */ | ||
| 626 | + *dot_example = '\0'; | ||
| 627 | + if (op == res_op_querydomain) | ||
| 628 | + ret = res_querydomain | ||
| 629 | + (example_stripped, "example", C_IN, T_A, buffer, size); | ||
| 630 | + else | ||
| 631 | + ret = res_nquerydomain | ||
| 632 | + (&_res, example_stripped, "example", C_IN, T_A, buffer, size); | ||
| 633 | + } | ||
| 634 | + else | ||
| 635 | + FAIL_EXIT1 ("invalid probe name: %s", probe_name); | ||
| 636 | + free (example_stripped); | ||
| 637 | + } | ||
| 638 | + break; | ||
| 639 | + } | ||
| 640 | + TEST_VERIFY_EXIT (ret > 12); | ||
| 641 | + unsigned char *end = buffer + ret; | ||
| 642 | + | ||
| 643 | + HEADER *hd = (HEADER *) buffer; | ||
| 644 | + TEST_VERIFY (ntohs (hd->qdcount) == 1); | ||
| 645 | + TEST_VERIFY (ntohs (hd->ancount) == 1); | ||
| 646 | + /* Skip over the header. */ | ||
| 647 | + unsigned char *p = buffer + sizeof (*hd); | ||
| 648 | + /* Skip over the question. */ | ||
| 649 | + ret = dn_skipname (p, end); | ||
| 650 | + TEST_VERIFY_EXIT (ret > 0); | ||
| 651 | + p += ret; | ||
| 652 | + TEST_VERIFY_EXIT (end - p >= 4); | ||
| 653 | + p += 4; | ||
| 654 | + /* Skip over the RNAME and the RR header, but stop at the RDATA | ||
| 655 | + length. */ | ||
| 656 | + ret = dn_skipname (p, end); | ||
| 657 | + TEST_VERIFY_EXIT (ret > 0); | ||
| 658 | + p += ret; | ||
| 659 | + TEST_VERIFY_EXIT (end - p >= 2 + 2 + 4 + 2 + 4); | ||
| 660 | + p += 2 + 2 + 4; | ||
| 661 | + /* The IP address should be 4 bytes long. */ | ||
| 662 | + TEST_VERIFY_EXIT (p[0] == 0); | ||
| 663 | + TEST_VERIFY_EXIT (p[1] == 4); | ||
| 664 | + /* Extract the address information. */ | ||
| 665 | + p += 2; | ||
| 666 | + struct response_data *data = decode_address (p, 4); | ||
| 667 | + | ||
| 668 | + verify_response_data_payload (data, expected_buffer_size); | ||
| 669 | + | ||
| 670 | + free (buffer); | ||
| 671 | +} | ||
| 672 | + | ||
| 673 | +static void | ||
| 674 | +run_test (const char *probe_name) | ||
| 675 | +{ | ||
| 676 | + if (test_verbose) | ||
| 677 | + printf ("\ninfo: * use_edns=%d use_dnssec=%d\n", | ||
| 678 | + use_edns, use_dnssec); | ||
| 679 | + check_hostent (gethostbyname (probe_name)); | ||
| 680 | + check_hostent (gethostbyname2 (probe_name, AF_INET)); | ||
| 681 | + check_hostent (gethostbyname2 (probe_name, AF_INET6)); | ||
| 682 | + do_ai (AF_UNSPEC); | ||
| 683 | + do_ai (AF_INET); | ||
| 684 | + do_ai (AF_INET6); | ||
| 685 | + | ||
| 686 | + for (int op = 0; op <= res_op_last; ++op) | ||
| 687 | + { | ||
| 688 | + do_res_search (probe_name, op, 301, 512); | ||
| 689 | + do_res_search (probe_name, op, 511, 512); | ||
| 690 | + do_res_search (probe_name, op, 512, 512); | ||
| 691 | + do_res_search (probe_name, op, 513, 513); | ||
| 692 | + do_res_search (probe_name, op, 657, 657); | ||
| 693 | + do_res_search (probe_name, op, 1199, 1199); | ||
| 694 | + do_res_search (probe_name, op, 1200, 1200); | ||
| 695 | + do_res_search (probe_name, op, 1201, 1200); | ||
| 696 | + do_res_search (probe_name, op, 65535, 1200); | ||
| 697 | + } | ||
| 698 | +} | ||
| 699 | + | ||
| 700 | +static int | ||
| 701 | +do_test (void) | ||
| 702 | +{ | ||
| 703 | + for (int do_edns = 0; do_edns < 2; ++do_edns) | ||
| 704 | + for (int do_dnssec = 0; do_dnssec < 2; ++do_dnssec) | ||
| 705 | + for (int do_tcp = 0; do_tcp < 2; ++do_tcp) | ||
| 706 | + { | ||
| 707 | + struct resolv_test *aux = resolv_test_start | ||
| 708 | + ((struct resolv_redirect_config) | ||
| 709 | + { | ||
| 710 | + .response_callback = response, | ||
| 711 | + }); | ||
| 712 | + | ||
| 713 | + use_edns = do_edns; | ||
| 714 | + if (do_edns) | ||
| 715 | + _res.options |= RES_USE_EDNS0; | ||
| 716 | + use_dnssec = do_dnssec; | ||
| 717 | + if (do_dnssec) | ||
| 718 | + _res.options |= RES_USE_DNSSEC; | ||
| 719 | + | ||
| 720 | + char *probe_name = xstrdup (EDNS_PROBE_EXAMPLE); | ||
| 721 | + if (do_tcp) | ||
| 722 | + { | ||
| 723 | + char *n = xasprintf ("tcp.%s", probe_name); | ||
| 724 | + free (probe_name); | ||
| 725 | + probe_name = n; | ||
| 726 | + } | ||
| 727 | + | ||
| 728 | + run_test (probe_name); | ||
| 729 | + | ||
| 730 | + free (probe_name); | ||
| 731 | + resolv_test_end (aux); | ||
| 732 | + } | ||
| 733 | + | ||
| 734 | + free_response_data (); | ||
| 735 | + return 0; | ||
| 736 | +} | ||
| 737 | + | ||
| 738 | +#include <support/test-driver.c> | ||
| 739 | diff --git a/support/resolv_test.c b/support/resolv_test.c | ||
| 740 | index 2d0ea3c..6b3554f 100644 | ||
| 741 | --- a/support/resolv_test.c | ||
| 742 | +++ b/support/resolv_test.c | ||
| 743 | @@ -428,6 +428,7 @@ struct query_info | ||
| 744 | char qname[MAXDNAME]; | ||
| 745 | uint16_t qclass; | ||
| 746 | uint16_t qtype; | ||
| 747 | + struct resolv_edns_info edns; | ||
| 748 | }; | ||
| 749 | |||
| 750 | /* Update *INFO from the specified DNS packet. */ | ||
| 751 | @@ -435,10 +436,26 @@ static void | ||
| 752 | parse_query (struct query_info *info, | ||
| 753 | const unsigned char *buffer, size_t length) | ||
| 754 | { | ||
| 755 | - if (length < 12) | ||
| 756 | + HEADER hd; | ||
| 757 | + _Static_assert (sizeof (hd) == 12, "DNS header size"); | ||
| 758 | + if (length < sizeof (hd)) | ||
| 759 | FAIL_EXIT1 ("malformed DNS query: too short: %zu bytes", length); | ||
| 760 | - | ||
| 761 | - int ret = dn_expand (buffer, buffer + length, buffer + 12, | ||
| 762 | + memcpy (&hd, buffer, sizeof (hd)); | ||
| 763 | + | ||
| 764 | + if (ntohs (hd.qdcount) != 1) | ||
| 765 | + FAIL_EXIT1 ("malformed DNS query: wrong question count: %d", | ||
| 766 | + (int) ntohs (hd.qdcount)); | ||
| 767 | + if (ntohs (hd.ancount) != 0) | ||
| 768 | + FAIL_EXIT1 ("malformed DNS query: wrong answer count: %d", | ||
| 769 | + (int) ntohs (hd.ancount)); | ||
| 770 | + if (ntohs (hd.nscount) != 0) | ||
| 771 | + FAIL_EXIT1 ("malformed DNS query: wrong authority count: %d", | ||
| 772 | + (int) ntohs (hd.nscount)); | ||
| 773 | + if (ntohs (hd.arcount) > 1) | ||
| 774 | + FAIL_EXIT1 ("malformed DNS query: wrong additional count: %d", | ||
| 775 | + (int) ntohs (hd.arcount)); | ||
| 776 | + | ||
| 777 | + int ret = dn_expand (buffer, buffer + length, buffer + sizeof (hd), | ||
| 778 | info->qname, sizeof (info->qname)); | ||
| 779 | if (ret < 0) | ||
| 780 | FAIL_EXIT1 ("malformed DNS query: cannot uncompress QNAME"); | ||
| 781 | @@ -456,6 +473,37 @@ parse_query (struct query_info *info, | ||
| 782 | memcpy (&qtype_qclass, buffer + 12 + ret, sizeof (qtype_qclass)); | ||
| 783 | info->qclass = ntohs (qtype_qclass.qclass); | ||
| 784 | info->qtype = ntohs (qtype_qclass.qtype); | ||
| 785 | + | ||
| 786 | + memset (&info->edns, 0, sizeof (info->edns)); | ||
| 787 | + if (ntohs (hd.arcount) > 0) | ||
| 788 | + { | ||
| 789 | + /* Parse EDNS record. */ | ||
| 790 | + struct __attribute__ ((packed, aligned (1))) | ||
| 791 | + { | ||
| 792 | + uint8_t root; | ||
| 793 | + uint16_t rtype; | ||
| 794 | + uint16_t payload; | ||
| 795 | + uint8_t edns_extended_rcode; | ||
| 796 | + uint8_t edns_version; | ||
| 797 | + uint16_t flags; | ||
| 798 | + uint16_t rdatalen; | ||
| 799 | + } rr; | ||
| 800 | + _Static_assert (sizeof (rr) == 11, "EDNS record size"); | ||
| 801 | + | ||
| 802 | + if (remaining < 4 + sizeof (rr)) | ||
| 803 | + FAIL_EXIT1 ("mailformed DNS query: no room for EDNS record"); | ||
| 804 | + memcpy (&rr, buffer + 12 + ret + 4, sizeof (rr)); | ||
| 805 | + if (rr.root != 0) | ||
| 806 | + FAIL_EXIT1 ("malformed DNS query: invalid OPT RNAME: %d\n", rr.root); | ||
| 807 | + if (rr.rtype != htons (41)) | ||
| 808 | + FAIL_EXIT1 ("malformed DNS query: invalid OPT type: %d\n", | ||
| 809 | + ntohs (rr.rtype)); | ||
| 810 | + info->edns.active = true; | ||
| 811 | + info->edns.extended_rcode = rr.edns_extended_rcode; | ||
| 812 | + info->edns.version = rr.edns_version; | ||
| 813 | + info->edns.flags = ntohs (rr.flags); | ||
| 814 | + info->edns.payload_size = ntohs (rr.payload); | ||
| 815 | + } | ||
| 816 | } | ||
| 817 | |||
| 818 | |||
| 819 | @@ -585,6 +633,7 @@ server_thread_udp_process_one (struct resolv_test *obj, int server_index) | ||
| 820 | .query_length = length, | ||
| 821 | .server_index = server_index, | ||
| 822 | .tcp = false, | ||
| 823 | + .edns = qinfo.edns, | ||
| 824 | }; | ||
| 825 | struct resolv_response_builder *b = response_builder_allocate (query, length); | ||
| 826 | obj->config.response_callback | ||
| 827 | @@ -820,6 +869,7 @@ server_thread_tcp_client (void *arg) | ||
| 828 | .query_length = query_length, | ||
| 829 | .server_index = closure->server_index, | ||
| 830 | .tcp = true, | ||
| 831 | + .edns = qinfo.edns, | ||
| 832 | }; | ||
| 833 | struct resolv_response_builder *b = response_builder_allocate | ||
| 834 | (query_buffer, query_length); | ||
| 835 | diff --git a/support/resolv_test.h b/support/resolv_test.h | ||
| 836 | index 7a9f1f7..6498751 100644 | ||
| 837 | --- a/support/resolv_test.h | ||
| 838 | +++ b/support/resolv_test.h | ||
| 839 | @@ -25,6 +25,16 @@ | ||
| 840 | |||
| 841 | __BEGIN_DECLS | ||
| 842 | |||
| 843 | +/* Information about EDNS properties of a DNS query. */ | ||
| 844 | +struct resolv_edns_info | ||
| 845 | +{ | ||
| 846 | + bool active; | ||
| 847 | + uint8_t extended_rcode; | ||
| 848 | + uint8_t version; | ||
| 849 | + uint16_t flags; | ||
| 850 | + uint16_t payload_size; | ||
| 851 | +}; | ||
| 852 | + | ||
| 853 | /* This struct provides context information when the response callback | ||
| 854 | specified in struct resolv_redirect_config is invoked. */ | ||
| 855 | struct resolv_response_context | ||
| 856 | @@ -33,6 +43,7 @@ struct resolv_response_context | ||
| 857 | size_t query_length; | ||
| 858 | int server_index; | ||
| 859 | bool tcp; | ||
| 860 | + struct resolv_edns_info edns; | ||
| 861 | }; | ||
| 862 | |||
| 863 | /* This opaque struct is used to construct responses from within the | ||
| 864 | -- | ||
| 865 | 1.9.1 | ||
| 866 | |||
diff --git a/recipes-core/glibc/glibc/CVE-2017-8804.patch b/recipes-core/glibc/glibc/CVE-2017-8804.patch deleted file mode 100644 index ae21ad0..0000000 --- a/recipes-core/glibc/glibc/CVE-2017-8804.patch +++ /dev/null | |||
| @@ -1,225 +0,0 @@ | |||
| 1 | From 45619a54f7d751a2a7dec7d7ee323e1545b881af Mon Sep 17 00:00:00 2001 | ||
| 2 | From: Sona Sarmadi <sona.sarmadi@enea.com> | ||
| 3 | Date: Mon, 11 Sep 2017 13:35:44 +0200 | ||
| 4 | Subject: [PATCH] CVE-2017-8804 | ||
| 5 | |||
| 6 | The xdr_bytes and xdr_string functions in the glibc or libc6 2.25 mishandle | ||
| 7 | failures of buffer deserialization, which allows remote attackers to cause | ||
| 8 | a denial of service (virtual memory allocation, or memory consumption if an | ||
| 9 | overcommit setting is not used) via a crafted UDP packet to port 111, a | ||
| 10 | related issue to CVE-2017-8779. | ||
| 11 | |||
| 12 | CVE: CVE-2017-8804 | ||
| 13 | Upstream-Status: Backport [https://sourceware.org/ml/libc-alpha/2017-05/msg00105.html] | ||
| 14 | |||
| 15 | Signed-off-by: Sona Sarmadi <sona.sarmadi@enea.com> | ||
| 16 | --- | ||
| 17 | NEWS | 3 ++ | ||
| 18 | sunrpc/Makefile | 10 ++++++- | ||
| 19 | sunrpc/tst-xdrmem3.c | 83 ++++++++++++++++++++++++++++++++++++++++++++++++++++ | ||
| 20 | sunrpc/xdr.c | 41 ++++++++++++++++++++------ | ||
| 21 | 4 files changed, 127 insertions(+), 10 deletions(-) | ||
| 22 | create mode 100644 sunrpc/tst-xdrmem3.c | ||
| 23 | |||
| 24 | diff --git a/NEWS b/NEWS | ||
| 25 | index ec15dde..29e795a 100644 | ||
| 26 | --- a/NEWS | ||
| 27 | +++ b/NEWS | ||
| 28 | @@ -211,6 +211,9 @@ Security related changes: | ||
| 29 | question type which is outside the range of valid question type values. | ||
| 30 | (CVE-2015-5180) | ||
| 31 | |||
| 32 | +* The xdr_bytes and xdr_string routines free the internally allocated buffer | ||
| 33 | + if deserialization of the buffer contents fails for any reason. | ||
| 34 | + | ||
| 35 | The following bugs are resolved with this release: | ||
| 36 | |||
| 37 | [4099] stdio: Overly agressive caching by stream i/o functions. | ||
| 38 | diff --git a/sunrpc/Makefile b/sunrpc/Makefile | ||
| 39 | index 0c1e612..12ec2e7 100644 | ||
| 40 | --- a/sunrpc/Makefile | ||
| 41 | +++ b/sunrpc/Makefile | ||
| 42 | @@ -93,9 +93,16 @@ rpcgen-objs = rpc_main.o rpc_hout.o rpc_cout.o rpc_parse.o \ | ||
| 43 | extra-objs = $(rpcgen-objs) $(addprefix cross-,$(rpcgen-objs)) | ||
| 44 | others += rpcgen | ||
| 45 | |||
| 46 | -tests = tst-xdrmem tst-xdrmem2 test-rpcent | ||
| 47 | +tests = tst-xdrmem tst-xdrmem2 test-rpcent tst-xdrmem3 | ||
| 48 | xtests := tst-getmyaddr | ||
| 49 | |||
| 50 | +tests-special += $(objpfx)mtrace-tst-xdrmem3.out | ||
| 51 | +generated += mtrace-tst-xdrmem3.out tst-xdrmem3.mtrace | ||
| 52 | +tst-xdrmem3-ENV = MALLOC_TRACE=$(objpfx)tst-xdrmem3.mtrace | ||
| 53 | +$(objpfx)mtrace-tst-xdrmem3.out: $(objpfx)tst-xdrmem3.out | ||
| 54 | + $(common-objpfx)malloc/mtrace $(objpfx)tst-xdrmem3.mtrace > $@; \ | ||
| 55 | + $(evaluate-test) | ||
| 56 | + | ||
| 57 | ifeq ($(have-thread-library),yes) | ||
| 58 | xtests += thrsvc | ||
| 59 | endif | ||
| 60 | @@ -155,6 +162,7 @@ BUILD_CPPFLAGS += $(sunrpc-CPPFLAGS) | ||
| 61 | $(objpfx)tst-getmyaddr: $(common-objpfx)linkobj/libc.so | ||
| 62 | $(objpfx)tst-xdrmem: $(common-objpfx)linkobj/libc.so | ||
| 63 | $(objpfx)tst-xdrmem2: $(common-objpfx)linkobj/libc.so | ||
| 64 | +(objpfx)tst-xdrmem2: $(common-objpfx)linkobj/libc.so | ||
| 65 | |||
| 66 | $(objpfx)rpcgen: $(addprefix $(objpfx),$(rpcgen-objs)) | ||
| 67 | |||
| 68 | diff --git a/sunrpc/tst-xdrmem3.c b/sunrpc/tst-xdrmem3.c | ||
| 69 | new file mode 100644 | ||
| 70 | index 0000000..b3c72ae | ||
| 71 | --- /dev/null | ||
| 72 | +++ b/sunrpc/tst-xdrmem3.c | ||
| 73 | @@ -0,0 +1,83 @@ | ||
| 74 | +/* Test xdr_bytes, xdr_string behavior on deserialization failure. | ||
| 75 | + Copyright (C) 2017 Free Software Foundation, Inc. | ||
| 76 | + This file is part of the GNU C Library. | ||
| 77 | + | ||
| 78 | + The GNU C Library is free software; you can redistribute it and/or | ||
| 79 | + modify it under the terms of the GNU Lesser General Public | ||
| 80 | + License as published by the Free Software Foundation; either | ||
| 81 | + version 2.1 of the License, or (at your option) any later version. | ||
| 82 | + | ||
| 83 | + The GNU C Library is distributed in the hope that it will be useful, | ||
| 84 | + but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 85 | + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| 86 | + Lesser General Public License for more details. | ||
| 87 | + | ||
| 88 | + You should have received a copy of the GNU Lesser General Public | ||
| 89 | + License along with the GNU C Library; if not, see | ||
| 90 | + <http://www.gnu.org/licenses/>. */ | ||
| 91 | + | ||
| 92 | +#include <mcheck.h> | ||
| 93 | +#include <rpc/rpc.h> | ||
| 94 | +#include <support/check.h> | ||
| 95 | +#include <support/support.h> | ||
| 96 | + | ||
| 97 | +static int | ||
| 98 | +do_test (void) | ||
| 99 | +{ | ||
| 100 | + mtrace (); | ||
| 101 | + | ||
| 102 | + /* If do_own_buffer, allocate the buffer and pass it to the | ||
| 103 | + deserialization routine. Otherwise the routine is requested to | ||
| 104 | + allocate the buffer. */ | ||
| 105 | + for (int do_own_buffer = 0; do_own_buffer < 2; ++do_own_buffer) | ||
| 106 | + { | ||
| 107 | + /* Length 16 MiB, but only 2 bytes of data in the packet. */ | ||
| 108 | + unsigned char buf[] = "\x01\x00\x00\x00\xff"; | ||
| 109 | + XDR xdrs; | ||
| 110 | + char *result; | ||
| 111 | + unsigned int result_len; | ||
| 112 | + | ||
| 113 | + /* Test xdr_bytes. */ | ||
| 114 | + xdrmem_create (&xdrs, (char *) buf, sizeof (buf), XDR_DECODE); | ||
| 115 | + result_len = 0; | ||
| 116 | + if (do_own_buffer) | ||
| 117 | + { | ||
| 118 | + char *own_buffer = xmalloc (10); | ||
| 119 | + result = own_buffer; | ||
| 120 | + TEST_VERIFY (!xdr_bytes (&xdrs, &result, &result_len, 10)); | ||
| 121 | + TEST_VERIFY (result == own_buffer); | ||
| 122 | + free (own_buffer); | ||
| 123 | + } | ||
| 124 | + else | ||
| 125 | + { | ||
| 126 | + result = NULL; | ||
| 127 | + TEST_VERIFY (!xdr_bytes (&xdrs, &result, &result_len, -1)); | ||
| 128 | + TEST_VERIFY (result == NULL); | ||
| 129 | + } | ||
| 130 | + TEST_VERIFY (result_len == 16 * 1024 * 1024); | ||
| 131 | + xdr_destroy (&xdrs); | ||
| 132 | + | ||
| 133 | + /* Test xdr_string. */ | ||
| 134 | + xdrmem_create (&xdrs, (char *) buf, sizeof (buf), XDR_DECODE); | ||
| 135 | + if (do_own_buffer) | ||
| 136 | + { | ||
| 137 | + char *own_buffer = xmalloc (10); | ||
| 138 | + result = own_buffer; | ||
| 139 | + TEST_VERIFY (!xdr_string (&xdrs, &result, 10)); | ||
| 140 | + TEST_VERIFY (result == own_buffer); | ||
| 141 | + free (own_buffer); | ||
| 142 | + } | ||
| 143 | + else | ||
| 144 | + { | ||
| 145 | + result = NULL; | ||
| 146 | + TEST_VERIFY (!xdr_string (&xdrs, &result, -1)); | ||
| 147 | + TEST_VERIFY (result == NULL); | ||
| 148 | + } | ||
| 149 | + xdr_destroy (&xdrs); | ||
| 150 | + } | ||
| 151 | + | ||
| 152 | + return 0; | ||
| 153 | +} | ||
| 154 | + | ||
| 155 | +#include <support/test-driver.c> | ||
| 156 | + | ||
| 157 | diff --git a/sunrpc/xdr.c b/sunrpc/xdr.c | ||
| 158 | index bfabf33..857f7c8 100644 | ||
| 159 | --- a/sunrpc/xdr.c | ||
| 160 | +++ b/sunrpc/xdr.c | ||
| 161 | @@ -620,14 +620,24 @@ xdr_bytes (XDR *xdrs, char **cpp, u_int *sizep, u_int maxsize) | ||
| 162 | } | ||
| 163 | if (sp == NULL) | ||
| 164 | { | ||
| 165 | - *cpp = sp = (char *) mem_alloc (nodesize); | ||
| 166 | + sp = (char *) mem_alloc (nodesize); | ||
| 167 | + if (sp == NULL) | ||
| 168 | + { | ||
| 169 | + (void) __fxprintf (NULL, "%s: %s", __func__, | ||
| 170 | + _("out of memory\n")); | ||
| 171 | + return FALSE; | ||
| 172 | + } | ||
| 173 | } | ||
| 174 | - if (sp == NULL) | ||
| 175 | + if (!xdr_opaque (xdrs, sp, nodesize)) | ||
| 176 | { | ||
| 177 | - (void) __fxprintf (NULL, "%s: %s", __func__, _("out of memory\n")); | ||
| 178 | + if (sp != *cpp) | ||
| 179 | + /* *cpp was NULL, so this function allocated a new | ||
| 180 | + buffer. */ | ||
| 181 | + free (sp); | ||
| 182 | return FALSE; | ||
| 183 | } | ||
| 184 | - /* fall into ... */ | ||
| 185 | + *cpp = sp; | ||
| 186 | + return TRUE; | ||
| 187 | |||
| 188 | case XDR_ENCODE: | ||
| 189 | return xdr_opaque (xdrs, sp, nodesize); | ||
| 190 | @@ -781,14 +791,27 @@ xdr_string (XDR *xdrs, char **cpp, u_int maxsize) | ||
| 191 | { | ||
| 192 | case XDR_DECODE: | ||
| 193 | if (sp == NULL) | ||
| 194 | - *cpp = sp = (char *) mem_alloc (nodesize); | ||
| 195 | - if (sp == NULL) | ||
| 196 | { | ||
| 197 | - (void) __fxprintf (NULL, "%s: %s", __func__, _("out of memory\n")); | ||
| 198 | - return FALSE; | ||
| 199 | + sp = (char *) mem_alloc (nodesize); | ||
| 200 | + if (sp == NULL) | ||
| 201 | + { | ||
| 202 | + (void) __fxprintf (NULL, "%s: %s", __func__, | ||
| 203 | + _("out of memory\n")); | ||
| 204 | + return FALSE; | ||
| 205 | + } | ||
| 206 | } | ||
| 207 | sp[size] = 0; | ||
| 208 | - /* fall into ... */ | ||
| 209 | + | ||
| 210 | + if (!xdr_opaque (xdrs, sp, size)) | ||
| 211 | + { | ||
| 212 | + if (sp != *cpp) | ||
| 213 | + /* *cpp was NULL, so this function allocated a new | ||
| 214 | + buffer. */ | ||
| 215 | + free (sp); | ||
| 216 | + return FALSE; | ||
| 217 | + } | ||
| 218 | + *cpp = sp; | ||
| 219 | + return TRUE; | ||
| 220 | |||
| 221 | case XDR_ENCODE: | ||
| 222 | return xdr_opaque (xdrs, sp, size); | ||
| 223 | -- | ||
| 224 | 1.9.1 | ||
| 225 | |||
diff --git a/recipes-core/glibc/glibc_%.bbappend b/recipes-core/glibc/glibc_%.bbappend deleted file mode 100644 index f2c9a31..0000000 --- a/recipes-core/glibc/glibc_%.bbappend +++ /dev/null | |||
| @@ -1,8 +0,0 @@ | |||
| 1 | # look for files in the layer first | ||
| 2 | FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:" | ||
| 3 | |||
| 4 | SRC_URI += "file://CVE-2017-1000366.patch \ | ||
| 5 | file://CVE-2017-12132.patch \ | ||
| 6 | file://CVE-2017-8804.patch \ | ||
| 7 | " | ||
| 8 | |||
diff --git a/recipes-core/systemd/systemd/CVE-2017-9445.patch b/recipes-core/systemd/systemd/CVE-2017-9445.patch deleted file mode 100644 index 031901d..0000000 --- a/recipes-core/systemd/systemd/CVE-2017-9445.patch +++ /dev/null | |||
| @@ -1,56 +0,0 @@ | |||
| 1 | From db848813bae4d28c524b3b6a7dad135e426659ce Mon Sep 17 00:00:00 2001 | ||
| 2 | From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl> | ||
| 3 | Date: Sun, 18 Jun 2017 16:07:57 -0400 | ||
| 4 | Subject: [PATCH] resolved: simplify alloc size calculation | ||
| 5 | |||
| 6 | The allocation size was calculated in a complicated way, and for values | ||
| 7 | close to the page size we would actually allocate less than requested. | ||
| 8 | |||
| 9 | Reported by Chris Coulson <chris.coulson@canonical.com>. | ||
| 10 | |||
| 11 | CVE-2017-9445 | ||
| 12 | |||
| 13 | CVE: CVE-2017-8872 | ||
| 14 | Upstream-Status: Backport | ||
| 15 | |||
| 16 | Signed-off-by: Sona Sarmadi <sona.sarmadi@enea.com> | ||
| 17 | --- | ||
| 18 | src/resolve/resolved-dns-packet.c | 8 +------- | ||
| 19 | src/resolve/resolved-dns-packet.h | 2 -- | ||
| 20 | 2 files changed, 1 insertion(+), 9 deletions(-) | ||
| 21 | |||
| 22 | diff --git a/src/resolve/resolved-dns-packet.c b/src/resolve/resolved-dns-packet.c | ||
| 23 | index 240ee44..821b66e 100644 | ||
| 24 | --- a/src/resolve/resolved-dns-packet.c | ||
| 25 | +++ b/src/resolve/resolved-dns-packet.c | ||
| 26 | @@ -47,13 +47,7 @@ int dns_packet_new(DnsPacket **ret, DnsProtocol protocol, size_t mtu) { | ||
| 27 | |||
| 28 | assert(ret); | ||
| 29 | |||
| 30 | - if (mtu <= UDP_PACKET_HEADER_SIZE) | ||
| 31 | - a = DNS_PACKET_SIZE_START; | ||
| 32 | - else | ||
| 33 | - a = mtu - UDP_PACKET_HEADER_SIZE; | ||
| 34 | - | ||
| 35 | - if (a < DNS_PACKET_HEADER_SIZE) | ||
| 36 | - a = DNS_PACKET_HEADER_SIZE; | ||
| 37 | + a = MAX(mtu, DNS_PACKET_HEADER_SIZE); | ||
| 38 | |||
| 39 | /* round up to next page size */ | ||
| 40 | a = PAGE_ALIGN(ALIGN(sizeof(DnsPacket)) + a) - ALIGN(sizeof(DnsPacket)); | ||
| 41 | diff --git a/src/resolve/resolved-dns-packet.h b/src/resolve/resolved-dns-packet.h | ||
| 42 | index 2c92392..3abcaf8 100644 | ||
| 43 | --- a/src/resolve/resolved-dns-packet.h | ||
| 44 | +++ b/src/resolve/resolved-dns-packet.h | ||
| 45 | @@ -66,8 +66,6 @@ struct DnsPacketHeader { | ||
| 46 | /* With EDNS0 we can use larger packets, default to 4096, which is what is commonly used */ | ||
| 47 | #define DNS_PACKET_UNICAST_SIZE_LARGE_MAX 4096 | ||
| 48 | |||
| 49 | -#define DNS_PACKET_SIZE_START 512 | ||
| 50 | - | ||
| 51 | struct DnsPacket { | ||
| 52 | int n_ref; | ||
| 53 | DnsProtocol protocol; | ||
| 54 | -- | ||
| 55 | 1.9.1 | ||
| 56 | |||
diff --git a/recipes-core/systemd/systemd_%.bbappend b/recipes-core/systemd/systemd_%.bbappend deleted file mode 100644 index e07dbe1..0000000 --- a/recipes-core/systemd/systemd_%.bbappend +++ /dev/null | |||
| @@ -1,6 +0,0 @@ | |||
| 1 | # look for files in the layer first | ||
| 2 | FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:" | ||
| 3 | |||
| 4 | SRC_URI += "file://CVE-2017-9445.patch \ | ||
| 5 | " | ||
| 6 | |||
diff --git a/recipes-devtools/dpkg/dpkg/CVE-2017-8283.patch b/recipes-devtools/dpkg/dpkg/CVE-2017-8283.patch deleted file mode 100644 index b4c8df1..0000000 --- a/recipes-devtools/dpkg/dpkg/CVE-2017-8283.patch +++ /dev/null | |||
| @@ -1,190 +0,0 @@ | |||
| 1 | From 67f2bc55ec79926f3334eb2956a62719f824e85b Mon Sep 17 00:00:00 2001 | ||
| 2 | From: Sona Sarmadi <sona.sarmadi@enea.com> | ||
| 3 | Date: Thu, 14 Dec 2017 10:21:01 +0100 | ||
| 4 | Subject: [PATCH] build: Detect the required GNU patch | ||
| 5 | |||
| 6 | This makes sure the perl module is using a directory traversal resistant | ||
| 7 | patch implementation, currently that's only GNU patch. | ||
| 8 | |||
| 9 | CVE: CVE-2017-8283 | ||
| 10 | Upstream-Status: Backport [remotes/origin/1.18.x: 8ba04d41c839318b5a024f6c5298848d3b54c723] | ||
| 11 | |||
| 12 | Signed-off-by: Sona Sarmadi <sona.sarmadi@enea.com> | ||
| 13 | --- | ||
| 14 | configure.ac | 1 + | ||
| 15 | debian/changelog | 5 +++++ | ||
| 16 | m4/dpkg-progs.m4 | 15 +++++++++++++++ | ||
| 17 | scripts/Dpkg.pm | 13 ++++++++++++- | ||
| 18 | scripts/Dpkg/Source/Patch.pm | 9 +++++---- | ||
| 19 | scripts/Makefile.am | 4 +++- | ||
| 20 | 6 files changed, 41 insertions(+), 6 deletions(-) | ||
| 21 | |||
| 22 | diff --git a/configure.ac b/configure.ac | ||
| 23 | index 3123d0c..0112d4d 100644 | ||
| 24 | --- a/configure.ac | ||
| 25 | +++ b/configure.ac | ||
| 26 | @@ -61,6 +61,7 @@ AC_PROG_CC | ||
| 27 | DPKG_C_C99 | ||
| 28 | AC_PROG_CXX | ||
| 29 | DPKG_CXX_CXX11 | ||
| 30 | +DPKG_PROG_PATCH | ||
| 31 | AC_CHECK_PROGS([DOXYGEN], [doxygen]) | ||
| 32 | AC_CHECK_PROG([HAVE_DOT], [dot], [YES], [NO]) | ||
| 33 | DPKG_PROG_PO4A | ||
| 34 | diff --git a/debian/changelog b/debian/changelog | ||
| 35 | index 695c55d..4b5b36b 100644 | ||
| 36 | --- a/debian/changelog | ||
| 37 | +++ b/debian/changelog | ||
| 38 | @@ -1,3 +1,8 @@ | ||
| 39 | + - Check that the detected patch is a GNU patch, so that we get a directory | ||
| 40 | + traversal resistant patch implementation. This fixes CVE-2017-8283 by | ||
| 41 | + delegating those checks to patch(1), so that we trap blank-indented | ||
| 42 | + diff hunks trying to escape from the source tree. | ||
| 43 | + | ||
| 44 | dpkg (1.18.10) unstable; urgency=medium | ||
| 45 | |||
| 46 | [ Guillem Jover ] | ||
| 47 | diff --git a/m4/dpkg-progs.m4 b/m4/dpkg-progs.m4 | ||
| 48 | index c59f595..577d50d 100644 | ||
| 49 | --- a/m4/dpkg-progs.m4 | ||
| 50 | +++ b/m4/dpkg-progs.m4 | ||
| 51 | @@ -49,3 +49,18 @@ AC_ARG_VAR([TAR], [GNU tar program]) | ||
| 52 | AC_CHECK_PROGS([TAR], [gnutar gtar tar], [tar]) | ||
| 53 | AC_DEFINE_UNQUOTED([TAR], ["$TAR"], [GNU tar program]) | ||
| 54 | ])# DPKG_DEB_PROG_TAR | ||
| 55 | + | ||
| 56 | +# DPKG_PROG_PATCH | ||
| 57 | +# --------------- | ||
| 58 | +# Specify GNU patch program name to use by dpkg-source. On GNU systems this | ||
| 59 | +# is usually simply patch, on BSD systems this is usually gpatch. | ||
| 60 | +# Even though most invocations would work with other patch implementations, | ||
| 61 | +# currently only GNU patch is directory traversal resistant. | ||
| 62 | +AC_DEFUN([DPKG_PROG_PATCH], [ | ||
| 63 | + AC_ARG_VAR([PATCH], [GNU patch program]) | ||
| 64 | + AC_CHECK_PROGS([PATCH], [gpatch patch], [patch]) | ||
| 65 | + AS_IF([! $PATCH --version 2>/dev/null | grep -q '^GNU patch'], [ | ||
| 66 | + AC_MSG_ERROR([cannot find a GNU patch program]) | ||
| 67 | + ]) | ||
| 68 | + AC_DEFINE_UNQUOTED([PATCH], ["$PATCH"], [GNU patch program]) | ||
| 69 | +])# DPKG_PROG_PATCH | ||
| 70 | diff --git a/scripts/Dpkg.pm b/scripts/Dpkg.pm | ||
| 71 | index deecfb3..4905ab8 100644 | ||
| 72 | --- a/scripts/Dpkg.pm | ||
| 73 | +++ b/scripts/Dpkg.pm | ||
| 74 | @@ -29,10 +29,11 @@ this system installation. | ||
| 75 | use strict; | ||
| 76 | use warnings; | ||
| 77 | |||
| 78 | -our $VERSION = '1.01'; | ||
| 79 | +our $VERSION = '1.03'; | ||
| 80 | our @EXPORT_OK = qw( | ||
| 81 | $PROGNAME | ||
| 82 | $PROGVERSION | ||
| 83 | + $PROGPATCH | ||
| 84 | $CONFDIR | ||
| 85 | $ADMINDIR | ||
| 86 | $LIBDIR | ||
| 87 | @@ -60,6 +61,11 @@ Contains the name of the current program. | ||
| 88 | |||
| 89 | Contains the version of the dpkg suite. | ||
| 90 | |||
| 91 | +=item $Dpkg::PROGPATCH | ||
| 92 | + | ||
| 93 | +Contains the name of the system GNU patch program (or another implementation | ||
| 94 | +that is directory traversal resistant). | ||
| 95 | + | ||
| 96 | =item $Dpkg::CONFDIR | ||
| 97 | |||
| 98 | Contains the path to the dpkg system configuration directory. | ||
| 99 | @@ -84,6 +90,7 @@ our ($PROGNAME) = $0 =~ m{(?:.*/)?([^/]*)}; | ||
| 100 | |||
| 101 | # The following lines are automatically fixed at install time | ||
| 102 | our $PROGVERSION = '1.18.x'; | ||
| 103 | +our $PROGPATCH = $ENV{DPKG_PROGPATCH} // 'patch'; | ||
| 104 | our $CONFDIR = '/etc/dpkg'; | ||
| 105 | our $ADMINDIR = '/var/lib/dpkg'; | ||
| 106 | our $LIBDIR = '.'; | ||
| 107 | @@ -100,6 +107,10 @@ our $pkgdatadir = $DATADIR; | ||
| 108 | |||
| 109 | =head1 CHANGES | ||
| 110 | |||
| 111 | +=head2 Version 1.03 (dpkg 1.18.10) | ||
| 112 | + | ||
| 113 | +New variable: $PROGPATCH. | ||
| 114 | + | ||
| 115 | =head2 Version 1.01 (dpkg 1.17.0) | ||
| 116 | |||
| 117 | New variables: $PROGNAME, $PROGVERSION, $CONFDIR, $ADMINDIR, $LIBDIR and | ||
| 118 | diff --git a/scripts/Dpkg/Source/Patch.pm b/scripts/Dpkg/Source/Patch.pm | ||
| 119 | index ee5e114..22e9d21 100644 | ||
| 120 | --- a/scripts/Dpkg/Source/Patch.pm | ||
| 121 | +++ b/scripts/Dpkg/Source/Patch.pm | ||
| 122 | @@ -30,6 +30,7 @@ use File::Compare; | ||
| 123 | use Fcntl ':mode'; | ||
| 124 | use Time::HiRes qw(stat); | ||
| 125 | |||
| 126 | +use Dpkg; | ||
| 127 | use Dpkg::Gettext; | ||
| 128 | use Dpkg::ErrorHandling; | ||
| 129 | use Dpkg::IPC; | ||
| 130 | @@ -582,7 +583,7 @@ sub apply { | ||
| 131 | $self->ensure_open('r'); | ||
| 132 | my ($stdout, $stderr) = ('', ''); | ||
| 133 | spawn( | ||
| 134 | - exec => [ 'patch', @{$opts{options}} ], | ||
| 135 | + exec => [ $Dpkg::PROGPATCH, @{$opts{options}} ], | ||
| 136 | chdir => $destdir, | ||
| 137 | env => { LC_ALL => 'C', LANG => 'C', PATCH_GET => '0' }, | ||
| 138 | delete_env => [ 'POSIXLY_CORRECT' ], # ensure expected patch behaviour | ||
| 139 | @@ -595,7 +596,7 @@ sub apply { | ||
| 140 | if ($?) { | ||
| 141 | print { *STDOUT } $stdout; | ||
| 142 | print { *STDERR } $stderr; | ||
| 143 | - subprocerr('LC_ALL=C patch ' . join(' ', @{$opts{options}}) . | ||
| 144 | + subprocerr("LC_ALL=C $Dpkg::PROGPATCH " . join(' ', @{$opts{options}}) . | ||
| 145 | ' < ' . $self->get_filename()); | ||
| 146 | } | ||
| 147 | $self->close(); | ||
| 148 | @@ -632,7 +633,7 @@ sub check_apply { | ||
| 149 | # Apply the patch | ||
| 150 | $self->ensure_open('r'); | ||
| 151 | my $patch_pid = spawn( | ||
| 152 | - exec => [ 'patch', @{$opts{options}} ], | ||
| 153 | + exec => [ $Dpkg::PROGPATCH, @{$opts{options}} ], | ||
| 154 | chdir => $destdir, | ||
| 155 | env => { LC_ALL => 'C', LANG => 'C', PATCH_GET => '0' }, | ||
| 156 | delete_env => [ 'POSIXLY_CORRECT' ], # ensure expected patch behaviour | ||
| 157 | @@ -642,7 +643,7 @@ sub check_apply { | ||
| 158 | ); | ||
| 159 | wait_child($patch_pid, nocheck => 1); | ||
| 160 | my $exit = WEXITSTATUS($?); | ||
| 161 | - subprocerr('patch --dry-run') unless WIFEXITED($?); | ||
| 162 | + subprocerr("$Dpkg::PROGPATCH --dry-run") unless WIFEXITED($?); | ||
| 163 | $self->close(); | ||
| 164 | return ($exit == 0); | ||
| 165 | } | ||
| 166 | diff --git a/scripts/Makefile.am b/scripts/Makefile.am | ||
| 167 | index 7b1ac36..84059c1 100644 | ||
| 168 | --- a/scripts/Makefile.am | ||
| 169 | +++ b/scripts/Makefile.am | ||
| 170 | @@ -127,6 +127,7 @@ do_perl_subst = $(AM_V_GEN) \ | ||
| 171 | -e "s:\$$ADMINDIR[[:space:]]*=[[:space:]]*['\"][^'\"]*['\"]:\$$ADMINDIR='$(admindir)':" \ | ||
| 172 | -e "s:\$$LIBDIR[[:space:]]*=[[:space:]]*['\"][^'\"]*['\"]:\$$LIBDIR='$(pkglibdir)':" \ | ||
| 173 | -e "s:\$$DATADIR[[:space:]]*=[[:space:]]*['\"][^'\"]*['\"]:\$$DATADIR='$(pkgdatadir)':" \ | ||
| 174 | + -e "s:our \$$PROGPATCH = .*;:our \$$PROGPATCH = '$(PATCH)';:" \ | ||
| 175 | -e "s:\$$PROGVERSION[[:space:]]*=[[:space:]]*['\"][^'\"]*[\"']:\$$PROGVERSION='$(PACKAGE_VERSION)':" | ||
| 176 | |||
| 177 | do_shell_subst = $(AM_V_GEN) \ | ||
| 178 | @@ -187,7 +188,8 @@ coverage-clean: | ||
| 179 | rm -rf cover_db | ||
| 180 | |||
| 181 | TEST_ENV_VARS = \ | ||
| 182 | - DPKG_DATADIR=$(srcdir)/.. \ | ||
| 183 | + DPKG_PROGPATCH=$(PATCH) \ | ||
| 184 | + DPKG_DATADIR=$(srcdir)/.. \ | ||
| 185 | DPKG_ORIGINS_DIR=$(srcdir)/t/origins | ||
| 186 | TEST_COVERAGE = $(PERL_COVERAGE) | ||
| 187 | |||
| 188 | -- | ||
| 189 | 1.9.1 | ||
| 190 | |||
diff --git a/recipes-devtools/dpkg/dpkg/test-case-for-CVE-2017-8283.patch b/recipes-devtools/dpkg/dpkg/test-case-for-CVE-2017-8283.patch deleted file mode 100644 index 5632d8f..0000000 --- a/recipes-devtools/dpkg/dpkg/test-case-for-CVE-2017-8283.patch +++ /dev/null | |||
| @@ -1,83 +0,0 @@ | |||
| 1 | From 57a3daba4d3dee1c33571e84f160aa1c67aece4c Mon Sep 17 00:00:00 2001 | ||
| 2 | From: Sona Sarmadi <sona.sarmadi@enea.com> | ||
| 3 | Date: Thu, 14 Dec 2017 10:40:42 +0100 | ||
| 4 | Subject: [PATCH] Dpkg::Source::Patch: Indented patch test-case | ||
| 5 | |||
| 6 | POSIX specifies that a diff hunk can be indented by spaces or tabs | ||
| 7 | (while the original patch(1) by Larry Wall also accepts 'X'), as long | ||
| 8 | as the amount of spaces is consistent for all subsequent lines. And as | ||
| 9 | we are not checking for this condition at all, any such indented hunk | ||
| 10 | can avoid the sanity checks performed by Dpkg::Source::Patch. | ||
| 11 | |||
| 12 | On systems using GNU patch >= 2.7.5, this should, in principle, not be | ||
| 13 | a problem anymore, as that implementation protects against directory | ||
| 14 | traversal issue. But on other systems where the patch implementation | ||
| 15 | does not perform such checks (such as the BSDs) this is an issue, so | ||
| 16 | check for this in the test-suite. | ||
| 17 | |||
| 18 | Those are arguably all security issues in these various patch | ||
| 19 | implementations, but given that we are performing sanity checks and that | ||
| 20 | those implementations are currently very lax, it seems prudent to do the | ||
| 21 | heavy lifting ourselves and also take the possible blame too. | ||
| 22 | |||
| 23 | Ref: test-case for CVE-2017-8283 | ||
| 24 | Upstream-Status: Backport | ||
| 25 | |||
| 26 | Signed-off-by: Sona Sarmadi <sona.sarmadi@enea.com> | ||
| 27 | --- | ||
| 28 | debian/changelog | 3 +++ | ||
| 29 | scripts/Makefile.am | 1 + | ||
| 30 | scripts/t/Dpkg_Source_Patch.t | 6 +++++- | ||
| 31 | 3 files changed, 9 insertions(+), 1 deletion(-) | ||
| 32 | |||
| 33 | diff --git a/debian/changelog b/debian/changelog | ||
| 34 | index 4b5b36b..596a59e 100644 | ||
| 35 | --- a/debian/changelog | ||
| 36 | +++ b/debian/changelog | ||
| 37 | @@ -2,6 +2,9 @@ | ||
| 38 | traversal resistant patch implementation. This fixes CVE-2017-8283 by | ||
| 39 | delegating those checks to patch(1), so that we trap blank-indented | ||
| 40 | diff hunks trying to escape from the source tree. | ||
| 41 | + * Test suite: | ||
| 42 | + - Add a test case for blank-indented patches which were the cause for | ||
| 43 | + CVE-2017-8283. | ||
| 44 | |||
| 45 | dpkg (1.18.10) unstable; urgency=medium | ||
| 46 | |||
| 47 | diff --git a/scripts/Makefile.am b/scripts/Makefile.am | ||
| 48 | index 84059c1..6ce0ad6 100644 | ||
| 49 | --- a/scripts/Makefile.am | ||
| 50 | +++ b/scripts/Makefile.am | ||
| 51 | @@ -275,6 +275,7 @@ test_data = \ | ||
| 52 | t/Dpkg_Shlibs/spacesyms-o-map.pl \ | ||
| 53 | t/Dpkg_Source_Patch/c-style.patch \ | ||
| 54 | t/Dpkg_Source_Patch/ghost-hunk.patch \ | ||
| 55 | + t/Dpkg_Source_Patch/indent-header.patch \ | ||
| 56 | t/Dpkg_Source_Patch/index-+++.patch \ | ||
| 57 | t/Dpkg_Source_Patch/index-alone.patch \ | ||
| 58 | t/Dpkg_Source_Patch/index-inert.patch \ | ||
| 59 | diff --git a/scripts/t/Dpkg_Source_Patch.t b/scripts/t/Dpkg_Source_Patch.t | ||
| 60 | index 258a9aa..30be77a 100644 | ||
| 61 | --- a/scripts/t/Dpkg_Source_Patch.t | ||
| 62 | +++ b/scripts/t/Dpkg_Source_Patch.t | ||
| 63 | @@ -16,7 +16,7 @@ | ||
| 64 | use strict; | ||
| 65 | use warnings; | ||
| 66 | |||
| 67 | -use Test::More tests => 9; | ||
| 68 | +use Test::More tests => 10; | ||
| 69 | |||
| 70 | use File::Path qw(make_path); | ||
| 71 | |||
| 72 | @@ -67,4 +67,8 @@ test_patch_escape('partial', 'symlink', 'partial.patch', | ||
| 73 | test_patch_escape('ghost-hunk', 'symlink', 'ghost-hunk.patch', | ||
| 74 | 'Patch cannot escape using a disabling hunk'); | ||
| 75 | |||
| 76 | +# This is CVE-2017-8283 | ||
| 77 | +test_patch_escape('indent-header', 'symlink', 'indent-header.patch', | ||
| 78 | + 'Patch cannot escape indented hunks'); | ||
| 79 | + | ||
| 80 | 1; | ||
| 81 | -- | ||
| 82 | 1.9.1 | ||
| 83 | |||
diff --git a/recipes-devtools/dpkg/dpkg_%.bbappend b/recipes-devtools/dpkg/dpkg_%.bbappend deleted file mode 100644 index 65d380e..0000000 --- a/recipes-devtools/dpkg/dpkg_%.bbappend +++ /dev/null | |||
| @@ -1,6 +0,0 @@ | |||
| 1 | # look for files in the layer first | ||
| 2 | FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:" | ||
| 3 | |||
| 4 | SRC_URI += "file://CVE-2017-8283.patch \ | ||
| 5 | file://test-case-for-CVE-2017-8283.patch \ | ||
| 6 | " | ||
diff --git a/recipes-networking/dnsmasq/dnsmasq/0001-CVE-2017-14491.patch b/recipes-networking/dnsmasq/dnsmasq/0001-CVE-2017-14491.patch deleted file mode 100644 index 1eda591..0000000 --- a/recipes-networking/dnsmasq/dnsmasq/0001-CVE-2017-14491.patch +++ /dev/null | |||
| @@ -1,269 +0,0 @@ | |||
| 1 | From 0549c73b7ea6b22a3c49beb4d432f185a81efcbc Mon Sep 17 00:00:00 2001 | ||
| 2 | From: Simon Kelley <simon@thekelleys.org.uk> | ||
| 3 | Date: Mon, 25 Sep 2017 18:17:11 +0100 | ||
| 4 | Subject: [PATCH] Security fix, CVE-2017-14491 DNS heap buffer overflow. | ||
| 5 | |||
| 6 | Fix heap overflow in DNS code. This is a potentially serious | ||
| 7 | security hole. It allows an attacker who can make DNS | ||
| 8 | requests to dnsmasq, and who controls the contents of | ||
| 9 | a domain, which is thereby queried, to overflow | ||
| 10 | (by 2 bytes) a heap buffer and either crash, or | ||
| 11 | even take control of, dnsmasq. | ||
| 12 | |||
| 13 | CVE: CVE-2017-14491 | ||
| 14 | Upstream-Status: Backport [src/dnsmasq.h patch failed, modified manually] | ||
| 15 | |||
| 16 | Signed-off-by: Sona Sarmadi <sona.sarmadi@enea.com> | ||
| 17 | |||
| 18 | diff -Nurp a/CHANGELOG b/CHANGELOG | ||
| 19 | --- a/CHANGELOG 2016-05-18 16:51:54.000000000 +0200 | ||
| 20 | +++ b/CHANGELOG 2017-10-04 09:38:20.445498463 +0200 | ||
| 21 | @@ -123,6 +123,18 @@ version 2.75 | ||
| 22 | dhcp-script is configured. Thanks to Adrian Davey for | ||
| 23 | reporting the bug and testing the fix. | ||
| 24 | |||
| 25 | + Fix heap overflow in DNS code. This is a potentially serious | ||
| 26 | + security hole. It allows an attacker who can make DNS | ||
| 27 | + requests to dnsmasq, and who controls the contents of | ||
| 28 | + a domain, which is thereby queried, to overflow | ||
| 29 | + (by 2 bytes) a heap buffer and either crash, or | ||
| 30 | + even take control of, dnsmasq. | ||
| 31 | + CVE-2017-14491 applies. | ||
| 32 | + Credit to Felix Wilhelm, Fermin J. Serna, Gabriel Campana | ||
| 33 | + and Kevin Hamacher of the Google Security Team for | ||
| 34 | + finding this. | ||
| 35 | + | ||
| 36 | + | ||
| 37 | |||
| 38 | version 2.74 | ||
| 39 | Fix reversion in 2.73 where --conf-file would attempt to | ||
| 40 | diff -Nurp a/src/dnsmasq.h b/src/dnsmasq.h | ||
| 41 | --- a/src/dnsmasq.h 2016-05-18 16:51:54.000000000 +0200 | ||
| 42 | +++ b/src/dnsmasq.h 2017-10-04 09:39:39.366156718 +0200 | ||
| 43 | @@ -1161,7 +1161,7 @@ u32 rand32(void); | ||
| 44 | u64 rand64(void); | ||
| 45 | int legal_hostname(char *c); | ||
| 46 | char *canonicalise(char *s, int *nomem); | ||
| 47 | -unsigned char *do_rfc1035_name(unsigned char *p, char *sval); | ||
| 48 | +unsigned char *do_rfc1035_name(unsigned char *p, char *sval, char *limit); | ||
| 49 | void *safe_malloc(size_t size); | ||
| 50 | void safe_pipe(int *fd, int read_noblock); | ||
| 51 | void *whine_malloc(size_t size); | ||
| 52 | diff -Nurp a/src/dnssec.c b/src/dnssec.c | ||
| 53 | --- a/src/dnssec.c 2016-05-18 16:51:54.000000000 +0200 | ||
| 54 | +++ b/src/dnssec.c 2017-10-04 09:38:20.445498463 +0200 | ||
| 55 | @@ -2227,7 +2227,7 @@ size_t dnssec_generate_query(struct dns_ | ||
| 56 | |||
| 57 | p = (unsigned char *)(header+1); | ||
| 58 | |||
| 59 | - p = do_rfc1035_name(p, name); | ||
| 60 | + p = do_rfc1035_name(p, name, NULL); | ||
| 61 | *p++ = 0; | ||
| 62 | PUTSHORT(type, p); | ||
| 63 | PUTSHORT(class, p); | ||
| 64 | diff -Nurp a/src/option.c b/src/option.c | ||
| 65 | --- a/src/option.c 2016-05-18 16:51:54.000000000 +0200 | ||
| 66 | +++ b/src/option.c 2017-10-04 09:38:20.449498294 +0200 | ||
| 67 | @@ -1378,7 +1378,7 @@ static int parse_dhcp_opt(char *errstr, | ||
| 68 | } | ||
| 69 | |||
| 70 | p = newp; | ||
| 71 | - end = do_rfc1035_name(p + len, dom); | ||
| 72 | + end = do_rfc1035_name(p + len, dom, NULL); | ||
| 73 | *end++ = 0; | ||
| 74 | len = end - p; | ||
| 75 | free(dom); | ||
| 76 | diff -Nurp a/src/rfc1035.c b/src/rfc1035.c | ||
| 77 | --- a/src/rfc1035.c 2016-05-18 16:51:54.000000000 +0200 | ||
| 78 | +++ b/src/rfc1035.c 2017-10-04 09:38:20.449498294 +0200 | ||
| 79 | @@ -1049,6 +1049,7 @@ int check_for_ignored_address(struct dns | ||
| 80 | return 0; | ||
| 81 | } | ||
| 82 | |||
| 83 | + | ||
| 84 | int add_resource_record(struct dns_header *header, char *limit, int *truncp, int nameoffset, unsigned char **pp, | ||
| 85 | unsigned long ttl, int *offset, unsigned short type, unsigned short class, char *format, ...) | ||
| 86 | { | ||
| 87 | @@ -1058,12 +1059,21 @@ int add_resource_record(struct dns_heade | ||
| 88 | unsigned short usval; | ||
| 89 | long lval; | ||
| 90 | char *sval; | ||
| 91 | +#define CHECK_LIMIT(size) \ | ||
| 92 | + if (limit && p + (size) > (unsigned char*)limit) \ | ||
| 93 | + { \ | ||
| 94 | + va_end(ap); \ | ||
| 95 | + goto truncated; \ | ||
| 96 | + } | ||
| 97 | |||
| 98 | if (truncp && *truncp) | ||
| 99 | return 0; | ||
| 100 | - | ||
| 101 | + | ||
| 102 | va_start(ap, format); /* make ap point to 1st unamed argument */ | ||
| 103 | - | ||
| 104 | + | ||
| 105 | + /* nameoffset (1 or 2) + type (2) + class (2) + ttl (4) + 0 (2) */ | ||
| 106 | + CHECK_LIMIT(12); | ||
| 107 | + | ||
| 108 | if (nameoffset > 0) | ||
| 109 | { | ||
| 110 | PUTSHORT(nameoffset | 0xc000, p); | ||
| 111 | @@ -1072,7 +1082,13 @@ int add_resource_record(struct dns_heade | ||
| 112 | { | ||
| 113 | char *name = va_arg(ap, char *); | ||
| 114 | if (name) | ||
| 115 | - p = do_rfc1035_name(p, name); | ||
| 116 | + p = do_rfc1035_name(p, name, limit); | ||
| 117 | + if (!p) | ||
| 118 | + { | ||
| 119 | + va_end(ap); | ||
| 120 | + goto truncated; | ||
| 121 | + } | ||
| 122 | + | ||
| 123 | if (nameoffset < 0) | ||
| 124 | { | ||
| 125 | PUTSHORT(-nameoffset | 0xc000, p); | ||
| 126 | @@ -1093,6 +1109,7 @@ int add_resource_record(struct dns_heade | ||
| 127 | { | ||
| 128 | #ifdef HAVE_IPV6 | ||
| 129 | case '6': | ||
| 130 | + CHECK_LIMIT(IN6ADDRSZ); | ||
| 131 | sval = va_arg(ap, char *); | ||
| 132 | memcpy(p, sval, IN6ADDRSZ); | ||
| 133 | p += IN6ADDRSZ; | ||
| 134 | @@ -1100,36 +1117,47 @@ int add_resource_record(struct dns_heade | ||
| 135 | #endif | ||
| 136 | |||
| 137 | case '4': | ||
| 138 | + CHECK_LIMIT(INADDRSZ); | ||
| 139 | sval = va_arg(ap, char *); | ||
| 140 | memcpy(p, sval, INADDRSZ); | ||
| 141 | p += INADDRSZ; | ||
| 142 | break; | ||
| 143 | |||
| 144 | case 'b': | ||
| 145 | + CHECK_LIMIT(1); | ||
| 146 | usval = va_arg(ap, int); | ||
| 147 | *p++ = usval; | ||
| 148 | break; | ||
| 149 | |||
| 150 | case 's': | ||
| 151 | + CHECK_LIMIT(2); | ||
| 152 | usval = va_arg(ap, int); | ||
| 153 | PUTSHORT(usval, p); | ||
| 154 | break; | ||
| 155 | |||
| 156 | case 'l': | ||
| 157 | + CHECK_LIMIT(4); | ||
| 158 | lval = va_arg(ap, long); | ||
| 159 | PUTLONG(lval, p); | ||
| 160 | break; | ||
| 161 | |||
| 162 | case 'd': | ||
| 163 | - /* get domain-name answer arg and store it in RDATA field */ | ||
| 164 | - if (offset) | ||
| 165 | - *offset = p - (unsigned char *)header; | ||
| 166 | - p = do_rfc1035_name(p, va_arg(ap, char *)); | ||
| 167 | - *p++ = 0; | ||
| 168 | + /* get domain-name answer arg and store it in RDATA field */ | ||
| 169 | + if (offset) | ||
| 170 | + *offset = p - (unsigned char *)header; | ||
| 171 | + p = do_rfc1035_name(p, va_arg(ap, char *), limit); | ||
| 172 | + if (!p) | ||
| 173 | + { | ||
| 174 | + va_end(ap); | ||
| 175 | + goto truncated; | ||
| 176 | + } | ||
| 177 | + CHECK_LIMIT(1); | ||
| 178 | + *p++ = 0; | ||
| 179 | break; | ||
| 180 | |||
| 181 | case 't': | ||
| 182 | usval = va_arg(ap, int); | ||
| 183 | + CHECK_LIMIT(usval); | ||
| 184 | sval = va_arg(ap, char *); | ||
| 185 | if (usval != 0) | ||
| 186 | memcpy(p, sval, usval); | ||
| 187 | @@ -1141,20 +1169,24 @@ int add_resource_record(struct dns_heade | ||
| 188 | usval = sval ? strlen(sval) : 0; | ||
| 189 | if (usval > 255) | ||
| 190 | usval = 255; | ||
| 191 | + CHECK_LIMIT(usval + 1); | ||
| 192 | *p++ = (unsigned char)usval; | ||
| 193 | memcpy(p, sval, usval); | ||
| 194 | p += usval; | ||
| 195 | break; | ||
| 196 | } | ||
| 197 | |||
| 198 | +#undef CHECK_LIMIT | ||
| 199 | va_end(ap); /* clean up variable argument pointer */ | ||
| 200 | |||
| 201 | j = p - sav - 2; | ||
| 202 | - PUTSHORT(j, sav); /* Now, store real RDLength */ | ||
| 203 | + /* this has already been checked against limit before */ | ||
| 204 | + PUTSHORT(j, sav); /* Now, store real RDLength */ | ||
| 205 | |||
| 206 | /* check for overflow of buffer */ | ||
| 207 | if (limit && ((unsigned char *)limit - p) < 0) | ||
| 208 | { | ||
| 209 | +truncated: | ||
| 210 | if (truncp) | ||
| 211 | *truncp = 1; | ||
| 212 | return 0; | ||
| 213 | diff -Nurp a/src/rfc2131.c b/src/rfc2131.c | ||
| 214 | --- a/src/rfc2131.c 2016-05-18 16:51:54.000000000 +0200 | ||
| 215 | +++ b/src/rfc2131.c 2017-10-04 09:38:20.449498294 +0200 | ||
| 216 | @@ -2419,10 +2419,10 @@ static void do_options(struct dhcp_conte | ||
| 217 | |||
| 218 | if (fqdn_flags & 0x04) | ||
| 219 | { | ||
| 220 | - p = do_rfc1035_name(p, hostname); | ||
| 221 | + p = do_rfc1035_name(p, hostname, NULL); | ||
| 222 | if (domain) | ||
| 223 | { | ||
| 224 | - p = do_rfc1035_name(p, domain); | ||
| 225 | + p = do_rfc1035_name(p, domain, NULL); | ||
| 226 | *p++ = 0; | ||
| 227 | } | ||
| 228 | } | ||
| 229 | diff -Nurp a/src/rfc3315.c b/src/rfc3315.c | ||
| 230 | --- a/src/rfc3315.c 2016-05-18 16:51:54.000000000 +0200 | ||
| 231 | +++ b/src/rfc3315.c 2017-10-04 09:38:20.449498294 +0200 | ||
| 232 | @@ -1472,10 +1472,10 @@ static struct dhcp_netid *add_options(st | ||
| 233 | if ((p = expand(len + 2))) | ||
| 234 | { | ||
| 235 | *(p++) = state->fqdn_flags; | ||
| 236 | - p = do_rfc1035_name(p, state->hostname); | ||
| 237 | + p = do_rfc1035_name(p, state->hostname, NULL); | ||
| 238 | if (state->send_domain) | ||
| 239 | { | ||
| 240 | - p = do_rfc1035_name(p, state->send_domain); | ||
| 241 | + p = do_rfc1035_name(p, state->send_domain, NULL); | ||
| 242 | *p = 0; | ||
| 243 | } | ||
| 244 | } | ||
| 245 | diff -Nurp a/src/util.c b/src/util.c | ||
| 246 | --- a/src/util.c 2016-05-18 16:51:54.000000000 +0200 | ||
| 247 | +++ b/src/util.c 2017-10-04 09:38:20.453498124 +0200 | ||
| 248 | @@ -218,15 +218,20 @@ char *canonicalise(char *in, int *nomem) | ||
| 249 | return ret; | ||
| 250 | } | ||
| 251 | |||
| 252 | -unsigned char *do_rfc1035_name(unsigned char *p, char *sval) | ||
| 253 | +unsigned char *do_rfc1035_name(unsigned char *p, char *sval, char *limit) | ||
| 254 | { | ||
| 255 | int j; | ||
| 256 | |||
| 257 | while (sval && *sval) | ||
| 258 | { | ||
| 259 | + if (limit && p + 1 > (unsigned char*)limit) | ||
| 260 | + return p; | ||
| 261 | + | ||
| 262 | unsigned char *cp = p++; | ||
| 263 | for (j = 0; *sval && (*sval != '.'); sval++, j++) | ||
| 264 | { | ||
| 265 | + if (limit && p + 1 > (unsigned char*)limit) | ||
| 266 | + return p; | ||
| 267 | #ifdef HAVE_DNSSEC | ||
| 268 | if (option_bool(OPT_DNSSEC_VALID) && *sval == NAME_ESCAPE) | ||
| 269 | *p++ = (*(++sval))-1; | ||
diff --git a/recipes-networking/dnsmasq/dnsmasq/0002-CVE-2017-14491.patch b/recipes-networking/dnsmasq/dnsmasq/0002-CVE-2017-14491.patch deleted file mode 100644 index 6f27667..0000000 --- a/recipes-networking/dnsmasq/dnsmasq/0002-CVE-2017-14491.patch +++ /dev/null | |||
| @@ -1,73 +0,0 @@ | |||
| 1 | From 62cb936cb7ad5f219715515ae7d32dd281a5aa1f Mon Sep 17 00:00:00 2001 | ||
| 2 | From: Simon Kelley <simon@thekelleys.org.uk> | ||
| 3 | Date: Tue, 26 Sep 2017 22:00:11 +0100 | ||
| 4 | Subject: [PATCH] Security fix, CVE-2017-14491, DNS heap buffer overflow. | ||
| 5 | |||
| 6 | Further fix to 0549c73b7ea6b22a3c49beb4d432f185a81efcbc | ||
| 7 | Handles case when RR name is not a pointer to the question, | ||
| 8 | only occurs for some auth-mode replies, therefore not | ||
| 9 | detected by fuzzing (?) | ||
| 10 | |||
| 11 | CVE: CVE-2017-14491 | ||
| 12 | Upstream-Status: Backport | ||
| 13 | |||
| 14 | Signed-off-by: Sona Sarmadi <sona.sarmadi@enea.com> | ||
| 15 | --- | ||
| 16 | src/rfc1035.c | 27 +++++++++++++++------------ | ||
| 17 | 1 file changed, 15 insertions(+), 12 deletions(-) | ||
| 18 | |||
| 19 | diff --git a/src/rfc1035.c b/src/rfc1035.c | ||
| 20 | index 27af023..56ab88b 100644 | ||
| 21 | --- a/src/rfc1035.c | ||
| 22 | +++ b/src/rfc1035.c | ||
| 23 | @@ -1086,32 +1086,35 @@ int add_resource_record(struct dns_header *header, char *limit, int *truncp, int | ||
| 24 | |||
| 25 | va_start(ap, format); /* make ap point to 1st unamed argument */ | ||
| 26 | |||
| 27 | - /* nameoffset (1 or 2) + type (2) + class (2) + ttl (4) + 0 (2) */ | ||
| 28 | - CHECK_LIMIT(12); | ||
| 29 | - | ||
| 30 | if (nameoffset > 0) | ||
| 31 | { | ||
| 32 | + CHECK_LIMIT(2); | ||
| 33 | PUTSHORT(nameoffset | 0xc000, p); | ||
| 34 | } | ||
| 35 | else | ||
| 36 | { | ||
| 37 | char *name = va_arg(ap, char *); | ||
| 38 | - if (name) | ||
| 39 | - p = do_rfc1035_name(p, name, limit); | ||
| 40 | - if (!p) | ||
| 41 | - { | ||
| 42 | - va_end(ap); | ||
| 43 | - goto truncated; | ||
| 44 | - } | ||
| 45 | - | ||
| 46 | + if (name && !(p = do_rfc1035_name(p, name, limit))) | ||
| 47 | + { | ||
| 48 | + va_end(ap); | ||
| 49 | + goto truncated; | ||
| 50 | + } | ||
| 51 | + | ||
| 52 | if (nameoffset < 0) | ||
| 53 | { | ||
| 54 | + CHECK_LIMIT(2); | ||
| 55 | PUTSHORT(-nameoffset | 0xc000, p); | ||
| 56 | } | ||
| 57 | else | ||
| 58 | - *p++ = 0; | ||
| 59 | + { | ||
| 60 | + CHECK_LIMIT(1); | ||
| 61 | + *p++ = 0; | ||
| 62 | + } | ||
| 63 | } | ||
| 64 | |||
| 65 | + /* type (2) + class (2) + ttl (4) + rdlen (2) */ | ||
| 66 | + CHECK_LIMIT(10); | ||
| 67 | + | ||
| 68 | PUTSHORT(type, p); | ||
| 69 | PUTSHORT(class, p); | ||
| 70 | PUTLONG(ttl, p); /* TTL */ | ||
| 71 | -- | ||
| 72 | 1.7.10.4 | ||
| 73 | |||
diff --git a/recipes-networking/dnsmasq/dnsmasq/CVE-2017-14492.patch b/recipes-networking/dnsmasq/dnsmasq/CVE-2017-14492.patch deleted file mode 100644 index 5b66944..0000000 --- a/recipes-networking/dnsmasq/dnsmasq/CVE-2017-14492.patch +++ /dev/null | |||
| @@ -1,57 +0,0 @@ | |||
| 1 | From 24036ea507862c7b7898b68289c8130f85599c10 Mon Sep 17 00:00:00 2001 | ||
| 2 | From: Simon Kelley <simon@thekelleys.org.uk> | ||
| 3 | Date: Mon, 25 Sep 2017 18:47:15 +0100 | ||
| 4 | Subject: [PATCH] Security fix, CVE-2017-14492, DHCPv6 RA heap overflow. | ||
| 5 | |||
| 6 | Fix heap overflow in IPv6 router advertisement code. | ||
| 7 | This is a potentially serious security hole, as a | ||
| 8 | crafted RA request can overflow a buffer and crash or | ||
| 9 | control dnsmasq. Attacker must be on the local network. | ||
| 10 | |||
| 11 | CVE: CVE-2017-14492 | ||
| 12 | Upstream-Status: Backport | ||
| 13 | |||
| 14 | Signed-off-by: Sona Sarmadi <sona.sarmadi@enea.com> | ||
| 15 | --- | ||
| 16 | CHANGELOG | 10 +++++++++- | ||
| 17 | src/radv.c | 3 +++ | ||
| 18 | 2 files changed, 12 insertions(+), 1 deletion(-) | ||
| 19 | |||
| 20 | diff --git a/CHANGELOG b/CHANGELOG | ||
| 21 | index a7c2f35..df6c157 100644 | ||
| 22 | --- a/CHANGELOG | ||
| 23 | +++ b/CHANGELOG | ||
| 24 | @@ -35,7 +35,15 @@ version 2.78 | ||
| 25 | and Kevin Hamacher of the Google Security Team for | ||
| 26 | finding this. | ||
| 27 | |||
| 28 | - | ||
| 29 | + Fix heap overflow in IPv6 router advertisement code. | ||
| 30 | + This is a potentially serious security hole, as a | ||
| 31 | + crafted RA request can overflow a buffer and crash or | ||
| 32 | + control dnsmasq. Attacker must be on the local network. | ||
| 33 | + CVE-2017-14492 applies. | ||
| 34 | + Credit to Felix Wilhelm, Fermin J. Serna, Gabriel Campana | ||
| 35 | + and Kevin Hamacher of the Google Security Team for | ||
| 36 | + finding this. | ||
| 37 | + | ||
| 38 | |||
| 39 | version 2.77 | ||
| 40 | Generate an error when configured with a CNAME loop, | ||
| 41 | diff --git a/src/radv.c b/src/radv.c | ||
| 42 | index 1032189..9b7e52c 100644 | ||
| 43 | --- a/src/radv.c | ||
| 44 | +++ b/src/radv.c | ||
| 45 | @@ -198,6 +198,9 @@ void icmp6_packet(time_t now) | ||
| 46 | /* look for link-layer address option for logging */ | ||
| 47 | if (sz >= 16 && packet[8] == ICMP6_OPT_SOURCE_MAC && (packet[9] * 8) + 8 <= sz) | ||
| 48 | { | ||
| 49 | + if ((packet[9] * 8 - 2) * 3 - 1 >= MAXDNAME) { | ||
| 50 | + return; | ||
| 51 | + } | ||
| 52 | print_mac(daemon->namebuff, &packet[10], (packet[9] * 8) - 2); | ||
| 53 | mac = daemon->namebuff; | ||
| 54 | } | ||
| 55 | -- | ||
| 56 | 1.7.10.4 | ||
| 57 | |||
diff --git a/recipes-networking/dnsmasq/dnsmasq/CVE-2017-14493.patch b/recipes-networking/dnsmasq/dnsmasq/CVE-2017-14493.patch deleted file mode 100644 index fedb825..0000000 --- a/recipes-networking/dnsmasq/dnsmasq/CVE-2017-14493.patch +++ /dev/null | |||
| @@ -1,55 +0,0 @@ | |||
| 1 | From 3d4ff1ba8419546490b464418223132529514033 Mon Sep 17 00:00:00 2001 | ||
| 2 | From: Simon Kelley <simon@thekelleys.org.uk> | ||
| 3 | Date: Mon, 25 Sep 2017 18:52:50 +0100 | ||
| 4 | Subject: [PATCH] Security fix, CVE-2017-14493, DHCPv6 - Stack buffer | ||
| 5 | overflow. | ||
| 6 | |||
| 7 | Fix stack overflow in DHCPv6 code. An attacker who can send | ||
| 8 | a DHCPv6 request to dnsmasq can overflow the stack frame and | ||
| 9 | crash or control dnsmasq. | ||
| 10 | |||
| 11 | CVE: CVE-2017-14493 | ||
| 12 | Upstream-Status: Backport | ||
| 13 | |||
| 14 | Signed-off-by: Sona Sarmadi <sona.sarmadi@enea.com> | ||
| 15 | --- | ||
| 16 | CHANGELOG | 8 ++++++++ | ||
| 17 | src/rfc3315.c | 3 +++ | ||
| 18 | 2 files changed, 11 insertions(+) | ||
| 19 | |||
| 20 | diff --git a/CHANGELOG b/CHANGELOG | ||
| 21 | index df6c157..c48378f 100644 | ||
| 22 | --- a/CHANGELOG | ||
| 23 | +++ b/CHANGELOG | ||
| 24 | @@ -43,6 +43,14 @@ version 2.78 | ||
| 25 | Credit to Felix Wilhelm, Fermin J. Serna, Gabriel Campana | ||
| 26 | and Kevin Hamacher of the Google Security Team for | ||
| 27 | finding this. | ||
| 28 | + | ||
| 29 | + Fix stack overflow in DHCPv6 code. An attacker who can send | ||
| 30 | + a DHCPv6 request to dnsmasq can overflow the stack frame and | ||
| 31 | + crash or control dnsmasq. | ||
| 32 | + CVE-2017-14493 applies. | ||
| 33 | + Credit to Felix Wilhelm, Fermin J. Serna, Gabriel Campana | ||
| 34 | + and Kevin Hamacher of the Google Security Team for | ||
| 35 | + finding this. | ||
| 36 | |||
| 37 | |||
| 38 | version 2.77 | ||
| 39 | diff --git a/src/rfc3315.c b/src/rfc3315.c | ||
| 40 | index 1687931..920907c 100644 | ||
| 41 | --- a/src/rfc3315.c | ||
| 42 | +++ b/src/rfc3315.c | ||
| 43 | @@ -206,6 +206,9 @@ static int dhcp6_maybe_relay(struct state *state, void *inbuff, size_t sz, | ||
| 44 | /* RFC-6939 */ | ||
| 45 | if ((opt = opt6_find(opts, end, OPTION6_CLIENT_MAC, 3))) | ||
| 46 | { | ||
| 47 | + if (opt6_len(opt) - 2 > DHCP_CHADDR_MAX) { | ||
| 48 | + return 0; | ||
| 49 | + } | ||
| 50 | state->mac_type = opt6_uint(opt, 0, 2); | ||
| 51 | state->mac_len = opt6_len(opt) - 2; | ||
| 52 | memcpy(&state->mac[0], opt6_ptr(opt, 2), state->mac_len); | ||
| 53 | -- | ||
| 54 | 1.7.10.4 | ||
| 55 | |||
diff --git a/recipes-networking/dnsmasq/dnsmasq/CVE-2017-14494.patch b/recipes-networking/dnsmasq/dnsmasq/CVE-2017-14494.patch deleted file mode 100644 index d32f713..0000000 --- a/recipes-networking/dnsmasq/dnsmasq/CVE-2017-14494.patch +++ /dev/null | |||
| @@ -1,55 +0,0 @@ | |||
| 1 | From 33e3f1029c9ec6c63e430ff51063a6301d4b2262 Mon Sep 17 00:00:00 2001 | ||
| 2 | From: Simon Kelley <simon@thekelleys.org.uk> | ||
| 3 | Date: Mon, 25 Sep 2017 20:05:11 +0100 | ||
| 4 | Subject: [PATCH] Security fix, CVE-2017-14494, Infoleak handling DHCPv6 | ||
| 5 | forwarded requests. | ||
| 6 | |||
| 7 | Fix information leak in DHCPv6. A crafted DHCPv6 packet can | ||
| 8 | cause dnsmasq to forward memory from outside the packet | ||
| 9 | buffer to a DHCPv6 server when acting as a relay. | ||
| 10 | |||
| 11 | CVE: CVE-2017-14494 | ||
| 12 | Upstream-Status: Backport | ||
| 13 | |||
| 14 | Signed-off-by: Sona Sarmadi <sona.sarmadi@enea.com> | ||
| 15 | --- | ||
| 16 | CHANGELOG | 8 ++++++++ | ||
| 17 | src/rfc3315.c | 3 +++ | ||
| 18 | 2 files changed, 11 insertions(+) | ||
| 19 | |||
| 20 | diff --git a/CHANGELOG b/CHANGELOG | ||
| 21 | index c48378f..d1cc074 100644 | ||
| 22 | --- a/CHANGELOG | ||
| 23 | +++ b/CHANGELOG | ||
| 24 | @@ -51,6 +51,14 @@ version 2.78 | ||
| 25 | Credit to Felix Wilhelm, Fermin J. Serna, Gabriel Campana | ||
| 26 | and Kevin Hamacher of the Google Security Team for | ||
| 27 | finding this. | ||
| 28 | + | ||
| 29 | + Fix information leak in DHCPv6. A crafted DHCPv6 packet can | ||
| 30 | + cause dnsmasq to forward memory from outside the packet | ||
| 31 | + buffer to a DHCPv6 server when acting as a relay. | ||
| 32 | + CVE-2017-14494 applies. | ||
| 33 | + Credit to Felix Wilhelm, Fermin J. Serna, Gabriel Campana | ||
| 34 | + and Kevin Hamacher of the Google Security Team for | ||
| 35 | + finding this. | ||
| 36 | |||
| 37 | |||
| 38 | version 2.77 | ||
| 39 | diff --git a/src/rfc3315.c b/src/rfc3315.c | ||
| 40 | index 920907c..4ca43e0 100644 | ||
| 41 | --- a/src/rfc3315.c | ||
| 42 | +++ b/src/rfc3315.c | ||
| 43 | @@ -216,6 +216,9 @@ static int dhcp6_maybe_relay(struct state *state, void *inbuff, size_t sz, | ||
| 44 | |||
| 45 | for (opt = opts; opt; opt = opt6_next(opt, end)) | ||
| 46 | { | ||
| 47 | + if (opt6_ptr(opt, 0) + opt6_len(opt) >= end) { | ||
| 48 | + return 0; | ||
| 49 | + } | ||
| 50 | int o = new_opt6(opt6_type(opt)); | ||
| 51 | if (opt6_type(opt) == OPTION6_RELAY_MSG) | ||
| 52 | { | ||
| 53 | -- | ||
| 54 | 1.7.10.4 | ||
| 55 | |||
diff --git a/recipes-networking/dnsmasq/dnsmasq/CVE-2017-14495.patch b/recipes-networking/dnsmasq/dnsmasq/CVE-2017-14495.patch deleted file mode 100644 index ba176a8..0000000 --- a/recipes-networking/dnsmasq/dnsmasq/CVE-2017-14495.patch +++ /dev/null | |||
| @@ -1,69 +0,0 @@ | |||
| 1 | From 51eadb692a5123b9838e5a68ecace3ac579a3a45 Mon Sep 17 00:00:00 2001 | ||
| 2 | From: Simon Kelley <simon@thekelleys.org.uk> | ||
| 3 | Date: Mon, 25 Sep 2017 20:16:50 +0100 | ||
| 4 | Subject: [PATCH] Security fix, CVE-2017-14495, OOM in DNS response creation. | ||
| 5 | |||
| 6 | Fix out-of-memory Dos vulnerability. An attacker which can | ||
| 7 | send malicious DNS queries to dnsmasq can trigger memory | ||
| 8 | allocations in the add_pseudoheader function | ||
| 9 | The allocated memory is never freed which leads to a DoS | ||
| 10 | through memory exhaustion. dnsmasq is vulnerable only | ||
| 11 | if one of the following option is specified: | ||
| 12 | --add-mac, --add-cpe-id or --add-subnet. | ||
| 13 | |||
| 14 | CVE: CVE-2017-14495 | ||
| 15 | Upstream-Status: Backport | ||
| 16 | |||
| 17 | Signed-off-by: Sona Sarmadi <sona.sarmadi@enea.com> | ||
| 18 | --- | ||
| 19 | CHANGELOG | 12 ++++++++++++ | ||
| 20 | src/edns0.c | 8 +++++++- | ||
| 21 | 2 files changed, 19 insertions(+), 1 deletion(-) | ||
| 22 | |||
| 23 | diff --git a/CHANGELOG b/CHANGELOG | ||
| 24 | index 8fe00ed..9523329 100644 | ||
| 25 | --- a/CHANGELOG | ||
| 26 | +++ b/CHANGELOG | ||
| 27 | @@ -70,6 +70,18 @@ version 2.78 | ||
| 28 | Credit to Felix Wilhelm, Fermin J. Serna, Gabriel Campana | ||
| 29 | and Kevin Hamacher of the Google Security Team for | ||
| 30 | finding this. | ||
| 31 | + | ||
| 32 | + Fix out-of-memory Dos vulnerability. An attacker which can | ||
| 33 | + send malicious DNS queries to dnsmasq can trigger memory | ||
| 34 | + allocations in the add_pseudoheader function | ||
| 35 | + The allocated memory is never freed which leads to a DoS | ||
| 36 | + through memory exhaustion. dnsmasq is vulnerable only | ||
| 37 | + if one of the following option is specified: | ||
| 38 | + --add-mac, --add-cpe-id or --add-subnet. | ||
| 39 | + CVE-2017-14495 applies. | ||
| 40 | + Credit to Felix Wilhelm, Fermin J. Serna, Gabriel Campana | ||
| 41 | + and Kevin Hamacher of the Google Security Team for | ||
| 42 | + finding this. | ||
| 43 | |||
| 44 | |||
| 45 | version 2.77 | ||
| 46 | diff --git a/src/edns0.c b/src/edns0.c | ||
| 47 | index 95b74ee..89b2692 100644 | ||
| 48 | --- a/src/edns0.c | ||
| 49 | +++ b/src/edns0.c | ||
| 50 | @@ -192,9 +192,15 @@ size_t add_pseudoheader(struct dns_header *header, size_t plen, unsigned char *l | ||
| 51 | !(p = skip_section(p, | ||
| 52 | ntohs(header->ancount) + ntohs(header->nscount) + ntohs(header->arcount), | ||
| 53 | header, plen))) | ||
| 54 | + { | ||
| 55 | + free(buff); | ||
| 56 | return plen; | ||
| 57 | + } | ||
| 58 | if (p + 11 > limit) | ||
| 59 | - return plen; /* Too big */ | ||
| 60 | + { | ||
| 61 | + free(buff); | ||
| 62 | + return plen; /* Too big */ | ||
| 63 | + } | ||
| 64 | *p++ = 0; /* empty name */ | ||
| 65 | PUTSHORT(T_OPT, p); | ||
| 66 | PUTSHORT(udp_sz, p); /* max packet length, 512 if not given in EDNS0 header */ | ||
| 67 | -- | ||
| 68 | 1.7.10.4 | ||
| 69 | |||
diff --git a/recipes-networking/dnsmasq/dnsmasq/CVE-2017-14496.patch b/recipes-networking/dnsmasq/dnsmasq/CVE-2017-14496.patch deleted file mode 100644 index 333a890..0000000 --- a/recipes-networking/dnsmasq/dnsmasq/CVE-2017-14496.patch +++ /dev/null | |||
| @@ -1,94 +0,0 @@ | |||
| 1 | From 897c113fda0886a28a986cc6ba17bb93bd6cb1c7 Mon Sep 17 00:00:00 2001 | ||
| 2 | From: Simon Kelley <simon@thekelleys.org.uk> | ||
| 3 | Date: Mon, 25 Sep 2017 20:11:58 +0100 | ||
| 4 | Subject: [PATCH] Security fix, CVE-2017-14496, Integer underflow in DNS | ||
| 5 | response creation. | ||
| 6 | |||
| 7 | Fix DoS in DNS. Invalid boundary checks in the | ||
| 8 | add_pseudoheader function allows a memcpy call with negative | ||
| 9 | size An attacker which can send malicious DNS queries | ||
| 10 | to dnsmasq can trigger a DoS remotely. | ||
| 11 | dnsmasq is vulnerable only if one of the following option is | ||
| 12 | specified: --add-mac, --add-cpe-id or --add-subnet. | ||
| 13 | |||
| 14 | CVE: CVE-2017-14496 | ||
| 15 | Upstream-Status: Backport | ||
| 16 | |||
| 17 | Signed-off-by: Sona Sarmadi <sona.sarmadi@enea.com> | ||
| 18 | --- | ||
| 19 | CHANGELOG | 11 +++++++++++ | ||
| 20 | src/edns0.c | 13 ++++++++++++- | ||
| 21 | 2 files changed, 23 insertions(+), 1 deletion(-) | ||
| 22 | |||
| 23 | diff --git a/CHANGELOG b/CHANGELOG | ||
| 24 | index d1cc074..8fe00ed 100644 | ||
| 25 | --- a/CHANGELOG | ||
| 26 | +++ b/CHANGELOG | ||
| 27 | @@ -60,6 +60,17 @@ version 2.78 | ||
| 28 | and Kevin Hamacher of the Google Security Team for | ||
| 29 | finding this. | ||
| 30 | |||
| 31 | + Fix DoS in DNS. Invalid boundary checks in the | ||
| 32 | + add_pseudoheader function allows a memcpy call with negative | ||
| 33 | + size An attacker which can send malicious DNS queries | ||
| 34 | + to dnsmasq can trigger a DoS remotely. | ||
| 35 | + dnsmasq is vulnerable only if one of the following option is | ||
| 36 | + specified: --add-mac, --add-cpe-id or --add-subnet. | ||
| 37 | + CVE-2017-14496 applies. | ||
| 38 | + Credit to Felix Wilhelm, Fermin J. Serna, Gabriel Campana | ||
| 39 | + and Kevin Hamacher of the Google Security Team for | ||
| 40 | + finding this. | ||
| 41 | + | ||
| 42 | |||
| 43 | version 2.77 | ||
| 44 | Generate an error when configured with a CNAME loop, | ||
| 45 | diff --git a/src/edns0.c b/src/edns0.c | ||
| 46 | index f5b798c..95b74ee 100644 | ||
| 47 | --- a/src/edns0.c | ||
| 48 | +++ b/src/edns0.c | ||
| 49 | @@ -144,7 +144,7 @@ size_t add_pseudoheader(struct dns_header *header, size_t plen, unsigned char *l | ||
| 50 | GETSHORT(len, p); | ||
| 51 | |||
| 52 | /* malformed option, delete the whole OPT RR and start again. */ | ||
| 53 | - if (i + len > rdlen) | ||
| 54 | + if (i + 4 + len > rdlen) | ||
| 55 | { | ||
| 56 | rdlen = 0; | ||
| 57 | is_last = 0; | ||
| 58 | @@ -193,6 +193,8 @@ size_t add_pseudoheader(struct dns_header *header, size_t plen, unsigned char *l | ||
| 59 | ntohs(header->ancount) + ntohs(header->nscount) + ntohs(header->arcount), | ||
| 60 | header, plen))) | ||
| 61 | return plen; | ||
| 62 | + if (p + 11 > limit) | ||
| 63 | + return plen; /* Too big */ | ||
| 64 | *p++ = 0; /* empty name */ | ||
| 65 | PUTSHORT(T_OPT, p); | ||
| 66 | PUTSHORT(udp_sz, p); /* max packet length, 512 if not given in EDNS0 header */ | ||
| 67 | @@ -204,6 +206,11 @@ size_t add_pseudoheader(struct dns_header *header, size_t plen, unsigned char *l | ||
| 68 | /* Copy back any options */ | ||
| 69 | if (buff) | ||
| 70 | { | ||
| 71 | + if (p + rdlen > limit) | ||
| 72 | + { | ||
| 73 | + free(buff); | ||
| 74 | + return plen; /* Too big */ | ||
| 75 | + } | ||
| 76 | memcpy(p, buff, rdlen); | ||
| 77 | free(buff); | ||
| 78 | p += rdlen; | ||
| 79 | @@ -220,8 +227,12 @@ size_t add_pseudoheader(struct dns_header *header, size_t plen, unsigned char *l | ||
| 80 | /* Add new option */ | ||
| 81 | if (optno != 0 && replace != 2) | ||
| 82 | { | ||
| 83 | + if (p + 4 > limit) | ||
| 84 | + return plen; /* Too big */ | ||
| 85 | PUTSHORT(optno, p); | ||
| 86 | PUTSHORT(optlen, p); | ||
| 87 | + if (p + optlen > limit) | ||
| 88 | + return plen; /* Too big */ | ||
| 89 | memcpy(p, opt, optlen); | ||
| 90 | p += optlen; | ||
| 91 | PUTSHORT(p - datap, lenp); | ||
| 92 | -- | ||
| 93 | 1.7.10.4 | ||
| 94 | |||
diff --git a/recipes-networking/dnsmasq/dnsmasq_%.bbappend b/recipes-networking/dnsmasq/dnsmasq_%.bbappend deleted file mode 100644 index ee31536..0000000 --- a/recipes-networking/dnsmasq/dnsmasq_%.bbappend +++ /dev/null | |||
| @@ -1,11 +0,0 @@ | |||
| 1 | # look for files in the layer first | ||
| 2 | FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:" | ||
| 3 | |||
| 4 | SRC_URI += "file://0001-CVE-2017-14491.patch \ | ||
| 5 | file://0002-CVE-2017-14491.patch \ | ||
| 6 | file://CVE-2017-14492.patch \ | ||
| 7 | file://CVE-2017-14493.patch \ | ||
| 8 | file://CVE-2017-14494.patch \ | ||
| 9 | file://CVE-2017-14496.patch \ | ||
| 10 | file://CVE-2017-14495.patch \ | ||
| 11 | " | ||
