diff options
Diffstat (limited to 'meta/recipes-connectivity')
38 files changed, 1441 insertions, 3567 deletions
diff --git a/meta/recipes-connectivity/avahi/avahi.inc b/meta/recipes-connectivity/avahi/avahi.inc index 94fe6a16b6..6acedb5412 100644 --- a/meta/recipes-connectivity/avahi/avahi.inc +++ b/meta/recipes-connectivity/avahi/avahi.inc | |||
@@ -77,6 +77,11 @@ do_install() { | |||
77 | rm -rf ${D}${datadir}/dbus-1/interfaces | 77 | rm -rf ${D}${datadir}/dbus-1/interfaces |
78 | test -d ${D}${datadir}/dbus-1 && rmdir --ignore-fail-on-non-empty ${D}${datadir}/dbus-1 | 78 | test -d ${D}${datadir}/dbus-1 && rmdir --ignore-fail-on-non-empty ${D}${datadir}/dbus-1 |
79 | rm -rf ${D}${libdir}/avahi | 79 | rm -rf ${D}${libdir}/avahi |
80 | |||
81 | # Move example service files out of /etc/avahi/services so we don't | ||
82 | # advertise ssh & sftp-ssh by default | ||
83 | install -d ${D}${docdir}/avahi | ||
84 | mv ${D}${sysconfdir}/avahi/services/* ${D}${docdir}/avahi | ||
80 | } | 85 | } |
81 | 86 | ||
82 | PACKAGES =+ "${@bb.utils.contains("PACKAGECONFIG", "libdns_sd", "libavahi-compat-libdnssd", "", d)}" | 87 | PACKAGES =+ "${@bb.utils.contains("PACKAGECONFIG", "libdns_sd", "libavahi-compat-libdnssd", "", d)}" |
diff --git a/meta/recipes-connectivity/bind/bind/0001-bind-fix-CVE-2019-6471.patch b/meta/recipes-connectivity/bind/bind/0001-bind-fix-CVE-2019-6471.patch deleted file mode 100644 index 2fed99e1bb..0000000000 --- a/meta/recipes-connectivity/bind/bind/0001-bind-fix-CVE-2019-6471.patch +++ /dev/null | |||
@@ -1,64 +0,0 @@ | |||
1 | Backport patch to fix CVE-2019-6471. | ||
2 | |||
3 | Ref: | ||
4 | https://security-tracker.debian.org/tracker/CVE-2019-6471 | ||
5 | |||
6 | CVE: CVE-2019-6471 | ||
7 | Upstream-Status: Backport [https://gitlab.isc.org/isc-projects/bind9/commit/3a9c7bb] | ||
8 | |||
9 | Signed-off-by: Kai Kang <kai.kang@windriver.com> | ||
10 | |||
11 | From 3a9c7bb80d4a609b86427406d9dd783199920b5b Mon Sep 17 00:00:00 2001 | ||
12 | From: Mark Andrews <marka@isc.org> | ||
13 | Date: Tue, 19 Mar 2019 14:14:21 +1100 | ||
14 | Subject: [PATCH] move item_out test inside lock in dns_dispatch_getnext() | ||
15 | |||
16 | (cherry picked from commit 60c42f849d520564ed42e5ed0ba46b4b69c07712) | ||
17 | --- | ||
18 | lib/dns/dispatch.c | 12 ++++++++---- | ||
19 | 1 file changed, 8 insertions(+), 4 deletions(-) | ||
20 | |||
21 | diff --git a/lib/dns/dispatch.c b/lib/dns/dispatch.c | ||
22 | index 408beda367..3278db4a07 100644 | ||
23 | --- a/lib/dns/dispatch.c | ||
24 | +++ b/lib/dns/dispatch.c | ||
25 | @@ -134,7 +134,7 @@ struct dns_dispentry { | ||
26 | isc_task_t *task; | ||
27 | isc_taskaction_t action; | ||
28 | void *arg; | ||
29 | - bool item_out; | ||
30 | + bool item_out; | ||
31 | dispsocket_t *dispsocket; | ||
32 | ISC_LIST(dns_dispatchevent_t) items; | ||
33 | ISC_LINK(dns_dispentry_t) link; | ||
34 | @@ -3422,13 +3422,14 @@ dns_dispatch_getnext(dns_dispentry_t *resp, dns_dispatchevent_t **sockevent) { | ||
35 | disp = resp->disp; | ||
36 | REQUIRE(VALID_DISPATCH(disp)); | ||
37 | |||
38 | - REQUIRE(resp->item_out == true); | ||
39 | - resp->item_out = false; | ||
40 | - | ||
41 | ev = *sockevent; | ||
42 | *sockevent = NULL; | ||
43 | |||
44 | LOCK(&disp->lock); | ||
45 | + | ||
46 | + REQUIRE(resp->item_out == true); | ||
47 | + resp->item_out = false; | ||
48 | + | ||
49 | if (ev->buffer.base != NULL) | ||
50 | free_buffer(disp, ev->buffer.base, ev->buffer.length); | ||
51 | free_devent(disp, ev); | ||
52 | @@ -3573,6 +3574,9 @@ dns_dispatch_removeresponse(dns_dispentry_t **resp, | ||
53 | isc_task_send(disp->task[0], &disp->ctlevent); | ||
54 | } | ||
55 | |||
56 | +/* | ||
57 | + * disp must be locked. | ||
58 | + */ | ||
59 | static void | ||
60 | do_cancel(dns_dispatch_t *disp) { | ||
61 | dns_dispatchevent_t *ev; | ||
62 | -- | ||
63 | 2.20.1 | ||
64 | |||
diff --git a/meta/recipes-connectivity/bind/bind/0001-configure.in-remove-useless-L-use_openssl-lib.patch b/meta/recipes-connectivity/bind/bind/0001-configure.in-remove-useless-L-use_openssl-lib.patch index 871bb2a5f6..9d31b98080 100644 --- a/meta/recipes-connectivity/bind/bind/0001-configure.in-remove-useless-L-use_openssl-lib.patch +++ b/meta/recipes-connectivity/bind/bind/0001-configure.in-remove-useless-L-use_openssl-lib.patch | |||
@@ -1,4 +1,4 @@ | |||
1 | From 950867d9fd3f690e271c8c807b6eed144b2935b2 Mon Sep 17 00:00:00 2001 | 1 | From 2325a92f1896a2a7f586611686801b41fbc91b50 Mon Sep 17 00:00:00 2001 |
2 | From: Hongxu Jia <hongxu.jia@windriver.com> | 2 | From: Hongxu Jia <hongxu.jia@windriver.com> |
3 | Date: Mon, 27 Aug 2018 15:00:51 +0800 | 3 | Date: Mon, 27 Aug 2018 15:00:51 +0800 |
4 | Subject: [PATCH] configure.in: remove useless `-L$use_openssl/lib' | 4 | Subject: [PATCH] configure.in: remove useless `-L$use_openssl/lib' |
@@ -10,15 +10,16 @@ and helpful for clean up host build path in isc-config.sh | |||
10 | Upstream-Status: Inappropriate [oe-core specific] | 10 | Upstream-Status: Inappropriate [oe-core specific] |
11 | 11 | ||
12 | Signed-off-by: Hongxu Jia <hongxu.jia@windriver.com> | 12 | Signed-off-by: Hongxu Jia <hongxu.jia@windriver.com> |
13 | |||
13 | --- | 14 | --- |
14 | configure.in | 2 +- | 15 | configure.ac | 2 +- |
15 | 1 file changed, 1 insertion(+), 1 deletion(-) | 16 | 1 file changed, 1 insertion(+), 1 deletion(-) |
16 | 17 | ||
17 | diff --git a/configure.in b/configure.in | 18 | diff --git a/configure.ac b/configure.ac |
18 | index 54efc55..76ac0eb 100644 | 19 | index e85a5c6..2bbfc58 100644 |
19 | --- a/configure.in | 20 | --- a/configure.ac |
20 | +++ b/configure.in | 21 | +++ b/configure.ac |
21 | @@ -1691,7 +1691,7 @@ If you don't want OpenSSL, use --without-openssl]) | 22 | @@ -1631,7 +1631,7 @@ If you don't want OpenSSL, use --without-openssl]) |
22 | fi | 23 | fi |
23 | ;; | 24 | ;; |
24 | *) | 25 | *) |
@@ -27,6 +28,3 @@ index 54efc55..76ac0eb 100644 | |||
27 | ;; | 28 | ;; |
28 | esac | 29 | esac |
29 | fi | 30 | fi |
30 | -- | ||
31 | 2.7.4 | ||
32 | |||
diff --git a/meta/recipes-connectivity/bind/bind/0001-fix-enforcement-of-tcp-clients-v1.patch b/meta/recipes-connectivity/bind/bind/0001-fix-enforcement-of-tcp-clients-v1.patch deleted file mode 100644 index 48ae125f84..0000000000 --- a/meta/recipes-connectivity/bind/bind/0001-fix-enforcement-of-tcp-clients-v1.patch +++ /dev/null | |||
@@ -1,60 +0,0 @@ | |||
1 | Backport patch to fix CVE-2018-5743. | ||
2 | |||
3 | Ref: | ||
4 | https://security-tracker.debian.org/tracker/CVE-2018-5743 | ||
5 | |||
6 | CVE: CVE-2018-5743 | ||
7 | Upstream-Status: Backport [https://gitlab.isc.org/isc-projects/bind9/commit/ec2d50d] | ||
8 | |||
9 | Signed-off-by: Kai Kang <kai.kang@windriver.com> | ||
10 | |||
11 | From ec2d50da8d81814640e28593d912f4b96c7efece Mon Sep 17 00:00:00 2001 | ||
12 | From: =?UTF-8?q?Witold=20Kr=C4=99cicki?= <wpk@isc.org> | ||
13 | Date: Thu, 3 Jan 2019 14:17:43 +0100 | ||
14 | Subject: [PATCH 1/6] fix enforcement of tcp-clients (v1) | ||
15 | |||
16 | tcp-clients settings could be exceeded in some cases by | ||
17 | creating more and more active TCP clients that are over | ||
18 | the set quota limit, which in the end could lead to a | ||
19 | DoS attack by e.g. exhaustion of file descriptors. | ||
20 | |||
21 | If TCP client we're closing went over the quota (so it's | ||
22 | not attached to a quota) mark it as mortal - so that it | ||
23 | will be destroyed and not set up to listen for new | ||
24 | connections - unless it's the last client for a specific | ||
25 | interface. | ||
26 | |||
27 | (cherry picked from commit f97131d21b97381cef72b971b157345c1f9b4115) | ||
28 | (cherry picked from commit 9689ffc485df8f971f0ad81ab8ab1f5389493776) | ||
29 | --- | ||
30 | bin/named/client.c | 13 ++++++++++++- | ||
31 | 1 file changed, 12 insertions(+), 1 deletion(-) | ||
32 | |||
33 | diff --git a/bin/named/client.c b/bin/named/client.c | ||
34 | index d482da7121..0739dd48af 100644 | ||
35 | --- a/bin/named/client.c | ||
36 | +++ b/bin/named/client.c | ||
37 | @@ -421,8 +421,19 @@ exit_check(ns_client_t *client) { | ||
38 | isc_socket_detach(&client->tcpsocket); | ||
39 | } | ||
40 | |||
41 | - if (client->tcpquota != NULL) | ||
42 | + if (client->tcpquota != NULL) { | ||
43 | isc_quota_detach(&client->tcpquota); | ||
44 | + } else { | ||
45 | + /* | ||
46 | + * We went over quota with this client, we don't | ||
47 | + * want to restart listening unless this is the | ||
48 | + * last client on this interface, which is | ||
49 | + * checked later. | ||
50 | + */ | ||
51 | + if (TCP_CLIENT(client)) { | ||
52 | + client->mortal = true; | ||
53 | + } | ||
54 | + } | ||
55 | |||
56 | if (client->timerset) { | ||
57 | (void)isc_timer_reset(client->timer, | ||
58 | -- | ||
59 | 2.20.1 | ||
60 | |||
diff --git a/meta/recipes-connectivity/bind/bind/0001-gen.c-extend-DIRNAMESIZE-from-256-to-512.patch b/meta/recipes-connectivity/bind/bind/0001-gen.c-extend-DIRNAMESIZE-from-256-to-512.patch deleted file mode 100644 index a8d601dcaa..0000000000 --- a/meta/recipes-connectivity/bind/bind/0001-gen.c-extend-DIRNAMESIZE-from-256-to-512.patch +++ /dev/null | |||
@@ -1,22 +0,0 @@ | |||
1 | Upstream-Status: Pending | ||
2 | |||
3 | Subject: gen.c: extend DIRNAMESIZE from 256 to 512 | ||
4 | |||
5 | Signed-off-by: Chen Qi <Qi.Chen@windriver.com> | ||
6 | --- | ||
7 | lib/dns/gen.c | 2 +- | ||
8 | 1 file changed, 1 insertion(+), 1 deletion(-) | ||
9 | |||
10 | Index: bind-9.11.3/lib/dns/gen.c | ||
11 | =================================================================== | ||
12 | --- bind-9.11.3.orig/lib/dns/gen.c | ||
13 | +++ bind-9.11.3/lib/dns/gen.c | ||
14 | @@ -130,7 +130,7 @@ static const char copyright[] = | ||
15 | #define TYPECLASSBUF (TYPECLASSLEN + 1) | ||
16 | #define TYPECLASSFMT "%" STR(TYPECLASSLEN) "[-0-9a-z]_%d" | ||
17 | #define ATTRIBUTESIZE 256 | ||
18 | -#define DIRNAMESIZE 256 | ||
19 | +#define DIRNAMESIZE 512 | ||
20 | |||
21 | static struct cc { | ||
22 | struct cc *next; | ||
diff --git a/meta/recipes-connectivity/bind/bind/0001-lib-dns-gen.c-fix-too-long-error.patch b/meta/recipes-connectivity/bind/bind/0001-lib-dns-gen.c-fix-too-long-error.patch deleted file mode 100644 index 01874a4407..0000000000 --- a/meta/recipes-connectivity/bind/bind/0001-lib-dns-gen.c-fix-too-long-error.patch +++ /dev/null | |||
@@ -1,31 +0,0 @@ | |||
1 | From 5bc3167a8b714ec0c4a3f1c7f3b9411296ec0a23 Mon Sep 17 00:00:00 2001 | ||
2 | From: Robert Yang <liezhi.yang@windriver.com> | ||
3 | Date: Wed, 16 Sep 2015 20:23:47 -0700 | ||
4 | Subject: [PATCH] lib/dns/gen.c: fix too long error | ||
5 | |||
6 | The 512 is a little short when build in deep dir, and cause "too long" | ||
7 | error, use PATH_MAX if defined. | ||
8 | |||
9 | Upstream-Status: Pending | ||
10 | |||
11 | Signed-off-by: Robert Yang <liezhi.yang@windriver.com> | ||
12 | --- | ||
13 | lib/dns/gen.c | 4 ++++ | ||
14 | 1 file changed, 4 insertions(+) | ||
15 | |||
16 | Index: bind-9.11.3/lib/dns/gen.c | ||
17 | =================================================================== | ||
18 | --- bind-9.11.3.orig/lib/dns/gen.c | ||
19 | +++ bind-9.11.3/lib/dns/gen.c | ||
20 | @@ -130,7 +130,11 @@ static const char copyright[] = | ||
21 | #define TYPECLASSBUF (TYPECLASSLEN + 1) | ||
22 | #define TYPECLASSFMT "%" STR(TYPECLASSLEN) "[-0-9a-z]_%d" | ||
23 | #define ATTRIBUTESIZE 256 | ||
24 | +#ifdef PATH_MAX | ||
25 | +#define DIRNAMESIZE PATH_MAX | ||
26 | +#else | ||
27 | #define DIRNAMESIZE 512 | ||
28 | +#endif | ||
29 | |||
30 | static struct cc { | ||
31 | struct cc *next; | ||
diff --git a/meta/recipes-connectivity/bind/bind/0002-tcp-clients-could-still-be-exceeded-v2.patch b/meta/recipes-connectivity/bind/bind/0002-tcp-clients-could-still-be-exceeded-v2.patch deleted file mode 100644 index ca4e8b1a66..0000000000 --- a/meta/recipes-connectivity/bind/bind/0002-tcp-clients-could-still-be-exceeded-v2.patch +++ /dev/null | |||
@@ -1,670 +0,0 @@ | |||
1 | Backport patch to fix CVE-2018-5743. | ||
2 | |||
3 | Ref: | ||
4 | https://security-tracker.debian.org/tracker/CVE-2018-5743 | ||
5 | |||
6 | CVE: CVE-2018-5743 | ||
7 | Upstream-Status: Backport [https://gitlab.isc.org/isc-projects/bind9/commit/719f604] | ||
8 | |||
9 | Signed-off-by: Kai Kang <kai.kang@windriver.com> | ||
10 | |||
11 | From 719f604e3fad5b7479bd14e2fa0ef4413f0a8fdc Mon Sep 17 00:00:00 2001 | ||
12 | From: =?UTF-8?q?Witold=20Kr=C4=99cicki?= <wpk@isc.org> | ||
13 | Date: Fri, 4 Jan 2019 12:50:51 +0100 | ||
14 | Subject: [PATCH 2/6] tcp-clients could still be exceeded (v2) | ||
15 | |||
16 | the TCP client quota could still be ineffective under some | ||
17 | circumstances. this change: | ||
18 | |||
19 | - improves quota accounting to ensure that TCP clients are | ||
20 | properly limited, while still guaranteeing that at least one client | ||
21 | is always available to serve TCP connections on each interface. | ||
22 | - uses more descriptive names and removes one (ntcptarget) that | ||
23 | was no longer needed | ||
24 | - adds comments | ||
25 | |||
26 | (cherry picked from commit 924651f1d5e605cd186d03f4f7340bcc54d77cc2) | ||
27 | (cherry picked from commit 55a7a458e30e47874d34bdf1079eb863a0512396) | ||
28 | --- | ||
29 | bin/named/client.c | 311 ++++++++++++++++++++----- | ||
30 | bin/named/include/named/client.h | 14 +- | ||
31 | bin/named/include/named/interfacemgr.h | 11 +- | ||
32 | bin/named/interfacemgr.c | 8 +- | ||
33 | 4 files changed, 267 insertions(+), 77 deletions(-) | ||
34 | |||
35 | diff --git a/bin/named/client.c b/bin/named/client.c | ||
36 | index 0739dd48af..a7b49a0f71 100644 | ||
37 | --- a/bin/named/client.c | ||
38 | +++ b/bin/named/client.c | ||
39 | @@ -246,10 +246,11 @@ static void ns_client_dumpmessage(ns_client_t *client, const char *reason); | ||
40 | static isc_result_t get_client(ns_clientmgr_t *manager, ns_interface_t *ifp, | ||
41 | dns_dispatch_t *disp, bool tcp); | ||
42 | static isc_result_t get_worker(ns_clientmgr_t *manager, ns_interface_t *ifp, | ||
43 | - isc_socket_t *sock); | ||
44 | + isc_socket_t *sock, ns_client_t *oldclient); | ||
45 | static inline bool | ||
46 | -allowed(isc_netaddr_t *addr, dns_name_t *signer, isc_netaddr_t *ecs_addr, | ||
47 | - uint8_t ecs_addrlen, uint8_t *ecs_scope, dns_acl_t *acl); | ||
48 | +allowed(isc_netaddr_t *addr, dns_name_t *signer, | ||
49 | + isc_netaddr_t *ecs_addr, uint8_t ecs_addrlen, | ||
50 | + uint8_t *ecs_scope, dns_acl_t *acl) | ||
51 | static void compute_cookie(ns_client_t *client, uint32_t when, | ||
52 | uint32_t nonce, const unsigned char *secret, | ||
53 | isc_buffer_t *buf); | ||
54 | @@ -405,8 +406,11 @@ exit_check(ns_client_t *client) { | ||
55 | */ | ||
56 | INSIST(client->recursionquota == NULL); | ||
57 | INSIST(client->newstate <= NS_CLIENTSTATE_READY); | ||
58 | - if (client->nreads > 0) | ||
59 | + | ||
60 | + if (client->nreads > 0) { | ||
61 | dns_tcpmsg_cancelread(&client->tcpmsg); | ||
62 | + } | ||
63 | + | ||
64 | if (client->nreads != 0) { | ||
65 | /* Still waiting for read cancel completion. */ | ||
66 | return (true); | ||
67 | @@ -416,25 +420,58 @@ exit_check(ns_client_t *client) { | ||
68 | dns_tcpmsg_invalidate(&client->tcpmsg); | ||
69 | client->tcpmsg_valid = false; | ||
70 | } | ||
71 | + | ||
72 | if (client->tcpsocket != NULL) { | ||
73 | CTRACE("closetcp"); | ||
74 | isc_socket_detach(&client->tcpsocket); | ||
75 | + | ||
76 | + if (client->tcpactive) { | ||
77 | + LOCK(&client->interface->lock); | ||
78 | + INSIST(client->interface->ntcpactive > 0); | ||
79 | + client->interface->ntcpactive--; | ||
80 | + UNLOCK(&client->interface->lock); | ||
81 | + client->tcpactive = false; | ||
82 | + } | ||
83 | } | ||
84 | |||
85 | if (client->tcpquota != NULL) { | ||
86 | - isc_quota_detach(&client->tcpquota); | ||
87 | - } else { | ||
88 | /* | ||
89 | - * We went over quota with this client, we don't | ||
90 | - * want to restart listening unless this is the | ||
91 | - * last client on this interface, which is | ||
92 | - * checked later. | ||
93 | + * If we are not in a pipeline group, or | ||
94 | + * we are the last client in the group, detach from | ||
95 | + * tcpquota; otherwise, transfer the quota to | ||
96 | + * another client in the same group. | ||
97 | */ | ||
98 | - if (TCP_CLIENT(client)) { | ||
99 | - client->mortal = true; | ||
100 | + if (!ISC_LINK_LINKED(client, glink) || | ||
101 | + (client->glink.next == NULL && | ||
102 | + client->glink.prev == NULL)) | ||
103 | + { | ||
104 | + isc_quota_detach(&client->tcpquota); | ||
105 | + } else if (client->glink.next != NULL) { | ||
106 | + INSIST(client->glink.next->tcpquota == NULL); | ||
107 | + client->glink.next->tcpquota = client->tcpquota; | ||
108 | + client->tcpquota = NULL; | ||
109 | + } else { | ||
110 | + INSIST(client->glink.prev->tcpquota == NULL); | ||
111 | + client->glink.prev->tcpquota = client->tcpquota; | ||
112 | + client->tcpquota = NULL; | ||
113 | } | ||
114 | } | ||
115 | |||
116 | + /* | ||
117 | + * Unlink from pipeline group. | ||
118 | + */ | ||
119 | + if (ISC_LINK_LINKED(client, glink)) { | ||
120 | + if (client->glink.next != NULL) { | ||
121 | + client->glink.next->glink.prev = | ||
122 | + client->glink.prev; | ||
123 | + } | ||
124 | + if (client->glink.prev != NULL) { | ||
125 | + client->glink.prev->glink.next = | ||
126 | + client->glink.next; | ||
127 | + } | ||
128 | + ISC_LINK_INIT(client, glink); | ||
129 | + } | ||
130 | + | ||
131 | if (client->timerset) { | ||
132 | (void)isc_timer_reset(client->timer, | ||
133 | isc_timertype_inactive, | ||
134 | @@ -455,15 +492,16 @@ exit_check(ns_client_t *client) { | ||
135 | * that already. Check whether this client needs to remain | ||
136 | * active and force it to go inactive if not. | ||
137 | * | ||
138 | - * UDP clients go inactive at this point, but TCP clients | ||
139 | - * may remain active if we have fewer active TCP client | ||
140 | - * objects than desired due to an earlier quota exhaustion. | ||
141 | + * UDP clients go inactive at this point, but a TCP client | ||
142 | + * will needs to remain active if no other clients are | ||
143 | + * listening for TCP requests on this interface, to | ||
144 | + * prevent this interface from going nonresponsive. | ||
145 | */ | ||
146 | if (client->mortal && TCP_CLIENT(client) && !ns_g_clienttest) { | ||
147 | LOCK(&client->interface->lock); | ||
148 | - if (client->interface->ntcpcurrent < | ||
149 | - client->interface->ntcptarget) | ||
150 | + if (client->interface->ntcpaccepting == 0) { | ||
151 | client->mortal = false; | ||
152 | + } | ||
153 | UNLOCK(&client->interface->lock); | ||
154 | } | ||
155 | |||
156 | @@ -472,15 +510,17 @@ exit_check(ns_client_t *client) { | ||
157 | * queue for recycling. | ||
158 | */ | ||
159 | if (client->mortal) { | ||
160 | - if (client->newstate > NS_CLIENTSTATE_INACTIVE) | ||
161 | + if (client->newstate > NS_CLIENTSTATE_INACTIVE) { | ||
162 | client->newstate = NS_CLIENTSTATE_INACTIVE; | ||
163 | + } | ||
164 | } | ||
165 | |||
166 | if (NS_CLIENTSTATE_READY == client->newstate) { | ||
167 | if (TCP_CLIENT(client)) { | ||
168 | client_accept(client); | ||
169 | - } else | ||
170 | + } else { | ||
171 | client_udprecv(client); | ||
172 | + } | ||
173 | client->newstate = NS_CLIENTSTATE_MAX; | ||
174 | return (true); | ||
175 | } | ||
176 | @@ -492,41 +532,57 @@ exit_check(ns_client_t *client) { | ||
177 | /* | ||
178 | * We are trying to enter the inactive state. | ||
179 | */ | ||
180 | - if (client->naccepts > 0) | ||
181 | + if (client->naccepts > 0) { | ||
182 | isc_socket_cancel(client->tcplistener, client->task, | ||
183 | ISC_SOCKCANCEL_ACCEPT); | ||
184 | + } | ||
185 | |||
186 | /* Still waiting for accept cancel completion. */ | ||
187 | - if (! (client->naccepts == 0)) | ||
188 | + if (! (client->naccepts == 0)) { | ||
189 | return (true); | ||
190 | + } | ||
191 | |||
192 | /* Accept cancel is complete. */ | ||
193 | - if (client->nrecvs > 0) | ||
194 | + if (client->nrecvs > 0) { | ||
195 | isc_socket_cancel(client->udpsocket, client->task, | ||
196 | ISC_SOCKCANCEL_RECV); | ||
197 | + } | ||
198 | |||
199 | /* Still waiting for recv cancel completion. */ | ||
200 | - if (! (client->nrecvs == 0)) | ||
201 | + if (! (client->nrecvs == 0)) { | ||
202 | return (true); | ||
203 | + } | ||
204 | |||
205 | /* Still waiting for control event to be delivered */ | ||
206 | - if (client->nctls > 0) | ||
207 | + if (client->nctls > 0) { | ||
208 | return (true); | ||
209 | - | ||
210 | - /* Deactivate the client. */ | ||
211 | - if (client->interface) | ||
212 | - ns_interface_detach(&client->interface); | ||
213 | + } | ||
214 | |||
215 | INSIST(client->naccepts == 0); | ||
216 | INSIST(client->recursionquota == NULL); | ||
217 | - if (client->tcplistener != NULL) | ||
218 | + if (client->tcplistener != NULL) { | ||
219 | isc_socket_detach(&client->tcplistener); | ||
220 | |||
221 | - if (client->udpsocket != NULL) | ||
222 | + if (client->tcpactive) { | ||
223 | + LOCK(&client->interface->lock); | ||
224 | + INSIST(client->interface->ntcpactive > 0); | ||
225 | + client->interface->ntcpactive--; | ||
226 | + UNLOCK(&client->interface->lock); | ||
227 | + client->tcpactive = false; | ||
228 | + } | ||
229 | + } | ||
230 | + if (client->udpsocket != NULL) { | ||
231 | isc_socket_detach(&client->udpsocket); | ||
232 | + } | ||
233 | |||
234 | - if (client->dispatch != NULL) | ||
235 | + /* Deactivate the client. */ | ||
236 | + if (client->interface != NULL) { | ||
237 | + ns_interface_detach(&client->interface); | ||
238 | + } | ||
239 | + | ||
240 | + if (client->dispatch != NULL) { | ||
241 | dns_dispatch_detach(&client->dispatch); | ||
242 | + } | ||
243 | |||
244 | client->attributes = 0; | ||
245 | client->mortal = false; | ||
246 | @@ -551,10 +607,13 @@ exit_check(ns_client_t *client) { | ||
247 | client->newstate = NS_CLIENTSTATE_MAX; | ||
248 | if (!ns_g_clienttest && manager != NULL && | ||
249 | !manager->exiting) | ||
250 | + { | ||
251 | ISC_QUEUE_PUSH(manager->inactive, client, | ||
252 | ilink); | ||
253 | - if (client->needshutdown) | ||
254 | + } | ||
255 | + if (client->needshutdown) { | ||
256 | isc_task_shutdown(client->task); | ||
257 | + } | ||
258 | return (true); | ||
259 | } | ||
260 | } | ||
261 | @@ -675,7 +734,6 @@ client_start(isc_task_t *task, isc_event_t *event) { | ||
262 | } | ||
263 | } | ||
264 | |||
265 | - | ||
266 | /*% | ||
267 | * The client's task has received a shutdown event. | ||
268 | */ | ||
269 | @@ -2507,17 +2565,12 @@ client_request(isc_task_t *task, isc_event_t *event) { | ||
270 | /* | ||
271 | * Pipeline TCP query processing. | ||
272 | */ | ||
273 | - if (client->message->opcode != dns_opcode_query) | ||
274 | + if (client->message->opcode != dns_opcode_query) { | ||
275 | client->pipelined = false; | ||
276 | + } | ||
277 | if (TCP_CLIENT(client) && client->pipelined) { | ||
278 | - result = isc_quota_reserve(&ns_g_server->tcpquota); | ||
279 | - if (result == ISC_R_SUCCESS) | ||
280 | - result = ns_client_replace(client); | ||
281 | + result = ns_client_replace(client); | ||
282 | if (result != ISC_R_SUCCESS) { | ||
283 | - ns_client_log(client, NS_LOGCATEGORY_CLIENT, | ||
284 | - NS_LOGMODULE_CLIENT, ISC_LOG_WARNING, | ||
285 | - "no more TCP clients(read): %s", | ||
286 | - isc_result_totext(result)); | ||
287 | client->pipelined = false; | ||
288 | } | ||
289 | } | ||
290 | @@ -3087,6 +3140,7 @@ client_create(ns_clientmgr_t *manager, ns_client_t **clientp) { | ||
291 | client->filter_aaaa = dns_aaaa_ok; | ||
292 | #endif | ||
293 | client->needshutdown = ns_g_clienttest; | ||
294 | + client->tcpactive = false; | ||
295 | |||
296 | ISC_EVENT_INIT(&client->ctlevent, sizeof(client->ctlevent), 0, NULL, | ||
297 | NS_EVENT_CLIENTCONTROL, client_start, client, client, | ||
298 | @@ -3100,6 +3154,7 @@ client_create(ns_clientmgr_t *manager, ns_client_t **clientp) { | ||
299 | client->formerrcache.id = 0; | ||
300 | ISC_LINK_INIT(client, link); | ||
301 | ISC_LINK_INIT(client, rlink); | ||
302 | + ISC_LINK_INIT(client, glink); | ||
303 | ISC_QLINK_INIT(client, ilink); | ||
304 | client->keytag = NULL; | ||
305 | client->keytag_len = 0; | ||
306 | @@ -3193,12 +3248,19 @@ client_newconn(isc_task_t *task, isc_event_t *event) { | ||
307 | |||
308 | INSIST(client->state == NS_CLIENTSTATE_READY); | ||
309 | |||
310 | + /* | ||
311 | + * The accept() was successful and we're now establishing a new | ||
312 | + * connection. We need to make note of it in the client and | ||
313 | + * interface objects so client objects can do the right thing | ||
314 | + * when going inactive in exit_check() (see comments in | ||
315 | + * client_accept() for details). | ||
316 | + */ | ||
317 | INSIST(client->naccepts == 1); | ||
318 | client->naccepts--; | ||
319 | |||
320 | LOCK(&client->interface->lock); | ||
321 | - INSIST(client->interface->ntcpcurrent > 0); | ||
322 | - client->interface->ntcpcurrent--; | ||
323 | + INSIST(client->interface->ntcpaccepting > 0); | ||
324 | + client->interface->ntcpaccepting--; | ||
325 | UNLOCK(&client->interface->lock); | ||
326 | |||
327 | /* | ||
328 | @@ -3232,6 +3294,9 @@ client_newconn(isc_task_t *task, isc_event_t *event) { | ||
329 | NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(3), | ||
330 | "accept failed: %s", | ||
331 | isc_result_totext(nevent->result)); | ||
332 | + if (client->tcpquota != NULL) { | ||
333 | + isc_quota_detach(&client->tcpquota); | ||
334 | + } | ||
335 | } | ||
336 | |||
337 | if (exit_check(client)) | ||
338 | @@ -3270,18 +3335,12 @@ client_newconn(isc_task_t *task, isc_event_t *event) { | ||
339 | * deny service to legitimate TCP clients. | ||
340 | */ | ||
341 | client->pipelined = false; | ||
342 | - result = isc_quota_attach(&ns_g_server->tcpquota, | ||
343 | - &client->tcpquota); | ||
344 | - if (result == ISC_R_SUCCESS) | ||
345 | - result = ns_client_replace(client); | ||
346 | - if (result != ISC_R_SUCCESS) { | ||
347 | - ns_client_log(client, NS_LOGCATEGORY_CLIENT, | ||
348 | - NS_LOGMODULE_CLIENT, ISC_LOG_WARNING, | ||
349 | - "no more TCP clients(accept): %s", | ||
350 | - isc_result_totext(result)); | ||
351 | - } else if (ns_g_server->keepresporder == NULL || | ||
352 | - !allowed(&netaddr, NULL, NULL, 0, NULL, | ||
353 | - ns_g_server->keepresporder)) { | ||
354 | + result = ns_client_replace(client); | ||
355 | + if (result == ISC_R_SUCCESS && | ||
356 | + (client->sctx->keepresporder == NULL || | ||
357 | + !allowed(&netaddr, NULL, NULL, 0, NULL, | ||
358 | + ns_g_server->keepresporder))) | ||
359 | + { | ||
360 | client->pipelined = true; | ||
361 | } | ||
362 | |||
363 | @@ -3298,12 +3357,80 @@ client_accept(ns_client_t *client) { | ||
364 | |||
365 | CTRACE("accept"); | ||
366 | |||
367 | + /* | ||
368 | + * The tcpquota object can only be simultaneously referenced a | ||
369 | + * pre-defined number of times; this is configured by 'tcp-clients' | ||
370 | + * in named.conf. If we can't attach to it here, that means the TCP | ||
371 | + * client quota has been exceeded. | ||
372 | + */ | ||
373 | + result = isc_quota_attach(&client->sctx->tcpquota, | ||
374 | + &client->tcpquota); | ||
375 | + if (result != ISC_R_SUCCESS) { | ||
376 | + bool exit; | ||
377 | + | ||
378 | + ns_client_log(client, NS_LOGCATEGORY_CLIENT, | ||
379 | + NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(1), | ||
380 | + "no more TCP clients: %s", | ||
381 | + isc_result_totext(result)); | ||
382 | + | ||
383 | + /* | ||
384 | + * We have exceeded the system-wide TCP client | ||
385 | + * quota. But, we can't just block this accept | ||
386 | + * in all cases, because if we did, a heavy TCP | ||
387 | + * load on other interfaces might cause this | ||
388 | + * interface to be starved, with no clients able | ||
389 | + * to accept new connections. | ||
390 | + * | ||
391 | + * So, we check here to see if any other client | ||
392 | + * is already servicing TCP queries on this | ||
393 | + * interface (whether accepting, reading, or | ||
394 | + * processing). | ||
395 | + * | ||
396 | + * If so, then it's okay *not* to call | ||
397 | + * accept - we can let this client to go inactive | ||
398 | + * and the other one handle the next connection | ||
399 | + * when it's ready. | ||
400 | + * | ||
401 | + * But if not, then we need to be a little bit | ||
402 | + * flexible about the quota. We allow *one* extra | ||
403 | + * TCP client through, to ensure we're listening on | ||
404 | + * every interface. | ||
405 | + * | ||
406 | + * (Note: In practice this means that the *real* | ||
407 | + * TCP client quota is tcp-clients plus the number | ||
408 | + * of interfaces.) | ||
409 | + */ | ||
410 | + LOCK(&client->interface->lock); | ||
411 | + exit = (client->interface->ntcpactive > 0); | ||
412 | + UNLOCK(&client->interface->lock); | ||
413 | + | ||
414 | + if (exit) { | ||
415 | + client->newstate = NS_CLIENTSTATE_INACTIVE; | ||
416 | + (void)exit_check(client); | ||
417 | + return; | ||
418 | + } | ||
419 | + } | ||
420 | + | ||
421 | + /* | ||
422 | + * By incrementing the interface's ntcpactive counter we signal | ||
423 | + * that there is at least one client servicing TCP queries for the | ||
424 | + * interface. | ||
425 | + * | ||
426 | + * We also make note of the fact in the client itself with the | ||
427 | + * tcpactive flag. This ensures proper accounting by preventing | ||
428 | + * us from accidentally incrementing or decrementing ntcpactive | ||
429 | + * more than once per client object. | ||
430 | + */ | ||
431 | + if (!client->tcpactive) { | ||
432 | + LOCK(&client->interface->lock); | ||
433 | + client->interface->ntcpactive++; | ||
434 | + UNLOCK(&client->interface->lock); | ||
435 | + client->tcpactive = true; | ||
436 | + } | ||
437 | + | ||
438 | result = isc_socket_accept(client->tcplistener, client->task, | ||
439 | client_newconn, client); | ||
440 | if (result != ISC_R_SUCCESS) { | ||
441 | - UNEXPECTED_ERROR(__FILE__, __LINE__, | ||
442 | - "isc_socket_accept() failed: %s", | ||
443 | - isc_result_totext(result)); | ||
444 | /* | ||
445 | * XXXRTH What should we do? We're trying to accept but | ||
446 | * it didn't work. If we just give up, then TCP | ||
447 | @@ -3311,12 +3438,39 @@ client_accept(ns_client_t *client) { | ||
448 | * | ||
449 | * For now, we just go idle. | ||
450 | */ | ||
451 | + UNEXPECTED_ERROR(__FILE__, __LINE__, | ||
452 | + "isc_socket_accept() failed: %s", | ||
453 | + isc_result_totext(result)); | ||
454 | + if (client->tcpquota != NULL) { | ||
455 | + isc_quota_detach(&client->tcpquota); | ||
456 | + } | ||
457 | return; | ||
458 | } | ||
459 | + | ||
460 | + /* | ||
461 | + * The client's 'naccepts' counter indicates that this client has | ||
462 | + * called accept() and is waiting for a new connection. It should | ||
463 | + * never exceed 1. | ||
464 | + */ | ||
465 | INSIST(client->naccepts == 0); | ||
466 | client->naccepts++; | ||
467 | + | ||
468 | + /* | ||
469 | + * The interface's 'ntcpaccepting' counter is incremented when | ||
470 | + * any client calls accept(), and decremented in client_newconn() | ||
471 | + * once the connection is established. | ||
472 | + * | ||
473 | + * When the client object is shutting down after handling a TCP | ||
474 | + * request (see exit_check()), it looks to see whether this value is | ||
475 | + * non-zero. If so, that means another client has already called | ||
476 | + * accept() and is waiting to establish the next connection, which | ||
477 | + * means the first client is free to go inactive. Otherwise, | ||
478 | + * the first client must come back and call accept() again; this | ||
479 | + * guarantees there will always be at least one client listening | ||
480 | + * for new TCP connections on each interface. | ||
481 | + */ | ||
482 | LOCK(&client->interface->lock); | ||
483 | - client->interface->ntcpcurrent++; | ||
484 | + client->interface->ntcpaccepting++; | ||
485 | UNLOCK(&client->interface->lock); | ||
486 | } | ||
487 | |||
488 | @@ -3390,13 +3544,14 @@ ns_client_replace(ns_client_t *client) { | ||
489 | tcp = TCP_CLIENT(client); | ||
490 | if (tcp && client->pipelined) { | ||
491 | result = get_worker(client->manager, client->interface, | ||
492 | - client->tcpsocket); | ||
493 | + client->tcpsocket, client); | ||
494 | } else { | ||
495 | result = get_client(client->manager, client->interface, | ||
496 | client->dispatch, tcp); | ||
497 | } | ||
498 | - if (result != ISC_R_SUCCESS) | ||
499 | + if (result != ISC_R_SUCCESS) { | ||
500 | return (result); | ||
501 | + } | ||
502 | |||
503 | /* | ||
504 | * The responsibility for listening for new requests is hereby | ||
505 | @@ -3585,6 +3740,7 @@ get_client(ns_clientmgr_t *manager, ns_interface_t *ifp, | ||
506 | client->attributes |= NS_CLIENTATTR_TCP; | ||
507 | isc_socket_attach(ifp->tcpsocket, | ||
508 | &client->tcplistener); | ||
509 | + | ||
510 | } else { | ||
511 | isc_socket_t *sock; | ||
512 | |||
513 | @@ -3602,7 +3758,8 @@ get_client(ns_clientmgr_t *manager, ns_interface_t *ifp, | ||
514 | } | ||
515 | |||
516 | static isc_result_t | ||
517 | -get_worker(ns_clientmgr_t *manager, ns_interface_t *ifp, isc_socket_t *sock) | ||
518 | +get_worker(ns_clientmgr_t *manager, ns_interface_t *ifp, isc_socket_t *sock, | ||
519 | + ns_client_t *oldclient) | ||
520 | { | ||
521 | isc_result_t result = ISC_R_SUCCESS; | ||
522 | isc_event_t *ev; | ||
523 | @@ -3610,6 +3767,7 @@ get_worker(ns_clientmgr_t *manager, ns_interface_t *ifp, isc_socket_t *sock) | ||
524 | MTRACE("get worker"); | ||
525 | |||
526 | REQUIRE(manager != NULL); | ||
527 | + REQUIRE(oldclient != NULL); | ||
528 | |||
529 | if (manager->exiting) | ||
530 | return (ISC_R_SHUTTINGDOWN); | ||
531 | @@ -3642,7 +3800,28 @@ get_worker(ns_clientmgr_t *manager, ns_interface_t *ifp, isc_socket_t *sock) | ||
532 | ns_interface_attach(ifp, &client->interface); | ||
533 | client->newstate = client->state = NS_CLIENTSTATE_WORKING; | ||
534 | INSIST(client->recursionquota == NULL); | ||
535 | - client->tcpquota = &ns_g_server->tcpquota; | ||
536 | + | ||
537 | + /* | ||
538 | + * Transfer TCP quota to the new client. | ||
539 | + */ | ||
540 | + INSIST(client->tcpquota == NULL); | ||
541 | + INSIST(oldclient->tcpquota != NULL); | ||
542 | + client->tcpquota = oldclient->tcpquota; | ||
543 | + oldclient->tcpquota = NULL; | ||
544 | + | ||
545 | + /* | ||
546 | + * Link to a pipeline group, creating it if needed. | ||
547 | + */ | ||
548 | + if (!ISC_LINK_LINKED(oldclient, glink)) { | ||
549 | + oldclient->glink.next = NULL; | ||
550 | + oldclient->glink.prev = NULL; | ||
551 | + } | ||
552 | + client->glink.next = oldclient->glink.next; | ||
553 | + client->glink.prev = oldclient; | ||
554 | + if (oldclient->glink.next != NULL) { | ||
555 | + oldclient->glink.next->glink.prev = client; | ||
556 | + } | ||
557 | + oldclient->glink.next = client; | ||
558 | |||
559 | client->dscp = ifp->dscp; | ||
560 | |||
561 | @@ -3656,6 +3835,12 @@ get_worker(ns_clientmgr_t *manager, ns_interface_t *ifp, isc_socket_t *sock) | ||
562 | (void)isc_socket_getpeername(client->tcpsocket, &client->peeraddr); | ||
563 | client->peeraddr_valid = true; | ||
564 | |||
565 | + LOCK(&client->interface->lock); | ||
566 | + client->interface->ntcpactive++; | ||
567 | + UNLOCK(&client->interface->lock); | ||
568 | + | ||
569 | + client->tcpactive = true; | ||
570 | + | ||
571 | INSIST(client->tcpmsg_valid == false); | ||
572 | dns_tcpmsg_init(client->mctx, client->tcpsocket, &client->tcpmsg); | ||
573 | client->tcpmsg_valid = true; | ||
574 | diff --git a/bin/named/include/named/client.h b/bin/named/include/named/client.h | ||
575 | index b23a7b191d..1f7973f9c5 100644 | ||
576 | --- a/bin/named/include/named/client.h | ||
577 | +++ b/bin/named/include/named/client.h | ||
578 | @@ -94,7 +94,8 @@ struct ns_client { | ||
579 | int nupdates; | ||
580 | int nctls; | ||
581 | int references; | ||
582 | - bool needshutdown; /* | ||
583 | + bool tcpactive; | ||
584 | + bool needshutdown; /* | ||
585 | * Used by clienttest to get | ||
586 | * the client to go from | ||
587 | * inactive to free state | ||
588 | @@ -130,9 +131,9 @@ struct ns_client { | ||
589 | isc_stdtime_t now; | ||
590 | isc_time_t tnow; | ||
591 | dns_name_t signername; /*%< [T]SIG key name */ | ||
592 | - dns_name_t * signer; /*%< NULL if not valid sig */ | ||
593 | - bool mortal; /*%< Die after handling request */ | ||
594 | - bool pipelined; /*%< TCP queries not in sequence */ | ||
595 | + dns_name_t *signer; /*%< NULL if not valid sig */ | ||
596 | + bool mortal; /*%< Die after handling request */ | ||
597 | + bool pipelined; /*%< TCP queries not in sequence */ | ||
598 | isc_quota_t *tcpquota; | ||
599 | isc_quota_t *recursionquota; | ||
600 | ns_interface_t *interface; | ||
601 | @@ -143,8 +144,8 @@ struct ns_client { | ||
602 | isc_sockaddr_t destsockaddr; | ||
603 | |||
604 | isc_netaddr_t ecs_addr; /*%< EDNS client subnet */ | ||
605 | - uint8_t ecs_addrlen; | ||
606 | - uint8_t ecs_scope; | ||
607 | + uint8_t ecs_addrlen; | ||
608 | + uint8_t ecs_scope; | ||
609 | |||
610 | struct in6_pktinfo pktinfo; | ||
611 | isc_dscp_t dscp; | ||
612 | @@ -166,6 +167,7 @@ struct ns_client { | ||
613 | |||
614 | ISC_LINK(ns_client_t) link; | ||
615 | ISC_LINK(ns_client_t) rlink; | ||
616 | + ISC_LINK(ns_client_t) glink; | ||
617 | ISC_QLINK(ns_client_t) ilink; | ||
618 | unsigned char cookie[8]; | ||
619 | uint32_t expire; | ||
620 | diff --git a/bin/named/include/named/interfacemgr.h b/bin/named/include/named/interfacemgr.h | ||
621 | index 7d1883e1e8..61b08826a6 100644 | ||
622 | --- a/bin/named/include/named/interfacemgr.h | ||
623 | +++ b/bin/named/include/named/interfacemgr.h | ||
624 | @@ -77,9 +77,14 @@ struct ns_interface { | ||
625 | /*%< UDP dispatchers. */ | ||
626 | isc_socket_t * tcpsocket; /*%< TCP socket. */ | ||
627 | isc_dscp_t dscp; /*%< "listen-on" DSCP value */ | ||
628 | - int ntcptarget; /*%< Desired number of concurrent | ||
629 | - TCP accepts */ | ||
630 | - int ntcpcurrent; /*%< Current ditto, locked */ | ||
631 | + int ntcpaccepting; /*%< Number of clients | ||
632 | + ready to accept new | ||
633 | + TCP connections on this | ||
634 | + interface */ | ||
635 | + int ntcpactive; /*%< Number of clients | ||
636 | + servicing TCP queries | ||
637 | + (whether accepting or | ||
638 | + connected) */ | ||
639 | int nudpdispatch; /*%< Number of UDP dispatches */ | ||
640 | ns_clientmgr_t * clientmgr; /*%< Client manager. */ | ||
641 | ISC_LINK(ns_interface_t) link; | ||
642 | diff --git a/bin/named/interfacemgr.c b/bin/named/interfacemgr.c | ||
643 | index 419927bf54..955096ef47 100644 | ||
644 | --- a/bin/named/interfacemgr.c | ||
645 | +++ b/bin/named/interfacemgr.c | ||
646 | @@ -386,8 +386,8 @@ ns_interface_create(ns_interfacemgr_t *mgr, isc_sockaddr_t *addr, | ||
647 | * connections will be handled in parallel even though there is | ||
648 | * only one client initially. | ||
649 | */ | ||
650 | - ifp->ntcptarget = 1; | ||
651 | - ifp->ntcpcurrent = 0; | ||
652 | + ifp->ntcpaccepting = 0; | ||
653 | + ifp->ntcpactive = 0; | ||
654 | ifp->nudpdispatch = 0; | ||
655 | |||
656 | ifp->dscp = -1; | ||
657 | @@ -522,9 +522,7 @@ ns_interface_accepttcp(ns_interface_t *ifp) { | ||
658 | */ | ||
659 | (void)isc_socket_filter(ifp->tcpsocket, "dataready"); | ||
660 | |||
661 | - result = ns_clientmgr_createclients(ifp->clientmgr, | ||
662 | - ifp->ntcptarget, ifp, | ||
663 | - true); | ||
664 | + result = ns_clientmgr_createclients(ifp->clientmgr, 1, ifp, true); | ||
665 | if (result != ISC_R_SUCCESS) { | ||
666 | UNEXPECTED_ERROR(__FILE__, __LINE__, | ||
667 | "TCP ns_clientmgr_createclients(): %s", | ||
668 | -- | ||
669 | 2.20.1 | ||
670 | |||
diff --git a/meta/recipes-connectivity/bind/bind/0003-use-reference-counter-for-pipeline-groups-v3.patch b/meta/recipes-connectivity/bind/bind/0003-use-reference-counter-for-pipeline-groups-v3.patch deleted file mode 100644 index 032cfb8c44..0000000000 --- a/meta/recipes-connectivity/bind/bind/0003-use-reference-counter-for-pipeline-groups-v3.patch +++ /dev/null | |||
@@ -1,278 +0,0 @@ | |||
1 | Backport patch to fix CVE-2018-5743. | ||
2 | |||
3 | Ref: | ||
4 | https://security-tracker.debian.org/tracker/CVE-2018-5743 | ||
5 | |||
6 | CVE: CVE-2018-5743 | ||
7 | Upstream-Status: Backport [https://gitlab.isc.org/isc-projects/bind9/commit/366b4e1] | ||
8 | |||
9 | Signed-off-by: Kai Kang <kai.kang@windriver.com> | ||
10 | |||
11 | From 366b4e1ede8aed690e981e07137cb1cb77879c36 Mon Sep 17 00:00:00 2001 | ||
12 | From: =?UTF-8?q?Micha=C5=82=20K=C4=99pie=C5=84?= <michal@isc.org> | ||
13 | Date: Thu, 17 Jan 2019 15:53:38 +0100 | ||
14 | Subject: [PATCH 3/6] use reference counter for pipeline groups (v3) | ||
15 | |||
16 | Track pipeline groups using a shared reference counter | ||
17 | instead of a linked list. | ||
18 | |||
19 | (cherry picked from commit 513afd33eb17d5dc41a3f0d2d38204ef8c5f6f91) | ||
20 | (cherry picked from commit 9446629b730c59c4215f08d37fbaf810282fbccb) | ||
21 | --- | ||
22 | bin/named/client.c | 171 ++++++++++++++++++++----------- | ||
23 | bin/named/include/named/client.h | 2 +- | ||
24 | 2 files changed, 110 insertions(+), 63 deletions(-) | ||
25 | |||
26 | diff --git a/bin/named/client.c b/bin/named/client.c | ||
27 | index a7b49a0f71..277656cef0 100644 | ||
28 | --- a/bin/named/client.c | ||
29 | +++ b/bin/named/client.c | ||
30 | @@ -299,6 +299,75 @@ ns_client_settimeout(ns_client_t *client, unsigned int seconds) { | ||
31 | } | ||
32 | } | ||
33 | |||
34 | +/*% | ||
35 | + * Allocate a reference counter that will track the number of client structures | ||
36 | + * using the TCP connection that 'client' called accept() for. This counter | ||
37 | + * will be shared between all client structures associated with this TCP | ||
38 | + * connection. | ||
39 | + */ | ||
40 | +static void | ||
41 | +pipeline_init(ns_client_t *client) { | ||
42 | + isc_refcount_t *refs; | ||
43 | + | ||
44 | + REQUIRE(client->pipeline_refs == NULL); | ||
45 | + | ||
46 | + /* | ||
47 | + * A global memory context is used for the allocation as different | ||
48 | + * client structures may have different memory contexts assigned and a | ||
49 | + * reference counter allocated here might need to be freed by a | ||
50 | + * different client. The performance impact caused by memory context | ||
51 | + * contention here is expected to be negligible, given that this code | ||
52 | + * is only executed for TCP connections. | ||
53 | + */ | ||
54 | + refs = isc_mem_allocate(client->sctx->mctx, sizeof(*refs)); | ||
55 | + isc_refcount_init(refs, 1); | ||
56 | + client->pipeline_refs = refs; | ||
57 | +} | ||
58 | + | ||
59 | +/*% | ||
60 | + * Increase the count of client structures using the TCP connection that | ||
61 | + * 'source' is associated with and put a pointer to that count in 'target', | ||
62 | + * thus associating it with the same TCP connection. | ||
63 | + */ | ||
64 | +static void | ||
65 | +pipeline_attach(ns_client_t *source, ns_client_t *target) { | ||
66 | + int old_refs; | ||
67 | + | ||
68 | + REQUIRE(source->pipeline_refs != NULL); | ||
69 | + REQUIRE(target->pipeline_refs == NULL); | ||
70 | + | ||
71 | + old_refs = isc_refcount_increment(source->pipeline_refs); | ||
72 | + INSIST(old_refs > 0); | ||
73 | + target->pipeline_refs = source->pipeline_refs; | ||
74 | +} | ||
75 | + | ||
76 | +/*% | ||
77 | + * Decrease the count of client structures using the TCP connection that | ||
78 | + * 'client' is associated with. If this is the last client using this TCP | ||
79 | + * connection, free the reference counter and return true; otherwise, return | ||
80 | + * false. | ||
81 | + */ | ||
82 | +static bool | ||
83 | +pipeline_detach(ns_client_t *client) { | ||
84 | + isc_refcount_t *refs; | ||
85 | + int old_refs; | ||
86 | + | ||
87 | + REQUIRE(client->pipeline_refs != NULL); | ||
88 | + | ||
89 | + refs = client->pipeline_refs; | ||
90 | + client->pipeline_refs = NULL; | ||
91 | + | ||
92 | + old_refs = isc_refcount_decrement(refs); | ||
93 | + INSIST(old_refs > 0); | ||
94 | + | ||
95 | + if (old_refs == 1) { | ||
96 | + isc_mem_free(client->sctx->mctx, refs); | ||
97 | + return (true); | ||
98 | + } | ||
99 | + | ||
100 | + return (false); | ||
101 | +} | ||
102 | + | ||
103 | /*% | ||
104 | * Check for a deactivation or shutdown request and take appropriate | ||
105 | * action. Returns true if either is in progress; in this case | ||
106 | @@ -421,6 +490,40 @@ exit_check(ns_client_t *client) { | ||
107 | client->tcpmsg_valid = false; | ||
108 | } | ||
109 | |||
110 | + if (client->tcpquota != NULL) { | ||
111 | + if (client->pipeline_refs == NULL || | ||
112 | + pipeline_detach(client)) | ||
113 | + { | ||
114 | + /* | ||
115 | + * Only detach from the TCP client quota if | ||
116 | + * there are no more client structures using | ||
117 | + * this TCP connection. | ||
118 | + * | ||
119 | + * Note that we check 'pipeline_refs' and not | ||
120 | + * 'pipelined' because in some cases (e.g. | ||
121 | + * after receiving a request with an opcode | ||
122 | + * different than QUERY) 'pipelined' is set to | ||
123 | + * false after the reference counter gets | ||
124 | + * allocated in pipeline_init() and we must | ||
125 | + * still drop our reference as failing to do so | ||
126 | + * would prevent the reference counter itself | ||
127 | + * from being freed. | ||
128 | + */ | ||
129 | + isc_quota_detach(&client->tcpquota); | ||
130 | + } else { | ||
131 | + /* | ||
132 | + * There are other client structures using this | ||
133 | + * TCP connection, so we cannot detach from the | ||
134 | + * TCP client quota to prevent excess TCP | ||
135 | + * connections from being accepted. However, | ||
136 | + * this client structure might later be reused | ||
137 | + * for accepting new connections and thus must | ||
138 | + * have its 'tcpquota' field set to NULL. | ||
139 | + */ | ||
140 | + client->tcpquota = NULL; | ||
141 | + } | ||
142 | + } | ||
143 | + | ||
144 | if (client->tcpsocket != NULL) { | ||
145 | CTRACE("closetcp"); | ||
146 | isc_socket_detach(&client->tcpsocket); | ||
147 | @@ -434,44 +537,6 @@ exit_check(ns_client_t *client) { | ||
148 | } | ||
149 | } | ||
150 | |||
151 | - if (client->tcpquota != NULL) { | ||
152 | - /* | ||
153 | - * If we are not in a pipeline group, or | ||
154 | - * we are the last client in the group, detach from | ||
155 | - * tcpquota; otherwise, transfer the quota to | ||
156 | - * another client in the same group. | ||
157 | - */ | ||
158 | - if (!ISC_LINK_LINKED(client, glink) || | ||
159 | - (client->glink.next == NULL && | ||
160 | - client->glink.prev == NULL)) | ||
161 | - { | ||
162 | - isc_quota_detach(&client->tcpquota); | ||
163 | - } else if (client->glink.next != NULL) { | ||
164 | - INSIST(client->glink.next->tcpquota == NULL); | ||
165 | - client->glink.next->tcpquota = client->tcpquota; | ||
166 | - client->tcpquota = NULL; | ||
167 | - } else { | ||
168 | - INSIST(client->glink.prev->tcpquota == NULL); | ||
169 | - client->glink.prev->tcpquota = client->tcpquota; | ||
170 | - client->tcpquota = NULL; | ||
171 | - } | ||
172 | - } | ||
173 | - | ||
174 | - /* | ||
175 | - * Unlink from pipeline group. | ||
176 | - */ | ||
177 | - if (ISC_LINK_LINKED(client, glink)) { | ||
178 | - if (client->glink.next != NULL) { | ||
179 | - client->glink.next->glink.prev = | ||
180 | - client->glink.prev; | ||
181 | - } | ||
182 | - if (client->glink.prev != NULL) { | ||
183 | - client->glink.prev->glink.next = | ||
184 | - client->glink.next; | ||
185 | - } | ||
186 | - ISC_LINK_INIT(client, glink); | ||
187 | - } | ||
188 | - | ||
189 | if (client->timerset) { | ||
190 | (void)isc_timer_reset(client->timer, | ||
191 | isc_timertype_inactive, | ||
192 | @@ -3130,6 +3195,7 @@ client_create(ns_clientmgr_t *manager, ns_client_t **clientp) { | ||
193 | dns_name_init(&client->signername, NULL); | ||
194 | client->mortal = false; | ||
195 | client->pipelined = false; | ||
196 | + client->pipeline_refs = NULL; | ||
197 | client->tcpquota = NULL; | ||
198 | client->recursionquota = NULL; | ||
199 | client->interface = NULL; | ||
200 | @@ -3154,7 +3220,6 @@ client_create(ns_clientmgr_t *manager, ns_client_t **clientp) { | ||
201 | client->formerrcache.id = 0; | ||
202 | ISC_LINK_INIT(client, link); | ||
203 | ISC_LINK_INIT(client, rlink); | ||
204 | - ISC_LINK_INIT(client, glink); | ||
205 | ISC_QLINK_INIT(client, ilink); | ||
206 | client->keytag = NULL; | ||
207 | client->keytag_len = 0; | ||
208 | @@ -3341,6 +3406,7 @@ client_newconn(isc_task_t *task, isc_event_t *event) { | ||
209 | !allowed(&netaddr, NULL, NULL, 0, NULL, | ||
210 | ns_g_server->keepresporder))) | ||
211 | { | ||
212 | + pipeline_init(client); | ||
213 | client->pipelined = true; | ||
214 | } | ||
215 | |||
216 | @@ -3800,35 +3866,16 @@ get_worker(ns_clientmgr_t *manager, ns_interface_t *ifp, isc_socket_t *sock, | ||
217 | ns_interface_attach(ifp, &client->interface); | ||
218 | client->newstate = client->state = NS_CLIENTSTATE_WORKING; | ||
219 | INSIST(client->recursionquota == NULL); | ||
220 | - | ||
221 | - /* | ||
222 | - * Transfer TCP quota to the new client. | ||
223 | - */ | ||
224 | - INSIST(client->tcpquota == NULL); | ||
225 | - INSIST(oldclient->tcpquota != NULL); | ||
226 | - client->tcpquota = oldclient->tcpquota; | ||
227 | - oldclient->tcpquota = NULL; | ||
228 | - | ||
229 | - /* | ||
230 | - * Link to a pipeline group, creating it if needed. | ||
231 | - */ | ||
232 | - if (!ISC_LINK_LINKED(oldclient, glink)) { | ||
233 | - oldclient->glink.next = NULL; | ||
234 | - oldclient->glink.prev = NULL; | ||
235 | - } | ||
236 | - client->glink.next = oldclient->glink.next; | ||
237 | - client->glink.prev = oldclient; | ||
238 | - if (oldclient->glink.next != NULL) { | ||
239 | - oldclient->glink.next->glink.prev = client; | ||
240 | - } | ||
241 | - oldclient->glink.next = client; | ||
242 | + client->tcpquota = &client->sctx->tcpquota; | ||
243 | |||
244 | client->dscp = ifp->dscp; | ||
245 | |||
246 | client->attributes |= NS_CLIENTATTR_TCP; | ||
247 | - client->pipelined = true; | ||
248 | client->mortal = true; | ||
249 | |||
250 | + pipeline_attach(oldclient, client); | ||
251 | + client->pipelined = true; | ||
252 | + | ||
253 | isc_socket_attach(ifp->tcpsocket, &client->tcplistener); | ||
254 | isc_socket_attach(sock, &client->tcpsocket); | ||
255 | isc_socket_setname(client->tcpsocket, "worker-tcp", NULL); | ||
256 | diff --git a/bin/named/include/named/client.h b/bin/named/include/named/client.h | ||
257 | index 1f7973f9c5..aeed9ccdda 100644 | ||
258 | --- a/bin/named/include/named/client.h | ||
259 | +++ b/bin/named/include/named/client.h | ||
260 | @@ -134,6 +134,7 @@ struct ns_client { | ||
261 | dns_name_t *signer; /*%< NULL if not valid sig */ | ||
262 | bool mortal; /*%< Die after handling request */ | ||
263 | bool pipelined; /*%< TCP queries not in sequence */ | ||
264 | + isc_refcount_t *pipeline_refs; | ||
265 | isc_quota_t *tcpquota; | ||
266 | isc_quota_t *recursionquota; | ||
267 | ns_interface_t *interface; | ||
268 | @@ -167,7 +168,6 @@ struct ns_client { | ||
269 | |||
270 | ISC_LINK(ns_client_t) link; | ||
271 | ISC_LINK(ns_client_t) rlink; | ||
272 | - ISC_LINK(ns_client_t) glink; | ||
273 | ISC_QLINK(ns_client_t) ilink; | ||
274 | unsigned char cookie[8]; | ||
275 | uint32_t expire; | ||
276 | -- | ||
277 | 2.20.1 | ||
278 | |||
diff --git a/meta/recipes-connectivity/bind/bind/0004-better-tcpquota-accounting-and-client-mortality-chec.patch b/meta/recipes-connectivity/bind/bind/0004-better-tcpquota-accounting-and-client-mortality-chec.patch deleted file mode 100644 index 034ab13303..0000000000 --- a/meta/recipes-connectivity/bind/bind/0004-better-tcpquota-accounting-and-client-mortality-chec.patch +++ /dev/null | |||
@@ -1,512 +0,0 @@ | |||
1 | Backport patch to fix CVE-2018-5743. | ||
2 | |||
3 | Ref: | ||
4 | https://security-tracker.debian.org/tracker/CVE-2018-5743 | ||
5 | |||
6 | CVE: CVE-2018-5743 | ||
7 | Upstream-Status: Backport [https://gitlab.isc.org/isc-projects/bind9/commit/2ab8a08] | ||
8 | |||
9 | Signed-off-by: Kai Kang <kai.kang@windriver.com> | ||
10 | |||
11 | From 2ab8a085b3c666f28f1f9229bd6ecb59915b26c3 Mon Sep 17 00:00:00 2001 | ||
12 | From: Evan Hunt <each@isc.org> | ||
13 | Date: Fri, 5 Apr 2019 16:12:18 -0700 | ||
14 | Subject: [PATCH 4/6] better tcpquota accounting and client mortality checks | ||
15 | |||
16 | - ensure that tcpactive is cleaned up correctly when accept() fails. | ||
17 | - set 'client->tcpattached' when the client is attached to the tcpquota. | ||
18 | carry this value on to new clients sharing the same pipeline group. | ||
19 | don't call isc_quota_detach() on the tcpquota unless tcpattached is | ||
20 | set. this way clients that were allowed to accept TCP connections | ||
21 | despite being over quota (and therefore, were never attached to the | ||
22 | quota) will not inadvertently detach from it and mess up the | ||
23 | accounting. | ||
24 | - simplify the code for tcpquota disconnection by using a new function | ||
25 | tcpquota_disconnect(). | ||
26 | - before deciding whether to reject a new connection due to quota | ||
27 | exhaustion, check to see whether there are at least two active | ||
28 | clients. previously, this was "at least one", but that could be | ||
29 | insufficient if there was one other client in READING state (waiting | ||
30 | for messages on an open connection) but none in READY (listening | ||
31 | for new connections). | ||
32 | - before deciding whether a TCP client object can to go inactive, we | ||
33 | must ensure there are enough other clients to maintain service | ||
34 | afterward -- both accepting new connections and reading/processing new | ||
35 | queries. A TCP client can't shut down unless at least one | ||
36 | client is accepting new connections and (in the case of pipelined | ||
37 | clients) at least one additional client is waiting to read. | ||
38 | |||
39 | (cherry picked from commit c7394738b2445c16f728a88394864dd61baad900) | ||
40 | (cherry picked from commit e965d5f11d3d0f6d59704e614fceca2093cb1856) | ||
41 | (cherry picked from commit 87d431161450777ea093821212abfb52d51b36e3) | ||
42 | --- | ||
43 | bin/named/client.c | 244 +++++++++++++++++++------------ | ||
44 | bin/named/include/named/client.h | 3 +- | ||
45 | 2 files changed, 152 insertions(+), 95 deletions(-) | ||
46 | |||
47 | diff --git a/bin/named/client.c b/bin/named/client.c | ||
48 | index 277656cef0..61e96dd28c 100644 | ||
49 | --- a/bin/named/client.c | ||
50 | +++ b/bin/named/client.c | ||
51 | @@ -244,13 +244,14 @@ static void client_start(isc_task_t *task, isc_event_t *event); | ||
52 | static void client_request(isc_task_t *task, isc_event_t *event); | ||
53 | static void ns_client_dumpmessage(ns_client_t *client, const char *reason); | ||
54 | static isc_result_t get_client(ns_clientmgr_t *manager, ns_interface_t *ifp, | ||
55 | - dns_dispatch_t *disp, bool tcp); | ||
56 | + dns_dispatch_t *disp, ns_client_t *oldclient, | ||
57 | + bool tcp); | ||
58 | static isc_result_t get_worker(ns_clientmgr_t *manager, ns_interface_t *ifp, | ||
59 | isc_socket_t *sock, ns_client_t *oldclient); | ||
60 | static inline bool | ||
61 | allowed(isc_netaddr_t *addr, dns_name_t *signer, | ||
62 | isc_netaddr_t *ecs_addr, uint8_t ecs_addrlen, | ||
63 | - uint8_t *ecs_scope, dns_acl_t *acl) | ||
64 | + uint8_t *ecs_scope, dns_acl_t *acl); | ||
65 | static void compute_cookie(ns_client_t *client, uint32_t when, | ||
66 | uint32_t nonce, const unsigned char *secret, | ||
67 | isc_buffer_t *buf); | ||
68 | @@ -319,7 +320,7 @@ pipeline_init(ns_client_t *client) { | ||
69 | * contention here is expected to be negligible, given that this code | ||
70 | * is only executed for TCP connections. | ||
71 | */ | ||
72 | - refs = isc_mem_allocate(client->sctx->mctx, sizeof(*refs)); | ||
73 | + refs = isc_mem_allocate(ns_g_mctx, sizeof(*refs)); | ||
74 | isc_refcount_init(refs, 1); | ||
75 | client->pipeline_refs = refs; | ||
76 | } | ||
77 | @@ -331,13 +332,13 @@ pipeline_init(ns_client_t *client) { | ||
78 | */ | ||
79 | static void | ||
80 | pipeline_attach(ns_client_t *source, ns_client_t *target) { | ||
81 | - int old_refs; | ||
82 | + int refs; | ||
83 | |||
84 | REQUIRE(source->pipeline_refs != NULL); | ||
85 | REQUIRE(target->pipeline_refs == NULL); | ||
86 | |||
87 | - old_refs = isc_refcount_increment(source->pipeline_refs); | ||
88 | - INSIST(old_refs > 0); | ||
89 | + isc_refcount_increment(source->pipeline_refs, &refs); | ||
90 | + INSIST(refs > 1); | ||
91 | target->pipeline_refs = source->pipeline_refs; | ||
92 | } | ||
93 | |||
94 | @@ -349,25 +350,51 @@ pipeline_attach(ns_client_t *source, ns_client_t *target) { | ||
95 | */ | ||
96 | static bool | ||
97 | pipeline_detach(ns_client_t *client) { | ||
98 | - isc_refcount_t *refs; | ||
99 | - int old_refs; | ||
100 | + isc_refcount_t *refcount; | ||
101 | + int refs; | ||
102 | |||
103 | REQUIRE(client->pipeline_refs != NULL); | ||
104 | |||
105 | - refs = client->pipeline_refs; | ||
106 | + refcount = client->pipeline_refs; | ||
107 | client->pipeline_refs = NULL; | ||
108 | |||
109 | - old_refs = isc_refcount_decrement(refs); | ||
110 | - INSIST(old_refs > 0); | ||
111 | + isc_refcount_decrement(refcount, refs); | ||
112 | |||
113 | - if (old_refs == 1) { | ||
114 | - isc_mem_free(client->sctx->mctx, refs); | ||
115 | + if (refs == 0) { | ||
116 | + isc_mem_free(ns_g_mctx, refs); | ||
117 | return (true); | ||
118 | } | ||
119 | |||
120 | return (false); | ||
121 | } | ||
122 | |||
123 | +/* | ||
124 | + * Detach a client from the TCP client quota if appropriate, and set | ||
125 | + * the quota pointer to NULL. | ||
126 | + * | ||
127 | + * Sometimes when the TCP client quota is exhausted but there are no other | ||
128 | + * clients servicing the interface, a client will be allowed to continue | ||
129 | + * running despite not having been attached to the quota. In this event, | ||
130 | + * the TCP quota was never attached to the client, so when the client (or | ||
131 | + * associated pipeline group) shuts down, the quota must NOT be detached. | ||
132 | + * | ||
133 | + * Otherwise, if the quota pointer is set, it should be detached. If not | ||
134 | + * set at all, we just return without doing anything. | ||
135 | + */ | ||
136 | +static void | ||
137 | +tcpquota_disconnect(ns_client_t *client) { | ||
138 | + if (client->tcpquota == NULL) { | ||
139 | + return; | ||
140 | + } | ||
141 | + | ||
142 | + if (client->tcpattached) { | ||
143 | + isc_quota_detach(&client->tcpquota); | ||
144 | + client->tcpattached = false; | ||
145 | + } else { | ||
146 | + client->tcpquota = NULL; | ||
147 | + } | ||
148 | +} | ||
149 | + | ||
150 | /*% | ||
151 | * Check for a deactivation or shutdown request and take appropriate | ||
152 | * action. Returns true if either is in progress; in this case | ||
153 | @@ -490,38 +517,31 @@ exit_check(ns_client_t *client) { | ||
154 | client->tcpmsg_valid = false; | ||
155 | } | ||
156 | |||
157 | - if (client->tcpquota != NULL) { | ||
158 | - if (client->pipeline_refs == NULL || | ||
159 | - pipeline_detach(client)) | ||
160 | - { | ||
161 | - /* | ||
162 | - * Only detach from the TCP client quota if | ||
163 | - * there are no more client structures using | ||
164 | - * this TCP connection. | ||
165 | - * | ||
166 | - * Note that we check 'pipeline_refs' and not | ||
167 | - * 'pipelined' because in some cases (e.g. | ||
168 | - * after receiving a request with an opcode | ||
169 | - * different than QUERY) 'pipelined' is set to | ||
170 | - * false after the reference counter gets | ||
171 | - * allocated in pipeline_init() and we must | ||
172 | - * still drop our reference as failing to do so | ||
173 | - * would prevent the reference counter itself | ||
174 | - * from being freed. | ||
175 | - */ | ||
176 | - isc_quota_detach(&client->tcpquota); | ||
177 | - } else { | ||
178 | - /* | ||
179 | - * There are other client structures using this | ||
180 | - * TCP connection, so we cannot detach from the | ||
181 | - * TCP client quota to prevent excess TCP | ||
182 | - * connections from being accepted. However, | ||
183 | - * this client structure might later be reused | ||
184 | - * for accepting new connections and thus must | ||
185 | - * have its 'tcpquota' field set to NULL. | ||
186 | - */ | ||
187 | - client->tcpquota = NULL; | ||
188 | - } | ||
189 | + /* | ||
190 | + * Detach from pipeline group and from TCP client quota, | ||
191 | + * if appropriate. | ||
192 | + * | ||
193 | + * - If no pipeline group is active, attempt to | ||
194 | + * detach from the TCP client quota. | ||
195 | + * | ||
196 | + * - If a pipeline group is active, detach from it; | ||
197 | + * if the return code indicates that there no more | ||
198 | + * clients left if this pipeline group, we also detach | ||
199 | + * from the TCP client quota. | ||
200 | + * | ||
201 | + * - Otherwise we don't try to detach, we just set the | ||
202 | + * TCP quota pointer to NULL if it wasn't NULL already. | ||
203 | + * | ||
204 | + * tcpquota_disconnect() will set tcpquota to NULL, either | ||
205 | + * by detaching it or by assignment, depending on the | ||
206 | + * needs of the client. See the comments on that function | ||
207 | + * for further information. | ||
208 | + */ | ||
209 | + if (client->pipeline_refs == NULL || pipeline_detach(client)) { | ||
210 | + tcpquota_disconnect(client); | ||
211 | + } else { | ||
212 | + client->tcpquota = NULL; | ||
213 | + client->tcpattached = false; | ||
214 | } | ||
215 | |||
216 | if (client->tcpsocket != NULL) { | ||
217 | @@ -544,8 +564,6 @@ exit_check(ns_client_t *client) { | ||
218 | client->timerset = false; | ||
219 | } | ||
220 | |||
221 | - client->pipelined = false; | ||
222 | - | ||
223 | client->peeraddr_valid = false; | ||
224 | |||
225 | client->state = NS_CLIENTSTATE_READY; | ||
226 | @@ -558,18 +576,27 @@ exit_check(ns_client_t *client) { | ||
227 | * active and force it to go inactive if not. | ||
228 | * | ||
229 | * UDP clients go inactive at this point, but a TCP client | ||
230 | - * will needs to remain active if no other clients are | ||
231 | - * listening for TCP requests on this interface, to | ||
232 | - * prevent this interface from going nonresponsive. | ||
233 | + * may need to remain active and go into ready state if | ||
234 | + * no other clients are available to listen for TCP | ||
235 | + * requests on this interface or (in the case of pipelined | ||
236 | + * clients) to read for additional messages on the current | ||
237 | + * connection. | ||
238 | */ | ||
239 | if (client->mortal && TCP_CLIENT(client) && !ns_g_clienttest) { | ||
240 | LOCK(&client->interface->lock); | ||
241 | - if (client->interface->ntcpaccepting == 0) { | ||
242 | + if ((client->interface->ntcpaccepting == 0 || | ||
243 | + (client->pipelined && | ||
244 | + client->interface->ntcpactive < 2)) && | ||
245 | + client->newstate != NS_CLIENTSTATE_FREED) | ||
246 | + { | ||
247 | client->mortal = false; | ||
248 | + client->newstate = NS_CLIENTSTATE_READY; | ||
249 | } | ||
250 | UNLOCK(&client->interface->lock); | ||
251 | } | ||
252 | |||
253 | + client->pipelined = false; | ||
254 | + | ||
255 | /* | ||
256 | * We don't need the client; send it to the inactive | ||
257 | * queue for recycling. | ||
258 | @@ -2634,6 +2661,18 @@ client_request(isc_task_t *task, isc_event_t *event) { | ||
259 | client->pipelined = false; | ||
260 | } | ||
261 | if (TCP_CLIENT(client) && client->pipelined) { | ||
262 | + /* | ||
263 | + * We're pipelining. Replace the client; the | ||
264 | + * the replacement can read the TCP socket looking | ||
265 | + * for new messages and this client can process the | ||
266 | + * current message asynchronously. | ||
267 | + * | ||
268 | + * There are now at least three clients using this | ||
269 | + * TCP socket - one accepting new connections, | ||
270 | + * one reading an existing connection to get new | ||
271 | + * messages, and one answering the message already | ||
272 | + * received. | ||
273 | + */ | ||
274 | result = ns_client_replace(client); | ||
275 | if (result != ISC_R_SUCCESS) { | ||
276 | client->pipelined = false; | ||
277 | @@ -3197,6 +3236,7 @@ client_create(ns_clientmgr_t *manager, ns_client_t **clientp) { | ||
278 | client->pipelined = false; | ||
279 | client->pipeline_refs = NULL; | ||
280 | client->tcpquota = NULL; | ||
281 | + client->tcpattached = false; | ||
282 | client->recursionquota = NULL; | ||
283 | client->interface = NULL; | ||
284 | client->peeraddr_valid = false; | ||
285 | @@ -3359,9 +3399,7 @@ client_newconn(isc_task_t *task, isc_event_t *event) { | ||
286 | NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(3), | ||
287 | "accept failed: %s", | ||
288 | isc_result_totext(nevent->result)); | ||
289 | - if (client->tcpquota != NULL) { | ||
290 | - isc_quota_detach(&client->tcpquota); | ||
291 | - } | ||
292 | + tcpquota_disconnect(client); | ||
293 | } | ||
294 | |||
295 | if (exit_check(client)) | ||
296 | @@ -3402,7 +3440,7 @@ client_newconn(isc_task_t *task, isc_event_t *event) { | ||
297 | client->pipelined = false; | ||
298 | result = ns_client_replace(client); | ||
299 | if (result == ISC_R_SUCCESS && | ||
300 | - (client->sctx->keepresporder == NULL || | ||
301 | + (ns_g_server->keepresporder == NULL || | ||
302 | !allowed(&netaddr, NULL, NULL, 0, NULL, | ||
303 | ns_g_server->keepresporder))) | ||
304 | { | ||
305 | @@ -3429,7 +3467,7 @@ client_accept(ns_client_t *client) { | ||
306 | * in named.conf. If we can't attach to it here, that means the TCP | ||
307 | * client quota has been exceeded. | ||
308 | */ | ||
309 | - result = isc_quota_attach(&client->sctx->tcpquota, | ||
310 | + result = isc_quota_attach(&ns_g_server->tcpquota, | ||
311 | &client->tcpquota); | ||
312 | if (result != ISC_R_SUCCESS) { | ||
313 | bool exit; | ||
314 | @@ -3447,27 +3485,27 @@ client_accept(ns_client_t *client) { | ||
315 | * interface to be starved, with no clients able | ||
316 | * to accept new connections. | ||
317 | * | ||
318 | - * So, we check here to see if any other client | ||
319 | - * is already servicing TCP queries on this | ||
320 | + * So, we check here to see if any other clients | ||
321 | + * are already servicing TCP queries on this | ||
322 | * interface (whether accepting, reading, or | ||
323 | - * processing). | ||
324 | - * | ||
325 | - * If so, then it's okay *not* to call | ||
326 | - * accept - we can let this client to go inactive | ||
327 | - * and the other one handle the next connection | ||
328 | - * when it's ready. | ||
329 | + * processing). If there are at least two | ||
330 | + * (one reading and one processing a request) | ||
331 | + * then it's okay *not* to call accept - we | ||
332 | + * can let this client go inactive and another | ||
333 | + * one will resume accepting when it's done. | ||
334 | * | ||
335 | - * But if not, then we need to be a little bit | ||
336 | - * flexible about the quota. We allow *one* extra | ||
337 | - * TCP client through, to ensure we're listening on | ||
338 | - * every interface. | ||
339 | + * If there aren't enough active clients on the | ||
340 | + * interface, then we can be a little bit | ||
341 | + * flexible about the quota. We'll allow *one* | ||
342 | + * extra client through to ensure we're listening | ||
343 | + * on every interface. | ||
344 | * | ||
345 | - * (Note: In practice this means that the *real* | ||
346 | - * TCP client quota is tcp-clients plus the number | ||
347 | - * of interfaces.) | ||
348 | + * (Note: In practice this means that the real | ||
349 | + * TCP client quota is tcp-clients plus the | ||
350 | + * number of listening interfaces plus 2.) | ||
351 | */ | ||
352 | LOCK(&client->interface->lock); | ||
353 | - exit = (client->interface->ntcpactive > 0); | ||
354 | + exit = (client->interface->ntcpactive > 1); | ||
355 | UNLOCK(&client->interface->lock); | ||
356 | |||
357 | if (exit) { | ||
358 | @@ -3475,6 +3513,9 @@ client_accept(ns_client_t *client) { | ||
359 | (void)exit_check(client); | ||
360 | return; | ||
361 | } | ||
362 | + | ||
363 | + } else { | ||
364 | + client->tcpattached = true; | ||
365 | } | ||
366 | |||
367 | /* | ||
368 | @@ -3507,9 +3548,16 @@ client_accept(ns_client_t *client) { | ||
369 | UNEXPECTED_ERROR(__FILE__, __LINE__, | ||
370 | "isc_socket_accept() failed: %s", | ||
371 | isc_result_totext(result)); | ||
372 | - if (client->tcpquota != NULL) { | ||
373 | - isc_quota_detach(&client->tcpquota); | ||
374 | + | ||
375 | + tcpquota_disconnect(client); | ||
376 | + | ||
377 | + if (client->tcpactive) { | ||
378 | + LOCK(&client->interface->lock); | ||
379 | + client->interface->ntcpactive--; | ||
380 | + UNLOCK(&client->interface->lock); | ||
381 | + client->tcpactive = false; | ||
382 | } | ||
383 | + | ||
384 | return; | ||
385 | } | ||
386 | |||
387 | @@ -3527,13 +3575,12 @@ client_accept(ns_client_t *client) { | ||
388 | * once the connection is established. | ||
389 | * | ||
390 | * When the client object is shutting down after handling a TCP | ||
391 | - * request (see exit_check()), it looks to see whether this value is | ||
392 | - * non-zero. If so, that means another client has already called | ||
393 | - * accept() and is waiting to establish the next connection, which | ||
394 | - * means the first client is free to go inactive. Otherwise, | ||
395 | - * the first client must come back and call accept() again; this | ||
396 | - * guarantees there will always be at least one client listening | ||
397 | - * for new TCP connections on each interface. | ||
398 | + * request (see exit_check()), if this value is at least one, that | ||
399 | + * means another client has called accept() and is waiting to | ||
400 | + * establish the next connection. That means the client may be | ||
401 | + * be free to become inactive; otherwise it may need to start | ||
402 | + * listening for connections itself to prevent the interface | ||
403 | + * going dead. | ||
404 | */ | ||
405 | LOCK(&client->interface->lock); | ||
406 | client->interface->ntcpaccepting++; | ||
407 | @@ -3613,19 +3660,19 @@ ns_client_replace(ns_client_t *client) { | ||
408 | client->tcpsocket, client); | ||
409 | } else { | ||
410 | result = get_client(client->manager, client->interface, | ||
411 | - client->dispatch, tcp); | ||
412 | + client->dispatch, client, tcp); | ||
413 | + | ||
414 | + /* | ||
415 | + * The responsibility for listening for new requests is hereby | ||
416 | + * transferred to the new client. Therefore, the old client | ||
417 | + * should refrain from listening for any more requests. | ||
418 | + */ | ||
419 | + client->mortal = true; | ||
420 | } | ||
421 | if (result != ISC_R_SUCCESS) { | ||
422 | return (result); | ||
423 | } | ||
424 | |||
425 | - /* | ||
426 | - * The responsibility for listening for new requests is hereby | ||
427 | - * transferred to the new client. Therefore, the old client | ||
428 | - * should refrain from listening for any more requests. | ||
429 | - */ | ||
430 | - client->mortal = true; | ||
431 | - | ||
432 | return (ISC_R_SUCCESS); | ||
433 | } | ||
434 | |||
435 | @@ -3759,7 +3806,7 @@ ns_clientmgr_destroy(ns_clientmgr_t **managerp) { | ||
436 | |||
437 | static isc_result_t | ||
438 | get_client(ns_clientmgr_t *manager, ns_interface_t *ifp, | ||
439 | - dns_dispatch_t *disp, bool tcp) | ||
440 | + dns_dispatch_t *disp, ns_client_t *oldclient, bool tcp) | ||
441 | { | ||
442 | isc_result_t result = ISC_R_SUCCESS; | ||
443 | isc_event_t *ev; | ||
444 | @@ -3803,6 +3850,16 @@ get_client(ns_clientmgr_t *manager, ns_interface_t *ifp, | ||
445 | client->dscp = ifp->dscp; | ||
446 | |||
447 | if (tcp) { | ||
448 | + client->tcpattached = false; | ||
449 | + if (oldclient != NULL) { | ||
450 | + client->tcpattached = oldclient->tcpattached; | ||
451 | + } | ||
452 | + | ||
453 | + LOCK(&client->interface->lock); | ||
454 | + client->interface->ntcpactive++; | ||
455 | + UNLOCK(&client->interface->lock); | ||
456 | + client->tcpactive = true; | ||
457 | + | ||
458 | client->attributes |= NS_CLIENTATTR_TCP; | ||
459 | isc_socket_attach(ifp->tcpsocket, | ||
460 | &client->tcplistener); | ||
461 | @@ -3866,7 +3923,8 @@ get_worker(ns_clientmgr_t *manager, ns_interface_t *ifp, isc_socket_t *sock, | ||
462 | ns_interface_attach(ifp, &client->interface); | ||
463 | client->newstate = client->state = NS_CLIENTSTATE_WORKING; | ||
464 | INSIST(client->recursionquota == NULL); | ||
465 | - client->tcpquota = &client->sctx->tcpquota; | ||
466 | + client->tcpquota = &ns_g_server->tcpquota; | ||
467 | + client->tcpattached = oldclient->tcpattached; | ||
468 | |||
469 | client->dscp = ifp->dscp; | ||
470 | |||
471 | @@ -3885,7 +3943,6 @@ get_worker(ns_clientmgr_t *manager, ns_interface_t *ifp, isc_socket_t *sock, | ||
472 | LOCK(&client->interface->lock); | ||
473 | client->interface->ntcpactive++; | ||
474 | UNLOCK(&client->interface->lock); | ||
475 | - | ||
476 | client->tcpactive = true; | ||
477 | |||
478 | INSIST(client->tcpmsg_valid == false); | ||
479 | @@ -3913,7 +3970,8 @@ ns_clientmgr_createclients(ns_clientmgr_t *manager, unsigned int n, | ||
480 | MTRACE("createclients"); | ||
481 | |||
482 | for (disp = 0; disp < n; disp++) { | ||
483 | - result = get_client(manager, ifp, ifp->udpdispatch[disp], tcp); | ||
484 | + result = get_client(manager, ifp, ifp->udpdispatch[disp], | ||
485 | + NULL, tcp); | ||
486 | if (result != ISC_R_SUCCESS) | ||
487 | break; | ||
488 | } | ||
489 | diff --git a/bin/named/include/named/client.h b/bin/named/include/named/client.h | ||
490 | index aeed9ccdda..e2c40acd28 100644 | ||
491 | --- a/bin/named/include/named/client.h | ||
492 | +++ b/bin/named/include/named/client.h | ||
493 | @@ -9,8 +9,6 @@ | ||
494 | * information regarding copyright ownership. | ||
495 | */ | ||
496 | |||
497 | -/* $Id: client.h,v 1.96 2012/01/31 23:47:31 tbox Exp $ */ | ||
498 | - | ||
499 | #ifndef NAMED_CLIENT_H | ||
500 | #define NAMED_CLIENT_H 1 | ||
501 | |||
502 | @@ -136,6 +134,7 @@ struct ns_client { | ||
503 | bool pipelined; /*%< TCP queries not in sequence */ | ||
504 | isc_refcount_t *pipeline_refs; | ||
505 | isc_quota_t *tcpquota; | ||
506 | + bool tcpattached; | ||
507 | isc_quota_t *recursionquota; | ||
508 | ns_interface_t *interface; | ||
509 | |||
510 | -- | ||
511 | 2.20.1 | ||
512 | |||
diff --git a/meta/recipes-connectivity/bind/bind/0005-refactor-tcpquota-and-pipeline-refs-allow-special-ca.patch b/meta/recipes-connectivity/bind/bind/0005-refactor-tcpquota-and-pipeline-refs-allow-special-ca.patch deleted file mode 100644 index 987e75bc0e..0000000000 --- a/meta/recipes-connectivity/bind/bind/0005-refactor-tcpquota-and-pipeline-refs-allow-special-ca.patch +++ /dev/null | |||
@@ -1,911 +0,0 @@ | |||
1 | Backport patch to fix CVE-2018-5743. | ||
2 | |||
3 | Ref: | ||
4 | https://security-tracker.debian.org/tracker/CVE-2018-5743 | ||
5 | |||
6 | CVE: CVE-2018-5743 | ||
7 | Upstream-Status: Backport [https://gitlab.isc.org/isc-projects/bind9/commit/c47ccf6] | ||
8 | |||
9 | Signed-off-by: Kai Kang <kai.kang@windriver.com> | ||
10 | |||
11 | From c47ccf630f147378568b33e8fdb7b754f228c346 Mon Sep 17 00:00:00 2001 | ||
12 | From: Evan Hunt <each@isc.org> | ||
13 | Date: Fri, 5 Apr 2019 16:26:05 -0700 | ||
14 | Subject: [PATCH 5/6] refactor tcpquota and pipeline refs; allow special-case | ||
15 | overrun in isc_quota | ||
16 | |||
17 | - if the TCP quota has been exceeded but there are no clients listening | ||
18 | for new connections on the interface, we can now force attachment to the | ||
19 | quota using isc_quota_force(), instead of carrying on with the quota not | ||
20 | attached. | ||
21 | - the TCP client quota is now referenced via a reference-counted | ||
22 | 'ns_tcpconn' object, one of which is created whenever a client begins | ||
23 | listening for new connections, and attached to by members of that | ||
24 | client's pipeline group. when the last reference to the tcpconn | ||
25 | object is detached, it is freed and the TCP quota slot is released. | ||
26 | - reduce code duplication by adding mark_tcp_active() function. | ||
27 | - convert counters to atomic. | ||
28 | |||
29 | (cherry picked from commit 7e8222378ca24f1302a0c1c638565050ab04681b) | ||
30 | (cherry picked from commit 4939451275722bfda490ea86ca13e84f6bc71e46) | ||
31 | (cherry picked from commit 13f7c918b8720d890408f678bd73c20e634539d9) | ||
32 | --- | ||
33 | bin/named/client.c | 444 +++++++++++-------------- | ||
34 | bin/named/include/named/client.h | 12 +- | ||
35 | bin/named/include/named/interfacemgr.h | 6 +- | ||
36 | bin/named/interfacemgr.c | 1 + | ||
37 | lib/isc/include/isc/quota.h | 7 + | ||
38 | lib/isc/quota.c | 33 +- | ||
39 | lib/isc/win32/libisc.def.in | 1 + | ||
40 | 7 files changed, 236 insertions(+), 268 deletions(-) | ||
41 | |||
42 | diff --git a/bin/named/client.c b/bin/named/client.c | ||
43 | index 61e96dd28c..d826ab32bf 100644 | ||
44 | --- a/bin/named/client.c | ||
45 | +++ b/bin/named/client.c | ||
46 | @@ -244,8 +244,7 @@ static void client_start(isc_task_t *task, isc_event_t *event); | ||
47 | static void client_request(isc_task_t *task, isc_event_t *event); | ||
48 | static void ns_client_dumpmessage(ns_client_t *client, const char *reason); | ||
49 | static isc_result_t get_client(ns_clientmgr_t *manager, ns_interface_t *ifp, | ||
50 | - dns_dispatch_t *disp, ns_client_t *oldclient, | ||
51 | - bool tcp); | ||
52 | + dns_dispatch_t *disp, bool tcp); | ||
53 | static isc_result_t get_worker(ns_clientmgr_t *manager, ns_interface_t *ifp, | ||
54 | isc_socket_t *sock, ns_client_t *oldclient); | ||
55 | static inline bool | ||
56 | @@ -301,16 +300,32 @@ ns_client_settimeout(ns_client_t *client, unsigned int seconds) { | ||
57 | } | ||
58 | |||
59 | /*% | ||
60 | - * Allocate a reference counter that will track the number of client structures | ||
61 | - * using the TCP connection that 'client' called accept() for. This counter | ||
62 | - * will be shared between all client structures associated with this TCP | ||
63 | - * connection. | ||
64 | + * Allocate a reference-counted object that will maintain a single pointer to | ||
65 | + * the (also reference-counted) TCP client quota, shared between all the | ||
66 | + * clients processing queries on a single TCP connection, so that all | ||
67 | + * clients sharing the one socket will together consume only one slot in | ||
68 | + * the 'tcp-clients' quota. | ||
69 | */ | ||
70 | -static void | ||
71 | -pipeline_init(ns_client_t *client) { | ||
72 | - isc_refcount_t *refs; | ||
73 | +static isc_result_t | ||
74 | +tcpconn_init(ns_client_t *client, bool force) { | ||
75 | + isc_result_t result; | ||
76 | + isc_quota_t *quota = NULL; | ||
77 | + ns_tcpconn_t *tconn = NULL; | ||
78 | |||
79 | - REQUIRE(client->pipeline_refs == NULL); | ||
80 | + REQUIRE(client->tcpconn == NULL); | ||
81 | + | ||
82 | + /* | ||
83 | + * Try to attach to the quota first, so we won't pointlessly | ||
84 | + * allocate memory for a tcpconn object if we can't get one. | ||
85 | + */ | ||
86 | + if (force) { | ||
87 | + result = isc_quota_force(&ns_g_server->tcpquota, "a); | ||
88 | + } else { | ||
89 | + result = isc_quota_attach(&ns_g_server->tcpquota, "a); | ||
90 | + } | ||
91 | + if (result != ISC_R_SUCCESS) { | ||
92 | + return (result); | ||
93 | + } | ||
94 | |||
95 | /* | ||
96 | * A global memory context is used for the allocation as different | ||
97 | @@ -320,78 +335,80 @@ pipeline_init(ns_client_t *client) { | ||
98 | * contention here is expected to be negligible, given that this code | ||
99 | * is only executed for TCP connections. | ||
100 | */ | ||
101 | - refs = isc_mem_allocate(ns_g_mctx, sizeof(*refs)); | ||
102 | - isc_refcount_init(refs, 1); | ||
103 | - client->pipeline_refs = refs; | ||
104 | + tconn = isc_mem_allocate(ns_g_mctx, sizeof(*tconn)); | ||
105 | + | ||
106 | + isc_refcount_init(&tconn->refs, 1); | ||
107 | + tconn->tcpquota = quota; | ||
108 | + quota = NULL; | ||
109 | + tconn->pipelined = false; | ||
110 | + | ||
111 | + client->tcpconn = tconn; | ||
112 | + | ||
113 | + return (ISC_R_SUCCESS); | ||
114 | } | ||
115 | |||
116 | /*% | ||
117 | - * Increase the count of client structures using the TCP connection that | ||
118 | - * 'source' is associated with and put a pointer to that count in 'target', | ||
119 | - * thus associating it with the same TCP connection. | ||
120 | + * Increase the count of client structures sharing the TCP connection | ||
121 | + * that 'source' is associated with; add a pointer to the same tcpconn | ||
122 | + * to 'target', thus associating it with the same TCP connection. | ||
123 | */ | ||
124 | static void | ||
125 | -pipeline_attach(ns_client_t *source, ns_client_t *target) { | ||
126 | +tcpconn_attach(ns_client_t *source, ns_client_t *target) { | ||
127 | int refs; | ||
128 | |||
129 | - REQUIRE(source->pipeline_refs != NULL); | ||
130 | - REQUIRE(target->pipeline_refs == NULL); | ||
131 | + REQUIRE(source->tcpconn != NULL); | ||
132 | + REQUIRE(target->tcpconn == NULL); | ||
133 | + REQUIRE(source->tcpconn->pipelined); | ||
134 | |||
135 | - isc_refcount_increment(source->pipeline_refs, &refs); | ||
136 | + isc_refcount_increment(&source->tcpconn->refs, &refs); | ||
137 | INSIST(refs > 1); | ||
138 | - target->pipeline_refs = source->pipeline_refs; | ||
139 | + target->tcpconn = source->tcpconn; | ||
140 | } | ||
141 | |||
142 | /*% | ||
143 | - * Decrease the count of client structures using the TCP connection that | ||
144 | + * Decrease the count of client structures sharing the TCP connection that | ||
145 | * 'client' is associated with. If this is the last client using this TCP | ||
146 | - * connection, free the reference counter and return true; otherwise, return | ||
147 | - * false. | ||
148 | + * connection, we detach from the TCP quota and free the tcpconn | ||
149 | + * object. Either way, client->tcpconn is set to NULL. | ||
150 | */ | ||
151 | -static bool | ||
152 | -pipeline_detach(ns_client_t *client) { | ||
153 | - isc_refcount_t *refcount; | ||
154 | +static void | ||
155 | +tcpconn_detach(ns_client_t *client) { | ||
156 | + ns_tcpconn_t *tconn = NULL; | ||
157 | int refs; | ||
158 | |||
159 | - REQUIRE(client->pipeline_refs != NULL); | ||
160 | - | ||
161 | - refcount = client->pipeline_refs; | ||
162 | - client->pipeline_refs = NULL; | ||
163 | + REQUIRE(client->tcpconn != NULL); | ||
164 | |||
165 | - isc_refcount_decrement(refcount, refs); | ||
166 | + tconn = client->tcpconn; | ||
167 | + client->tcpconn = NULL; | ||
168 | |||
169 | + isc_refcount_decrement(&tconn->refs, &refs); | ||
170 | if (refs == 0) { | ||
171 | - isc_mem_free(ns_g_mctx, refs); | ||
172 | - return (true); | ||
173 | + isc_quota_detach(&tconn->tcpquota); | ||
174 | + isc_mem_free(ns_g_mctx, tconn); | ||
175 | } | ||
176 | - | ||
177 | - return (false); | ||
178 | } | ||
179 | |||
180 | -/* | ||
181 | - * Detach a client from the TCP client quota if appropriate, and set | ||
182 | - * the quota pointer to NULL. | ||
183 | - * | ||
184 | - * Sometimes when the TCP client quota is exhausted but there are no other | ||
185 | - * clients servicing the interface, a client will be allowed to continue | ||
186 | - * running despite not having been attached to the quota. In this event, | ||
187 | - * the TCP quota was never attached to the client, so when the client (or | ||
188 | - * associated pipeline group) shuts down, the quota must NOT be detached. | ||
189 | +/*% | ||
190 | + * Mark a client as active and increment the interface's 'ntcpactive' | ||
191 | + * counter, as a signal that there is at least one client servicing | ||
192 | + * TCP queries for the interface. If we reach the TCP client quota at | ||
193 | + * some point, this will be used to determine whether a quota overrun | ||
194 | + * should be permitted. | ||
195 | * | ||
196 | - * Otherwise, if the quota pointer is set, it should be detached. If not | ||
197 | - * set at all, we just return without doing anything. | ||
198 | + * Marking the client active with the 'tcpactive' flag ensures proper | ||
199 | + * accounting, by preventing us from incrementing or decrementing | ||
200 | + * 'ntcpactive' more than once per client. | ||
201 | */ | ||
202 | static void | ||
203 | -tcpquota_disconnect(ns_client_t *client) { | ||
204 | - if (client->tcpquota == NULL) { | ||
205 | - return; | ||
206 | - } | ||
207 | - | ||
208 | - if (client->tcpattached) { | ||
209 | - isc_quota_detach(&client->tcpquota); | ||
210 | - client->tcpattached = false; | ||
211 | - } else { | ||
212 | - client->tcpquota = NULL; | ||
213 | +mark_tcp_active(ns_client_t *client, bool active) { | ||
214 | + if (active && !client->tcpactive) { | ||
215 | + isc_atomic_xadd(&client->interface->ntcpactive, 1); | ||
216 | + client->tcpactive = active; | ||
217 | + } else if (!active && client->tcpactive) { | ||
218 | + uint32_t old = | ||
219 | + isc_atomic_xadd(&client->interface->ntcpactive, -1); | ||
220 | + INSIST(old > 0); | ||
221 | + client->tcpactive = active; | ||
222 | } | ||
223 | } | ||
224 | |||
225 | @@ -484,7 +501,8 @@ exit_check(ns_client_t *client) { | ||
226 | INSIST(client->recursionquota == NULL); | ||
227 | |||
228 | if (NS_CLIENTSTATE_READING == client->newstate) { | ||
229 | - if (!client->pipelined) { | ||
230 | + INSIST(client->tcpconn != NULL); | ||
231 | + if (!client->tcpconn->pipelined) { | ||
232 | client_read(client); | ||
233 | client->newstate = NS_CLIENTSTATE_MAX; | ||
234 | return (true); /* We're done. */ | ||
235 | @@ -507,8 +525,8 @@ exit_check(ns_client_t *client) { | ||
236 | dns_tcpmsg_cancelread(&client->tcpmsg); | ||
237 | } | ||
238 | |||
239 | - if (client->nreads != 0) { | ||
240 | - /* Still waiting for read cancel completion. */ | ||
241 | + /* Still waiting for read cancel completion. */ | ||
242 | + if (client->nreads > 0) { | ||
243 | return (true); | ||
244 | } | ||
245 | |||
246 | @@ -518,43 +536,45 @@ exit_check(ns_client_t *client) { | ||
247 | } | ||
248 | |||
249 | /* | ||
250 | - * Detach from pipeline group and from TCP client quota, | ||
251 | - * if appropriate. | ||
252 | + * Soon the client will be ready to accept a new TCP | ||
253 | + * connection or UDP request, but we may have enough | ||
254 | + * clients doing that already. Check whether this client | ||
255 | + * needs to remain active and allow it go inactive if | ||
256 | + * not. | ||
257 | * | ||
258 | - * - If no pipeline group is active, attempt to | ||
259 | - * detach from the TCP client quota. | ||
260 | + * UDP clients always go inactive at this point, but a TCP | ||
261 | + * client may need to stay active and return to READY | ||
262 | + * state if no other clients are available to listen | ||
263 | + * for TCP requests on this interface. | ||
264 | * | ||
265 | - * - If a pipeline group is active, detach from it; | ||
266 | - * if the return code indicates that there no more | ||
267 | - * clients left if this pipeline group, we also detach | ||
268 | - * from the TCP client quota. | ||
269 | - * | ||
270 | - * - Otherwise we don't try to detach, we just set the | ||
271 | - * TCP quota pointer to NULL if it wasn't NULL already. | ||
272 | - * | ||
273 | - * tcpquota_disconnect() will set tcpquota to NULL, either | ||
274 | - * by detaching it or by assignment, depending on the | ||
275 | - * needs of the client. See the comments on that function | ||
276 | - * for further information. | ||
277 | + * Regardless, if we're going to FREED state, that means | ||
278 | + * the system is shutting down and we don't need to | ||
279 | + * retain clients. | ||
280 | */ | ||
281 | - if (client->pipeline_refs == NULL || pipeline_detach(client)) { | ||
282 | - tcpquota_disconnect(client); | ||
283 | - } else { | ||
284 | - client->tcpquota = NULL; | ||
285 | - client->tcpattached = false; | ||
286 | + if (client->mortal && TCP_CLIENT(client) && | ||
287 | + client->newstate != NS_CLIENTSTATE_FREED && | ||
288 | + !ns_g_clienttest && | ||
289 | + isc_atomic_xadd(&client->interface->ntcpaccepting, 0) == 0) | ||
290 | + { | ||
291 | + /* Nobody else is accepting */ | ||
292 | + client->mortal = false; | ||
293 | + client->newstate = NS_CLIENTSTATE_READY; | ||
294 | + } | ||
295 | + | ||
296 | + /* | ||
297 | + * Detach from TCP connection and TCP client quota, | ||
298 | + * if appropriate. If this is the last reference to | ||
299 | + * the TCP connection in our pipeline group, the | ||
300 | + * TCP quota slot will be released. | ||
301 | + */ | ||
302 | + if (client->tcpconn) { | ||
303 | + tcpconn_detach(client); | ||
304 | } | ||
305 | |||
306 | if (client->tcpsocket != NULL) { | ||
307 | CTRACE("closetcp"); | ||
308 | isc_socket_detach(&client->tcpsocket); | ||
309 | - | ||
310 | - if (client->tcpactive) { | ||
311 | - LOCK(&client->interface->lock); | ||
312 | - INSIST(client->interface->ntcpactive > 0); | ||
313 | - client->interface->ntcpactive--; | ||
314 | - UNLOCK(&client->interface->lock); | ||
315 | - client->tcpactive = false; | ||
316 | - } | ||
317 | + mark_tcp_active(client, false); | ||
318 | } | ||
319 | |||
320 | if (client->timerset) { | ||
321 | @@ -567,35 +587,6 @@ exit_check(ns_client_t *client) { | ||
322 | client->peeraddr_valid = false; | ||
323 | |||
324 | client->state = NS_CLIENTSTATE_READY; | ||
325 | - INSIST(client->recursionquota == NULL); | ||
326 | - | ||
327 | - /* | ||
328 | - * Now the client is ready to accept a new TCP connection | ||
329 | - * or UDP request, but we may have enough clients doing | ||
330 | - * that already. Check whether this client needs to remain | ||
331 | - * active and force it to go inactive if not. | ||
332 | - * | ||
333 | - * UDP clients go inactive at this point, but a TCP client | ||
334 | - * may need to remain active and go into ready state if | ||
335 | - * no other clients are available to listen for TCP | ||
336 | - * requests on this interface or (in the case of pipelined | ||
337 | - * clients) to read for additional messages on the current | ||
338 | - * connection. | ||
339 | - */ | ||
340 | - if (client->mortal && TCP_CLIENT(client) && !ns_g_clienttest) { | ||
341 | - LOCK(&client->interface->lock); | ||
342 | - if ((client->interface->ntcpaccepting == 0 || | ||
343 | - (client->pipelined && | ||
344 | - client->interface->ntcpactive < 2)) && | ||
345 | - client->newstate != NS_CLIENTSTATE_FREED) | ||
346 | - { | ||
347 | - client->mortal = false; | ||
348 | - client->newstate = NS_CLIENTSTATE_READY; | ||
349 | - } | ||
350 | - UNLOCK(&client->interface->lock); | ||
351 | - } | ||
352 | - | ||
353 | - client->pipelined = false; | ||
354 | |||
355 | /* | ||
356 | * We don't need the client; send it to the inactive | ||
357 | @@ -630,7 +621,7 @@ exit_check(ns_client_t *client) { | ||
358 | } | ||
359 | |||
360 | /* Still waiting for accept cancel completion. */ | ||
361 | - if (! (client->naccepts == 0)) { | ||
362 | + if (client->naccepts > 0) { | ||
363 | return (true); | ||
364 | } | ||
365 | |||
366 | @@ -641,7 +632,7 @@ exit_check(ns_client_t *client) { | ||
367 | } | ||
368 | |||
369 | /* Still waiting for recv cancel completion. */ | ||
370 | - if (! (client->nrecvs == 0)) { | ||
371 | + if (client->nrecvs > 0) { | ||
372 | return (true); | ||
373 | } | ||
374 | |||
375 | @@ -654,14 +645,7 @@ exit_check(ns_client_t *client) { | ||
376 | INSIST(client->recursionquota == NULL); | ||
377 | if (client->tcplistener != NULL) { | ||
378 | isc_socket_detach(&client->tcplistener); | ||
379 | - | ||
380 | - if (client->tcpactive) { | ||
381 | - LOCK(&client->interface->lock); | ||
382 | - INSIST(client->interface->ntcpactive > 0); | ||
383 | - client->interface->ntcpactive--; | ||
384 | - UNLOCK(&client->interface->lock); | ||
385 | - client->tcpactive = false; | ||
386 | - } | ||
387 | + mark_tcp_active(client, false); | ||
388 | } | ||
389 | if (client->udpsocket != NULL) { | ||
390 | isc_socket_detach(&client->udpsocket); | ||
391 | @@ -816,7 +800,7 @@ client_start(isc_task_t *task, isc_event_t *event) { | ||
392 | return; | ||
393 | |||
394 | if (TCP_CLIENT(client)) { | ||
395 | - if (client->pipelined) { | ||
396 | + if (client->tcpconn != NULL) { | ||
397 | client_read(client); | ||
398 | } else { | ||
399 | client_accept(client); | ||
400 | @@ -2470,6 +2454,7 @@ client_request(isc_task_t *task, isc_event_t *event) { | ||
401 | client->nrecvs--; | ||
402 | } else { | ||
403 | INSIST(TCP_CLIENT(client)); | ||
404 | + INSIST(client->tcpconn != NULL); | ||
405 | REQUIRE(event->ev_type == DNS_EVENT_TCPMSG); | ||
406 | REQUIRE(event->ev_sender == &client->tcpmsg); | ||
407 | buffer = &client->tcpmsg.buffer; | ||
408 | @@ -2657,17 +2642,19 @@ client_request(isc_task_t *task, isc_event_t *event) { | ||
409 | /* | ||
410 | * Pipeline TCP query processing. | ||
411 | */ | ||
412 | - if (client->message->opcode != dns_opcode_query) { | ||
413 | - client->pipelined = false; | ||
414 | + if (TCP_CLIENT(client) && | ||
415 | + client->message->opcode != dns_opcode_query) | ||
416 | + { | ||
417 | + client->tcpconn->pipelined = false; | ||
418 | } | ||
419 | - if (TCP_CLIENT(client) && client->pipelined) { | ||
420 | + if (TCP_CLIENT(client) && client->tcpconn->pipelined) { | ||
421 | /* | ||
422 | * We're pipelining. Replace the client; the | ||
423 | - * the replacement can read the TCP socket looking | ||
424 | - * for new messages and this client can process the | ||
425 | + * replacement can read the TCP socket looking | ||
426 | + * for new messages and this one can process the | ||
427 | * current message asynchronously. | ||
428 | * | ||
429 | - * There are now at least three clients using this | ||
430 | + * There will now be at least three clients using this | ||
431 | * TCP socket - one accepting new connections, | ||
432 | * one reading an existing connection to get new | ||
433 | * messages, and one answering the message already | ||
434 | @@ -2675,7 +2662,7 @@ client_request(isc_task_t *task, isc_event_t *event) { | ||
435 | */ | ||
436 | result = ns_client_replace(client); | ||
437 | if (result != ISC_R_SUCCESS) { | ||
438 | - client->pipelined = false; | ||
439 | + client->tcpconn->pipelined = false; | ||
440 | } | ||
441 | } | ||
442 | |||
443 | @@ -3233,10 +3220,7 @@ client_create(ns_clientmgr_t *manager, ns_client_t **clientp) { | ||
444 | client->signer = NULL; | ||
445 | dns_name_init(&client->signername, NULL); | ||
446 | client->mortal = false; | ||
447 | - client->pipelined = false; | ||
448 | - client->pipeline_refs = NULL; | ||
449 | - client->tcpquota = NULL; | ||
450 | - client->tcpattached = false; | ||
451 | + client->tcpconn = NULL; | ||
452 | client->recursionquota = NULL; | ||
453 | client->interface = NULL; | ||
454 | client->peeraddr_valid = false; | ||
455 | @@ -3341,9 +3325,10 @@ client_read(ns_client_t *client) { | ||
456 | |||
457 | static void | ||
458 | client_newconn(isc_task_t *task, isc_event_t *event) { | ||
459 | + isc_result_t result; | ||
460 | ns_client_t *client = event->ev_arg; | ||
461 | isc_socket_newconnev_t *nevent = (isc_socket_newconnev_t *)event; | ||
462 | - isc_result_t result; | ||
463 | + uint32_t old; | ||
464 | |||
465 | REQUIRE(event->ev_type == ISC_SOCKEVENT_NEWCONN); | ||
466 | REQUIRE(NS_CLIENT_VALID(client)); | ||
467 | @@ -3363,10 +3348,8 @@ client_newconn(isc_task_t *task, isc_event_t *event) { | ||
468 | INSIST(client->naccepts == 1); | ||
469 | client->naccepts--; | ||
470 | |||
471 | - LOCK(&client->interface->lock); | ||
472 | - INSIST(client->interface->ntcpaccepting > 0); | ||
473 | - client->interface->ntcpaccepting--; | ||
474 | - UNLOCK(&client->interface->lock); | ||
475 | + old = isc_atomic_xadd(&client->interface->ntcpaccepting, -1); | ||
476 | + INSIST(old > 0); | ||
477 | |||
478 | /* | ||
479 | * We must take ownership of the new socket before the exit | ||
480 | @@ -3399,7 +3382,7 @@ client_newconn(isc_task_t *task, isc_event_t *event) { | ||
481 | NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(3), | ||
482 | "accept failed: %s", | ||
483 | isc_result_totext(nevent->result)); | ||
484 | - tcpquota_disconnect(client); | ||
485 | + tcpconn_detach(client); | ||
486 | } | ||
487 | |||
488 | if (exit_check(client)) | ||
489 | @@ -3437,15 +3420,13 @@ client_newconn(isc_task_t *task, isc_event_t *event) { | ||
490 | * telnetting to port 53 (once per CPU) will | ||
491 | * deny service to legitimate TCP clients. | ||
492 | */ | ||
493 | - client->pipelined = false; | ||
494 | result = ns_client_replace(client); | ||
495 | if (result == ISC_R_SUCCESS && | ||
496 | (ns_g_server->keepresporder == NULL || | ||
497 | !allowed(&netaddr, NULL, NULL, 0, NULL, | ||
498 | ns_g_server->keepresporder))) | ||
499 | { | ||
500 | - pipeline_init(client); | ||
501 | - client->pipelined = true; | ||
502 | + client->tcpconn->pipelined = true; | ||
503 | } | ||
504 | |||
505 | client_read(client); | ||
506 | @@ -3462,78 +3443,59 @@ client_accept(ns_client_t *client) { | ||
507 | CTRACE("accept"); | ||
508 | |||
509 | /* | ||
510 | - * The tcpquota object can only be simultaneously referenced a | ||
511 | - * pre-defined number of times; this is configured by 'tcp-clients' | ||
512 | - * in named.conf. If we can't attach to it here, that means the TCP | ||
513 | - * client quota has been exceeded. | ||
514 | + * Set up a new TCP connection. This means try to attach to the | ||
515 | + * TCP client quota (tcp-clients), but fail if we're over quota. | ||
516 | */ | ||
517 | - result = isc_quota_attach(&ns_g_server->tcpquota, | ||
518 | - &client->tcpquota); | ||
519 | + result = tcpconn_init(client, false); | ||
520 | if (result != ISC_R_SUCCESS) { | ||
521 | - bool exit; | ||
522 | + bool exit; | ||
523 | |||
524 | - ns_client_log(client, NS_LOGCATEGORY_CLIENT, | ||
525 | - NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(1), | ||
526 | - "no more TCP clients: %s", | ||
527 | - isc_result_totext(result)); | ||
528 | - | ||
529 | - /* | ||
530 | - * We have exceeded the system-wide TCP client | ||
531 | - * quota. But, we can't just block this accept | ||
532 | - * in all cases, because if we did, a heavy TCP | ||
533 | - * load on other interfaces might cause this | ||
534 | - * interface to be starved, with no clients able | ||
535 | - * to accept new connections. | ||
536 | - * | ||
537 | - * So, we check here to see if any other clients | ||
538 | - * are already servicing TCP queries on this | ||
539 | - * interface (whether accepting, reading, or | ||
540 | - * processing). If there are at least two | ||
541 | - * (one reading and one processing a request) | ||
542 | - * then it's okay *not* to call accept - we | ||
543 | - * can let this client go inactive and another | ||
544 | - * one will resume accepting when it's done. | ||
545 | - * | ||
546 | - * If there aren't enough active clients on the | ||
547 | - * interface, then we can be a little bit | ||
548 | - * flexible about the quota. We'll allow *one* | ||
549 | - * extra client through to ensure we're listening | ||
550 | - * on every interface. | ||
551 | - * | ||
552 | - * (Note: In practice this means that the real | ||
553 | - * TCP client quota is tcp-clients plus the | ||
554 | - * number of listening interfaces plus 2.) | ||
555 | - */ | ||
556 | - LOCK(&client->interface->lock); | ||
557 | - exit = (client->interface->ntcpactive > 1); | ||
558 | - UNLOCK(&client->interface->lock); | ||
559 | + ns_client_log(client, NS_LOGCATEGORY_CLIENT, | ||
560 | + NS_LOGMODULE_CLIENT, ISC_LOG_WARNING, | ||
561 | + "TCP client quota reached: %s", | ||
562 | + isc_result_totext(result)); | ||
563 | |||
564 | - if (exit) { | ||
565 | - client->newstate = NS_CLIENTSTATE_INACTIVE; | ||
566 | - (void)exit_check(client); | ||
567 | - return; | ||
568 | - } | ||
569 | + /* | ||
570 | + * We have exceeded the system-wide TCP client quota. But, | ||
571 | + * we can't just block this accept in all cases, because if | ||
572 | + * we did, a heavy TCP load on other interfaces might cause | ||
573 | + * this interface to be starved, with no clients able to | ||
574 | + * accept new connections. | ||
575 | + * | ||
576 | + * So, we check here to see if any other clients are | ||
577 | + * already servicing TCP queries on this interface (whether | ||
578 | + * accepting, reading, or processing). If we find at least | ||
579 | + * one, then it's okay *not* to call accept - we can let this | ||
580 | + * client go inactive and another will take over when it's | ||
581 | + * done. | ||
582 | + * | ||
583 | + * If there aren't enough active clients on the interface, | ||
584 | + * then we can be a little bit flexible about the quota. | ||
585 | + * We'll allow *one* extra client through to ensure we're | ||
586 | + * listening on every interface; we do this by setting the | ||
587 | + * 'force' option to tcpconn_init(). | ||
588 | + * | ||
589 | + * (Note: In practice this means that the real TCP client | ||
590 | + * quota is tcp-clients plus the number of listening | ||
591 | + * interfaces plus 1.) | ||
592 | + */ | ||
593 | + exit = (isc_atomic_xadd(&client->interface->ntcpactive, 0) > 0); | ||
594 | + if (exit) { | ||
595 | + client->newstate = NS_CLIENTSTATE_INACTIVE; | ||
596 | + (void)exit_check(client); | ||
597 | + return; | ||
598 | + } | ||
599 | |||
600 | - } else { | ||
601 | - client->tcpattached = true; | ||
602 | + result = tcpconn_init(client, true); | ||
603 | + RUNTIME_CHECK(result == ISC_R_SUCCESS); | ||
604 | } | ||
605 | |||
606 | /* | ||
607 | - * By incrementing the interface's ntcpactive counter we signal | ||
608 | - * that there is at least one client servicing TCP queries for the | ||
609 | - * interface. | ||
610 | - * | ||
611 | - * We also make note of the fact in the client itself with the | ||
612 | - * tcpactive flag. This ensures proper accounting by preventing | ||
613 | - * us from accidentally incrementing or decrementing ntcpactive | ||
614 | - * more than once per client object. | ||
615 | + * If this client was set up using get_client() or get_worker(), | ||
616 | + * then TCP is already marked active. However, if it was restarted | ||
617 | + * from exit_check(), it might not be, so we take care of it now. | ||
618 | */ | ||
619 | - if (!client->tcpactive) { | ||
620 | - LOCK(&client->interface->lock); | ||
621 | - client->interface->ntcpactive++; | ||
622 | - UNLOCK(&client->interface->lock); | ||
623 | - client->tcpactive = true; | ||
624 | - } | ||
625 | + mark_tcp_active(client, true); | ||
626 | |||
627 | result = isc_socket_accept(client->tcplistener, client->task, | ||
628 | client_newconn, client); | ||
629 | @@ -3549,15 +3511,8 @@ client_accept(ns_client_t *client) { | ||
630 | "isc_socket_accept() failed: %s", | ||
631 | isc_result_totext(result)); | ||
632 | |||
633 | - tcpquota_disconnect(client); | ||
634 | - | ||
635 | - if (client->tcpactive) { | ||
636 | - LOCK(&client->interface->lock); | ||
637 | - client->interface->ntcpactive--; | ||
638 | - UNLOCK(&client->interface->lock); | ||
639 | - client->tcpactive = false; | ||
640 | - } | ||
641 | - | ||
642 | + tcpconn_detach(client); | ||
643 | + mark_tcp_active(client, false); | ||
644 | return; | ||
645 | } | ||
646 | |||
647 | @@ -3582,9 +3537,7 @@ client_accept(ns_client_t *client) { | ||
648 | * listening for connections itself to prevent the interface | ||
649 | * going dead. | ||
650 | */ | ||
651 | - LOCK(&client->interface->lock); | ||
652 | - client->interface->ntcpaccepting++; | ||
653 | - UNLOCK(&client->interface->lock); | ||
654 | + isc_atomic_xadd(&client->interface->ntcpaccepting, 1); | ||
655 | } | ||
656 | |||
657 | static void | ||
658 | @@ -3655,24 +3608,25 @@ ns_client_replace(ns_client_t *client) { | ||
659 | REQUIRE(client->manager != NULL); | ||
660 | |||
661 | tcp = TCP_CLIENT(client); | ||
662 | - if (tcp && client->pipelined) { | ||
663 | + if (tcp && client->tcpconn != NULL && client->tcpconn->pipelined) { | ||
664 | result = get_worker(client->manager, client->interface, | ||
665 | client->tcpsocket, client); | ||
666 | } else { | ||
667 | result = get_client(client->manager, client->interface, | ||
668 | - client->dispatch, client, tcp); | ||
669 | + client->dispatch, tcp); | ||
670 | |||
671 | - /* | ||
672 | - * The responsibility for listening for new requests is hereby | ||
673 | - * transferred to the new client. Therefore, the old client | ||
674 | - * should refrain from listening for any more requests. | ||
675 | - */ | ||
676 | - client->mortal = true; | ||
677 | } | ||
678 | if (result != ISC_R_SUCCESS) { | ||
679 | return (result); | ||
680 | } | ||
681 | |||
682 | + /* | ||
683 | + * The responsibility for listening for new requests is hereby | ||
684 | + * transferred to the new client. Therefore, the old client | ||
685 | + * should refrain from listening for any more requests. | ||
686 | + */ | ||
687 | + client->mortal = true; | ||
688 | + | ||
689 | return (ISC_R_SUCCESS); | ||
690 | } | ||
691 | |||
692 | @@ -3806,7 +3760,7 @@ ns_clientmgr_destroy(ns_clientmgr_t **managerp) { | ||
693 | |||
694 | static isc_result_t | ||
695 | get_client(ns_clientmgr_t *manager, ns_interface_t *ifp, | ||
696 | - dns_dispatch_t *disp, ns_client_t *oldclient, bool tcp) | ||
697 | + dns_dispatch_t *disp, bool tcp) | ||
698 | { | ||
699 | isc_result_t result = ISC_R_SUCCESS; | ||
700 | isc_event_t *ev; | ||
701 | @@ -3850,15 +3804,7 @@ get_client(ns_clientmgr_t *manager, ns_interface_t *ifp, | ||
702 | client->dscp = ifp->dscp; | ||
703 | |||
704 | if (tcp) { | ||
705 | - client->tcpattached = false; | ||
706 | - if (oldclient != NULL) { | ||
707 | - client->tcpattached = oldclient->tcpattached; | ||
708 | - } | ||
709 | - | ||
710 | - LOCK(&client->interface->lock); | ||
711 | - client->interface->ntcpactive++; | ||
712 | - UNLOCK(&client->interface->lock); | ||
713 | - client->tcpactive = true; | ||
714 | + mark_tcp_active(client, true); | ||
715 | |||
716 | client->attributes |= NS_CLIENTATTR_TCP; | ||
717 | isc_socket_attach(ifp->tcpsocket, | ||
718 | @@ -3923,16 +3869,14 @@ get_worker(ns_clientmgr_t *manager, ns_interface_t *ifp, isc_socket_t *sock, | ||
719 | ns_interface_attach(ifp, &client->interface); | ||
720 | client->newstate = client->state = NS_CLIENTSTATE_WORKING; | ||
721 | INSIST(client->recursionquota == NULL); | ||
722 | - client->tcpquota = &ns_g_server->tcpquota; | ||
723 | - client->tcpattached = oldclient->tcpattached; | ||
724 | |||
725 | client->dscp = ifp->dscp; | ||
726 | |||
727 | client->attributes |= NS_CLIENTATTR_TCP; | ||
728 | client->mortal = true; | ||
729 | |||
730 | - pipeline_attach(oldclient, client); | ||
731 | - client->pipelined = true; | ||
732 | + tcpconn_attach(oldclient, client); | ||
733 | + mark_tcp_active(client, true); | ||
734 | |||
735 | isc_socket_attach(ifp->tcpsocket, &client->tcplistener); | ||
736 | isc_socket_attach(sock, &client->tcpsocket); | ||
737 | @@ -3940,11 +3884,6 @@ get_worker(ns_clientmgr_t *manager, ns_interface_t *ifp, isc_socket_t *sock, | ||
738 | (void)isc_socket_getpeername(client->tcpsocket, &client->peeraddr); | ||
739 | client->peeraddr_valid = true; | ||
740 | |||
741 | - LOCK(&client->interface->lock); | ||
742 | - client->interface->ntcpactive++; | ||
743 | - UNLOCK(&client->interface->lock); | ||
744 | - client->tcpactive = true; | ||
745 | - | ||
746 | INSIST(client->tcpmsg_valid == false); | ||
747 | dns_tcpmsg_init(client->mctx, client->tcpsocket, &client->tcpmsg); | ||
748 | client->tcpmsg_valid = true; | ||
749 | @@ -3970,8 +3909,7 @@ ns_clientmgr_createclients(ns_clientmgr_t *manager, unsigned int n, | ||
750 | MTRACE("createclients"); | ||
751 | |||
752 | for (disp = 0; disp < n; disp++) { | ||
753 | - result = get_client(manager, ifp, ifp->udpdispatch[disp], | ||
754 | - NULL, tcp); | ||
755 | + result = get_client(manager, ifp, ifp->udpdispatch[disp], tcp); | ||
756 | if (result != ISC_R_SUCCESS) | ||
757 | break; | ||
758 | } | ||
759 | diff --git a/bin/named/include/named/client.h b/bin/named/include/named/client.h | ||
760 | index e2c40acd28..969ee4c08f 100644 | ||
761 | --- a/bin/named/include/named/client.h | ||
762 | +++ b/bin/named/include/named/client.h | ||
763 | @@ -78,6 +78,13 @@ | ||
764 | *** Types | ||
765 | ***/ | ||
766 | |||
767 | +/*% reference-counted TCP connection object */ | ||
768 | +typedef struct ns_tcpconn { | ||
769 | + isc_refcount_t refs; | ||
770 | + isc_quota_t *tcpquota; | ||
771 | + bool pipelined; | ||
772 | +} ns_tcpconn_t; | ||
773 | + | ||
774 | /*% nameserver client structure */ | ||
775 | struct ns_client { | ||
776 | unsigned int magic; | ||
777 | @@ -131,10 +138,7 @@ struct ns_client { | ||
778 | dns_name_t signername; /*%< [T]SIG key name */ | ||
779 | dns_name_t *signer; /*%< NULL if not valid sig */ | ||
780 | bool mortal; /*%< Die after handling request */ | ||
781 | - bool pipelined; /*%< TCP queries not in sequence */ | ||
782 | - isc_refcount_t *pipeline_refs; | ||
783 | - isc_quota_t *tcpquota; | ||
784 | - bool tcpattached; | ||
785 | + ns_tcpconn_t *tcpconn; | ||
786 | isc_quota_t *recursionquota; | ||
787 | ns_interface_t *interface; | ||
788 | |||
789 | diff --git a/bin/named/include/named/interfacemgr.h b/bin/named/include/named/interfacemgr.h | ||
790 | index 61b08826a6..3535ef22a8 100644 | ||
791 | --- a/bin/named/include/named/interfacemgr.h | ||
792 | +++ b/bin/named/include/named/interfacemgr.h | ||
793 | @@ -9,8 +9,6 @@ | ||
794 | * information regarding copyright ownership. | ||
795 | */ | ||
796 | |||
797 | -/* $Id: interfacemgr.h,v 1.35 2011/07/28 23:47:58 tbox Exp $ */ | ||
798 | - | ||
799 | #ifndef NAMED_INTERFACEMGR_H | ||
800 | #define NAMED_INTERFACEMGR_H 1 | ||
801 | |||
802 | @@ -77,11 +75,11 @@ struct ns_interface { | ||
803 | /*%< UDP dispatchers. */ | ||
804 | isc_socket_t * tcpsocket; /*%< TCP socket. */ | ||
805 | isc_dscp_t dscp; /*%< "listen-on" DSCP value */ | ||
806 | - int ntcpaccepting; /*%< Number of clients | ||
807 | + int32_t ntcpaccepting; /*%< Number of clients | ||
808 | ready to accept new | ||
809 | TCP connections on this | ||
810 | interface */ | ||
811 | - int ntcpactive; /*%< Number of clients | ||
812 | + int32_t ntcpactive; /*%< Number of clients | ||
813 | servicing TCP queries | ||
814 | (whether accepting or | ||
815 | connected) */ | ||
816 | diff --git a/bin/named/interfacemgr.c b/bin/named/interfacemgr.c | ||
817 | index 955096ef47..d9f6df5802 100644 | ||
818 | --- a/bin/named/interfacemgr.c | ||
819 | +++ b/bin/named/interfacemgr.c | ||
820 | @@ -388,6 +388,7 @@ ns_interface_create(ns_interfacemgr_t *mgr, isc_sockaddr_t *addr, | ||
821 | */ | ||
822 | ifp->ntcpaccepting = 0; | ||
823 | ifp->ntcpactive = 0; | ||
824 | + | ||
825 | ifp->nudpdispatch = 0; | ||
826 | |||
827 | ifp->dscp = -1; | ||
828 | diff --git a/lib/isc/include/isc/quota.h b/lib/isc/include/isc/quota.h | ||
829 | index b9bf59877a..36c5830242 100644 | ||
830 | --- a/lib/isc/include/isc/quota.h | ||
831 | +++ b/lib/isc/include/isc/quota.h | ||
832 | @@ -100,6 +100,13 @@ isc_quota_attach(isc_quota_t *quota, isc_quota_t **p); | ||
833 | * quota if successful (ISC_R_SUCCESS or ISC_R_SOFTQUOTA). | ||
834 | */ | ||
835 | |||
836 | +isc_result_t | ||
837 | +isc_quota_force(isc_quota_t *quota, isc_quota_t **p); | ||
838 | +/*%< | ||
839 | + * Like isc_quota_attach, but will attach '*p' to the quota | ||
840 | + * even if the hard quota has been exceeded. | ||
841 | + */ | ||
842 | + | ||
843 | void | ||
844 | isc_quota_detach(isc_quota_t **p); | ||
845 | /*%< | ||
846 | diff --git a/lib/isc/quota.c b/lib/isc/quota.c | ||
847 | index 3ddff0d875..556a61f21d 100644 | ||
848 | --- a/lib/isc/quota.c | ||
849 | +++ b/lib/isc/quota.c | ||
850 | @@ -74,20 +74,39 @@ isc_quota_release(isc_quota_t *quota) { | ||
851 | UNLOCK("a->lock); | ||
852 | } | ||
853 | |||
854 | -isc_result_t | ||
855 | -isc_quota_attach(isc_quota_t *quota, isc_quota_t **p) | ||
856 | -{ | ||
857 | +static isc_result_t | ||
858 | +doattach(isc_quota_t *quota, isc_quota_t **p, bool force) { | ||
859 | isc_result_t result; | ||
860 | - INSIST(p != NULL && *p == NULL); | ||
861 | + REQUIRE(p != NULL && *p == NULL); | ||
862 | + | ||
863 | result = isc_quota_reserve(quota); | ||
864 | - if (result == ISC_R_SUCCESS || result == ISC_R_SOFTQUOTA) | ||
865 | + if (result == ISC_R_SUCCESS || result == ISC_R_SOFTQUOTA) { | ||
866 | + *p = quota; | ||
867 | + } else if (result == ISC_R_QUOTA && force) { | ||
868 | + /* attach anyway */ | ||
869 | + LOCK("a->lock); | ||
870 | + quota->used++; | ||
871 | + UNLOCK("a->lock); | ||
872 | + | ||
873 | *p = quota; | ||
874 | + result = ISC_R_SUCCESS; | ||
875 | + } | ||
876 | + | ||
877 | return (result); | ||
878 | } | ||
879 | |||
880 | +isc_result_t | ||
881 | +isc_quota_attach(isc_quota_t *quota, isc_quota_t **p) { | ||
882 | + return (doattach(quota, p, false)); | ||
883 | +} | ||
884 | + | ||
885 | +isc_result_t | ||
886 | +isc_quota_force(isc_quota_t *quota, isc_quota_t **p) { | ||
887 | + return (doattach(quota, p, true)); | ||
888 | +} | ||
889 | + | ||
890 | void | ||
891 | -isc_quota_detach(isc_quota_t **p) | ||
892 | -{ | ||
893 | +isc_quota_detach(isc_quota_t **p) { | ||
894 | INSIST(p != NULL && *p != NULL); | ||
895 | isc_quota_release(*p); | ||
896 | *p = NULL; | ||
897 | diff --git a/lib/isc/win32/libisc.def.in b/lib/isc/win32/libisc.def.in | ||
898 | index a82facec0f..7b9f23d776 100644 | ||
899 | --- a/lib/isc/win32/libisc.def.in | ||
900 | +++ b/lib/isc/win32/libisc.def.in | ||
901 | @@ -519,6 +519,7 @@ isc_portset_removerange | ||
902 | isc_quota_attach | ||
903 | isc_quota_destroy | ||
904 | isc_quota_detach | ||
905 | +isc_quota_force | ||
906 | isc_quota_init | ||
907 | isc_quota_max | ||
908 | isc_quota_release | ||
909 | -- | ||
910 | 2.20.1 | ||
911 | |||
diff --git a/meta/recipes-connectivity/bind/bind/0006-restore-allowance-for-tcp-clients-interfaces.patch b/meta/recipes-connectivity/bind/bind/0006-restore-allowance-for-tcp-clients-interfaces.patch deleted file mode 100644 index 3821d18501..0000000000 --- a/meta/recipes-connectivity/bind/bind/0006-restore-allowance-for-tcp-clients-interfaces.patch +++ /dev/null | |||
@@ -1,80 +0,0 @@ | |||
1 | Backport patch to fix CVE-2018-5743. | ||
2 | |||
3 | Ref: | ||
4 | https://security-tracker.debian.org/tracker/CVE-2018-5743 | ||
5 | |||
6 | CVE: CVE-2018-5743 | ||
7 | Upstream-Status: Backport [https://gitlab.isc.org/isc-projects/bind9/commit/59434b9] | ||
8 | |||
9 | Signed-off-by: Kai Kang <kai.kang@windriver.com> | ||
10 | |||
11 | From 59434b987e8eb436b08c24e559ee094c4e939daa Mon Sep 17 00:00:00 2001 | ||
12 | From: Evan Hunt <each@isc.org> | ||
13 | Date: Fri, 5 Apr 2019 16:26:19 -0700 | ||
14 | Subject: [PATCH 6/6] restore allowance for tcp-clients < interfaces | ||
15 | |||
16 | in the "refactor tcpquota and pipeline refs" commit, the counting | ||
17 | of active interfaces was tightened in such a way that named could | ||
18 | fail to listen on an interface if there were more interfaces than | ||
19 | tcp-clients. when checking the quota to start accepting on an | ||
20 | interface, if the number of active clients was above zero, then | ||
21 | it was presumed that some other client was able to handle accepting | ||
22 | new connections. this, however, ignored the fact that the current client | ||
23 | could be included in that count, so if the quota was already exceeded | ||
24 | before all the interfaces were listening, some interfaces would never | ||
25 | listen. | ||
26 | |||
27 | we now check whether the current client has been marked active; if so, | ||
28 | then the number of active clients on the interface must be greater | ||
29 | than 1, not 0. | ||
30 | |||
31 | (cherry picked from commit 0b4e2cd4c3192ba88569dd344f542a8cc43742b5) | ||
32 | (cherry picked from commit d01023aaac35543daffbdf48464e320150235d41) | ||
33 | --- | ||
34 | bin/named/client.c | 8 +++++--- | ||
35 | doc/arm/Bv9ARM-book.xml | 3 ++- | ||
36 | 2 files changed, 7 insertions(+), 4 deletions(-) | ||
37 | |||
38 | diff --git a/bin/named/client.c b/bin/named/client.c | ||
39 | index d826ab32bf..845326abc0 100644 | ||
40 | --- a/bin/named/client.c | ||
41 | +++ b/bin/named/client.c | ||
42 | @@ -3464,8 +3464,9 @@ client_accept(ns_client_t *client) { | ||
43 | * | ||
44 | * So, we check here to see if any other clients are | ||
45 | * already servicing TCP queries on this interface (whether | ||
46 | - * accepting, reading, or processing). If we find at least | ||
47 | - * one, then it's okay *not* to call accept - we can let this | ||
48 | + * accepting, reading, or processing). If we find that at | ||
49 | + * least one client other than this one is active, then | ||
50 | + * it's okay *not* to call accept - we can let this | ||
51 | * client go inactive and another will take over when it's | ||
52 | * done. | ||
53 | * | ||
54 | @@ -3479,7 +3480,8 @@ client_accept(ns_client_t *client) { | ||
55 | * quota is tcp-clients plus the number of listening | ||
56 | * interfaces plus 1.) | ||
57 | */ | ||
58 | - exit = (isc_atomic_xadd(&client->interface->ntcpactive, 0) > 0); | ||
59 | + exit = (isc_atomic_xadd(&client->interface->ntcpactive, 0) > | ||
60 | + (client->tcpactive ? 1 : 0)); | ||
61 | if (exit) { | ||
62 | client->newstate = NS_CLIENTSTATE_INACTIVE; | ||
63 | (void)exit_check(client); | ||
64 | diff --git a/doc/arm/Bv9ARM-book.xml b/doc/arm/Bv9ARM-book.xml | ||
65 | index 381768d540..9c76d3cd6f 100644 | ||
66 | --- a/doc/arm/Bv9ARM-book.xml | ||
67 | +++ b/doc/arm/Bv9ARM-book.xml | ||
68 | @@ -8493,7 +8493,8 @@ avoid-v6-udp-ports { 40000; range 50000 60000; }; | ||
69 | <para> | ||
70 | The number of file descriptors reserved for TCP, stdio, | ||
71 | etc. This needs to be big enough to cover the number of | ||
72 | - interfaces <command>named</command> listens on, <command>tcp-clients</command> as well as | ||
73 | + interfaces <command>named</command> listens on plus | ||
74 | + <command>tcp-clients</command>, as well as | ||
75 | to provide room for outgoing TCP queries and incoming zone | ||
76 | transfers. The default is <literal>512</literal>. | ||
77 | The minimum value is <literal>128</literal> and the | ||
78 | -- | ||
79 | 2.20.1 | ||
80 | |||
diff --git a/meta/recipes-connectivity/bind/bind/0007-Replace-atomic-operations-in-bin-named-client.c-with.patch b/meta/recipes-connectivity/bind/bind/0007-Replace-atomic-operations-in-bin-named-client.c-with.patch deleted file mode 100644 index 1a84eca58a..0000000000 --- a/meta/recipes-connectivity/bind/bind/0007-Replace-atomic-operations-in-bin-named-client.c-with.patch +++ /dev/null | |||
@@ -1,140 +0,0 @@ | |||
1 | Backport commit to fix compile error on arm caused by commits which are | ||
2 | to fix CVE-2018-5743. | ||
3 | |||
4 | CVE: CVE-2018-5743 | ||
5 | Upstream-Status: Backport [https://gitlab.isc.org/isc-projects/bind9/commit/ef49780] | ||
6 | |||
7 | Signed-off-by: Kai Kang <kai.kang@windriver.com> | ||
8 | |||
9 | From ef49780d30d3ddc5735cfc32561b678a634fa72f Mon Sep 17 00:00:00 2001 | ||
10 | From: =?UTF-8?q?Ond=C5=99ej=20Sur=C3=BD?= <ondrej@sury.org> | ||
11 | Date: Wed, 17 Apr 2019 15:22:27 +0200 | ||
12 | Subject: [PATCH] Replace atomic operations in bin/named/client.c with | ||
13 | isc_refcount reference counting | ||
14 | |||
15 | --- | ||
16 | bin/named/client.c | 18 +++++++----------- | ||
17 | bin/named/include/named/interfacemgr.h | 5 +++-- | ||
18 | bin/named/interfacemgr.c | 7 +++++-- | ||
19 | 3 files changed, 15 insertions(+), 15 deletions(-) | ||
20 | |||
21 | diff --git a/bin/named/client.c b/bin/named/client.c | ||
22 | index 845326abc0..29fecadca8 100644 | ||
23 | --- a/bin/named/client.c | ||
24 | +++ b/bin/named/client.c | ||
25 | @@ -402,12 +402,10 @@ tcpconn_detach(ns_client_t *client) { | ||
26 | static void | ||
27 | mark_tcp_active(ns_client_t *client, bool active) { | ||
28 | if (active && !client->tcpactive) { | ||
29 | - isc_atomic_xadd(&client->interface->ntcpactive, 1); | ||
30 | + isc_refcount_increment0(&client->interface->ntcpactive, NULL); | ||
31 | client->tcpactive = active; | ||
32 | } else if (!active && client->tcpactive) { | ||
33 | - uint32_t old = | ||
34 | - isc_atomic_xadd(&client->interface->ntcpactive, -1); | ||
35 | - INSIST(old > 0); | ||
36 | + isc_refcount_decrement(&client->interface->ntcpactive, NULL); | ||
37 | client->tcpactive = active; | ||
38 | } | ||
39 | } | ||
40 | @@ -554,7 +552,7 @@ exit_check(ns_client_t *client) { | ||
41 | if (client->mortal && TCP_CLIENT(client) && | ||
42 | client->newstate != NS_CLIENTSTATE_FREED && | ||
43 | !ns_g_clienttest && | ||
44 | - isc_atomic_xadd(&client->interface->ntcpaccepting, 0) == 0) | ||
45 | + isc_refcount_current(&client->interface->ntcpaccepting) == 0) | ||
46 | { | ||
47 | /* Nobody else is accepting */ | ||
48 | client->mortal = false; | ||
49 | @@ -3328,7 +3326,6 @@ client_newconn(isc_task_t *task, isc_event_t *event) { | ||
50 | isc_result_t result; | ||
51 | ns_client_t *client = event->ev_arg; | ||
52 | isc_socket_newconnev_t *nevent = (isc_socket_newconnev_t *)event; | ||
53 | - uint32_t old; | ||
54 | |||
55 | REQUIRE(event->ev_type == ISC_SOCKEVENT_NEWCONN); | ||
56 | REQUIRE(NS_CLIENT_VALID(client)); | ||
57 | @@ -3348,8 +3345,7 @@ client_newconn(isc_task_t *task, isc_event_t *event) { | ||
58 | INSIST(client->naccepts == 1); | ||
59 | client->naccepts--; | ||
60 | |||
61 | - old = isc_atomic_xadd(&client->interface->ntcpaccepting, -1); | ||
62 | - INSIST(old > 0); | ||
63 | + isc_refcount_decrement(&client->interface->ntcpaccepting, NULL); | ||
64 | |||
65 | /* | ||
66 | * We must take ownership of the new socket before the exit | ||
67 | @@ -3480,8 +3476,8 @@ client_accept(ns_client_t *client) { | ||
68 | * quota is tcp-clients plus the number of listening | ||
69 | * interfaces plus 1.) | ||
70 | */ | ||
71 | - exit = (isc_atomic_xadd(&client->interface->ntcpactive, 0) > | ||
72 | - (client->tcpactive ? 1 : 0)); | ||
73 | + exit = (isc_refcount_current(&client->interface->ntcpactive) > | ||
74 | + (client->tcpactive ? 1U : 0U)); | ||
75 | if (exit) { | ||
76 | client->newstate = NS_CLIENTSTATE_INACTIVE; | ||
77 | (void)exit_check(client); | ||
78 | @@ -3539,7 +3535,7 @@ client_accept(ns_client_t *client) { | ||
79 | * listening for connections itself to prevent the interface | ||
80 | * going dead. | ||
81 | */ | ||
82 | - isc_atomic_xadd(&client->interface->ntcpaccepting, 1); | ||
83 | + isc_refcount_increment0(&client->interface->ntcpaccepting, NULL); | ||
84 | } | ||
85 | |||
86 | static void | ||
87 | diff --git a/bin/named/include/named/interfacemgr.h b/bin/named/include/named/interfacemgr.h | ||
88 | index 3535ef22a8..6e10f210fd 100644 | ||
89 | --- a/bin/named/include/named/interfacemgr.h | ||
90 | +++ b/bin/named/include/named/interfacemgr.h | ||
91 | @@ -45,6 +45,7 @@ | ||
92 | #include <isc/magic.h> | ||
93 | #include <isc/mem.h> | ||
94 | #include <isc/socket.h> | ||
95 | +#include <isc/refcount.h> | ||
96 | |||
97 | #include <dns/result.h> | ||
98 | |||
99 | @@ -75,11 +76,11 @@ struct ns_interface { | ||
100 | /*%< UDP dispatchers. */ | ||
101 | isc_socket_t * tcpsocket; /*%< TCP socket. */ | ||
102 | isc_dscp_t dscp; /*%< "listen-on" DSCP value */ | ||
103 | - int32_t ntcpaccepting; /*%< Number of clients | ||
104 | + isc_refcount_t ntcpaccepting; /*%< Number of clients | ||
105 | ready to accept new | ||
106 | TCP connections on this | ||
107 | interface */ | ||
108 | - int32_t ntcpactive; /*%< Number of clients | ||
109 | + isc_refcount_t ntcpactive; /*%< Number of clients | ||
110 | servicing TCP queries | ||
111 | (whether accepting or | ||
112 | connected) */ | ||
113 | diff --git a/bin/named/interfacemgr.c b/bin/named/interfacemgr.c | ||
114 | index d9f6df5802..135533be6b 100644 | ||
115 | --- a/bin/named/interfacemgr.c | ||
116 | +++ b/bin/named/interfacemgr.c | ||
117 | @@ -386,8 +386,8 @@ ns_interface_create(ns_interfacemgr_t *mgr, isc_sockaddr_t *addr, | ||
118 | * connections will be handled in parallel even though there is | ||
119 | * only one client initially. | ||
120 | */ | ||
121 | - ifp->ntcpaccepting = 0; | ||
122 | - ifp->ntcpactive = 0; | ||
123 | + isc_refcount_init(&ifp->ntcpaccepting, 0); | ||
124 | + isc_refcount_init(&ifp->ntcpactive, 0); | ||
125 | |||
126 | ifp->nudpdispatch = 0; | ||
127 | |||
128 | @@ -618,6 +618,9 @@ ns_interface_destroy(ns_interface_t *ifp) { | ||
129 | |||
130 | ns_interfacemgr_detach(&ifp->mgr); | ||
131 | |||
132 | + isc_refcount_destroy(&ifp->ntcpactive); | ||
133 | + isc_refcount_destroy(&ifp->ntcpaccepting); | ||
134 | + | ||
135 | ifp->magic = 0; | ||
136 | isc_mem_put(mctx, ifp, sizeof(*ifp)); | ||
137 | } | ||
138 | -- | ||
139 | 2.20.1 | ||
140 | |||
diff --git a/meta/recipes-connectivity/bind/bind/CVE-2020-8622.patch b/meta/recipes-connectivity/bind/bind/CVE-2020-8622.patch new file mode 100644 index 0000000000..dec5672657 --- /dev/null +++ b/meta/recipes-connectivity/bind/bind/CVE-2020-8622.patch | |||
@@ -0,0 +1,60 @@ | |||
1 | From ca543240380475d888d660ea3296fc880ce52f35 Mon Sep 17 00:00:00 2001 | ||
2 | From: Mark Andrews <marka@isc.org> | ||
3 | Date: Wed, 15 Jul 2020 16:07:51 +1000 | ||
4 | Subject: [PATCH] bind: Always keep a copy of the message | ||
5 | |||
6 | this allows it to be available even when dns_message_parse() | ||
7 | returns a error. | ||
8 | |||
9 | Upstream-Status: Backport | ||
10 | CVE: CVE-2020-8622 | ||
11 | Signed-off-by: Li Zhou <li.zhou@windriver.com> | ||
12 | --- | ||
13 | lib/dns/message.c | 24 +++++++++++++----------- | ||
14 | 1 file changed, 13 insertions(+), 11 deletions(-) | ||
15 | |||
16 | diff --git a/lib/dns/message.c b/lib/dns/message.c | ||
17 | index ac637a2..39ed80f 100644 | ||
18 | --- a/lib/dns/message.c | ||
19 | +++ b/lib/dns/message.c | ||
20 | @@ -1679,6 +1679,19 @@ dns_message_parse(dns_message_t *msg, isc_buffer_t *source, | ||
21 | msg->header_ok = 0; | ||
22 | msg->question_ok = 0; | ||
23 | |||
24 | + if ((options & DNS_MESSAGEPARSE_CLONEBUFFER) == 0) { | ||
25 | + isc_buffer_usedregion(&origsource, &msg->saved); | ||
26 | + } else { | ||
27 | + msg->saved.length = isc_buffer_usedlength(&origsource); | ||
28 | + msg->saved.base = isc_mem_get(msg->mctx, msg->saved.length); | ||
29 | + if (msg->saved.base == NULL) { | ||
30 | + return (ISC_R_NOMEMORY); | ||
31 | + } | ||
32 | + memmove(msg->saved.base, isc_buffer_base(&origsource), | ||
33 | + msg->saved.length); | ||
34 | + msg->free_saved = 1; | ||
35 | + } | ||
36 | + | ||
37 | isc_buffer_remainingregion(source, &r); | ||
38 | if (r.length < DNS_MESSAGE_HEADERLEN) | ||
39 | return (ISC_R_UNEXPECTEDEND); | ||
40 | @@ -1754,17 +1767,6 @@ dns_message_parse(dns_message_t *msg, isc_buffer_t *source, | ||
41 | } | ||
42 | |||
43 | truncated: | ||
44 | - if ((options & DNS_MESSAGEPARSE_CLONEBUFFER) == 0) | ||
45 | - isc_buffer_usedregion(&origsource, &msg->saved); | ||
46 | - else { | ||
47 | - msg->saved.length = isc_buffer_usedlength(&origsource); | ||
48 | - msg->saved.base = isc_mem_get(msg->mctx, msg->saved.length); | ||
49 | - if (msg->saved.base == NULL) | ||
50 | - return (ISC_R_NOMEMORY); | ||
51 | - memmove(msg->saved.base, isc_buffer_base(&origsource), | ||
52 | - msg->saved.length); | ||
53 | - msg->free_saved = 1; | ||
54 | - } | ||
55 | |||
56 | if (ret == ISC_R_UNEXPECTEDEND && ignore_tc) | ||
57 | return (DNS_R_RECOVERABLE); | ||
58 | -- | ||
59 | 1.9.1 | ||
60 | |||
diff --git a/meta/recipes-connectivity/bind/bind/CVE-2020-8623.patch b/meta/recipes-connectivity/bind/bind/CVE-2020-8623.patch new file mode 100644 index 0000000000..8e5412a89e --- /dev/null +++ b/meta/recipes-connectivity/bind/bind/CVE-2020-8623.patch | |||
@@ -0,0 +1,402 @@ | |||
1 | From 8d807cc21655eaa6e6a08afafeec3682c0f3f2ab Mon Sep 17 00:00:00 2001 | ||
2 | From: =?UTF-8?q?Ond=C5=99ej=20Sur=C3=BD?= <ondrej@isc.org> | ||
3 | Date: Tue, 21 Jul 2020 14:42:47 +0200 | ||
4 | Subject: [PATCH] Fix crash in pk11_numbits() when native-pkcs11 is used | ||
5 | |||
6 | When pk11_numbits() is passed a user provided input that contains all | ||
7 | zeroes (via crafted DNS message), it would crash with assertion | ||
8 | failure. Fix that by properly handling such input. | ||
9 | |||
10 | Upstream-Status: Backport | ||
11 | CVE: CVE-2020-8623 | ||
12 | Signed-off-by: Li Zhou <li.zhou@windriver.com> | ||
13 | --- | ||
14 | lib/dns/pkcs11dh_link.c | 15 ++++++- | ||
15 | lib/dns/pkcs11dsa_link.c | 8 +++- | ||
16 | lib/dns/pkcs11rsa_link.c | 79 +++++++++++++++++++++++++-------- | ||
17 | lib/isc/include/pk11/internal.h | 3 +- | ||
18 | lib/isc/pk11.c | 61 ++++++++++++++++--------- | ||
19 | 5 files changed, 121 insertions(+), 45 deletions(-) | ||
20 | |||
21 | diff --git a/lib/dns/pkcs11dh_link.c b/lib/dns/pkcs11dh_link.c | ||
22 | index e2b60ea7c5..4cd8e32d60 100644 | ||
23 | --- a/lib/dns/pkcs11dh_link.c | ||
24 | +++ b/lib/dns/pkcs11dh_link.c | ||
25 | @@ -748,6 +748,7 @@ pkcs11dh_fromdns(dst_key_t *key, isc_buffer_t *data) { | ||
26 | CK_BYTE *prime = NULL, *base = NULL, *pub = NULL; | ||
27 | CK_ATTRIBUTE *attr; | ||
28 | int special = 0; | ||
29 | + unsigned int bits; | ||
30 | isc_result_t result; | ||
31 | |||
32 | isc_buffer_remainingregion(data, &r); | ||
33 | @@ -852,7 +853,11 @@ pkcs11dh_fromdns(dst_key_t *key, isc_buffer_t *data) { | ||
34 | pub = r.base; | ||
35 | isc_region_consume(&r, publen); | ||
36 | |||
37 | - key->key_size = pk11_numbits(prime, plen_); | ||
38 | + result = pk11_numbits(prime, plen_, &bits); | ||
39 | + if (result != ISC_R_SUCCESS) { | ||
40 | + goto cleanup; | ||
41 | + } | ||
42 | + key->key_size = bits; | ||
43 | |||
44 | dh->repr = (CK_ATTRIBUTE *) isc_mem_get(key->mctx, sizeof(*attr) * 3); | ||
45 | if (dh->repr == NULL) | ||
46 | @@ -1012,6 +1017,7 @@ pkcs11dh_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) { | ||
47 | dst_private_t priv; | ||
48 | isc_result_t ret; | ||
49 | int i; | ||
50 | + unsigned int bits; | ||
51 | pk11_object_t *dh = NULL; | ||
52 | CK_ATTRIBUTE *attr; | ||
53 | isc_mem_t *mctx; | ||
54 | @@ -1082,7 +1088,12 @@ pkcs11dh_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) { | ||
55 | |||
56 | attr = pk11_attribute_bytype(dh, CKA_PRIME); | ||
57 | INSIST(attr != NULL); | ||
58 | - key->key_size = pk11_numbits(attr->pValue, attr->ulValueLen); | ||
59 | + | ||
60 | + ret = pk11_numbits(attr->pValue, attr->ulValueLen, &bits); | ||
61 | + if (ret != ISC_R_SUCCESS) { | ||
62 | + goto err; | ||
63 | + } | ||
64 | + key->key_size = bits; | ||
65 | |||
66 | return (ISC_R_SUCCESS); | ||
67 | |||
68 | diff --git a/lib/dns/pkcs11dsa_link.c b/lib/dns/pkcs11dsa_link.c | ||
69 | index 12d707a112..24d4c149ff 100644 | ||
70 | --- a/lib/dns/pkcs11dsa_link.c | ||
71 | +++ b/lib/dns/pkcs11dsa_link.c | ||
72 | @@ -983,6 +983,7 @@ pkcs11dsa_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) { | ||
73 | dst_private_t priv; | ||
74 | isc_result_t ret; | ||
75 | int i; | ||
76 | + unsigned int bits; | ||
77 | pk11_object_t *dsa = NULL; | ||
78 | CK_ATTRIBUTE *attr; | ||
79 | isc_mem_t *mctx = key->mctx; | ||
80 | @@ -1072,7 +1073,12 @@ pkcs11dsa_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) { | ||
81 | |||
82 | attr = pk11_attribute_bytype(dsa, CKA_PRIME); | ||
83 | INSIST(attr != NULL); | ||
84 | - key->key_size = pk11_numbits(attr->pValue, attr->ulValueLen); | ||
85 | + | ||
86 | + ret = pk11_numbits(attr->pValue, attr->ulValueLen, &bits); | ||
87 | + if (ret != ISC_R_SUCCESS) { | ||
88 | + goto err; | ||
89 | + } | ||
90 | + key->key_size = bits; | ||
91 | |||
92 | return (ISC_R_SUCCESS); | ||
93 | |||
94 | diff --git a/lib/dns/pkcs11rsa_link.c b/lib/dns/pkcs11rsa_link.c | ||
95 | index 096c1a8e91..1d10d26564 100644 | ||
96 | --- a/lib/dns/pkcs11rsa_link.c | ||
97 | +++ b/lib/dns/pkcs11rsa_link.c | ||
98 | @@ -332,6 +332,7 @@ pkcs11rsa_createctx_verify(dst_key_t *key, unsigned int maxbits, | ||
99 | key->key_alg == DST_ALG_RSASHA256 || | ||
100 | key->key_alg == DST_ALG_RSASHA512); | ||
101 | #endif | ||
102 | + REQUIRE(maxbits <= RSA_MAX_PUBEXP_BITS); | ||
103 | |||
104 | /* | ||
105 | * Reject incorrect RSA key lengths. | ||
106 | @@ -376,6 +377,7 @@ pkcs11rsa_createctx_verify(dst_key_t *key, unsigned int maxbits, | ||
107 | for (attr = pk11_attribute_first(rsa); | ||
108 | attr != NULL; | ||
109 | attr = pk11_attribute_next(rsa, attr)) | ||
110 | + { | ||
111 | switch (attr->type) { | ||
112 | case CKA_MODULUS: | ||
113 | INSIST(keyTemplate[5].type == attr->type); | ||
114 | @@ -396,12 +398,16 @@ pkcs11rsa_createctx_verify(dst_key_t *key, unsigned int maxbits, | ||
115 | memmove(keyTemplate[6].pValue, attr->pValue, | ||
116 | attr->ulValueLen); | ||
117 | keyTemplate[6].ulValueLen = attr->ulValueLen; | ||
118 | - if (pk11_numbits(attr->pValue, | ||
119 | - attr->ulValueLen) > maxbits && | ||
120 | - maxbits != 0) | ||
121 | + unsigned int bits; | ||
122 | + ret = pk11_numbits(attr->pValue, attr->ulValueLen, | ||
123 | + &bits); | ||
124 | + if (ret != ISC_R_SUCCESS || | ||
125 | + (bits > maxbits && maxbits != 0)) { | ||
126 | DST_RET(DST_R_VERIFYFAILURE); | ||
127 | + } | ||
128 | break; | ||
129 | } | ||
130 | + } | ||
131 | pk11_ctx->object = CK_INVALID_HANDLE; | ||
132 | pk11_ctx->ontoken = false; | ||
133 | PK11_RET(pkcs_C_CreateObject, | ||
134 | @@ -1072,6 +1078,7 @@ pkcs11rsa_verify(dst_context_t *dctx, const isc_region_t *sig) { | ||
135 | keyTemplate[5].ulValueLen = attr->ulValueLen; | ||
136 | break; | ||
137 | case CKA_PUBLIC_EXPONENT: | ||
138 | + unsigned int bits; | ||
139 | INSIST(keyTemplate[6].type == attr->type); | ||
140 | keyTemplate[6].pValue = isc_mem_get(dctx->mctx, | ||
141 | attr->ulValueLen); | ||
142 | @@ -1080,10 +1087,12 @@ pkcs11rsa_verify(dst_context_t *dctx, const isc_region_t *sig) { | ||
143 | memmove(keyTemplate[6].pValue, attr->pValue, | ||
144 | attr->ulValueLen); | ||
145 | keyTemplate[6].ulValueLen = attr->ulValueLen; | ||
146 | - if (pk11_numbits(attr->pValue, | ||
147 | - attr->ulValueLen) | ||
148 | - > RSA_MAX_PUBEXP_BITS) | ||
149 | + ret = pk11_numbits(attr->pValue, attr->ulValueLen, | ||
150 | + &bits); | ||
151 | + if (ret != ISC_R_SUCCESS || bits > RSA_MAX_PUBEXP_BITS) | ||
152 | + { | ||
153 | DST_RET(DST_R_VERIFYFAILURE); | ||
154 | + } | ||
155 | break; | ||
156 | } | ||
157 | pk11_ctx->object = CK_INVALID_HANDLE; | ||
158 | @@ -1461,6 +1470,8 @@ pkcs11rsa_fromdns(dst_key_t *key, isc_buffer_t *data) { | ||
159 | CK_BYTE *exponent = NULL, *modulus = NULL; | ||
160 | CK_ATTRIBUTE *attr; | ||
161 | unsigned int length; | ||
162 | + unsigned int bits; | ||
163 | + isc_result_t ret = ISC_R_SUCCESS; | ||
164 | |||
165 | isc_buffer_remainingregion(data, &r); | ||
166 | if (r.length == 0) | ||
167 | @@ -1478,9 +1489,7 @@ pkcs11rsa_fromdns(dst_key_t *key, isc_buffer_t *data) { | ||
168 | |||
169 | if (e_bytes == 0) { | ||
170 | if (r.length < 2) { | ||
171 | - isc_safe_memwipe(rsa, sizeof(*rsa)); | ||
172 | - isc_mem_put(key->mctx, rsa, sizeof(*rsa)); | ||
173 | - return (DST_R_INVALIDPUBLICKEY); | ||
174 | + DST_RET(DST_R_INVALIDPUBLICKEY); | ||
175 | } | ||
176 | e_bytes = (*r.base) << 8; | ||
177 | isc_region_consume(&r, 1); | ||
178 | @@ -1489,16 +1498,18 @@ pkcs11rsa_fromdns(dst_key_t *key, isc_buffer_t *data) { | ||
179 | } | ||
180 | |||
181 | if (r.length < e_bytes) { | ||
182 | - isc_safe_memwipe(rsa, sizeof(*rsa)); | ||
183 | - isc_mem_put(key->mctx, rsa, sizeof(*rsa)); | ||
184 | - return (DST_R_INVALIDPUBLICKEY); | ||
185 | + DST_RET(DST_R_INVALIDPUBLICKEY); | ||
186 | } | ||
187 | exponent = r.base; | ||
188 | isc_region_consume(&r, e_bytes); | ||
189 | modulus = r.base; | ||
190 | mod_bytes = r.length; | ||
191 | |||
192 | - key->key_size = pk11_numbits(modulus, mod_bytes); | ||
193 | + ret = pk11_numbits(modulus, mod_bytes, &bits); | ||
194 | + if (ret != ISC_R_SUCCESS) { | ||
195 | + goto err; | ||
196 | + } | ||
197 | + key->key_size = bits; | ||
198 | |||
199 | isc_buffer_forward(data, length); | ||
200 | |||
201 | @@ -1548,9 +1559,12 @@ pkcs11rsa_fromdns(dst_key_t *key, isc_buffer_t *data) { | ||
202 | rsa->repr, | ||
203 | rsa->attrcnt * sizeof(*attr)); | ||
204 | } | ||
205 | + ret = ISC_R_NOMEMORY; | ||
206 | + | ||
207 | + err: | ||
208 | isc_safe_memwipe(rsa, sizeof(*rsa)); | ||
209 | isc_mem_put(key->mctx, rsa, sizeof(*rsa)); | ||
210 | - return (ISC_R_NOMEMORY); | ||
211 | + return (ret); | ||
212 | } | ||
213 | |||
214 | static isc_result_t | ||
215 | @@ -1729,6 +1743,7 @@ pkcs11rsa_fetch(dst_key_t *key, const char *engine, const char *label, | ||
216 | pk11_object_t *pubrsa; | ||
217 | pk11_context_t *pk11_ctx = NULL; | ||
218 | isc_result_t ret; | ||
219 | + unsigned int bits; | ||
220 | |||
221 | if (label == NULL) | ||
222 | return (DST_R_NOENGINE); | ||
223 | @@ -1815,7 +1830,11 @@ pkcs11rsa_fetch(dst_key_t *key, const char *engine, const char *label, | ||
224 | |||
225 | attr = pk11_attribute_bytype(rsa, CKA_MODULUS); | ||
226 | INSIST(attr != NULL); | ||
227 | - key->key_size = pk11_numbits(attr->pValue, attr->ulValueLen); | ||
228 | + ret = pk11_numbits(attr->pValue, attr->ulValueLen, &bits); | ||
229 | + if (ret != ISC_R_SUCCESS) { | ||
230 | + goto err; | ||
231 | + } | ||
232 | + key->key_size = bits; | ||
233 | |||
234 | return (ISC_R_SUCCESS); | ||
235 | |||
236 | @@ -1901,6 +1920,7 @@ pkcs11rsa_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) { | ||
237 | CK_ATTRIBUTE *attr; | ||
238 | isc_mem_t *mctx = key->mctx; | ||
239 | const char *engine = NULL, *label = NULL; | ||
240 | + unsigned int bits; | ||
241 | |||
242 | /* read private key file */ | ||
243 | ret = dst__privstruct_parse(key, DST_ALG_RSA, lexer, mctx, &priv); | ||
244 | @@ -2044,12 +2064,22 @@ pkcs11rsa_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) { | ||
245 | |||
246 | attr = pk11_attribute_bytype(rsa, CKA_MODULUS); | ||
247 | INSIST(attr != NULL); | ||
248 | - key->key_size = pk11_numbits(attr->pValue, attr->ulValueLen); | ||
249 | + ret = pk11_numbits(attr->pValue, attr->ulValueLen, &bits); | ||
250 | + if (ret != ISC_R_SUCCESS) { | ||
251 | + goto err; | ||
252 | + } | ||
253 | + key->key_size = bits; | ||
254 | |||
255 | attr = pk11_attribute_bytype(rsa, CKA_PUBLIC_EXPONENT); | ||
256 | INSIST(attr != NULL); | ||
257 | - if (pk11_numbits(attr->pValue, attr->ulValueLen) > RSA_MAX_PUBEXP_BITS) | ||
258 | + | ||
259 | + ret = pk11_numbits(attr->pValue, attr->ulValueLen, &bits); | ||
260 | + if (ret != ISC_R_SUCCESS) { | ||
261 | + goto err; | ||
262 | + } | ||
263 | + if (bits > RSA_MAX_PUBEXP_BITS) { | ||
264 | DST_RET(ISC_R_RANGE); | ||
265 | + } | ||
266 | |||
267 | dst__privstruct_free(&priv, mctx); | ||
268 | isc_safe_memwipe(&priv, sizeof(priv)); | ||
269 | @@ -2084,6 +2114,7 @@ pkcs11rsa_fromlabel(dst_key_t *key, const char *engine, const char *label, | ||
270 | pk11_context_t *pk11_ctx = NULL; | ||
271 | isc_result_t ret; | ||
272 | unsigned int i; | ||
273 | + unsigned int bits; | ||
274 | |||
275 | UNUSED(pin); | ||
276 | |||
277 | @@ -2178,12 +2209,22 @@ pkcs11rsa_fromlabel(dst_key_t *key, const char *engine, const char *label, | ||
278 | |||
279 | attr = pk11_attribute_bytype(rsa, CKA_PUBLIC_EXPONENT); | ||
280 | INSIST(attr != NULL); | ||
281 | - if (pk11_numbits(attr->pValue, attr->ulValueLen) > RSA_MAX_PUBEXP_BITS) | ||
282 | + | ||
283 | + ret = pk11_numbits(attr->pValue, attr->ulValueLen, &bits); | ||
284 | + if (ret != ISC_R_SUCCESS) { | ||
285 | + goto err; | ||
286 | + } | ||
287 | + if (bits > RSA_MAX_PUBEXP_BITS) { | ||
288 | DST_RET(ISC_R_RANGE); | ||
289 | + } | ||
290 | |||
291 | attr = pk11_attribute_bytype(rsa, CKA_MODULUS); | ||
292 | INSIST(attr != NULL); | ||
293 | - key->key_size = pk11_numbits(attr->pValue, attr->ulValueLen); | ||
294 | + ret = pk11_numbits(attr->pValue, attr->ulValueLen, &bits); | ||
295 | + if (ret != ISC_R_SUCCESS) { | ||
296 | + goto err; | ||
297 | + } | ||
298 | + key->key_size = bits; | ||
299 | |||
300 | pk11_return_session(pk11_ctx); | ||
301 | isc_safe_memwipe(pk11_ctx, sizeof(*pk11_ctx)); | ||
302 | diff --git a/lib/isc/include/pk11/internal.h b/lib/isc/include/pk11/internal.h | ||
303 | index aa8907ab08..7cc8ec812b 100644 | ||
304 | --- a/lib/isc/include/pk11/internal.h | ||
305 | +++ b/lib/isc/include/pk11/internal.h | ||
306 | @@ -25,7 +25,8 @@ void pk11_mem_put(void *ptr, size_t size); | ||
307 | |||
308 | CK_SLOT_ID pk11_get_best_token(pk11_optype_t optype); | ||
309 | |||
310 | -unsigned int pk11_numbits(CK_BYTE_PTR data, unsigned int bytecnt); | ||
311 | +isc_result_t | ||
312 | +pk11_numbits(CK_BYTE_PTR data, unsigned int bytecnt, unsigned int *bits); | ||
313 | |||
314 | CK_ATTRIBUTE *pk11_attribute_first(const pk11_object_t *obj); | ||
315 | |||
316 | diff --git a/lib/isc/pk11.c b/lib/isc/pk11.c | ||
317 | index 012afd968a..4e4052044b 100644 | ||
318 | --- a/lib/isc/pk11.c | ||
319 | +++ b/lib/isc/pk11.c | ||
320 | @@ -962,13 +962,15 @@ pk11_get_best_token(pk11_optype_t optype) { | ||
321 | return (token->slotid); | ||
322 | } | ||
323 | |||
324 | -unsigned int | ||
325 | -pk11_numbits(CK_BYTE_PTR data, unsigned int bytecnt) { | ||
326 | +isc_result_t | ||
327 | +pk11_numbits(CK_BYTE_PTR data, unsigned int bytecnt, unsigned int *bits) { | ||
328 | unsigned int bitcnt, i; | ||
329 | CK_BYTE top; | ||
330 | |||
331 | - if (bytecnt == 0) | ||
332 | - return (0); | ||
333 | + if (bytecnt == 0) { | ||
334 | + *bits = 0; | ||
335 | + return (ISC_R_SUCCESS); | ||
336 | + } | ||
337 | bitcnt = bytecnt * 8; | ||
338 | for (i = 0; i < bytecnt; i++) { | ||
339 | top = data[i]; | ||
340 | @@ -976,26 +978,41 @@ pk11_numbits(CK_BYTE_PTR data, unsigned int bytecnt) { | ||
341 | bitcnt -= 8; | ||
342 | continue; | ||
343 | } | ||
344 | - if (top & 0x80) | ||
345 | - return (bitcnt); | ||
346 | - if (top & 0x40) | ||
347 | - return (bitcnt - 1); | ||
348 | - if (top & 0x20) | ||
349 | - return (bitcnt - 2); | ||
350 | - if (top & 0x10) | ||
351 | - return (bitcnt - 3); | ||
352 | - if (top & 0x08) | ||
353 | - return (bitcnt - 4); | ||
354 | - if (top & 0x04) | ||
355 | - return (bitcnt - 5); | ||
356 | - if (top & 0x02) | ||
357 | - return (bitcnt - 6); | ||
358 | - if (top & 0x01) | ||
359 | - return (bitcnt - 7); | ||
360 | + if (top & 0x80) { | ||
361 | + *bits = bitcnt; | ||
362 | + return (ISC_R_SUCCESS); | ||
363 | + } | ||
364 | + if (top & 0x40) { | ||
365 | + *bits = bitcnt - 1; | ||
366 | + return (ISC_R_SUCCESS); | ||
367 | + } | ||
368 | + if (top & 0x20) { | ||
369 | + *bits = bitcnt - 2; | ||
370 | + return (ISC_R_SUCCESS); | ||
371 | + } | ||
372 | + if (top & 0x10) { | ||
373 | + *bits = bitcnt - 3; | ||
374 | + return (ISC_R_SUCCESS); | ||
375 | + } | ||
376 | + if (top & 0x08) { | ||
377 | + *bits = bitcnt - 4; | ||
378 | + return (ISC_R_SUCCESS); | ||
379 | + } | ||
380 | + if (top & 0x04) { | ||
381 | + *bits = bitcnt - 5; | ||
382 | + return (ISC_R_SUCCESS); | ||
383 | + } | ||
384 | + if (top & 0x02) { | ||
385 | + *bits = bitcnt - 6; | ||
386 | + return (ISC_R_SUCCESS); | ||
387 | + } | ||
388 | + if (top & 0x01) { | ||
389 | + *bits = bitcnt - 7; | ||
390 | + return (ISC_R_SUCCESS); | ||
391 | + } | ||
392 | break; | ||
393 | } | ||
394 | - INSIST(0); | ||
395 | - ISC_UNREACHABLE(); | ||
396 | + return (ISC_R_RANGE); | ||
397 | } | ||
398 | |||
399 | CK_ATTRIBUTE * | ||
400 | -- | ||
401 | 2.17.1 | ||
402 | |||
diff --git a/meta/recipes-connectivity/bind/bind/CVE-2020-8624.patch b/meta/recipes-connectivity/bind/bind/CVE-2020-8624.patch new file mode 100644 index 0000000000..9cffe358bf --- /dev/null +++ b/meta/recipes-connectivity/bind/bind/CVE-2020-8624.patch | |||
@@ -0,0 +1,33 @@ | |||
1 | From a73c3d30de7fe98af9e4dc0e490f732a48412380 Mon Sep 17 00:00:00 2001 | ||
2 | From: Mark Andrews <marka@isc.org> | ||
3 | Date: Wed, 29 Jul 2020 23:36:03 +1000 | ||
4 | Subject: [PATCH] bind: Update-policy 'subdomain' was incorrectly treated as | ||
5 | 'zonesub' | ||
6 | |||
7 | resulting in names outside the specified subdomain having the wrong | ||
8 | restrictions for the given key. | ||
9 | |||
10 | Upstream-Status: Backport | ||
11 | CVE: CVE-2020-8624 | ||
12 | Signed-off-by: Li Zhou <li.zhou@windriver.com> | ||
13 | --- | ||
14 | bin/named/zoneconf.c | 3 ++- | ||
15 | 1 file changed, 2 insertions(+), 1 deletion(-) | ||
16 | |||
17 | diff --git a/bin/named/zoneconf.c b/bin/named/zoneconf.c | ||
18 | index e237bdb..4898447 100644 | ||
19 | --- a/bin/named/zoneconf.c | ||
20 | +++ b/bin/named/zoneconf.c | ||
21 | @@ -237,7 +237,8 @@ configure_zone_ssutable(const cfg_obj_t *zconfig, dns_zone_t *zone, | ||
22 | |||
23 | str = cfg_obj_asstring(matchtype); | ||
24 | CHECK(dns_ssu_mtypefromstring(str, &mtype)); | ||
25 | - if (mtype == dns_ssumatchtype_subdomain) { | ||
26 | + if (mtype == dns_ssumatchtype_subdomain && | ||
27 | + strcasecmp(str, "zonesub") == 0) { | ||
28 | usezone = true; | ||
29 | } | ||
30 | |||
31 | -- | ||
32 | 1.9.1 | ||
33 | |||
diff --git a/meta/recipes-connectivity/bind/bind/bind-ensure-searching-for-json-headers-searches-sysr.patch b/meta/recipes-connectivity/bind/bind/bind-ensure-searching-for-json-headers-searches-sysr.patch index 37e210e6da..84559e5f37 100644 --- a/meta/recipes-connectivity/bind/bind/bind-ensure-searching-for-json-headers-searches-sysr.patch +++ b/meta/recipes-connectivity/bind/bind/bind-ensure-searching-for-json-headers-searches-sysr.patch | |||
@@ -1,4 +1,4 @@ | |||
1 | From 9473d29843579802e96b0293a3e953fed93de82c Mon Sep 17 00:00:00 2001 | 1 | From edda20fb5a6e88548f85e39d34d6c074306e15bc Mon Sep 17 00:00:00 2001 |
2 | From: Paul Gortmaker <paul.gortmaker@windriver.com> | 2 | From: Paul Gortmaker <paul.gortmaker@windriver.com> |
3 | Date: Tue, 9 Jun 2015 11:22:00 -0400 | 3 | Date: Tue, 9 Jun 2015 11:22:00 -0400 |
4 | Subject: [PATCH] bind: ensure searching for json headers searches sysroot | 4 | Subject: [PATCH] bind: ensure searching for json headers searches sysroot |
@@ -27,15 +27,16 @@ to make use of the combination some day. | |||
27 | 27 | ||
28 | Upstream-Status: Inappropriate [OE Specific] | 28 | Upstream-Status: Inappropriate [OE Specific] |
29 | Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com> | 29 | Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com> |
30 | |||
30 | --- | 31 | --- |
31 | configure.in | 2 +- | 32 | configure.ac | 2 +- |
32 | 1 file changed, 1 insertion(+), 1 deletion(-) | 33 | 1 file changed, 1 insertion(+), 1 deletion(-) |
33 | 34 | ||
34 | Index: bind-9.11.3/configure.in | 35 | diff --git a/configure.ac b/configure.ac |
35 | =================================================================== | 36 | index 17392fd..e85a5c6 100644 |
36 | --- bind-9.11.3.orig/configure.in | 37 | --- a/configure.ac |
37 | +++ bind-9.11.3/configure.in | 38 | +++ b/configure.ac |
38 | @@ -2574,7 +2574,7 @@ case "$use_libjson" in | 39 | @@ -2449,7 +2449,7 @@ case "$use_libjson" in |
39 | libjson_libs="" | 40 | libjson_libs="" |
40 | ;; | 41 | ;; |
41 | auto|yes) | 42 | auto|yes) |
diff --git a/meta/recipes-connectivity/bind/bind_9.11.5-P4.bb b/meta/recipes-connectivity/bind/bind_9.11.19.bb index b0bb64b7c7..d4467b0b48 100644 --- a/meta/recipes-connectivity/bind/bind_9.11.5-P4.bb +++ b/meta/recipes-connectivity/bind/bind_9.11.19.bb | |||
@@ -3,7 +3,7 @@ HOMEPAGE = "http://www.isc.org/sw/bind/" | |||
3 | SECTION = "console/network" | 3 | SECTION = "console/network" |
4 | 4 | ||
5 | LICENSE = "ISC & BSD" | 5 | LICENSE = "ISC & BSD" |
6 | LIC_FILES_CHKSUM = "file://COPYRIGHT;md5=8f17f64e47e83b60cd920a1e4b54419e" | 6 | LIC_FILES_CHKSUM = "file://COPYRIGHT;md5=bf39058a7f64b2a934ce14dc9ec1dd45" |
7 | 7 | ||
8 | DEPENDS = "openssl libcap zlib" | 8 | DEPENDS = "openssl libcap zlib" |
9 | 9 | ||
@@ -15,23 +15,15 @@ SRC_URI = "https://ftp.isc.org/isc/bind9/${PV}/${BPN}-${PV}.tar.gz \ | |||
15 | file://make-etc-initd-bind-stop-work.patch \ | 15 | file://make-etc-initd-bind-stop-work.patch \ |
16 | file://init.d-add-support-for-read-only-rootfs.patch \ | 16 | file://init.d-add-support-for-read-only-rootfs.patch \ |
17 | file://bind-ensure-searching-for-json-headers-searches-sysr.patch \ | 17 | file://bind-ensure-searching-for-json-headers-searches-sysr.patch \ |
18 | file://0001-gen.c-extend-DIRNAMESIZE-from-256-to-512.patch \ | ||
19 | file://0001-lib-dns-gen.c-fix-too-long-error.patch \ | ||
20 | file://0001-configure.in-remove-useless-L-use_openssl-lib.patch \ | 18 | file://0001-configure.in-remove-useless-L-use_openssl-lib.patch \ |
21 | file://0001-named-lwresd-V-and-start-log-hide-build-options.patch \ | 19 | file://0001-named-lwresd-V-and-start-log-hide-build-options.patch \ |
22 | file://0001-avoid-start-failure-with-bind-user.patch \ | 20 | file://0001-avoid-start-failure-with-bind-user.patch \ |
23 | file://0001-bind-fix-CVE-2019-6471.patch \ | 21 | file://CVE-2020-8622.patch \ |
24 | file://0001-fix-enforcement-of-tcp-clients-v1.patch \ | 22 | file://CVE-2020-8623.patch \ |
25 | file://0002-tcp-clients-could-still-be-exceeded-v2.patch \ | 23 | file://CVE-2020-8624.patch \ |
26 | file://0003-use-reference-counter-for-pipeline-groups-v3.patch \ | 24 | " |
27 | file://0004-better-tcpquota-accounting-and-client-mortality-chec.patch \ | 25 | |
28 | file://0005-refactor-tcpquota-and-pipeline-refs-allow-special-ca.patch \ | 26 | SRC_URI[sha256sum] = "0dee554a4caa368948b32da9a0c97b516c19103bc13ff5b3762c5d8552f52329" |
29 | file://0006-restore-allowance-for-tcp-clients-interfaces.patch \ | ||
30 | file://0007-Replace-atomic-operations-in-bin-named-client.c-with.patch \ | ||
31 | " | ||
32 | |||
33 | SRC_URI[md5sum] = "8ddab4b61fa4516fe404679c74e37960" | ||
34 | SRC_URI[sha256sum] = "7e8c08192bcbaeb6e9f2391a70e67583b027b90e8c4bc1605da6eb126edde434" | ||
35 | 27 | ||
36 | UPSTREAM_CHECK_URI = "https://ftp.isc.org/isc/bind9/" | 28 | UPSTREAM_CHECK_URI = "https://ftp.isc.org/isc/bind9/" |
37 | # stay at 9.11 until 9.16, from 9.16 follow the ESV versions divisible by 4 | 29 | # stay at 9.11 until 9.16, from 9.16 follow the ESV versions divisible by 4 |
diff --git a/meta/recipes-connectivity/bluez5/bluez5.inc b/meta/recipes-connectivity/bluez5/bluez5.inc index f582a07e22..75fc2dbf4c 100644 --- a/meta/recipes-connectivity/bluez5/bluez5.inc +++ b/meta/recipes-connectivity/bluez5/bluez5.inc | |||
@@ -58,6 +58,8 @@ SRC_URI = "\ | |||
58 | file://CVE-2018-10910.patch \ | 58 | file://CVE-2018-10910.patch \ |
59 | file://gcc9-fixes.patch \ | 59 | file://gcc9-fixes.patch \ |
60 | file://0001-tools-Fix-build-after-y2038-changes-in-glibc.patch \ | 60 | file://0001-tools-Fix-build-after-y2038-changes-in-glibc.patch \ |
61 | file://CVE-2020-0556-1.patch \ | ||
62 | file://CVE-2020-0556-2.patch \ | ||
61 | " | 63 | " |
62 | S = "${WORKDIR}/bluez-${PV}" | 64 | S = "${WORKDIR}/bluez-${PV}" |
63 | 65 | ||
diff --git a/meta/recipes-connectivity/bluez5/bluez5/CVE-2020-0556-1.patch b/meta/recipes-connectivity/bluez5/bluez5/CVE-2020-0556-1.patch new file mode 100644 index 0000000000..a6bf31e14b --- /dev/null +++ b/meta/recipes-connectivity/bluez5/bluez5/CVE-2020-0556-1.patch | |||
@@ -0,0 +1,35 @@ | |||
1 | From 8cdbd3b09f29da29374e2f83369df24228da0ad1 Mon Sep 17 00:00:00 2001 | ||
2 | From: Alain Michaud <alainm@chromium.org> | ||
3 | Date: Tue, 10 Mar 2020 02:35:16 +0000 | ||
4 | Subject: [PATCH 1/2] HOGP must only accept data from bonded devices. | ||
5 | |||
6 | HOGP 1.0 Section 6.1 establishes that the HOGP must require bonding. | ||
7 | |||
8 | Reference: | ||
9 | https://www.intel.com/content/www/us/en/security-center/advisory/intel-sa-00352.htm | ||
10 | |||
11 | Upstream-Status: Backport [https://git.kernel.org/pub/scm/bluetooth/bluez.git/commit/?id=8cdbd3b09f29da29374e2f83369df24228da0ad1] | ||
12 | Signed-off-by: Anuj Mittal <anuj.mittal@intel.com> | ||
13 | CVE: CVE-2020-0556 | ||
14 | --- | ||
15 | profiles/input/hog.c | 4 ++++ | ||
16 | 1 file changed, 4 insertions(+) | ||
17 | |||
18 | diff --git a/profiles/input/hog.c b/profiles/input/hog.c | ||
19 | index 83c017dcb..dfac68921 100644 | ||
20 | --- a/profiles/input/hog.c | ||
21 | +++ b/profiles/input/hog.c | ||
22 | @@ -186,6 +186,10 @@ static int hog_accept(struct btd_service *service) | ||
23 | return -EINVAL; | ||
24 | } | ||
25 | |||
26 | + /* HOGP 1.0 Section 6.1 requires bonding */ | ||
27 | + if (!device_is_bonded(device, btd_device_get_bdaddr_type(device))) | ||
28 | + return -ECONNREFUSED; | ||
29 | + | ||
30 | /* TODO: Replace GAttrib with bt_gatt_client */ | ||
31 | bt_hog_attach(dev->hog, attrib); | ||
32 | |||
33 | -- | ||
34 | 2.24.1 | ||
35 | |||
diff --git a/meta/recipes-connectivity/bluez5/bluez5/CVE-2020-0556-2.patch b/meta/recipes-connectivity/bluez5/bluez5/CVE-2020-0556-2.patch new file mode 100644 index 0000000000..8acb2f15ec --- /dev/null +++ b/meta/recipes-connectivity/bluez5/bluez5/CVE-2020-0556-2.patch | |||
@@ -0,0 +1,143 @@ | |||
1 | From 3cccdbab2324086588df4ccf5f892fb3ce1f1787 Mon Sep 17 00:00:00 2001 | ||
2 | From: Alain Michaud <alainm@chromium.org> | ||
3 | Date: Tue, 10 Mar 2020 02:35:18 +0000 | ||
4 | Subject: [PATCH 2/2] HID accepts bonded device connections only. | ||
5 | |||
6 | This change adds a configuration for platforms to choose a more secure | ||
7 | posture for the HID profile. While some older mice are known to not | ||
8 | support pairing or encryption, some platform may choose a more secure | ||
9 | posture by requiring the device to be bonded and require the | ||
10 | connection to be encrypted when bonding is required. | ||
11 | |||
12 | Reference: | ||
13 | https://www.intel.com/content/www/us/en/security-center/advisory/intel-sa-00352.html | ||
14 | |||
15 | Upstream-Status: Backport [https://git.kernel.org/pub/scm/bluetooth/bluez.git/commit/?id=3cccdbab2324086588df4ccf5f892fb3ce1f1787] | ||
16 | Signed-off-by: Anuj Mittal <anuj.mittal@intel.com> | ||
17 | CVE: CVE-2020-0556 | ||
18 | |||
19 | --- | ||
20 | profiles/input/device.c | 23 ++++++++++++++++++++++- | ||
21 | profiles/input/device.h | 1 + | ||
22 | profiles/input/input.conf | 8 ++++++++ | ||
23 | profiles/input/manager.c | 13 ++++++++++++- | ||
24 | 4 files changed, 43 insertions(+), 2 deletions(-) | ||
25 | |||
26 | diff --git a/profiles/input/device.c b/profiles/input/device.c | ||
27 | index 2cb3811c8..d89da2d7c 100644 | ||
28 | --- a/profiles/input/device.c | ||
29 | +++ b/profiles/input/device.c | ||
30 | @@ -92,6 +92,7 @@ struct input_device { | ||
31 | |||
32 | static int idle_timeout = 0; | ||
33 | static bool uhid_enabled = false; | ||
34 | +static bool classic_bonded_only = false; | ||
35 | |||
36 | void input_set_idle_timeout(int timeout) | ||
37 | { | ||
38 | @@ -103,6 +104,11 @@ void input_enable_userspace_hid(bool state) | ||
39 | uhid_enabled = state; | ||
40 | } | ||
41 | |||
42 | +void input_set_classic_bonded_only(bool state) | ||
43 | +{ | ||
44 | + classic_bonded_only = state; | ||
45 | +} | ||
46 | + | ||
47 | static void input_device_enter_reconnect_mode(struct input_device *idev); | ||
48 | static int connection_disconnect(struct input_device *idev, uint32_t flags); | ||
49 | |||
50 | @@ -970,8 +976,18 @@ static int hidp_add_connection(struct input_device *idev) | ||
51 | if (device_name_known(idev->device)) | ||
52 | device_get_name(idev->device, req->name, sizeof(req->name)); | ||
53 | |||
54 | + /* Make sure the device is bonded if required */ | ||
55 | + if (classic_bonded_only && !device_is_bonded(idev->device, | ||
56 | + btd_device_get_bdaddr_type(idev->device))) { | ||
57 | + error("Rejected connection from !bonded device %s", dst_addr); | ||
58 | + goto cleanup; | ||
59 | + } | ||
60 | + | ||
61 | /* Encryption is mandatory for keyboards */ | ||
62 | - if (req->subclass & 0x40) { | ||
63 | + /* Some platforms may choose to require encryption for all devices */ | ||
64 | + /* Note that this only matters for pre 2.1 devices as otherwise the */ | ||
65 | + /* device is encrypted by default by the lower layers */ | ||
66 | + if (classic_bonded_only || req->subclass & 0x40) { | ||
67 | if (!bt_io_set(idev->intr_io, &gerr, | ||
68 | BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_MEDIUM, | ||
69 | BT_IO_OPT_INVALID)) { | ||
70 | @@ -1203,6 +1219,11 @@ static void input_device_enter_reconnect_mode(struct input_device *idev) | ||
71 | DBG("path=%s reconnect_mode=%s", idev->path, | ||
72 | reconnect_mode_to_string(idev->reconnect_mode)); | ||
73 | |||
74 | + /* Make sure the device is bonded if required */ | ||
75 | + if (classic_bonded_only && !device_is_bonded(idev->device, | ||
76 | + btd_device_get_bdaddr_type(idev->device))) | ||
77 | + return; | ||
78 | + | ||
79 | /* Only attempt an auto-reconnect when the device is required to | ||
80 | * accept reconnections from the host. | ||
81 | */ | ||
82 | diff --git a/profiles/input/device.h b/profiles/input/device.h | ||
83 | index 51a9aee18..3044db673 100644 | ||
84 | --- a/profiles/input/device.h | ||
85 | +++ b/profiles/input/device.h | ||
86 | @@ -29,6 +29,7 @@ struct input_conn; | ||
87 | |||
88 | void input_set_idle_timeout(int timeout); | ||
89 | void input_enable_userspace_hid(bool state); | ||
90 | +void input_set_classic_bonded_only(bool state); | ||
91 | |||
92 | int input_device_register(struct btd_service *service); | ||
93 | void input_device_unregister(struct btd_service *service); | ||
94 | diff --git a/profiles/input/input.conf b/profiles/input/input.conf | ||
95 | index 3e1d65aae..166aff4a4 100644 | ||
96 | --- a/profiles/input/input.conf | ||
97 | +++ b/profiles/input/input.conf | ||
98 | @@ -11,3 +11,11 @@ | ||
99 | # Enable HID protocol handling in userspace input profile | ||
100 | # Defaults to false (HIDP handled in HIDP kernel module) | ||
101 | #UserspaceHID=true | ||
102 | + | ||
103 | +# Limit HID connections to bonded devices | ||
104 | +# The HID Profile does not specify that devices must be bonded, however some | ||
105 | +# platforms may want to make sure that input connections only come from bonded | ||
106 | +# device connections. Several older mice have been known for not supporting | ||
107 | +# pairing/encryption. | ||
108 | +# Defaults to false to maximize device compatibility. | ||
109 | +#ClassicBondedOnly=true | ||
110 | diff --git a/profiles/input/manager.c b/profiles/input/manager.c | ||
111 | index 1d31b0652..5cd27b839 100644 | ||
112 | --- a/profiles/input/manager.c | ||
113 | +++ b/profiles/input/manager.c | ||
114 | @@ -96,7 +96,7 @@ static int input_init(void) | ||
115 | config = load_config_file(CONFIGDIR "/input.conf"); | ||
116 | if (config) { | ||
117 | int idle_timeout; | ||
118 | - gboolean uhid_enabled; | ||
119 | + gboolean uhid_enabled, classic_bonded_only; | ||
120 | |||
121 | idle_timeout = g_key_file_get_integer(config, "General", | ||
122 | "IdleTimeout", &err); | ||
123 | @@ -114,6 +114,17 @@ static int input_init(void) | ||
124 | input_enable_userspace_hid(uhid_enabled); | ||
125 | } else | ||
126 | g_clear_error(&err); | ||
127 | + | ||
128 | + classic_bonded_only = g_key_file_get_boolean(config, "General", | ||
129 | + "ClassicBondedOnly", &err); | ||
130 | + | ||
131 | + if (!err) { | ||
132 | + DBG("input.conf: ClassicBondedOnly=%s", | ||
133 | + classic_bonded_only ? "true" : "false"); | ||
134 | + input_set_classic_bonded_only(classic_bonded_only); | ||
135 | + } else | ||
136 | + g_clear_error(&err); | ||
137 | + | ||
138 | } | ||
139 | |||
140 | btd_profile_register(&input_profile); | ||
141 | -- | ||
142 | 2.24.1 | ||
143 | |||
diff --git a/meta/recipes-connectivity/dhcp/dhcp/0001-Ensure-context-is-running-prior-to-calling-isc_app_c.patch b/meta/recipes-connectivity/dhcp/dhcp/0001-Ensure-context-is-running-prior-to-calling-isc_app_c.patch new file mode 100644 index 0000000000..34b2ae1e5c --- /dev/null +++ b/meta/recipes-connectivity/dhcp/dhcp/0001-Ensure-context-is-running-prior-to-calling-isc_app_c.patch | |||
@@ -0,0 +1,165 @@ | |||
1 | From f369dbb9e67eb5ef336944af63039b6d8f838384 Mon Sep 17 00:00:00 2001 | ||
2 | From: Thomas Markwalder <tmark@isc.org> | ||
3 | Date: Thu, 12 Sep 2019 10:35:46 -0400 | ||
4 | Subject: [PATCH 1/3] Ensure context is running prior to calling | ||
5 | isc_app_ctxsuspend | ||
6 | |||
7 | Add a release note. | ||
8 | |||
9 | includes/omapip/isclib.h | ||
10 | Added actx_running flag to global context, dhcp_gbl_ctx | ||
11 | |||
12 | omapip/isclib.c | ||
13 | set_ctx_running() - new function used as the ctxonrun callback | ||
14 | |||
15 | dhcp_context_create() - installs set_ctx_running callback | ||
16 | |||
17 | dhcp_signal_handler() - modified to use act_running flag to | ||
18 | determine is context is running and should be suspended | ||
19 | |||
20 | Upstream-Status: Backport [https://gitlab.isc.org/isc-projects/dhcp.git] | ||
21 | |||
22 | Signed-off-by: Ovidiu Panait <ovidiu.panait@windriver.com> | ||
23 | --- | ||
24 | RELNOTES | 7 +++++ | ||
25 | includes/omapip/isclib.h | 3 ++- | ||
26 | omapip/isclib.c | 57 +++++++++++++++++++++++++++++++++------- | ||
27 | 3 files changed, 57 insertions(+), 10 deletions(-) | ||
28 | |||
29 | diff --git a/RELNOTES b/RELNOTES | ||
30 | index f10305d..1730473 100644 | ||
31 | --- a/RELNOTES | ||
32 | +++ b/RELNOTES | ||
33 | @@ -6,6 +6,13 @@ | ||
34 | |||
35 | NEW FEATURES | ||
36 | |||
37 | +- Closed a small window of time between the installation of graceful | ||
38 | + shutdown signal handlers and application context startup, during which | ||
39 | + the receipt of shutdown signal would cause a REQUIRE() assertion to | ||
40 | + occur. Note this issue is only visible when compiling with | ||
41 | + ENABLE_GENTLE_SHUTDOWN defined. | ||
42 | + [Gitlab #53,!18 git TBD] | ||
43 | + | ||
44 | Please note that that ISC DHCP is now licensed under the Mozilla Public License, | ||
45 | MPL 2.0. Please see https://www.mozilla.org/en-US/MPL/2.0/ to read the MPL 2.0 | ||
46 | license terms. | ||
47 | diff --git a/includes/omapip/isclib.h b/includes/omapip/isclib.h | ||
48 | index 6c20584..af6a6fc 100644 | ||
49 | --- a/includes/omapip/isclib.h | ||
50 | +++ b/includes/omapip/isclib.h | ||
51 | @@ -94,7 +94,8 @@ | ||
52 | typedef struct dhcp_context { | ||
53 | isc_mem_t *mctx; | ||
54 | isc_appctx_t *actx; | ||
55 | - int actx_started; | ||
56 | + int actx_started; // ISC_TRUE if ctxstart has been called | ||
57 | + int actx_running; // ISC_TRUE if ctxrun has been called | ||
58 | isc_taskmgr_t *taskmgr; | ||
59 | isc_task_t *task; | ||
60 | isc_socketmgr_t *socketmgr; | ||
61 | diff --git a/omapip/isclib.c b/omapip/isclib.c | ||
62 | index ce4b4a1..73e017c 100644 | ||
63 | --- a/omapip/isclib.c | ||
64 | +++ b/omapip/isclib.c | ||
65 | @@ -134,6 +134,35 @@ handle_signal(int sig, void (*handler)(int)) { | ||
66 | } | ||
67 | } | ||
68 | |||
69 | +/* Callback passed to isc_app_ctxonrun | ||
70 | + * | ||
71 | + * BIND9 context code will invoke this handler once the context has | ||
72 | + * entered the running state. We use it to set a global marker so that | ||
73 | + * we can tell if the context is running. Several of the isc_app_ | ||
74 | + * calls REQUIRE that the context is running and we need a way to | ||
75 | + * know that. | ||
76 | + * | ||
77 | + * We also check to see if we received a shutdown signal prior to | ||
78 | + * the context entering the run state. If we did, then we can just | ||
79 | + * simply shut the context down now. This closes the relatively | ||
80 | + * small window between start up and entering run via the call | ||
81 | + * to dispatch(). | ||
82 | + * | ||
83 | + */ | ||
84 | +static void | ||
85 | +set_ctx_running(isc_task_t *task, isc_event_t *event) { | ||
86 | + task = task; // unused; | ||
87 | + dhcp_gbl_ctx.actx_running = ISC_TRUE; | ||
88 | + | ||
89 | + if (shutdown_signal) { | ||
90 | + // We got signaled shutdown before we entered running state. | ||
91 | + // Now that we've reached running state, shut'er down. | ||
92 | + isc_app_ctxsuspend(dhcp_gbl_ctx.actx); | ||
93 | + } | ||
94 | + | ||
95 | + isc_event_free(&event); | ||
96 | +} | ||
97 | + | ||
98 | isc_result_t | ||
99 | dhcp_context_create(int flags, | ||
100 | struct in_addr *local4, | ||
101 | @@ -141,6 +170,9 @@ dhcp_context_create(int flags, | ||
102 | isc_result_t result; | ||
103 | |||
104 | if ((flags & DHCP_CONTEXT_PRE_DB) != 0) { | ||
105 | + dhcp_gbl_ctx.actx_started = ISC_FALSE; | ||
106 | + dhcp_gbl_ctx.actx_running = ISC_FALSE; | ||
107 | + | ||
108 | /* | ||
109 | * Set up the error messages, this isn't the right place | ||
110 | * for this call but it is convienent for now. | ||
111 | @@ -204,15 +236,24 @@ dhcp_context_create(int flags, | ||
112 | if (result != ISC_R_SUCCESS) | ||
113 | goto cleanup; | ||
114 | |||
115 | - result = isc_task_create(dhcp_gbl_ctx.taskmgr, 0, &dhcp_gbl_ctx.task); | ||
116 | + result = isc_task_create(dhcp_gbl_ctx.taskmgr, 0, | ||
117 | + &dhcp_gbl_ctx.task); | ||
118 | if (result != ISC_R_SUCCESS) | ||
119 | goto cleanup; | ||
120 | |||
121 | result = isc_app_ctxstart(dhcp_gbl_ctx.actx); | ||
122 | if (result != ISC_R_SUCCESS) | ||
123 | - return (result); | ||
124 | + goto cleanup; | ||
125 | + | ||
126 | dhcp_gbl_ctx.actx_started = ISC_TRUE; | ||
127 | |||
128 | + // Install the onrun callback. | ||
129 | + result = isc_app_ctxonrun(dhcp_gbl_ctx.actx, dhcp_gbl_ctx.mctx, | ||
130 | + dhcp_gbl_ctx.task, set_ctx_running, | ||
131 | + dhcp_gbl_ctx.actx); | ||
132 | + if (result != ISC_R_SUCCESS) | ||
133 | + goto cleanup; | ||
134 | + | ||
135 | /* Not all OSs support suppressing SIGPIPE through socket | ||
136 | * options, so set the sigal action to be ignore. This allows | ||
137 | * broken connections to fail gracefully with EPIPE on writes */ | ||
138 | @@ -335,19 +376,17 @@ isclib_make_dst_key(char *inname, | ||
139 | * @param signal signal code that we received | ||
140 | */ | ||
141 | void dhcp_signal_handler(int signal) { | ||
142 | - isc_appctx_t *ctx = dhcp_gbl_ctx.actx; | ||
143 | - int prev = shutdown_signal; | ||
144 | - | ||
145 | - if (prev != 0) { | ||
146 | + if (shutdown_signal != 0) { | ||
147 | /* Already in shutdown. */ | ||
148 | return; | ||
149 | } | ||
150 | + | ||
151 | /* Possible race but does it matter? */ | ||
152 | shutdown_signal = signal; | ||
153 | |||
154 | - /* Use reload (aka suspend) for easier dispatch() reenter. */ | ||
155 | - if (ctx && ctx->methods && ctx->methods->ctxsuspend) { | ||
156 | - (void) isc_app_ctxsuspend(ctx); | ||
157 | + /* If the application context is running tell it to shut down */ | ||
158 | + if (dhcp_gbl_ctx.actx_running == ISC_TRUE) { | ||
159 | + (void) isc_app_ctxsuspend(dhcp_gbl_ctx.actx); | ||
160 | } | ||
161 | } | ||
162 | |||
163 | -- | ||
164 | 2.23.0 | ||
165 | |||
diff --git a/meta/recipes-connectivity/dhcp/dhcp/0002-Added-shutdown-log-statment-to-dhcrelay.patch b/meta/recipes-connectivity/dhcp/dhcp/0002-Added-shutdown-log-statment-to-dhcrelay.patch new file mode 100644 index 0000000000..78b2b74f45 --- /dev/null +++ b/meta/recipes-connectivity/dhcp/dhcp/0002-Added-shutdown-log-statment-to-dhcrelay.patch | |||
@@ -0,0 +1,29 @@ | |||
1 | From adcd34ae1f56b16d7e9696d980332b4cf6c7ce91 Mon Sep 17 00:00:00 2001 | ||
2 | From: Thomas Markwalder <tmark@isc.org> | ||
3 | Date: Fri, 13 Sep 2019 15:03:31 -0400 | ||
4 | Subject: [PATCH 2/3] Added shutdown log statment to dhcrelay | ||
5 | |||
6 | Upstream-Status: Backport [https://gitlab.isc.org/isc-projects/dhcp.git] | ||
7 | |||
8 | Signed-off-by: Ovidiu Panait <ovidiu.panait@windriver.com> | ||
9 | --- | ||
10 | relay/dhcrelay.c | 3 +++ | ||
11 | 1 file changed, 3 insertions(+) | ||
12 | |||
13 | diff --git a/relay/dhcrelay.c b/relay/dhcrelay.c | ||
14 | index d8caaaf..4bd1d47 100644 | ||
15 | --- a/relay/dhcrelay.c | ||
16 | +++ b/relay/dhcrelay.c | ||
17 | @@ -2076,6 +2076,9 @@ dhcp_set_control_state(control_object_state_t oldstate, | ||
18 | if (newstate != server_shutdown) | ||
19 | return ISC_R_SUCCESS; | ||
20 | |||
21 | + /* Log shutdown on signal. */ | ||
22 | + log_info("Received signal %d, initiating shutdown.", shutdown_signal); | ||
23 | + | ||
24 | if (no_pid_file == ISC_FALSE) | ||
25 | (void) unlink(path_dhcrelay_pid); | ||
26 | |||
27 | -- | ||
28 | 2.23.0 | ||
29 | |||
diff --git a/meta/recipes-connectivity/dhcp/dhcp/0003-Addressed-review-comment.patch b/meta/recipes-connectivity/dhcp/dhcp/0003-Addressed-review-comment.patch new file mode 100644 index 0000000000..a51b6cf526 --- /dev/null +++ b/meta/recipes-connectivity/dhcp/dhcp/0003-Addressed-review-comment.patch | |||
@@ -0,0 +1,31 @@ | |||
1 | From e4b54b4d676783152d487103714cba2913661ef8 Mon Sep 17 00:00:00 2001 | ||
2 | From: Thomas Markwalder <tmark@isc.org> | ||
3 | Date: Wed, 6 Nov 2019 15:53:50 -0500 | ||
4 | Subject: [PATCH 3/3] Addressed review comment. | ||
5 | |||
6 | omapip/isclib.c | ||
7 | Added use of IGNORE_UNUSED() | ||
8 | |||
9 | Upstream-Status: Backport [https://gitlab.isc.org/isc-projects/dhcp.git] | ||
10 | |||
11 | Signed-off-by: Ovidiu Panait <ovidiu.panait@windriver.com> | ||
12 | --- | ||
13 | omapip/isclib.c | 2 +- | ||
14 | 1 file changed, 1 insertion(+), 1 deletion(-) | ||
15 | |||
16 | diff --git a/omapip/isclib.c b/omapip/isclib.c | ||
17 | index 73e017c..1d52463 100644 | ||
18 | --- a/omapip/isclib.c | ||
19 | +++ b/omapip/isclib.c | ||
20 | @@ -151,7 +151,7 @@ handle_signal(int sig, void (*handler)(int)) { | ||
21 | */ | ||
22 | static void | ||
23 | set_ctx_running(isc_task_t *task, isc_event_t *event) { | ||
24 | - task = task; // unused; | ||
25 | + IGNORE_UNUSED(task); | ||
26 | dhcp_gbl_ctx.actx_running = ISC_TRUE; | ||
27 | |||
28 | if (shutdown_signal) { | ||
29 | -- | ||
30 | 2.23.0 | ||
31 | |||
diff --git a/meta/recipes-connectivity/dhcp/dhcp_4.4.1.bb b/meta/recipes-connectivity/dhcp/dhcp_4.4.1.bb index 275961a603..ddc8b60254 100644 --- a/meta/recipes-connectivity/dhcp/dhcp_4.4.1.bb +++ b/meta/recipes-connectivity/dhcp/dhcp_4.4.1.bb | |||
@@ -11,6 +11,9 @@ SRC_URI += "file://0001-define-macro-_PATH_DHCPD_CONF-and-_PATH_DHCLIENT_CON.pat | |||
11 | file://0013-fixup_use_libbind.patch \ | 11 | file://0013-fixup_use_libbind.patch \ |
12 | file://0001-master-Added-includes-of-new-BIND9-compatibility-hea.patch \ | 12 | file://0001-master-Added-includes-of-new-BIND9-compatibility-hea.patch \ |
13 | file://0001-Fix-a-NSUPDATE-compiling-issue.patch \ | 13 | file://0001-Fix-a-NSUPDATE-compiling-issue.patch \ |
14 | file://0001-Ensure-context-is-running-prior-to-calling-isc_app_c.patch \ | ||
15 | file://0002-Added-shutdown-log-statment-to-dhcrelay.patch \ | ||
16 | file://0003-Addressed-review-comment.patch \ | ||
14 | " | 17 | " |
15 | 18 | ||
16 | SRC_URI[md5sum] = "18c7f4dcbb0a63df25098216d47b1ede" | 19 | SRC_URI[md5sum] = "18c7f4dcbb0a63df25098216d47b1ede" |
diff --git a/meta/recipes-connectivity/inetutils/inetutils_1.9.4.bb b/meta/recipes-connectivity/inetutils/inetutils_1.9.4.bb index 684fbe09e1..cc9410b94e 100644 --- a/meta/recipes-connectivity/inetutils/inetutils_1.9.4.bb +++ b/meta/recipes-connectivity/inetutils/inetutils_1.9.4.bb | |||
@@ -143,11 +143,15 @@ ALTERNATIVE_${PN}-traceroute = "traceroute" | |||
143 | ALTERNATIVE_${PN}-hostname = "hostname" | 143 | ALTERNATIVE_${PN}-hostname = "hostname" |
144 | ALTERNATIVE_LINK_NAME[hostname] = "${base_bindir}/hostname" | 144 | ALTERNATIVE_LINK_NAME[hostname] = "${base_bindir}/hostname" |
145 | 145 | ||
146 | ALTERNATIVE_${PN}-doc = "hostname.1 dnsdomainname.1 logger.1 syslogd.8" | 146 | ALTERNATIVE_${PN}-doc = "hostname.1 dnsdomainname.1 logger.1 syslogd.8 \ |
147 | tftpd.8 tftp.1 telnetd.8" | ||
147 | ALTERNATIVE_LINK_NAME[hostname.1] = "${mandir}/man1/hostname.1" | 148 | ALTERNATIVE_LINK_NAME[hostname.1] = "${mandir}/man1/hostname.1" |
148 | ALTERNATIVE_LINK_NAME[dnsdomainname.1] = "${mandir}/man1/dnsdomainname.1" | 149 | ALTERNATIVE_LINK_NAME[dnsdomainname.1] = "${mandir}/man1/dnsdomainname.1" |
149 | ALTERNATIVE_LINK_NAME[logger.1] = "${mandir}/man1/logger.1" | 150 | ALTERNATIVE_LINK_NAME[logger.1] = "${mandir}/man1/logger.1" |
150 | ALTERNATIVE_LINK_NAME[syslogd.8] = "${mandir}/man8/syslogd.8" | 151 | ALTERNATIVE_LINK_NAME[syslogd.8] = "${mandir}/man8/syslogd.8" |
152 | ALTERNATIVE_LINK_NAME[telnetd.8] = "${mandir}/man8/telnetd.8" | ||
153 | ALTERNATIVE_LINK_NAME[tftpd.8] = "${mandir}/man8/tftpd.8" | ||
154 | ALTERNATIVE_LINK_NAME[tftp.1] = "${mandir}/man1/tftp.1" | ||
151 | 155 | ||
152 | ALTERNATIVE_${PN}-ifconfig = "ifconfig" | 156 | ALTERNATIVE_${PN}-ifconfig = "ifconfig" |
153 | ALTERNATIVE_LINK_NAME[ifconfig] = "${base_sbindir}/ifconfig" | 157 | ALTERNATIVE_LINK_NAME[ifconfig] = "${base_sbindir}/ifconfig" |
diff --git a/meta/recipes-connectivity/nfs-utils/nfs-utils/0001-Disable-statx-if-using-glibc-emulation.patch b/meta/recipes-connectivity/nfs-utils/nfs-utils/0001-Disable-statx-if-using-glibc-emulation.patch new file mode 100644 index 0000000000..98b1391923 --- /dev/null +++ b/meta/recipes-connectivity/nfs-utils/nfs-utils/0001-Disable-statx-if-using-glibc-emulation.patch | |||
@@ -0,0 +1,34 @@ | |||
1 | From ff3ad88c233ecd87f7983ad13836323f944540ec Mon Sep 17 00:00:00 2001 | ||
2 | From: Doug Nazar <nazard@nazar.ca> | ||
3 | Date: Mon, 9 Dec 2019 10:53:37 -0500 | ||
4 | Subject: [PATCH] Disable statx if using glibc emulation | ||
5 | |||
6 | On older kernels without statx, glibc with statx support will attempt | ||
7 | to emulate the call. However it doesn't support AT_STATX_DONT_SYNC and | ||
8 | will return EINVAL. This causes all xstat/xlstat calls to fail. | ||
9 | |||
10 | Upstream-Status: Backport | ||
11 | |||
12 | Signed-off-by: Doug Nazar <nazard@nazar.ca> | ||
13 | Signed-off-by: Steve Dickson <steved@redhat.com> | ||
14 | --- | ||
15 | support/misc/xstat.c | 3 +++ | ||
16 | 1 file changed, 3 insertions(+) | ||
17 | |||
18 | diff --git a/support/misc/xstat.c b/support/misc/xstat.c | ||
19 | index 661e29e4..a438fbcc 100644 | ||
20 | --- a/support/misc/xstat.c | ||
21 | +++ b/support/misc/xstat.c | ||
22 | @@ -51,6 +51,9 @@ statx_do_stat(int fd, const char *pathname, struct stat *statbuf, int flags) | ||
23 | statx_copy(statbuf, &stxbuf); | ||
24 | return 0; | ||
25 | } | ||
26 | + /* glibc emulation doesn't support AT_STATX_DONT_SYNC */ | ||
27 | + if (errno == EINVAL) | ||
28 | + errno = ENOSYS; | ||
29 | if (errno == ENOSYS) | ||
30 | statx_supported = 0; | ||
31 | } else | ||
32 | -- | ||
33 | 2.19.1 | ||
34 | |||
diff --git a/meta/recipes-connectivity/nfs-utils/nfs-utils/0001-statd-take-user-id-from-var-lib-nfs-sm.patch b/meta/recipes-connectivity/nfs-utils/nfs-utils/0001-statd-take-user-id-from-var-lib-nfs-sm.patch new file mode 100644 index 0000000000..87f4f098e0 --- /dev/null +++ b/meta/recipes-connectivity/nfs-utils/nfs-utils/0001-statd-take-user-id-from-var-lib-nfs-sm.patch | |||
@@ -0,0 +1,102 @@ | |||
1 | From 12ee0ff1120a6e42b67cc90ad7d5006555e866c3 Mon Sep 17 00:00:00 2001 | ||
2 | From: NeilBrown <neilb@suse.de> | ||
3 | Date: Tue, 23 Jun 2020 09:22:22 +0000 | ||
4 | Subject: [PATCH] statd: take user-id from /var/lib/nfs/sm | ||
5 | |||
6 | Having /var/lib/nfs writeable by statd is not ideal | ||
7 | as there are files in there that statd doesn't need | ||
8 | to access. | ||
9 | After dropping privs, statd and sm-notify only need to | ||
10 | access files in the directories sm and sm.bak. | ||
11 | So take the uid for these deamons from 'sm'. | ||
12 | |||
13 | Upstream-Status: Backport [https://git.linux-nfs.org/?p=steved/nfs-utils.git;a=commitdiff;h=fee2cc29e888f2ced6a76990923aef19d326dc0e] | ||
14 | CVE: CVE-2019-3689 | ||
15 | |||
16 | Signed-off-by: NeilBrown <neilb@suse.de> | ||
17 | Signed-off-by: Steve Dickson <steved@redhat.com> | ||
18 | Signed-off-by: Wenlin Kang <wenlin.kang@windriver.com> | ||
19 | --- | ||
20 | support/nsm/file.c | 16 +++++----------- | ||
21 | utils/statd/sm-notify.man | 10 +++++++++- | ||
22 | utils/statd/statd.man | 10 +++++++++- | ||
23 | 3 files changed, 23 insertions(+), 13 deletions(-) | ||
24 | |||
25 | diff --git a/support/nsm/file.c b/support/nsm/file.c | ||
26 | index 0b66f12..f5b4480 100644 | ||
27 | --- a/support/nsm/file.c | ||
28 | +++ b/support/nsm/file.c | ||
29 | @@ -388,23 +388,17 @@ nsm_drop_privileges(const int pidfd) | ||
30 | |||
31 | (void)umask(S_IRWXO); | ||
32 | |||
33 | - /* | ||
34 | - * XXX: If we can't stat dirname, or if dirname is owned by | ||
35 | - * root, we should use "statduser" instead, which is set up | ||
36 | - * by configure.ac. Nothing in nfs-utils seems to use | ||
37 | - * "statduser," though. | ||
38 | - */ | ||
39 | - if (lstat(nsm_base_dirname, &st) == -1) { | ||
40 | - xlog(L_ERROR, "Failed to stat %s: %m", nsm_base_dirname); | ||
41 | - return false; | ||
42 | - } | ||
43 | - | ||
44 | if (chdir(nsm_base_dirname) == -1) { | ||
45 | xlog(L_ERROR, "Failed to change working directory to %s: %m", | ||
46 | nsm_base_dirname); | ||
47 | return false; | ||
48 | } | ||
49 | |||
50 | + if (lstat(NSM_MONITOR_DIR, &st) == -1) { | ||
51 | + xlog(L_ERROR, "Failed to stat %s/%s: %m", nsm_base_dirname, NSM_MONITOR_DIR); | ||
52 | + return false; | ||
53 | + } | ||
54 | + | ||
55 | if (!prune_bounding_set()) | ||
56 | return false; | ||
57 | |||
58 | diff --git a/utils/statd/sm-notify.man b/utils/statd/sm-notify.man | ||
59 | index cfe1e4b..addf5d3 100644 | ||
60 | --- a/utils/statd/sm-notify.man | ||
61 | +++ b/utils/statd/sm-notify.man | ||
62 | @@ -190,7 +190,15 @@ by default. | ||
63 | After starting, | ||
64 | .B sm-notify | ||
65 | attempts to set its effective UID and GID to the owner | ||
66 | -and group of this directory. | ||
67 | +and group of the subdirectory | ||
68 | +.B sm | ||
69 | +of this directory. After changing the effective ids, | ||
70 | +.B sm-notify | ||
71 | +only needs to access files in | ||
72 | +.B sm | ||
73 | +and | ||
74 | +.B sm.bak | ||
75 | +within the state-directory-path. | ||
76 | .TP | ||
77 | .BI -v " ipaddr " | " hostname | ||
78 | Specifies the network address from which to send reboot notifications, | ||
79 | diff --git a/utils/statd/statd.man b/utils/statd/statd.man | ||
80 | index 71d5846..6222701 100644 | ||
81 | --- a/utils/statd/statd.man | ||
82 | +++ b/utils/statd/statd.man | ||
83 | @@ -259,7 +259,15 @@ by default. | ||
84 | After starting, | ||
85 | .B rpc.statd | ||
86 | attempts to set its effective UID and GID to the owner | ||
87 | -and group of this directory. | ||
88 | +and group of the subdirectory | ||
89 | +.B sm | ||
90 | +of this directory. After changing the effective ids, | ||
91 | +.B rpc.statd | ||
92 | +only needs to access files in | ||
93 | +.B sm | ||
94 | +and | ||
95 | +.B sm.bak | ||
96 | +within the state-directory-path. | ||
97 | .TP | ||
98 | .BR -v ", " -V ", " --version | ||
99 | Causes | ||
100 | -- | ||
101 | 2.23.0 | ||
102 | |||
diff --git a/meta/recipes-connectivity/nfs-utils/nfs-utils_2.4.1.bb b/meta/recipes-connectivity/nfs-utils/nfs-utils_2.4.1.bb index 7e80354e4e..458e534864 100644 --- a/meta/recipes-connectivity/nfs-utils/nfs-utils_2.4.1.bb +++ b/meta/recipes-connectivity/nfs-utils/nfs-utils_2.4.1.bb | |||
@@ -33,6 +33,8 @@ SRC_URI = "${KERNELORG_MIRROR}/linux/utils/nfs-utils/${PV}/nfs-utils-${PV}.tar.x | |||
33 | file://0001-Makefile.am-fix-undefined-function-for-libnsm.a.patch \ | 33 | file://0001-Makefile.am-fix-undefined-function-for-libnsm.a.patch \ |
34 | file://0001-Don-t-build-tools-with-CC_FOR_BUILD.patch \ | 34 | file://0001-Don-t-build-tools-with-CC_FOR_BUILD.patch \ |
35 | file://0001-Fix-include-order-between-config.h-and-stat.h.patch \ | 35 | file://0001-Fix-include-order-between-config.h-and-stat.h.patch \ |
36 | file://0001-Disable-statx-if-using-glibc-emulation.patch \ | ||
37 | file://0001-statd-take-user-id-from-var-lib-nfs-sm.patch \ | ||
36 | " | 38 | " |
37 | SRC_URI_append_libc-glibc = " file://0001-configure.ac-Do-not-fatalize-Wmissing-prototypes.patch" | 39 | SRC_URI_append_libc-glibc = " file://0001-configure.ac-Do-not-fatalize-Wmissing-prototypes.patch" |
38 | SRC_URI_append_libc-musl = " file://nfs-utils-musl-res_querydomain.patch" | 40 | SRC_URI_append_libc-musl = " file://nfs-utils-musl-res_querydomain.patch" |
diff --git a/meta/recipes-connectivity/openssh/openssh/0001-upstream-what-bozo-decided-to-use-2020-as-a-future-d.patch b/meta/recipes-connectivity/openssh/openssh/0001-upstream-what-bozo-decided-to-use-2020-as-a-future-d.patch new file mode 100644 index 0000000000..e2930c3c7d --- /dev/null +++ b/meta/recipes-connectivity/openssh/openssh/0001-upstream-what-bozo-decided-to-use-2020-as-a-future-d.patch | |||
@@ -0,0 +1,46 @@ | |||
1 | From 3cccc0a2ab597b8273bddf08e9a3cc5551d7e530 Mon Sep 17 00:00:00 2001 | ||
2 | From: "djm@openbsd.org" <djm@openbsd.org> | ||
3 | Date: Fri, 3 Jan 2020 03:02:26 +0000 | ||
4 | Subject: [PATCH] upstream: what bozo decided to use 2020 as a future date in a | ||
5 | regress | ||
6 | |||
7 | test? | ||
8 | |||
9 | OpenBSD-Regress-ID: 3b953df5a7e14081ff6cf495d4e8d40e153cbc3a | ||
10 | |||
11 | Upstream-Status: Backport [https://github.com/openssh/openssh-portable/commit/ff31f15773ee173502eec4d7861ec56f26bba381] | ||
12 | |||
13 | [Dropped the script version and copyright year change at the top] | ||
14 | |||
15 | Signed-off-by: Anuj Mittal <anuj.mittal@intel.com> | ||
16 | --- | ||
17 | regress/cert-hostkey.sh | 2 +- | ||
18 | regress/cert-userkey.sh | 2 +- | ||
19 | 2 files changed, 2 insertions(+), 2 deletions(-) | ||
20 | |||
21 | diff --git a/regress/cert-hostkey.sh b/regress/cert-hostkey.sh | ||
22 | index 3ce7779..74d5a53 100644 | ||
23 | --- a/regress/cert-hostkey.sh | ||
24 | +++ b/regress/cert-hostkey.sh | ||
25 | @@ -248,7 +248,7 @@ test_one() { | ||
26 | test_one "user-certificate" failure "-n $HOSTS" | ||
27 | test_one "empty principals" success "-h" | ||
28 | test_one "wrong principals" failure "-h -n foo" | ||
29 | -test_one "cert not yet valid" failure "-h -V20200101:20300101" | ||
30 | +test_one "cert not yet valid" failure "-h -V20300101:20320101" | ||
31 | test_one "cert expired" failure "-h -V19800101:19900101" | ||
32 | test_one "cert valid interval" success "-h -V-1w:+2w" | ||
33 | test_one "cert has constraints" failure "-h -Oforce-command=false" | ||
34 | diff --git a/regress/cert-userkey.sh b/regress/cert-userkey.sh | ||
35 | index 6849e99..de455b8 100644 | ||
36 | --- a/regress/cert-userkey.sh | ||
37 | +++ b/regress/cert-userkey.sh | ||
38 | @@ -327,7 +327,7 @@ test_one() { | ||
39 | test_one "correct principal" success "-n ${USER}" | ||
40 | test_one "host-certificate" failure "-n ${USER} -h" | ||
41 | test_one "wrong principals" failure "-n foo" | ||
42 | -test_one "cert not yet valid" failure "-n ${USER} -V20200101:20300101" | ||
43 | +test_one "cert not yet valid" failure "-n ${USER} -V20300101:20320101" | ||
44 | test_one "cert expired" failure "-n ${USER} -V19800101:19900101" | ||
45 | test_one "cert valid interval" success "-n ${USER} -V-1w:+2w" | ||
46 | test_one "wrong source-address" failure "-n ${USER} -Osource-address=10.0.0.0/8" | ||
diff --git a/meta/recipes-connectivity/openssh/openssh_8.0p1.bb b/meta/recipes-connectivity/openssh/openssh_8.0p1.bb index 2ffbc9a95f..3d16f9d347 100644 --- a/meta/recipes-connectivity/openssh/openssh_8.0p1.bb +++ b/meta/recipes-connectivity/openssh/openssh_8.0p1.bb | |||
@@ -25,6 +25,7 @@ SRC_URI = "http://ftp.openbsd.org/pub/OpenBSD/OpenSSH/portable/openssh-${PV}.tar | |||
25 | file://sshd_check_keys \ | 25 | file://sshd_check_keys \ |
26 | file://add-test-support-for-busybox.patch \ | 26 | file://add-test-support-for-busybox.patch \ |
27 | file://0001-upstream-fix-integer-overflow-in-XMSS-private-key-pa.patch \ | 27 | file://0001-upstream-fix-integer-overflow-in-XMSS-private-key-pa.patch \ |
28 | file://0001-upstream-what-bozo-decided-to-use-2020-as-a-future-d.patch \ | ||
28 | " | 29 | " |
29 | SRC_URI[md5sum] = "bf050f002fe510e1daecd39044e1122d" | 30 | SRC_URI[md5sum] = "bf050f002fe510e1daecd39044e1122d" |
30 | SRC_URI[sha256sum] = "bd943879e69498e8031eb6b7f44d08cdc37d59a7ab689aa0b437320c3481fd68" | 31 | SRC_URI[sha256sum] = "bd943879e69498e8031eb6b7f44d08cdc37d59a7ab689aa0b437320c3481fd68" |
diff --git a/meta/recipes-connectivity/openssl/openssl/CVE-2019-1551.patch b/meta/recipes-connectivity/openssl/openssl/CVE-2019-1551.patch deleted file mode 100644 index 0cc19cb5f4..0000000000 --- a/meta/recipes-connectivity/openssl/openssl/CVE-2019-1551.patch +++ /dev/null | |||
@@ -1,758 +0,0 @@ | |||
1 | From 419102400a2811582a7a3d4a4e317d72e5ce0a8f Mon Sep 17 00:00:00 2001 | ||
2 | From: Andy Polyakov <appro@openssl.org> | ||
3 | Date: Wed, 4 Dec 2019 12:48:21 +0100 | ||
4 | Subject: [PATCH] Fix an overflow bug in rsaz_512_sqr | ||
5 | |||
6 | There is an overflow bug in the x64_64 Montgomery squaring procedure used in | ||
7 | exponentiation with 512-bit moduli. No EC algorithms are affected. Analysis | ||
8 | suggests that attacks against 2-prime RSA1024, 3-prime RSA1536, and DSA1024 as a | ||
9 | result of this defect would be very difficult to perform and are not believed | ||
10 | likely. Attacks against DH512 are considered just feasible. However, for an | ||
11 | attack the target would have to re-use the DH512 private key, which is not | ||
12 | recommended anyway. Also applications directly using the low level API | ||
13 | BN_mod_exp may be affected if they use BN_FLG_CONSTTIME. | ||
14 | |||
15 | CVE-2019-1551 | ||
16 | |||
17 | Reviewed-by: Paul Dale <paul.dale@oracle.com> | ||
18 | Reviewed-by: Bernd Edlinger <bernd.edlinger@hotmail.de> | ||
19 | (Merged from https://github.com/openssl/openssl/pull/10575) | ||
20 | |||
21 | CVE: CVE-2019-1551 | ||
22 | Upstream-Status: Backport | ||
23 | Signed-off-by: Anuj Mittal <anuj.mittal@intel.com> | ||
24 | --- | ||
25 | crypto/bn/asm/rsaz-x86_64.pl | 381 ++++++++++++++++++----------------- | ||
26 | 1 file changed, 197 insertions(+), 184 deletions(-) | ||
27 | |||
28 | diff --git a/crypto/bn/asm/rsaz-x86_64.pl b/crypto/bn/asm/rsaz-x86_64.pl | ||
29 | index b1797b649f0..7534d5cd03e 100755 | ||
30 | --- a/crypto/bn/asm/rsaz-x86_64.pl | ||
31 | +++ b/crypto/bn/asm/rsaz-x86_64.pl | ||
32 | @@ -116,7 +116,7 @@ | ||
33 | subq \$128+24, %rsp | ||
34 | .cfi_adjust_cfa_offset 128+24 | ||
35 | .Lsqr_body: | ||
36 | - movq $mod, %rbp # common argument | ||
37 | + movq $mod, %xmm1 # common off-load | ||
38 | movq ($inp), %rdx | ||
39 | movq 8($inp), %rax | ||
40 | movq $n0, 128(%rsp) | ||
41 | @@ -134,7 +134,8 @@ | ||
42 | .Loop_sqr: | ||
43 | movl $times,128+8(%rsp) | ||
44 | #first iteration | ||
45 | - movq %rdx, %rbx | ||
46 | + movq %rdx, %rbx # 0($inp) | ||
47 | + mov %rax, %rbp # 8($inp) | ||
48 | mulq %rdx | ||
49 | movq %rax, %r8 | ||
50 | movq 16($inp), %rax | ||
51 | @@ -173,31 +174,29 @@ | ||
52 | mulq %rbx | ||
53 | addq %rax, %r14 | ||
54 | movq %rbx, %rax | ||
55 | - movq %rdx, %r15 | ||
56 | - adcq \$0, %r15 | ||
57 | + adcq \$0, %rdx | ||
58 | |||
59 | - addq %r8, %r8 #shlq \$1, %r8 | ||
60 | - movq %r9, %rcx | ||
61 | - adcq %r9, %r9 #shld \$1, %r8, %r9 | ||
62 | + xorq %rcx,%rcx # rcx:r8 = r8 << 1 | ||
63 | + addq %r8, %r8 | ||
64 | + movq %rdx, %r15 | ||
65 | + adcq \$0, %rcx | ||
66 | |||
67 | mulq %rax | ||
68 | - movq %rax, (%rsp) | ||
69 | - addq %rdx, %r8 | ||
70 | - adcq \$0, %r9 | ||
71 | + addq %r8, %rdx | ||
72 | + adcq \$0, %rcx | ||
73 | |||
74 | - movq %r8, 8(%rsp) | ||
75 | - shrq \$63, %rcx | ||
76 | + movq %rax, (%rsp) | ||
77 | + movq %rdx, 8(%rsp) | ||
78 | |||
79 | #second iteration | ||
80 | - movq 8($inp), %r8 | ||
81 | movq 16($inp), %rax | ||
82 | - mulq %r8 | ||
83 | + mulq %rbp | ||
84 | addq %rax, %r10 | ||
85 | movq 24($inp), %rax | ||
86 | movq %rdx, %rbx | ||
87 | adcq \$0, %rbx | ||
88 | |||
89 | - mulq %r8 | ||
90 | + mulq %rbp | ||
91 | addq %rax, %r11 | ||
92 | movq 32($inp), %rax | ||
93 | adcq \$0, %rdx | ||
94 | @@ -205,7 +204,7 @@ | ||
95 | movq %rdx, %rbx | ||
96 | adcq \$0, %rbx | ||
97 | |||
98 | - mulq %r8 | ||
99 | + mulq %rbp | ||
100 | addq %rax, %r12 | ||
101 | movq 40($inp), %rax | ||
102 | adcq \$0, %rdx | ||
103 | @@ -213,7 +212,7 @@ | ||
104 | movq %rdx, %rbx | ||
105 | adcq \$0, %rbx | ||
106 | |||
107 | - mulq %r8 | ||
108 | + mulq %rbp | ||
109 | addq %rax, %r13 | ||
110 | movq 48($inp), %rax | ||
111 | adcq \$0, %rdx | ||
112 | @@ -221,7 +220,7 @@ | ||
113 | movq %rdx, %rbx | ||
114 | adcq \$0, %rbx | ||
115 | |||
116 | - mulq %r8 | ||
117 | + mulq %rbp | ||
118 | addq %rax, %r14 | ||
119 | movq 56($inp), %rax | ||
120 | adcq \$0, %rdx | ||
121 | @@ -229,39 +228,39 @@ | ||
122 | movq %rdx, %rbx | ||
123 | adcq \$0, %rbx | ||
124 | |||
125 | - mulq %r8 | ||
126 | + mulq %rbp | ||
127 | addq %rax, %r15 | ||
128 | - movq %r8, %rax | ||
129 | + movq %rbp, %rax | ||
130 | adcq \$0, %rdx | ||
131 | addq %rbx, %r15 | ||
132 | - movq %rdx, %r8 | ||
133 | - movq %r10, %rdx | ||
134 | - adcq \$0, %r8 | ||
135 | + adcq \$0, %rdx | ||
136 | |||
137 | - add %rdx, %rdx | ||
138 | - lea (%rcx,%r10,2), %r10 #shld \$1, %rcx, %r10 | ||
139 | - movq %r11, %rbx | ||
140 | - adcq %r11, %r11 #shld \$1, %r10, %r11 | ||
141 | + xorq %rbx, %rbx # rbx:r10:r9 = r10:r9 << 1 | ||
142 | + addq %r9, %r9 | ||
143 | + movq %rdx, %r8 | ||
144 | + adcq %r10, %r10 | ||
145 | + adcq \$0, %rbx | ||
146 | |||
147 | mulq %rax | ||
148 | + addq %rcx, %rax | ||
149 | + movq 16($inp), %rbp | ||
150 | + adcq \$0, %rdx | ||
151 | addq %rax, %r9 | ||
152 | + movq 24($inp), %rax | ||
153 | adcq %rdx, %r10 | ||
154 | - adcq \$0, %r11 | ||
155 | + adcq \$0, %rbx | ||
156 | |||
157 | movq %r9, 16(%rsp) | ||
158 | movq %r10, 24(%rsp) | ||
159 | - shrq \$63, %rbx | ||
160 | |||
161 | #third iteration | ||
162 | - movq 16($inp), %r9 | ||
163 | - movq 24($inp), %rax | ||
164 | - mulq %r9 | ||
165 | + mulq %rbp | ||
166 | addq %rax, %r12 | ||
167 | movq 32($inp), %rax | ||
168 | movq %rdx, %rcx | ||
169 | adcq \$0, %rcx | ||
170 | |||
171 | - mulq %r9 | ||
172 | + mulq %rbp | ||
173 | addq %rax, %r13 | ||
174 | movq 40($inp), %rax | ||
175 | adcq \$0, %rdx | ||
176 | @@ -269,7 +268,7 @@ | ||
177 | movq %rdx, %rcx | ||
178 | adcq \$0, %rcx | ||
179 | |||
180 | - mulq %r9 | ||
181 | + mulq %rbp | ||
182 | addq %rax, %r14 | ||
183 | movq 48($inp), %rax | ||
184 | adcq \$0, %rdx | ||
185 | @@ -277,9 +276,7 @@ | ||
186 | movq %rdx, %rcx | ||
187 | adcq \$0, %rcx | ||
188 | |||
189 | - mulq %r9 | ||
190 | - movq %r12, %r10 | ||
191 | - lea (%rbx,%r12,2), %r12 #shld \$1, %rbx, %r12 | ||
192 | + mulq %rbp | ||
193 | addq %rax, %r15 | ||
194 | movq 56($inp), %rax | ||
195 | adcq \$0, %rdx | ||
196 | @@ -287,36 +284,40 @@ | ||
197 | movq %rdx, %rcx | ||
198 | adcq \$0, %rcx | ||
199 | |||
200 | - mulq %r9 | ||
201 | - shrq \$63, %r10 | ||
202 | + mulq %rbp | ||
203 | addq %rax, %r8 | ||
204 | - movq %r9, %rax | ||
205 | + movq %rbp, %rax | ||
206 | adcq \$0, %rdx | ||
207 | addq %rcx, %r8 | ||
208 | - movq %rdx, %r9 | ||
209 | - adcq \$0, %r9 | ||
210 | + adcq \$0, %rdx | ||
211 | |||
212 | - movq %r13, %rcx | ||
213 | - leaq (%r10,%r13,2), %r13 #shld \$1, %r12, %r13 | ||
214 | + xorq %rcx, %rcx # rcx:r12:r11 = r12:r11 << 1 | ||
215 | + addq %r11, %r11 | ||
216 | + movq %rdx, %r9 | ||
217 | + adcq %r12, %r12 | ||
218 | + adcq \$0, %rcx | ||
219 | |||
220 | mulq %rax | ||
221 | + addq %rbx, %rax | ||
222 | + movq 24($inp), %r10 | ||
223 | + adcq \$0, %rdx | ||
224 | addq %rax, %r11 | ||
225 | + movq 32($inp), %rax | ||
226 | adcq %rdx, %r12 | ||
227 | - adcq \$0, %r13 | ||
228 | + adcq \$0, %rcx | ||
229 | |||
230 | movq %r11, 32(%rsp) | ||
231 | movq %r12, 40(%rsp) | ||
232 | - shrq \$63, %rcx | ||
233 | |||
234 | #fourth iteration | ||
235 | - movq 24($inp), %r10 | ||
236 | - movq 32($inp), %rax | ||
237 | + mov %rax, %r11 # 32($inp) | ||
238 | mulq %r10 | ||
239 | addq %rax, %r14 | ||
240 | movq 40($inp), %rax | ||
241 | movq %rdx, %rbx | ||
242 | adcq \$0, %rbx | ||
243 | |||
244 | + mov %rax, %r12 # 40($inp) | ||
245 | mulq %r10 | ||
246 | addq %rax, %r15 | ||
247 | movq 48($inp), %rax | ||
248 | @@ -325,9 +326,8 @@ | ||
249 | movq %rdx, %rbx | ||
250 | adcq \$0, %rbx | ||
251 | |||
252 | + mov %rax, %rbp # 48($inp) | ||
253 | mulq %r10 | ||
254 | - movq %r14, %r12 | ||
255 | - leaq (%rcx,%r14,2), %r14 #shld \$1, %rcx, %r14 | ||
256 | addq %rax, %r8 | ||
257 | movq 56($inp), %rax | ||
258 | adcq \$0, %rdx | ||
259 | @@ -336,32 +336,33 @@ | ||
260 | adcq \$0, %rbx | ||
261 | |||
262 | mulq %r10 | ||
263 | - shrq \$63, %r12 | ||
264 | addq %rax, %r9 | ||
265 | movq %r10, %rax | ||
266 | adcq \$0, %rdx | ||
267 | addq %rbx, %r9 | ||
268 | - movq %rdx, %r10 | ||
269 | - adcq \$0, %r10 | ||
270 | + adcq \$0, %rdx | ||
271 | |||
272 | - movq %r15, %rbx | ||
273 | - leaq (%r12,%r15,2),%r15 #shld \$1, %r14, %r15 | ||
274 | + xorq %rbx, %rbx # rbx:r13:r14 = r13:r14 << 1 | ||
275 | + addq %r13, %r13 | ||
276 | + movq %rdx, %r10 | ||
277 | + adcq %r14, %r14 | ||
278 | + adcq \$0, %rbx | ||
279 | |||
280 | mulq %rax | ||
281 | + addq %rcx, %rax | ||
282 | + adcq \$0, %rdx | ||
283 | addq %rax, %r13 | ||
284 | + movq %r12, %rax # 40($inp) | ||
285 | adcq %rdx, %r14 | ||
286 | - adcq \$0, %r15 | ||
287 | + adcq \$0, %rbx | ||
288 | |||
289 | movq %r13, 48(%rsp) | ||
290 | movq %r14, 56(%rsp) | ||
291 | - shrq \$63, %rbx | ||
292 | |||
293 | #fifth iteration | ||
294 | - movq 32($inp), %r11 | ||
295 | - movq 40($inp), %rax | ||
296 | mulq %r11 | ||
297 | addq %rax, %r8 | ||
298 | - movq 48($inp), %rax | ||
299 | + movq %rbp, %rax # 48($inp) | ||
300 | movq %rdx, %rcx | ||
301 | adcq \$0, %rcx | ||
302 | |||
303 | @@ -369,97 +370,99 @@ | ||
304 | addq %rax, %r9 | ||
305 | movq 56($inp), %rax | ||
306 | adcq \$0, %rdx | ||
307 | - movq %r8, %r12 | ||
308 | - leaq (%rbx,%r8,2), %r8 #shld \$1, %rbx, %r8 | ||
309 | addq %rcx, %r9 | ||
310 | movq %rdx, %rcx | ||
311 | adcq \$0, %rcx | ||
312 | |||
313 | + mov %rax, %r14 # 56($inp) | ||
314 | mulq %r11 | ||
315 | - shrq \$63, %r12 | ||
316 | addq %rax, %r10 | ||
317 | movq %r11, %rax | ||
318 | adcq \$0, %rdx | ||
319 | addq %rcx, %r10 | ||
320 | - movq %rdx, %r11 | ||
321 | - adcq \$0, %r11 | ||
322 | + adcq \$0, %rdx | ||
323 | |||
324 | - movq %r9, %rcx | ||
325 | - leaq (%r12,%r9,2), %r9 #shld \$1, %r8, %r9 | ||
326 | + xorq %rcx, %rcx # rcx:r8:r15 = r8:r15 << 1 | ||
327 | + addq %r15, %r15 | ||
328 | + movq %rdx, %r11 | ||
329 | + adcq %r8, %r8 | ||
330 | + adcq \$0, %rcx | ||
331 | |||
332 | mulq %rax | ||
333 | + addq %rbx, %rax | ||
334 | + adcq \$0, %rdx | ||
335 | addq %rax, %r15 | ||
336 | + movq %rbp, %rax # 48($inp) | ||
337 | adcq %rdx, %r8 | ||
338 | - adcq \$0, %r9 | ||
339 | + adcq \$0, %rcx | ||
340 | |||
341 | movq %r15, 64(%rsp) | ||
342 | movq %r8, 72(%rsp) | ||
343 | - shrq \$63, %rcx | ||
344 | |||
345 | #sixth iteration | ||
346 | - movq 40($inp), %r12 | ||
347 | - movq 48($inp), %rax | ||
348 | mulq %r12 | ||
349 | addq %rax, %r10 | ||
350 | - movq 56($inp), %rax | ||
351 | + movq %r14, %rax # 56($inp) | ||
352 | movq %rdx, %rbx | ||
353 | adcq \$0, %rbx | ||
354 | |||
355 | mulq %r12 | ||
356 | addq %rax, %r11 | ||
357 | movq %r12, %rax | ||
358 | - movq %r10, %r15 | ||
359 | - leaq (%rcx,%r10,2), %r10 #shld \$1, %rcx, %r10 | ||
360 | adcq \$0, %rdx | ||
361 | - shrq \$63, %r15 | ||
362 | addq %rbx, %r11 | ||
363 | - movq %rdx, %r12 | ||
364 | - adcq \$0, %r12 | ||
365 | + adcq \$0, %rdx | ||
366 | |||
367 | - movq %r11, %rbx | ||
368 | - leaq (%r15,%r11,2), %r11 #shld \$1, %r10, %r11 | ||
369 | + xorq %rbx, %rbx # rbx:r10:r9 = r10:r9 << 1 | ||
370 | + addq %r9, %r9 | ||
371 | + movq %rdx, %r12 | ||
372 | + adcq %r10, %r10 | ||
373 | + adcq \$0, %rbx | ||
374 | |||
375 | mulq %rax | ||
376 | + addq %rcx, %rax | ||
377 | + adcq \$0, %rdx | ||
378 | addq %rax, %r9 | ||
379 | + movq %r14, %rax # 56($inp) | ||
380 | adcq %rdx, %r10 | ||
381 | - adcq \$0, %r11 | ||
382 | + adcq \$0, %rbx | ||
383 | |||
384 | movq %r9, 80(%rsp) | ||
385 | movq %r10, 88(%rsp) | ||
386 | |||
387 | #seventh iteration | ||
388 | - movq 48($inp), %r13 | ||
389 | - movq 56($inp), %rax | ||
390 | - mulq %r13 | ||
391 | + mulq %rbp | ||
392 | addq %rax, %r12 | ||
393 | - movq %r13, %rax | ||
394 | - movq %rdx, %r13 | ||
395 | - adcq \$0, %r13 | ||
396 | + movq %rbp, %rax | ||
397 | + adcq \$0, %rdx | ||
398 | |||
399 | - xorq %r14, %r14 | ||
400 | - shlq \$1, %rbx | ||
401 | - adcq %r12, %r12 #shld \$1, %rbx, %r12 | ||
402 | - adcq %r13, %r13 #shld \$1, %r12, %r13 | ||
403 | - adcq %r14, %r14 #shld \$1, %r13, %r14 | ||
404 | + xorq %rcx, %rcx # rcx:r12:r11 = r12:r11 << 1 | ||
405 | + addq %r11, %r11 | ||
406 | + movq %rdx, %r13 | ||
407 | + adcq %r12, %r12 | ||
408 | + adcq \$0, %rcx | ||
409 | |||
410 | mulq %rax | ||
411 | + addq %rbx, %rax | ||
412 | + adcq \$0, %rdx | ||
413 | addq %rax, %r11 | ||
414 | + movq %r14, %rax # 56($inp) | ||
415 | adcq %rdx, %r12 | ||
416 | - adcq \$0, %r13 | ||
417 | + adcq \$0, %rcx | ||
418 | |||
419 | movq %r11, 96(%rsp) | ||
420 | movq %r12, 104(%rsp) | ||
421 | |||
422 | #eighth iteration | ||
423 | - movq 56($inp), %rax | ||
424 | + xorq %rbx, %rbx # rbx:r13 = r13 << 1 | ||
425 | + addq %r13, %r13 | ||
426 | + adcq \$0, %rbx | ||
427 | + | ||
428 | mulq %rax | ||
429 | - addq %rax, %r13 | ||
430 | + addq %rcx, %rax | ||
431 | adcq \$0, %rdx | ||
432 | - | ||
433 | - addq %rdx, %r14 | ||
434 | - | ||
435 | - movq %r13, 112(%rsp) | ||
436 | - movq %r14, 120(%rsp) | ||
437 | + addq %r13, %rax | ||
438 | + adcq %rbx, %rdx | ||
439 | |||
440 | movq (%rsp), %r8 | ||
441 | movq 8(%rsp), %r9 | ||
442 | @@ -469,6 +472,10 @@ | ||
443 | movq 40(%rsp), %r13 | ||
444 | movq 48(%rsp), %r14 | ||
445 | movq 56(%rsp), %r15 | ||
446 | + movq %xmm1, %rbp | ||
447 | + | ||
448 | + movq %rax, 112(%rsp) | ||
449 | + movq %rdx, 120(%rsp) | ||
450 | |||
451 | call __rsaz_512_reduce | ||
452 | |||
453 | @@ -500,9 +507,9 @@ | ||
454 | .Loop_sqrx: | ||
455 | movl $times,128+8(%rsp) | ||
456 | movq $out, %xmm0 # off-load | ||
457 | - movq %rbp, %xmm1 # off-load | ||
458 | #first iteration | ||
459 | mulx %rax, %r8, %r9 | ||
460 | + mov %rax, %rbx | ||
461 | |||
462 | mulx 16($inp), %rcx, %r10 | ||
463 | xor %rbp, %rbp # cf=0, of=0 | ||
464 | @@ -510,40 +517,39 @@ | ||
465 | mulx 24($inp), %rax, %r11 | ||
466 | adcx %rcx, %r9 | ||
467 | |||
468 | - mulx 32($inp), %rcx, %r12 | ||
469 | + .byte 0xc4,0x62,0xf3,0xf6,0xa6,0x20,0x00,0x00,0x00 # mulx 32($inp), %rcx, %r12 | ||
470 | adcx %rax, %r10 | ||
471 | |||
472 | - mulx 40($inp), %rax, %r13 | ||
473 | + .byte 0xc4,0x62,0xfb,0xf6,0xae,0x28,0x00,0x00,0x00 # mulx 40($inp), %rax, %r13 | ||
474 | adcx %rcx, %r11 | ||
475 | |||
476 | - .byte 0xc4,0x62,0xf3,0xf6,0xb6,0x30,0x00,0x00,0x00 # mulx 48($inp), %rcx, %r14 | ||
477 | + mulx 48($inp), %rcx, %r14 | ||
478 | adcx %rax, %r12 | ||
479 | adcx %rcx, %r13 | ||
480 | |||
481 | - .byte 0xc4,0x62,0xfb,0xf6,0xbe,0x38,0x00,0x00,0x00 # mulx 56($inp), %rax, %r15 | ||
482 | + mulx 56($inp), %rax, %r15 | ||
483 | adcx %rax, %r14 | ||
484 | adcx %rbp, %r15 # %rbp is 0 | ||
485 | |||
486 | - mov %r9, %rcx | ||
487 | - shld \$1, %r8, %r9 | ||
488 | - shl \$1, %r8 | ||
489 | - | ||
490 | - xor %ebp, %ebp | ||
491 | - mulx %rdx, %rax, %rdx | ||
492 | - adcx %rdx, %r8 | ||
493 | - mov 8($inp), %rdx | ||
494 | - adcx %rbp, %r9 | ||
495 | + mulx %rdx, %rax, $out | ||
496 | + mov %rbx, %rdx # 8($inp) | ||
497 | + xor %rcx, %rcx | ||
498 | + adox %r8, %r8 | ||
499 | + adcx $out, %r8 | ||
500 | + adox %rbp, %rcx | ||
501 | + adcx %rbp, %rcx | ||
502 | |||
503 | mov %rax, (%rsp) | ||
504 | mov %r8, 8(%rsp) | ||
505 | |||
506 | #second iteration | ||
507 | - mulx 16($inp), %rax, %rbx | ||
508 | + .byte 0xc4,0xe2,0xfb,0xf6,0x9e,0x10,0x00,0x00,0x00 # mulx 16($inp), %rax, %rbx | ||
509 | adox %rax, %r10 | ||
510 | adcx %rbx, %r11 | ||
511 | |||
512 | - .byte 0xc4,0x62,0xc3,0xf6,0x86,0x18,0x00,0x00,0x00 # mulx 24($inp), $out, %r8 | ||
513 | + mulx 24($inp), $out, %r8 | ||
514 | adox $out, %r11 | ||
515 | + .byte 0x66 | ||
516 | adcx %r8, %r12 | ||
517 | |||
518 | mulx 32($inp), %rax, %rbx | ||
519 | @@ -561,24 +567,25 @@ | ||
520 | .byte 0xc4,0x62,0xc3,0xf6,0x86,0x38,0x00,0x00,0x00 # mulx 56($inp), $out, %r8 | ||
521 | adox $out, %r15 | ||
522 | adcx %rbp, %r8 | ||
523 | + mulx %rdx, %rax, $out | ||
524 | adox %rbp, %r8 | ||
525 | + .byte 0x48,0x8b,0x96,0x10,0x00,0x00,0x00 # mov 16($inp), %rdx | ||
526 | |||
527 | - mov %r11, %rbx | ||
528 | - shld \$1, %r10, %r11 | ||
529 | - shld \$1, %rcx, %r10 | ||
530 | - | ||
531 | - xor %ebp,%ebp | ||
532 | - mulx %rdx, %rax, %rcx | ||
533 | - mov 16($inp), %rdx | ||
534 | + xor %rbx, %rbx | ||
535 | + adcx %rcx, %rax | ||
536 | + adox %r9, %r9 | ||
537 | + adcx %rbp, $out | ||
538 | + adox %r10, %r10 | ||
539 | adcx %rax, %r9 | ||
540 | - adcx %rcx, %r10 | ||
541 | - adcx %rbp, %r11 | ||
542 | + adox %rbp, %rbx | ||
543 | + adcx $out, %r10 | ||
544 | + adcx %rbp, %rbx | ||
545 | |||
546 | mov %r9, 16(%rsp) | ||
547 | .byte 0x4c,0x89,0x94,0x24,0x18,0x00,0x00,0x00 # mov %r10, 24(%rsp) | ||
548 | |||
549 | #third iteration | ||
550 | - .byte 0xc4,0x62,0xc3,0xf6,0x8e,0x18,0x00,0x00,0x00 # mulx 24($inp), $out, %r9 | ||
551 | + mulx 24($inp), $out, %r9 | ||
552 | adox $out, %r12 | ||
553 | adcx %r9, %r13 | ||
554 | |||
555 | @@ -586,7 +593,7 @@ | ||
556 | adox %rax, %r13 | ||
557 | adcx %rcx, %r14 | ||
558 | |||
559 | - mulx 40($inp), $out, %r9 | ||
560 | + .byte 0xc4,0x62,0xc3,0xf6,0x8e,0x28,0x00,0x00,0x00 # mulx 40($inp), $out, %r9 | ||
561 | adox $out, %r14 | ||
562 | adcx %r9, %r15 | ||
563 | |||
564 | @@ -594,27 +601,28 @@ | ||
565 | adox %rax, %r15 | ||
566 | adcx %rcx, %r8 | ||
567 | |||
568 | - .byte 0xc4,0x62,0xc3,0xf6,0x8e,0x38,0x00,0x00,0x00 # mulx 56($inp), $out, %r9 | ||
569 | + mulx 56($inp), $out, %r9 | ||
570 | adox $out, %r8 | ||
571 | adcx %rbp, %r9 | ||
572 | + mulx %rdx, %rax, $out | ||
573 | adox %rbp, %r9 | ||
574 | + mov 24($inp), %rdx | ||
575 | |||
576 | - mov %r13, %rcx | ||
577 | - shld \$1, %r12, %r13 | ||
578 | - shld \$1, %rbx, %r12 | ||
579 | - | ||
580 | - xor %ebp, %ebp | ||
581 | - mulx %rdx, %rax, %rdx | ||
582 | + xor %rcx, %rcx | ||
583 | + adcx %rbx, %rax | ||
584 | + adox %r11, %r11 | ||
585 | + adcx %rbp, $out | ||
586 | + adox %r12, %r12 | ||
587 | adcx %rax, %r11 | ||
588 | - adcx %rdx, %r12 | ||
589 | - mov 24($inp), %rdx | ||
590 | - adcx %rbp, %r13 | ||
591 | + adox %rbp, %rcx | ||
592 | + adcx $out, %r12 | ||
593 | + adcx %rbp, %rcx | ||
594 | |||
595 | mov %r11, 32(%rsp) | ||
596 | - .byte 0x4c,0x89,0xa4,0x24,0x28,0x00,0x00,0x00 # mov %r12, 40(%rsp) | ||
597 | + mov %r12, 40(%rsp) | ||
598 | |||
599 | #fourth iteration | ||
600 | - .byte 0xc4,0xe2,0xfb,0xf6,0x9e,0x20,0x00,0x00,0x00 # mulx 32($inp), %rax, %rbx | ||
601 | + mulx 32($inp), %rax, %rbx | ||
602 | adox %rax, %r14 | ||
603 | adcx %rbx, %r15 | ||
604 | |||
605 | @@ -629,25 +637,25 @@ | ||
606 | mulx 56($inp), $out, %r10 | ||
607 | adox $out, %r9 | ||
608 | adcx %rbp, %r10 | ||
609 | + mulx %rdx, %rax, $out | ||
610 | adox %rbp, %r10 | ||
611 | + mov 32($inp), %rdx | ||
612 | |||
613 | - .byte 0x66 | ||
614 | - mov %r15, %rbx | ||
615 | - shld \$1, %r14, %r15 | ||
616 | - shld \$1, %rcx, %r14 | ||
617 | - | ||
618 | - xor %ebp, %ebp | ||
619 | - mulx %rdx, %rax, %rdx | ||
620 | + xor %rbx, %rbx | ||
621 | + adcx %rcx, %rax | ||
622 | + adox %r13, %r13 | ||
623 | + adcx %rbp, $out | ||
624 | + adox %r14, %r14 | ||
625 | adcx %rax, %r13 | ||
626 | - adcx %rdx, %r14 | ||
627 | - mov 32($inp), %rdx | ||
628 | - adcx %rbp, %r15 | ||
629 | + adox %rbp, %rbx | ||
630 | + adcx $out, %r14 | ||
631 | + adcx %rbp, %rbx | ||
632 | |||
633 | mov %r13, 48(%rsp) | ||
634 | mov %r14, 56(%rsp) | ||
635 | |||
636 | #fifth iteration | ||
637 | - .byte 0xc4,0x62,0xc3,0xf6,0x9e,0x28,0x00,0x00,0x00 # mulx 40($inp), $out, %r11 | ||
638 | + mulx 40($inp), $out, %r11 | ||
639 | adox $out, %r8 | ||
640 | adcx %r11, %r9 | ||
641 | |||
642 | @@ -658,18 +666,19 @@ | ||
643 | mulx 56($inp), $out, %r11 | ||
644 | adox $out, %r10 | ||
645 | adcx %rbp, %r11 | ||
646 | + mulx %rdx, %rax, $out | ||
647 | + mov 40($inp), %rdx | ||
648 | adox %rbp, %r11 | ||
649 | |||
650 | - mov %r9, %rcx | ||
651 | - shld \$1, %r8, %r9 | ||
652 | - shld \$1, %rbx, %r8 | ||
653 | - | ||
654 | - xor %ebp, %ebp | ||
655 | - mulx %rdx, %rax, %rdx | ||
656 | + xor %rcx, %rcx | ||
657 | + adcx %rbx, %rax | ||
658 | + adox %r15, %r15 | ||
659 | + adcx %rbp, $out | ||
660 | + adox %r8, %r8 | ||
661 | adcx %rax, %r15 | ||
662 | - adcx %rdx, %r8 | ||
663 | - mov 40($inp), %rdx | ||
664 | - adcx %rbp, %r9 | ||
665 | + adox %rbp, %rcx | ||
666 | + adcx $out, %r8 | ||
667 | + adcx %rbp, %rcx | ||
668 | |||
669 | mov %r15, 64(%rsp) | ||
670 | mov %r8, 72(%rsp) | ||
671 | @@ -682,18 +691,19 @@ | ||
672 | .byte 0xc4,0x62,0xc3,0xf6,0xa6,0x38,0x00,0x00,0x00 # mulx 56($inp), $out, %r12 | ||
673 | adox $out, %r11 | ||
674 | adcx %rbp, %r12 | ||
675 | + mulx %rdx, %rax, $out | ||
676 | adox %rbp, %r12 | ||
677 | + mov 48($inp), %rdx | ||
678 | |||
679 | - mov %r11, %rbx | ||
680 | - shld \$1, %r10, %r11 | ||
681 | - shld \$1, %rcx, %r10 | ||
682 | - | ||
683 | - xor %ebp, %ebp | ||
684 | - mulx %rdx, %rax, %rdx | ||
685 | + xor %rbx, %rbx | ||
686 | + adcx %rcx, %rax | ||
687 | + adox %r9, %r9 | ||
688 | + adcx %rbp, $out | ||
689 | + adox %r10, %r10 | ||
690 | adcx %rax, %r9 | ||
691 | - adcx %rdx, %r10 | ||
692 | - mov 48($inp), %rdx | ||
693 | - adcx %rbp, %r11 | ||
694 | + adcx $out, %r10 | ||
695 | + adox %rbp, %rbx | ||
696 | + adcx %rbp, %rbx | ||
697 | |||
698 | mov %r9, 80(%rsp) | ||
699 | mov %r10, 88(%rsp) | ||
700 | @@ -703,31 +713,31 @@ | ||
701 | adox %rax, %r12 | ||
702 | adox %rbp, %r13 | ||
703 | |||
704 | - xor %r14, %r14 | ||
705 | - shld \$1, %r13, %r14 | ||
706 | - shld \$1, %r12, %r13 | ||
707 | - shld \$1, %rbx, %r12 | ||
708 | - | ||
709 | - xor %ebp, %ebp | ||
710 | - mulx %rdx, %rax, %rdx | ||
711 | - adcx %rax, %r11 | ||
712 | - adcx %rdx, %r12 | ||
713 | + mulx %rdx, %rax, $out | ||
714 | + xor %rcx, %rcx | ||
715 | mov 56($inp), %rdx | ||
716 | - adcx %rbp, %r13 | ||
717 | + adcx %rbx, %rax | ||
718 | + adox %r11, %r11 | ||
719 | + adcx %rbp, $out | ||
720 | + adox %r12, %r12 | ||
721 | + adcx %rax, %r11 | ||
722 | + adox %rbp, %rcx | ||
723 | + adcx $out, %r12 | ||
724 | + adcx %rbp, %rcx | ||
725 | |||
726 | .byte 0x4c,0x89,0x9c,0x24,0x60,0x00,0x00,0x00 # mov %r11, 96(%rsp) | ||
727 | .byte 0x4c,0x89,0xa4,0x24,0x68,0x00,0x00,0x00 # mov %r12, 104(%rsp) | ||
728 | |||
729 | #eighth iteration | ||
730 | mulx %rdx, %rax, %rdx | ||
731 | - adox %rax, %r13 | ||
732 | - adox %rbp, %rdx | ||
733 | + xor %rbx, %rbx | ||
734 | + adcx %rcx, %rax | ||
735 | + adox %r13, %r13 | ||
736 | + adcx %rbp, %rdx | ||
737 | + adox %rbp, %rbx | ||
738 | + adcx %r13, %rax | ||
739 | + adcx %rdx, %rbx | ||
740 | |||
741 | - .byte 0x66 | ||
742 | - add %rdx, %r14 | ||
743 | - | ||
744 | - movq %r13, 112(%rsp) | ||
745 | - movq %r14, 120(%rsp) | ||
746 | movq %xmm0, $out | ||
747 | movq %xmm1, %rbp | ||
748 | |||
749 | @@ -741,6 +751,9 @@ | ||
750 | movq 48(%rsp), %r14 | ||
751 | movq 56(%rsp), %r15 | ||
752 | |||
753 | + movq %rax, 112(%rsp) | ||
754 | + movq %rbx, 120(%rsp) | ||
755 | + | ||
756 | call __rsaz_512_reducex | ||
757 | |||
758 | addq 64(%rsp), %r8 | ||
diff --git a/meta/recipes-connectivity/openssl/openssl_1.1.1d.bb b/meta/recipes-connectivity/openssl/openssl_1.1.1g.bb index 169824a8be..c514fcd82a 100644 --- a/meta/recipes-connectivity/openssl/openssl_1.1.1d.bb +++ b/meta/recipes-connectivity/openssl/openssl_1.1.1g.bb | |||
@@ -16,7 +16,6 @@ SRC_URI = "http://www.openssl.org/source/openssl-${PV}.tar.gz \ | |||
16 | file://0001-skip-test_symbol_presence.patch \ | 16 | file://0001-skip-test_symbol_presence.patch \ |
17 | file://0001-buildinfo-strip-sysroot-and-debug-prefix-map-from-co.patch \ | 17 | file://0001-buildinfo-strip-sysroot-and-debug-prefix-map-from-co.patch \ |
18 | file://afalg.patch \ | 18 | file://afalg.patch \ |
19 | file://CVE-2019-1551.patch \ | ||
20 | file://reproducible.patch \ | 19 | file://reproducible.patch \ |
21 | " | 20 | " |
22 | 21 | ||
@@ -24,8 +23,7 @@ SRC_URI_append_class-nativesdk = " \ | |||
24 | file://environment.d-openssl.sh \ | 23 | file://environment.d-openssl.sh \ |
25 | " | 24 | " |
26 | 25 | ||
27 | SRC_URI[md5sum] = "3be209000dbc7e1b95bcdf47980a3baa" | 26 | SRC_URI[sha256sum] = "ddb04774f1e32f0c49751e21b67216ac87852ceb056b75209af2443400636d46" |
28 | SRC_URI[sha256sum] = "1e3a91bc1f9dfce01af26026f856e064eab4c8ee0a8f457b5ae30b40b8b711f2" | ||
29 | 27 | ||
30 | inherit lib_package multilib_header multilib_script ptest | 28 | inherit lib_package multilib_header multilib_script ptest |
31 | MULTILIB_SCRIPTS = "${PN}-bin:${bindir}/c_rehash" | 29 | MULTILIB_SCRIPTS = "${PN}-bin:${bindir}/c_rehash" |
@@ -34,7 +32,7 @@ PACKAGECONFIG ?= "" | |||
34 | PACKAGECONFIG_class-native = "" | 32 | PACKAGECONFIG_class-native = "" |
35 | PACKAGECONFIG_class-nativesdk = "" | 33 | PACKAGECONFIG_class-nativesdk = "" |
36 | 34 | ||
37 | PACKAGECONFIG[cryptodev-linux] = "enable-devcryptoeng,disable-devcryptoeng,cryptodev-linux" | 35 | PACKAGECONFIG[cryptodev-linux] = "enable-devcryptoeng,disable-devcryptoeng,cryptodev-linux,,cryptodev-module" |
38 | 36 | ||
39 | B = "${WORKDIR}/build" | 37 | B = "${WORKDIR}/build" |
40 | do_configure[cleandirs] = "${B}" | 38 | do_configure[cleandirs] = "${B}" |
diff --git a/meta/recipes-connectivity/ppp/ppp/0001-pppd-Fix-bounds-check-in-EAP-code.patch b/meta/recipes-connectivity/ppp/ppp/0001-pppd-Fix-bounds-check-in-EAP-code.patch new file mode 100644 index 0000000000..b7ba7ba643 --- /dev/null +++ b/meta/recipes-connectivity/ppp/ppp/0001-pppd-Fix-bounds-check-in-EAP-code.patch | |||
@@ -0,0 +1,47 @@ | |||
1 | From 8d7970b8f3db727fe798b65f3377fe6787575426 Mon Sep 17 00:00:00 2001 | ||
2 | From: Paul Mackerras <paulus@ozlabs.org> | ||
3 | Date: Mon, 3 Feb 2020 15:53:28 +1100 | ||
4 | Subject: [PATCH] pppd: Fix bounds check in EAP code | ||
5 | |||
6 | Given that we have just checked vallen < len, it can never be the case | ||
7 | that vallen >= len + sizeof(rhostname). This fixes the check so we | ||
8 | actually avoid overflowing the rhostname array. | ||
9 | |||
10 | Reported-by: Ilja Van Sprundel <ivansprundel@ioactive.com> | ||
11 | Signed-off-by: Paul Mackerras <paulus@ozlabs.org> | ||
12 | |||
13 | Upstream-Status: Backport | ||
14 | [https://github.com/paulusmack/ppp/commit/8d7970b8f3db727fe798b65f3377fe6787575426] | ||
15 | |||
16 | CVE: CVE-2020-8597 | ||
17 | |||
18 | Signed-off-by: Yi Zhao <yi.zhao@windriver.com> | ||
19 | --- | ||
20 | pppd/eap.c | 4 ++-- | ||
21 | 1 file changed, 2 insertions(+), 2 deletions(-) | ||
22 | |||
23 | diff --git a/pppd/eap.c b/pppd/eap.c | ||
24 | index 94407f5..1b93db0 100644 | ||
25 | --- a/pppd/eap.c | ||
26 | +++ b/pppd/eap.c | ||
27 | @@ -1420,7 +1420,7 @@ int len; | ||
28 | } | ||
29 | |||
30 | /* Not so likely to happen. */ | ||
31 | - if (vallen >= len + sizeof (rhostname)) { | ||
32 | + if (len - vallen >= sizeof (rhostname)) { | ||
33 | dbglog("EAP: trimming really long peer name down"); | ||
34 | BCOPY(inp + vallen, rhostname, sizeof (rhostname) - 1); | ||
35 | rhostname[sizeof (rhostname) - 1] = '\0'; | ||
36 | @@ -1846,7 +1846,7 @@ int len; | ||
37 | } | ||
38 | |||
39 | /* Not so likely to happen. */ | ||
40 | - if (vallen >= len + sizeof (rhostname)) { | ||
41 | + if (len - vallen >= sizeof (rhostname)) { | ||
42 | dbglog("EAP: trimming really long peer name down"); | ||
43 | BCOPY(inp + vallen, rhostname, sizeof (rhostname) - 1); | ||
44 | rhostname[sizeof (rhostname) - 1] = '\0'; | ||
45 | -- | ||
46 | 2.17.1 | ||
47 | |||
diff --git a/meta/recipes-connectivity/ppp/ppp_2.4.7.bb b/meta/recipes-connectivity/ppp/ppp_2.4.7.bb index 644cde4562..60c56dd0bd 100644 --- a/meta/recipes-connectivity/ppp/ppp_2.4.7.bb +++ b/meta/recipes-connectivity/ppp/ppp_2.4.7.bb | |||
@@ -33,6 +33,7 @@ SRC_URI = "https://download.samba.org/pub/${BPN}/${BP}.tar.gz \ | |||
33 | file://0001-pppoe-include-netinet-in.h-before-linux-in.h.patch \ | 33 | file://0001-pppoe-include-netinet-in.h-before-linux-in.h.patch \ |
34 | file://0001-ppp-Remove-unneeded-include.patch \ | 34 | file://0001-ppp-Remove-unneeded-include.patch \ |
35 | file://ppp-2.4.7-DES-openssl.patch \ | 35 | file://ppp-2.4.7-DES-openssl.patch \ |
36 | file://0001-pppd-Fix-bounds-check-in-EAP-code.patch \ | ||
36 | " | 37 | " |
37 | 38 | ||
38 | SRC_URI_append_libc-musl = "\ | 39 | SRC_URI_append_libc-musl = "\ |
diff --git a/meta/recipes-connectivity/wpa-supplicant/wpa-supplicant/0001-WPS-UPnP-Do-not-allow-event-subscriptions-with-URLs-.patch b/meta/recipes-connectivity/wpa-supplicant/wpa-supplicant/0001-WPS-UPnP-Do-not-allow-event-subscriptions-with-URLs-.patch new file mode 100644 index 0000000000..53ad5d028a --- /dev/null +++ b/meta/recipes-connectivity/wpa-supplicant/wpa-supplicant/0001-WPS-UPnP-Do-not-allow-event-subscriptions-with-URLs-.patch | |||
@@ -0,0 +1,151 @@ | |||
1 | From 5b78c8f961f25f4dc22d6f2b77ddd06d712cec63 Mon Sep 17 00:00:00 2001 | ||
2 | From: Jouni Malinen <jouni@codeaurora.org> | ||
3 | Date: Wed, 3 Jun 2020 23:17:35 +0300 | ||
4 | Subject: [PATCH 1/3] WPS UPnP: Do not allow event subscriptions with URLs to | ||
5 | other networks | ||
6 | |||
7 | The UPnP Device Architecture 2.0 specification errata ("UDA errata | ||
8 | 16-04-2020.docx") addresses a problem with notifications being allowed | ||
9 | to go out to other domains by disallowing such cases. Do such filtering | ||
10 | for the notification callback URLs to avoid undesired connections to | ||
11 | external networks based on subscriptions that any device in the local | ||
12 | network could request when WPS support for external registrars is | ||
13 | enabled (the upnp_iface parameter in hostapd configuration). | ||
14 | |||
15 | Upstream-Status: Backport | ||
16 | CVE: CVE-2020-12695 patch #1 | ||
17 | Signed-off-by: Jouni Malinen <jouni@codeaurora.org> | ||
18 | Signed-off-by: Armin Kuster <akuster@mvista.com> | ||
19 | |||
20 | --- | ||
21 | src/wps/wps_er.c | 2 +- | ||
22 | src/wps/wps_upnp.c | 38 ++++++++++++++++++++++++++++++++++++-- | ||
23 | src/wps/wps_upnp_i.h | 3 ++- | ||
24 | 3 files changed, 39 insertions(+), 4 deletions(-) | ||
25 | |||
26 | Index: wpa_supplicant-2.9/src/wps/wps_er.c | ||
27 | =================================================================== | ||
28 | --- wpa_supplicant-2.9.orig/src/wps/wps_er.c | ||
29 | +++ wpa_supplicant-2.9/src/wps/wps_er.c | ||
30 | @@ -1298,7 +1298,7 @@ wps_er_init(struct wps_context *wps, con | ||
31 | "with %s", filter); | ||
32 | } | ||
33 | if (get_netif_info(er->ifname, &er->ip_addr, &er->ip_addr_text, | ||
34 | - er->mac_addr)) { | ||
35 | + NULL, er->mac_addr)) { | ||
36 | wpa_printf(MSG_INFO, "WPS UPnP: Could not get IP/MAC address " | ||
37 | "for %s. Does it have IP address?", er->ifname); | ||
38 | wps_er_deinit(er, NULL, NULL); | ||
39 | Index: wpa_supplicant-2.9/src/wps/wps_upnp.c | ||
40 | =================================================================== | ||
41 | --- wpa_supplicant-2.9.orig/src/wps/wps_upnp.c | ||
42 | +++ wpa_supplicant-2.9/src/wps/wps_upnp.c | ||
43 | @@ -303,6 +303,14 @@ static void subscr_addr_free_all(struct | ||
44 | } | ||
45 | |||
46 | |||
47 | +static int local_network_addr(struct upnp_wps_device_sm *sm, | ||
48 | + struct sockaddr_in *addr) | ||
49 | +{ | ||
50 | + return (addr->sin_addr.s_addr & sm->netmask.s_addr) == | ||
51 | + (sm->ip_addr & sm->netmask.s_addr); | ||
52 | +} | ||
53 | + | ||
54 | + | ||
55 | /* subscr_addr_add_url -- add address(es) for one url to subscription */ | ||
56 | static void subscr_addr_add_url(struct subscription *s, const char *url, | ||
57 | size_t url_len) | ||
58 | @@ -381,6 +389,7 @@ static void subscr_addr_add_url(struct s | ||
59 | |||
60 | for (rp = result; rp; rp = rp->ai_next) { | ||
61 | struct subscr_addr *a; | ||
62 | + struct sockaddr_in *addr = (struct sockaddr_in *) rp->ai_addr; | ||
63 | |||
64 | /* Limit no. of address to avoid denial of service attack */ | ||
65 | if (dl_list_len(&s->addr_list) >= MAX_ADDR_PER_SUBSCRIPTION) { | ||
66 | @@ -389,6 +398,13 @@ static void subscr_addr_add_url(struct s | ||
67 | break; | ||
68 | } | ||
69 | |||
70 | + if (!local_network_addr(s->sm, addr)) { | ||
71 | + wpa_printf(MSG_INFO, | ||
72 | + "WPS UPnP: Ignore a delivery URL that points to another network %s", | ||
73 | + inet_ntoa(addr->sin_addr)); | ||
74 | + continue; | ||
75 | + } | ||
76 | + | ||
77 | a = os_zalloc(sizeof(*a) + alloc_len); | ||
78 | if (a == NULL) | ||
79 | break; | ||
80 | @@ -889,11 +905,12 @@ static int eth_get(const char *device, u | ||
81 | * @net_if: Selected network interface name | ||
82 | * @ip_addr: Buffer for returning IP address in network byte order | ||
83 | * @ip_addr_text: Buffer for returning a pointer to allocated IP address text | ||
84 | + * @netmask: Buffer for returning netmask or %NULL if not needed | ||
85 | * @mac: Buffer for returning MAC address | ||
86 | * Returns: 0 on success, -1 on failure | ||
87 | */ | ||
88 | int get_netif_info(const char *net_if, unsigned *ip_addr, char **ip_addr_text, | ||
89 | - u8 mac[ETH_ALEN]) | ||
90 | + struct in_addr *netmask, u8 mac[ETH_ALEN]) | ||
91 | { | ||
92 | struct ifreq req; | ||
93 | int sock = -1; | ||
94 | @@ -919,6 +936,19 @@ int get_netif_info(const char *net_if, u | ||
95 | in_addr.s_addr = *ip_addr; | ||
96 | os_snprintf(*ip_addr_text, 16, "%s", inet_ntoa(in_addr)); | ||
97 | |||
98 | + if (netmask) { | ||
99 | + os_memset(&req, 0, sizeof(req)); | ||
100 | + os_strlcpy(req.ifr_name, net_if, sizeof(req.ifr_name)); | ||
101 | + if (ioctl(sock, SIOCGIFNETMASK, &req) < 0) { | ||
102 | + wpa_printf(MSG_ERROR, | ||
103 | + "WPS UPnP: SIOCGIFNETMASK failed: %d (%s)", | ||
104 | + errno, strerror(errno)); | ||
105 | + goto fail; | ||
106 | + } | ||
107 | + addr = (struct sockaddr_in *) &req.ifr_netmask; | ||
108 | + netmask->s_addr = addr->sin_addr.s_addr; | ||
109 | + } | ||
110 | + | ||
111 | #ifdef __linux__ | ||
112 | os_strlcpy(req.ifr_name, net_if, sizeof(req.ifr_name)); | ||
113 | if (ioctl(sock, SIOCGIFHWADDR, &req) < 0) { | ||
114 | @@ -1025,11 +1055,15 @@ static int upnp_wps_device_start(struct | ||
115 | |||
116 | /* Determine which IP and mac address we're using */ | ||
117 | if (get_netif_info(net_if, &sm->ip_addr, &sm->ip_addr_text, | ||
118 | - sm->mac_addr)) { | ||
119 | + &sm->netmask, sm->mac_addr)) { | ||
120 | wpa_printf(MSG_INFO, "WPS UPnP: Could not get IP/MAC address " | ||
121 | "for %s. Does it have IP address?", net_if); | ||
122 | goto fail; | ||
123 | } | ||
124 | + wpa_printf(MSG_DEBUG, "WPS UPnP: Local IP address %s netmask %s hwaddr " | ||
125 | + MACSTR, | ||
126 | + sm->ip_addr_text, inet_ntoa(sm->netmask), | ||
127 | + MAC2STR(sm->mac_addr)); | ||
128 | |||
129 | /* Listen for incoming TCP connections so that others | ||
130 | * can fetch our "xml files" from us. | ||
131 | Index: wpa_supplicant-2.9/src/wps/wps_upnp_i.h | ||
132 | =================================================================== | ||
133 | --- wpa_supplicant-2.9.orig/src/wps/wps_upnp_i.h | ||
134 | +++ wpa_supplicant-2.9/src/wps/wps_upnp_i.h | ||
135 | @@ -128,6 +128,7 @@ struct upnp_wps_device_sm { | ||
136 | u8 mac_addr[ETH_ALEN]; /* mac addr of network i.f. we use */ | ||
137 | char *ip_addr_text; /* IP address of network i.f. we use */ | ||
138 | unsigned ip_addr; /* IP address of network i.f. we use (host order) */ | ||
139 | + struct in_addr netmask; | ||
140 | int multicast_sd; /* send multicast messages over this socket */ | ||
141 | int ssdp_sd; /* receive discovery UPD packets on socket */ | ||
142 | int ssdp_sd_registered; /* nonzero if we must unregister */ | ||
143 | @@ -158,7 +159,7 @@ struct subscription * subscription_find( | ||
144 | const u8 uuid[UUID_LEN]); | ||
145 | void subscr_addr_delete(struct subscr_addr *a); | ||
146 | int get_netif_info(const char *net_if, unsigned *ip_addr, char **ip_addr_text, | ||
147 | - u8 mac[ETH_ALEN]); | ||
148 | + struct in_addr *netmask, u8 mac[ETH_ALEN]); | ||
149 | |||
150 | /* wps_upnp_ssdp.c */ | ||
151 | void msearchreply_state_machine_stop(struct advertisement_state_machine *a); | ||
diff --git a/meta/recipes-connectivity/wpa-supplicant/wpa-supplicant/0002-WPS-UPnP-Fix-event-message-generation-using-a-long-U.patch b/meta/recipes-connectivity/wpa-supplicant/wpa-supplicant/0002-WPS-UPnP-Fix-event-message-generation-using-a-long-U.patch new file mode 100644 index 0000000000..59640859dd --- /dev/null +++ b/meta/recipes-connectivity/wpa-supplicant/wpa-supplicant/0002-WPS-UPnP-Fix-event-message-generation-using-a-long-U.patch | |||
@@ -0,0 +1,62 @@ | |||
1 | From f7d268864a2660b7239b9a8ff5ad37faeeb751ba Mon Sep 17 00:00:00 2001 | ||
2 | From: Jouni Malinen <jouni@codeaurora.org> | ||
3 | Date: Wed, 3 Jun 2020 22:41:02 +0300 | ||
4 | Subject: [PATCH 2/3] WPS UPnP: Fix event message generation using a long URL | ||
5 | path | ||
6 | |||
7 | More than about 700 character URL ended up overflowing the wpabuf used | ||
8 | for building the event notification and this resulted in the wpabuf | ||
9 | buffer overflow checks terminating the hostapd process. Fix this by | ||
10 | allocating the buffer to be large enough to contain the full URL path. | ||
11 | However, since that around 700 character limit has been the practical | ||
12 | limit for more than ten years, start explicitly enforcing that as the | ||
13 | limit or the callback URLs since any longer ones had not worked before | ||
14 | and there is no need to enable them now either. | ||
15 | |||
16 | Upstream-Status: Backport | ||
17 | CVE: CVE-2020-12695 patch #2 | ||
18 | Signed-off-by: Jouni Malinen <jouni@codeaurora.org> | ||
19 | Signed-off-by: Armin Kuster <akuster@mvista.com> | ||
20 | |||
21 | --- | ||
22 | src/wps/wps_upnp.c | 9 +++++++-- | ||
23 | src/wps/wps_upnp_event.c | 3 ++- | ||
24 | 2 files changed, 9 insertions(+), 3 deletions(-) | ||
25 | |||
26 | diff --git a/src/wps/wps_upnp.c b/src/wps/wps_upnp.c | ||
27 | index 7d4b7439940e..ab685d52ecab 100644 | ||
28 | --- a/src/wps/wps_upnp.c | ||
29 | +++ b/src/wps/wps_upnp.c | ||
30 | @@ -328,9 +328,14 @@ static void subscr_addr_add_url(struct subscription *s, const char *url, | ||
31 | int rerr; | ||
32 | size_t host_len, path_len; | ||
33 | |||
34 | - /* url MUST begin with http: */ | ||
35 | - if (url_len < 7 || os_strncasecmp(url, "http://", 7)) | ||
36 | + /* URL MUST begin with HTTP scheme. In addition, limit the length of | ||
37 | + * the URL to 700 characters which is around the limit that was | ||
38 | + * implicitly enforced for more than 10 years due to a bug in | ||
39 | + * generating the event messages. */ | ||
40 | + if (url_len < 7 || os_strncasecmp(url, "http://", 7) || url_len > 700) { | ||
41 | + wpa_printf(MSG_DEBUG, "WPS UPnP: Reject an unacceptable URL"); | ||
42 | goto fail; | ||
43 | + } | ||
44 | url += 7; | ||
45 | url_len -= 7; | ||
46 | |||
47 | diff --git a/src/wps/wps_upnp_event.c b/src/wps/wps_upnp_event.c | ||
48 | index d7e6edcc6503..08a23612f338 100644 | ||
49 | --- a/src/wps/wps_upnp_event.c | ||
50 | +++ b/src/wps/wps_upnp_event.c | ||
51 | @@ -147,7 +147,8 @@ static struct wpabuf * event_build_message(struct wps_event_ *e) | ||
52 | struct wpabuf *buf; | ||
53 | char *b; | ||
54 | |||
55 | - buf = wpabuf_alloc(1000 + wpabuf_len(e->data)); | ||
56 | + buf = wpabuf_alloc(1000 + os_strlen(e->addr->path) + | ||
57 | + wpabuf_len(e->data)); | ||
58 | if (buf == NULL) | ||
59 | return NULL; | ||
60 | wpabuf_printf(buf, "NOTIFY %s HTTP/1.1\r\n", e->addr->path); | ||
61 | -- | ||
62 | 2.20.1 | ||
diff --git a/meta/recipes-connectivity/wpa-supplicant/wpa-supplicant/0003-WPS-UPnP-Handle-HTTP-initiation-failures-for-events-.patch b/meta/recipes-connectivity/wpa-supplicant/wpa-supplicant/0003-WPS-UPnP-Handle-HTTP-initiation-failures-for-events-.patch new file mode 100644 index 0000000000..8a014ef28a --- /dev/null +++ b/meta/recipes-connectivity/wpa-supplicant/wpa-supplicant/0003-WPS-UPnP-Handle-HTTP-initiation-failures-for-events-.patch | |||
@@ -0,0 +1,50 @@ | |||
1 | From 85aac526af8612c21b3117dadc8ef5944985b476 Mon Sep 17 00:00:00 2001 | ||
2 | From: Jouni Malinen <jouni@codeaurora.org> | ||
3 | Date: Thu, 4 Jun 2020 21:24:04 +0300 | ||
4 | Subject: [PATCH 3/3] WPS UPnP: Handle HTTP initiation failures for events more | ||
5 | properly | ||
6 | |||
7 | While it is appropriate to try to retransmit the event to another | ||
8 | callback URL on a failure to initiate the HTTP client connection, there | ||
9 | is no point in trying the exact same operation multiple times in a row. | ||
10 | Replve the event_retry() calls with event_addr_failure() for these cases | ||
11 | to avoid busy loops trying to repeat the same failing operation. | ||
12 | |||
13 | These potential busy loops would go through eloop callbacks, so the | ||
14 | process is not completely stuck on handling them, but unnecessary CPU | ||
15 | would be used to process the continues retries that will keep failing | ||
16 | for the same reason. | ||
17 | |||
18 | Upstream-Status: Backport | ||
19 | CVE: CVE-2020-12695 patch #2 | ||
20 | Signed-off-by: Jouni Malinen <jouni@codeaurora.org> | ||
21 | Signed-off-by: Armin Kuster <akuster@mvista.com> | ||
22 | |||
23 | --- | ||
24 | src/wps/wps_upnp_event.c | 4 ++-- | ||
25 | 1 file changed, 2 insertions(+), 2 deletions(-) | ||
26 | |||
27 | diff --git a/src/wps/wps_upnp_event.c b/src/wps/wps_upnp_event.c | ||
28 | index 08a23612f338..c0d9e41d9a38 100644 | ||
29 | --- a/src/wps/wps_upnp_event.c | ||
30 | +++ b/src/wps/wps_upnp_event.c | ||
31 | @@ -294,7 +294,7 @@ static int event_send_start(struct subscription *s) | ||
32 | |||
33 | buf = event_build_message(e); | ||
34 | if (buf == NULL) { | ||
35 | - event_retry(e, 0); | ||
36 | + event_addr_failure(e); | ||
37 | return -1; | ||
38 | } | ||
39 | |||
40 | @@ -302,7 +302,7 @@ static int event_send_start(struct subscription *s) | ||
41 | event_http_cb, e); | ||
42 | if (e->http_event == NULL) { | ||
43 | wpabuf_free(buf); | ||
44 | - event_retry(e, 0); | ||
45 | + event_addr_failure(e); | ||
46 | return -1; | ||
47 | } | ||
48 | |||
49 | -- | ||
50 | 2.20.1 | ||
diff --git a/meta/recipes-connectivity/wpa-supplicant/wpa-supplicant_2.9.bb b/meta/recipes-connectivity/wpa-supplicant/wpa-supplicant_2.9.bb index 2db09ad2c6..de882fad55 100644 --- a/meta/recipes-connectivity/wpa-supplicant/wpa-supplicant_2.9.bb +++ b/meta/recipes-connectivity/wpa-supplicant/wpa-supplicant_2.9.bb | |||
@@ -15,7 +15,7 @@ PACKAGECONFIG[openssl] = ",,openssl" | |||
15 | 15 | ||
16 | inherit pkgconfig systemd | 16 | inherit pkgconfig systemd |
17 | 17 | ||
18 | SYSTEMD_SERVICE_${PN} = "wpa_supplicant.service wpa_supplicant-nl80211@.service wpa_supplicant-wired@.service" | 18 | SYSTEMD_SERVICE_${PN} = "wpa_supplicant.service" |
19 | SYSTEMD_AUTO_ENABLE = "disable" | 19 | SYSTEMD_AUTO_ENABLE = "disable" |
20 | 20 | ||
21 | SRC_URI = "http://w1.fi/releases/wpa_supplicant-${PV}.tar.gz \ | 21 | SRC_URI = "http://w1.fi/releases/wpa_supplicant-${PV}.tar.gz \ |
@@ -25,7 +25,10 @@ SRC_URI = "http://w1.fi/releases/wpa_supplicant-${PV}.tar.gz \ | |||
25 | file://wpa_supplicant.conf-sane \ | 25 | file://wpa_supplicant.conf-sane \ |
26 | file://99_wpa_supplicant \ | 26 | file://99_wpa_supplicant \ |
27 | file://0001-replace-systemd-install-Alias-with-WantedBy.patch \ | 27 | file://0001-replace-systemd-install-Alias-with-WantedBy.patch \ |
28 | file://0001-AP-Silently-ignore-management-frame-from-unexpected-.patch \ | 28 | file://0001-AP-Silently-ignore-management-frame-from-unexpected-.patch \ |
29 | file://0001-WPS-UPnP-Do-not-allow-event-subscriptions-with-URLs-.patch \ | ||
30 | file://0002-WPS-UPnP-Fix-event-message-generation-using-a-long-U.patch \ | ||
31 | file://0003-WPS-UPnP-Handle-HTTP-initiation-failures-for-events-.patch \ | ||
29 | " | 32 | " |
30 | SRC_URI[md5sum] = "2d2958c782576dc9901092fbfecb4190" | 33 | SRC_URI[md5sum] = "2d2958c782576dc9901092fbfecb4190" |
31 | SRC_URI[sha256sum] = "fcbdee7b4a64bea8177973299c8c824419c413ec2e3a95db63dd6a5dc3541f17" | 34 | SRC_URI[sha256sum] = "fcbdee7b4a64bea8177973299c8c824419c413ec2e3a95db63dd6a5dc3541f17" |
@@ -37,13 +40,13 @@ S = "${WORKDIR}/wpa_supplicant-${PV}" | |||
37 | PACKAGES_prepend = "wpa-supplicant-passphrase wpa-supplicant-cli " | 40 | PACKAGES_prepend = "wpa-supplicant-passphrase wpa-supplicant-cli " |
38 | FILES_wpa-supplicant-passphrase = "${bindir}/wpa_passphrase" | 41 | FILES_wpa-supplicant-passphrase = "${bindir}/wpa_passphrase" |
39 | FILES_wpa-supplicant-cli = "${sbindir}/wpa_cli" | 42 | FILES_wpa-supplicant-cli = "${sbindir}/wpa_cli" |
40 | FILES_${PN} += "${datadir}/dbus-1/system-services/*" | 43 | FILES_${PN} += "${datadir}/dbus-1/system-services/* ${systemd_system_unitdir}/*" |
41 | CONFFILES_${PN} += "${sysconfdir}/wpa_supplicant.conf" | 44 | CONFFILES_${PN} += "${sysconfdir}/wpa_supplicant.conf" |
42 | 45 | ||
43 | do_configure () { | 46 | do_configure () { |
44 | ${MAKE} -C wpa_supplicant clean | 47 | ${MAKE} -C wpa_supplicant clean |
45 | install -m 0755 ${WORKDIR}/defconfig wpa_supplicant/.config | 48 | install -m 0755 ${WORKDIR}/defconfig wpa_supplicant/.config |
46 | 49 | ||
47 | if echo "${PACKAGECONFIG}" | grep -qw "openssl"; then | 50 | if echo "${PACKAGECONFIG}" | grep -qw "openssl"; then |
48 | ssl=openssl | 51 | ssl=openssl |
49 | elif echo "${PACKAGECONFIG}" | grep -qw "gnutls"; then | 52 | elif echo "${PACKAGECONFIG}" | grep -qw "gnutls"; then |