summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChen Qi <Qi.Chen@windriver.com>2023-09-14 12:00:26 +0800
committerArmin Kuster <akuster808@gmail.com>2023-09-15 07:22:08 -0400
commit48b590afc4381cebc477d27a4d1efebed23c32e8 (patch)
tree73a74ecbdf3c1abf8da23a155d806b5045daf058
parent63a9c4978136caa12f9a5dccb5123e5b9d09f7e8 (diff)
downloadmeta-openembedded-48b590afc4381cebc477d27a4d1efebed23c32e8.tar.gz
grpc: fix CVE-2023-33953
Signed-off-by: Chen Qi <Qi.Chen@windriver.com> Signed-off-by: Armin Kuster <akuster808@gmail.com>
-rw-r--r--meta-oe/recipes-devtools/grpc/grpc/0001-backport-iomgr-EventEngine-Improve-server-handling-o.patch224
-rw-r--r--meta-oe/recipes-devtools/grpc/grpc_1.50.1.bb1
2 files changed, 225 insertions, 0 deletions
diff --git a/meta-oe/recipes-devtools/grpc/grpc/0001-backport-iomgr-EventEngine-Improve-server-handling-o.patch b/meta-oe/recipes-devtools/grpc/grpc/0001-backport-iomgr-EventEngine-Improve-server-handling-o.patch
new file mode 100644
index 0000000000..4488df172f
--- /dev/null
+++ b/meta-oe/recipes-devtools/grpc/grpc/0001-backport-iomgr-EventEngine-Improve-server-handling-o.patch
@@ -0,0 +1,224 @@
1From b3c105c59dfb7d932b36b0d9ac7ab62875ab23e8 Mon Sep 17 00:00:00 2001
2From: AJ Heller <hork@google.com>
3Date: Wed, 12 Jul 2023 18:42:09 -0700
4Subject: [PATCH] [backport][iomgr][EventEngine] Improve server handling of
5 file descriptor exhaustion (#33672)
6
7Backport of #33656
8
9CVE: CVE-2023-33953
10
11Upstream-Status: Backport [1e86ca5834b94cae7d5e6d219056c0fc895cf95d]
12The patch is backported with tweaks to fit 1.50.1.
13
14Signed-off-by: Chen Qi <Qi.Chen@windriver.com>
15---
16 .../event_engine/posix_engine/posix_engine.h | 1 +
17 src/core/lib/iomgr/tcp_server_posix.cc | 51 ++++++++++++++-----
18 src/core/lib/iomgr/tcp_server_utils_posix.h | 14 ++++-
19 .../iomgr/tcp_server_utils_posix_common.cc | 22 ++++++++
20 4 files changed, 73 insertions(+), 15 deletions(-)
21
22diff --git a/src/core/lib/event_engine/posix_engine/posix_engine.h b/src/core/lib/event_engine/posix_engine/posix_engine.h
23index eac6dfb4c5..866c04bcfa 100644
24--- a/src/core/lib/event_engine/posix_engine/posix_engine.h
25+++ b/src/core/lib/event_engine/posix_engine/posix_engine.h
26@@ -97,6 +97,7 @@ class PosixEventEngine final : public EventEngine {
27 const DNSResolver::ResolverOptions& options) override;
28 void Run(Closure* closure) override;
29 void Run(absl::AnyInvocable<void()> closure) override;
30+ // Caution!! The timer implementation cannot create any fds. See #20418.
31 TaskHandle RunAfter(Duration when, Closure* closure) override;
32 TaskHandle RunAfter(Duration when,
33 absl::AnyInvocable<void()> closure) override;
34diff --git a/src/core/lib/iomgr/tcp_server_posix.cc b/src/core/lib/iomgr/tcp_server_posix.cc
35index d43113fb03..32be997cff 100644
36--- a/src/core/lib/iomgr/tcp_server_posix.cc
37+++ b/src/core/lib/iomgr/tcp_server_posix.cc
38@@ -16,13 +16,17 @@
39 *
40 */
41
42-/* FIXME: "posix" files shouldn't be depending on _GNU_SOURCE */
43+#include <grpc/support/port_platform.h>
44+
45+#include <utility>
46+
47+#include <grpc/support/atm.h>
48+
49+// FIXME: "posix" files shouldn't be depending on _GNU_SOURCE
50 #ifndef _GNU_SOURCE
51 #define _GNU_SOURCE
52 #endif
53
54-#include <grpc/support/port_platform.h>
55-
56 #include "src/core/lib/iomgr/port.h"
57
58 #ifdef GRPC_POSIX_SOCKET_TCP_SERVER
59@@ -44,6 +48,7 @@
60 #include "absl/strings/str_format.h"
61
62 #include <grpc/event_engine/endpoint_config.h>
63+#include <grpc/event_engine/event_engine.h>
64 #include <grpc/support/alloc.h>
65 #include <grpc/support/log.h>
66 #include <grpc/support/sync.h>
67@@ -63,6 +68,8 @@
68 #include "src/core/lib/resource_quota/api.h"
69
70 static std::atomic<int64_t> num_dropped_connections{0};
71+static constexpr grpc_core::Duration kRetryAcceptWaitTime{
72+ grpc_core::Duration::Seconds(1)};
73
74 using ::grpc_event_engine::experimental::EndpointConfig;
75
76@@ -195,21 +202,35 @@ static void on_read(void* arg, grpc_error_handle err) {
77 if (fd < 0) {
78 if (errno == EINTR) {
79 continue;
80- } else if (errno == EAGAIN || errno == ECONNABORTED ||
81- errno == EWOULDBLOCK) {
82+ }
83+ // When the process runs out of fds, accept4() returns EMFILE. When this
84+ // happens, the connection is left in the accept queue until either a
85+ // read event triggers the on_read callback, or time has passed and the
86+ // accept should be re-tried regardless. This callback is not cancelled,
87+ // so a spurious wakeup may occur even when there's nothing to accept.
88+ // This is not a performant code path, but if an fd limit has been
89+ // reached, the system is likely in an unhappy state regardless.
90+ if (errno == EMFILE) {
91 grpc_fd_notify_on_read(sp->emfd, &sp->read_closure);
92+ if (gpr_atm_full_xchg(&sp->retry_timer_armed, true)) return;
93+ grpc_timer_init(&sp->retry_timer,
94+ grpc_core::Timestamp::Now() + kRetryAcceptWaitTime,
95+ &sp->retry_closure);
96 return;
97+ }
98+ if (errno == EAGAIN || errno == ECONNABORTED || errno == EWOULDBLOCK) {
99+ grpc_fd_notify_on_read(sp->emfd, &sp->read_closure);
100+ return;
101+ }
102+ gpr_mu_lock(&sp->server->mu);
103+ if (!sp->server->shutdown_listeners) {
104+ gpr_log(GPR_ERROR, "Failed accept4: %s", strerror(errno));
105 } else {
106- gpr_mu_lock(&sp->server->mu);
107- if (!sp->server->shutdown_listeners) {
108- gpr_log(GPR_ERROR, "Failed accept4: %s", strerror(errno));
109- } else {
110- /* if we have shutdown listeners, accept4 could fail, and we
111- needn't notify users */
112- }
113- gpr_mu_unlock(&sp->server->mu);
114- goto error;
115+ // if we have shutdown listeners, accept4 could fail, and we
116+ // needn't notify users
117 }
118+ gpr_mu_unlock(&sp->server->mu);
119+ goto error;
120 }
121
122 if (sp->server->memory_quota->IsMemoryPressureHigh()) {
123@@ -403,6 +424,7 @@ static grpc_error_handle clone_port(grpc_tcp_listener* listener,
124 sp->port_index = listener->port_index;
125 sp->fd_index = listener->fd_index + count - i;
126 GPR_ASSERT(sp->emfd);
127+ grpc_tcp_server_listener_initialize_retry_timer(sp);
128 while (listener->server->tail->next != nullptr) {
129 listener->server->tail = listener->server->tail->next;
130 }
131@@ -575,6 +597,7 @@ static void tcp_server_shutdown_listeners(grpc_tcp_server* s) {
132 if (s->active_ports) {
133 grpc_tcp_listener* sp;
134 for (sp = s->head; sp; sp = sp->next) {
135+ grpc_timer_cancel(&sp->retry_timer);
136 grpc_fd_shutdown(sp->emfd,
137 GRPC_ERROR_CREATE_FROM_STATIC_STRING("Server shutdown"));
138 }
139diff --git a/src/core/lib/iomgr/tcp_server_utils_posix.h b/src/core/lib/iomgr/tcp_server_utils_posix.h
140index 94faa2c17e..2e78ce555f 100644
141--- a/src/core/lib/iomgr/tcp_server_utils_posix.h
142+++ b/src/core/lib/iomgr/tcp_server_utils_posix.h
143@@ -25,6 +25,7 @@
144 #include "src/core/lib/iomgr/resolve_address.h"
145 #include "src/core/lib/iomgr/socket_utils_posix.h"
146 #include "src/core/lib/iomgr/tcp_server.h"
147+#include "src/core/lib/iomgr/timer.h"
148 #include "src/core/lib/resource_quota/memory_quota.h"
149
150 /* one listening port */
151@@ -47,6 +48,11 @@ typedef struct grpc_tcp_listener {
152 identified while iterating through 'next'. */
153 struct grpc_tcp_listener* sibling;
154 int is_sibling;
155+ // If an accept4() call fails, a timer is started to drain the accept queue in
156+ // case no further connection attempts reach the gRPC server.
157+ grpc_closure retry_closure;
158+ grpc_timer retry_timer;
159+ gpr_atm retry_timer_armed;
160 } grpc_tcp_listener;
161
162 /* the overall server */
163@@ -126,4 +132,10 @@ grpc_error_handle grpc_tcp_server_prepare_socket(
164 /* Ruturn true if the platform supports ifaddrs */
165 bool grpc_tcp_server_have_ifaddrs(void);
166
167-#endif /* GRPC_CORE_LIB_IOMGR_TCP_SERVER_UTILS_POSIX_H */
168+// Initialize (but don't start) the timer and callback to retry accept4() on a
169+// listening socket after file descriptors have been exhausted. This must be
170+// called when creating a new listener.
171+void grpc_tcp_server_listener_initialize_retry_timer(
172+ grpc_tcp_listener* listener);
173+
174+#endif // GRPC_SRC_CORE_LIB_IOMGR_TCP_SERVER_UTILS_POSIX_H
175diff --git a/src/core/lib/iomgr/tcp_server_utils_posix_common.cc b/src/core/lib/iomgr/tcp_server_utils_posix_common.cc
176index 73a6b943ec..0e671c6485 100644
177--- a/src/core/lib/iomgr/tcp_server_utils_posix_common.cc
178+++ b/src/core/lib/iomgr/tcp_server_utils_posix_common.cc
179@@ -18,6 +18,8 @@
180
181 #include <grpc/support/port_platform.h>
182
183+#include <grpc/support/atm.h>
184+
185 #include "src/core/lib/iomgr/port.h"
186
187 #ifdef GRPC_POSIX_SOCKET_TCP_SERVER_UTILS_COMMON
188@@ -80,6 +82,24 @@ static int get_max_accept_queue_size(void) {
189 return s_max_accept_queue_size;
190 }
191
192+static void listener_retry_timer_cb(void* arg, grpc_error_handle err) {
193+ // Do nothing if cancelled.
194+ if (!err.ok()) return;
195+ grpc_tcp_listener* listener = static_cast<grpc_tcp_listener*>(arg);
196+ gpr_atm_no_barrier_store(&listener->retry_timer_armed, false);
197+ if (!grpc_fd_is_shutdown(listener->emfd)) {
198+ grpc_fd_set_readable(listener->emfd);
199+ }
200+}
201+
202+void grpc_tcp_server_listener_initialize_retry_timer(
203+ grpc_tcp_listener* listener) {
204+ gpr_atm_no_barrier_store(&listener->retry_timer_armed, false);
205+ grpc_timer_init_unset(&listener->retry_timer);
206+ GRPC_CLOSURE_INIT(&listener->retry_closure, listener_retry_timer_cb, listener,
207+ grpc_schedule_on_exec_ctx);
208+}
209+
210 static grpc_error_handle add_socket_to_server(grpc_tcp_server* s, int fd,
211 const grpc_resolved_address* addr,
212 unsigned port_index,
213@@ -112,6 +132,8 @@ static grpc_error_handle add_socket_to_server(grpc_tcp_server* s, int fd,
214 sp->server = s;
215 sp->fd = fd;
216 sp->emfd = grpc_fd_create(fd, name.c_str(), true);
217+ grpc_tcp_server_listener_initialize_retry_timer(sp);
218+
219 memcpy(&sp->addr, addr, sizeof(grpc_resolved_address));
220 sp->port = port;
221 sp->port_index = port_index;
222--
2232.34.1
224
diff --git a/meta-oe/recipes-devtools/grpc/grpc_1.50.1.bb b/meta-oe/recipes-devtools/grpc/grpc_1.50.1.bb
index b3956ce40c..3cfd0210db 100644
--- a/meta-oe/recipes-devtools/grpc/grpc_1.50.1.bb
+++ b/meta-oe/recipes-devtools/grpc/grpc_1.50.1.bb
@@ -27,6 +27,7 @@ SRC_URI = "gitsm://github.com/grpc/grpc.git;protocol=https;name=grpc;branch=${BR
27 file://0001-cmake-add-separate-export-for-plugin-targets.patch \ 27 file://0001-cmake-add-separate-export-for-plugin-targets.patch \
28 file://0001-cmake-Link-with-libatomic-on-rv32-rv64.patch \ 28 file://0001-cmake-Link-with-libatomic-on-rv32-rv64.patch \
29 file://0001-fix-CVE-2023-32732.patch \ 29 file://0001-fix-CVE-2023-32732.patch \
30 file://0001-backport-iomgr-EventEngine-Improve-server-handling-o.patch \
30 " 31 "
31# Fixes build with older compilers 4.8 especially on ubuntu 14.04 32# Fixes build with older compilers 4.8 especially on ubuntu 14.04
32CXXFLAGS:append:class-native = " -Wl,--no-as-needed" 33CXXFLAGS:append:class-native = " -Wl,--no-as-needed"