diff options
Diffstat (limited to 'meta/recipes-connectivity/bind/bind/0003-use-reference-counter-for-pipeline-groups-v3.patch')
-rw-r--r-- | meta/recipes-connectivity/bind/bind/0003-use-reference-counter-for-pipeline-groups-v3.patch | 278 |
1 files changed, 0 insertions, 278 deletions
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 @@ -Backport patch to fix CVE-2018-5743. - -Ref: -https://security-tracker.debian.org/tracker/CVE-2018-5743 - -CVE: CVE-2018-5743 -Upstream-Status: Backport [https://gitlab.isc.org/isc-projects/bind9/commit/366b4e1] - -Signed-off-by: Kai Kang <kai.kang@windriver.com> - -From 366b4e1ede8aed690e981e07137cb1cb77879c36 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Micha=C5=82=20K=C4=99pie=C5=84?= <michal@isc.org> -Date: Thu, 17 Jan 2019 15:53:38 +0100 -Subject: [PATCH 3/6] use reference counter for pipeline groups (v3) - -Track pipeline groups using a shared reference counter -instead of a linked list. - -(cherry picked from commit 513afd33eb17d5dc41a3f0d2d38204ef8c5f6f91) -(cherry picked from commit 9446629b730c59c4215f08d37fbaf810282fbccb) ---- - bin/named/client.c | 171 ++++++++++++++++++++----------- - bin/named/include/named/client.h | 2 +- - 2 files changed, 110 insertions(+), 63 deletions(-) - -diff --git a/bin/named/client.c b/bin/named/client.c -index a7b49a0f71..277656cef0 100644 ---- a/bin/named/client.c -+++ b/bin/named/client.c -@@ -299,6 +299,75 @@ ns_client_settimeout(ns_client_t *client, unsigned int seconds) { - } - } - -+/*% -+ * Allocate a reference counter that will track the number of client structures -+ * using the TCP connection that 'client' called accept() for. This counter -+ * will be shared between all client structures associated with this TCP -+ * connection. -+ */ -+static void -+pipeline_init(ns_client_t *client) { -+ isc_refcount_t *refs; -+ -+ REQUIRE(client->pipeline_refs == NULL); -+ -+ /* -+ * A global memory context is used for the allocation as different -+ * client structures may have different memory contexts assigned and a -+ * reference counter allocated here might need to be freed by a -+ * different client. The performance impact caused by memory context -+ * contention here is expected to be negligible, given that this code -+ * is only executed for TCP connections. -+ */ -+ refs = isc_mem_allocate(client->sctx->mctx, sizeof(*refs)); -+ isc_refcount_init(refs, 1); -+ client->pipeline_refs = refs; -+} -+ -+/*% -+ * Increase the count of client structures using the TCP connection that -+ * 'source' is associated with and put a pointer to that count in 'target', -+ * thus associating it with the same TCP connection. -+ */ -+static void -+pipeline_attach(ns_client_t *source, ns_client_t *target) { -+ int old_refs; -+ -+ REQUIRE(source->pipeline_refs != NULL); -+ REQUIRE(target->pipeline_refs == NULL); -+ -+ old_refs = isc_refcount_increment(source->pipeline_refs); -+ INSIST(old_refs > 0); -+ target->pipeline_refs = source->pipeline_refs; -+} -+ -+/*% -+ * Decrease the count of client structures using the TCP connection that -+ * 'client' is associated with. If this is the last client using this TCP -+ * connection, free the reference counter and return true; otherwise, return -+ * false. -+ */ -+static bool -+pipeline_detach(ns_client_t *client) { -+ isc_refcount_t *refs; -+ int old_refs; -+ -+ REQUIRE(client->pipeline_refs != NULL); -+ -+ refs = client->pipeline_refs; -+ client->pipeline_refs = NULL; -+ -+ old_refs = isc_refcount_decrement(refs); -+ INSIST(old_refs > 0); -+ -+ if (old_refs == 1) { -+ isc_mem_free(client->sctx->mctx, refs); -+ return (true); -+ } -+ -+ return (false); -+} -+ - /*% - * Check for a deactivation or shutdown request and take appropriate - * action. Returns true if either is in progress; in this case -@@ -421,6 +490,40 @@ exit_check(ns_client_t *client) { - client->tcpmsg_valid = false; - } - -+ if (client->tcpquota != NULL) { -+ if (client->pipeline_refs == NULL || -+ pipeline_detach(client)) -+ { -+ /* -+ * Only detach from the TCP client quota if -+ * there are no more client structures using -+ * this TCP connection. -+ * -+ * Note that we check 'pipeline_refs' and not -+ * 'pipelined' because in some cases (e.g. -+ * after receiving a request with an opcode -+ * different than QUERY) 'pipelined' is set to -+ * false after the reference counter gets -+ * allocated in pipeline_init() and we must -+ * still drop our reference as failing to do so -+ * would prevent the reference counter itself -+ * from being freed. -+ */ -+ isc_quota_detach(&client->tcpquota); -+ } else { -+ /* -+ * There are other client structures using this -+ * TCP connection, so we cannot detach from the -+ * TCP client quota to prevent excess TCP -+ * connections from being accepted. However, -+ * this client structure might later be reused -+ * for accepting new connections and thus must -+ * have its 'tcpquota' field set to NULL. -+ */ -+ client->tcpquota = NULL; -+ } -+ } -+ - if (client->tcpsocket != NULL) { - CTRACE("closetcp"); - isc_socket_detach(&client->tcpsocket); -@@ -434,44 +537,6 @@ exit_check(ns_client_t *client) { - } - } - -- if (client->tcpquota != NULL) { -- /* -- * If we are not in a pipeline group, or -- * we are the last client in the group, detach from -- * tcpquota; otherwise, transfer the quota to -- * another client in the same group. -- */ -- if (!ISC_LINK_LINKED(client, glink) || -- (client->glink.next == NULL && -- client->glink.prev == NULL)) -- { -- isc_quota_detach(&client->tcpquota); -- } else if (client->glink.next != NULL) { -- INSIST(client->glink.next->tcpquota == NULL); -- client->glink.next->tcpquota = client->tcpquota; -- client->tcpquota = NULL; -- } else { -- INSIST(client->glink.prev->tcpquota == NULL); -- client->glink.prev->tcpquota = client->tcpquota; -- client->tcpquota = NULL; -- } -- } -- -- /* -- * Unlink from pipeline group. -- */ -- if (ISC_LINK_LINKED(client, glink)) { -- if (client->glink.next != NULL) { -- client->glink.next->glink.prev = -- client->glink.prev; -- } -- if (client->glink.prev != NULL) { -- client->glink.prev->glink.next = -- client->glink.next; -- } -- ISC_LINK_INIT(client, glink); -- } -- - if (client->timerset) { - (void)isc_timer_reset(client->timer, - isc_timertype_inactive, -@@ -3130,6 +3195,7 @@ client_create(ns_clientmgr_t *manager, ns_client_t **clientp) { - dns_name_init(&client->signername, NULL); - client->mortal = false; - client->pipelined = false; -+ client->pipeline_refs = NULL; - client->tcpquota = NULL; - client->recursionquota = NULL; - client->interface = NULL; -@@ -3154,7 +3220,6 @@ client_create(ns_clientmgr_t *manager, ns_client_t **clientp) { - client->formerrcache.id = 0; - ISC_LINK_INIT(client, link); - ISC_LINK_INIT(client, rlink); -- ISC_LINK_INIT(client, glink); - ISC_QLINK_INIT(client, ilink); - client->keytag = NULL; - client->keytag_len = 0; -@@ -3341,6 +3406,7 @@ client_newconn(isc_task_t *task, isc_event_t *event) { - !allowed(&netaddr, NULL, NULL, 0, NULL, - ns_g_server->keepresporder))) - { -+ pipeline_init(client); - client->pipelined = true; - } - -@@ -3800,35 +3866,16 @@ get_worker(ns_clientmgr_t *manager, ns_interface_t *ifp, isc_socket_t *sock, - ns_interface_attach(ifp, &client->interface); - client->newstate = client->state = NS_CLIENTSTATE_WORKING; - INSIST(client->recursionquota == NULL); -- -- /* -- * Transfer TCP quota to the new client. -- */ -- INSIST(client->tcpquota == NULL); -- INSIST(oldclient->tcpquota != NULL); -- client->tcpquota = oldclient->tcpquota; -- oldclient->tcpquota = NULL; -- -- /* -- * Link to a pipeline group, creating it if needed. -- */ -- if (!ISC_LINK_LINKED(oldclient, glink)) { -- oldclient->glink.next = NULL; -- oldclient->glink.prev = NULL; -- } -- client->glink.next = oldclient->glink.next; -- client->glink.prev = oldclient; -- if (oldclient->glink.next != NULL) { -- oldclient->glink.next->glink.prev = client; -- } -- oldclient->glink.next = client; -+ client->tcpquota = &client->sctx->tcpquota; - - client->dscp = ifp->dscp; - - client->attributes |= NS_CLIENTATTR_TCP; -- client->pipelined = true; - client->mortal = true; - -+ pipeline_attach(oldclient, client); -+ client->pipelined = true; -+ - isc_socket_attach(ifp->tcpsocket, &client->tcplistener); - isc_socket_attach(sock, &client->tcpsocket); - isc_socket_setname(client->tcpsocket, "worker-tcp", NULL); -diff --git a/bin/named/include/named/client.h b/bin/named/include/named/client.h -index 1f7973f9c5..aeed9ccdda 100644 ---- a/bin/named/include/named/client.h -+++ b/bin/named/include/named/client.h -@@ -134,6 +134,7 @@ struct ns_client { - dns_name_t *signer; /*%< NULL if not valid sig */ - bool mortal; /*%< Die after handling request */ - bool pipelined; /*%< TCP queries not in sequence */ -+ isc_refcount_t *pipeline_refs; - isc_quota_t *tcpquota; - isc_quota_t *recursionquota; - ns_interface_t *interface; -@@ -167,7 +168,6 @@ struct ns_client { - - ISC_LINK(ns_client_t) link; - ISC_LINK(ns_client_t) rlink; -- ISC_LINK(ns_client_t) glink; - ISC_QLINK(ns_client_t) ilink; - unsigned char cookie[8]; - uint32_t expire; --- -2.20.1 - |