diff options
| author | Dirk Engling <erdgeist@erdgeist.org> | 2026-10-30 01:00:52 +0100 |
|---|---|---|
| committer | Dirk Engling <erdgeist@erdgeist.org> | 2026-10-30 01:00:52 +0100 |
| commit | 79f4110365fe85f4377c50f0893134a8d5e45575 (patch) | |
| tree | e69f5ceae67e4f283bede83f6649b7df0ded7076 /opentracker.c | |
| parent | d92945fe3a7960cfc7ddfd70a9a37d6db666c1e2 (diff) | |
Consolidate all tcp/http tear down into a single http_close function to prevent a rare UAF for expiring connections
Diffstat (limited to 'opentracker.c')
| -rw-r--r-- | opentracker.c | 27 |
1 files changed, 5 insertions, 22 deletions
diff --git a/opentracker.c b/opentracker.c index e0f16d7..6160696 100644 --- a/opentracker.c +++ b/opentracker.c | |||
| @@ -115,29 +115,12 @@ static ssize_t header_complete(char *request, ssize_t byte_count) { | |||
| 115 | return 0; | 115 | return 0; |
| 116 | } | 116 | } |
| 117 | 117 | ||
| 118 | static void handle_dead(const int64_t sock) { | ||
| 119 | struct http_data *cookie = fdstate_cookie(sock); | ||
| 120 | if (cookie) { | ||
| 121 | if (cookie->batch) | ||
| 122 | batch_reset(cookie->batch); | ||
| 123 | free(cookie->batch); | ||
| 124 | buf_reset(&cookie->request); | ||
| 125 | if (cookie->flag & (STRUCT_HTTP_FLAG_WAITINGFORTASK | STRUCT_HTTP_FLAG_CHUNKED_IN_TRANSFER)) | ||
| 126 | mutex_workqueue_canceltask(sock); | ||
| 127 | free(cookie); | ||
| 128 | } | ||
| 129 | /* The generation has to move before the kernel can reissue the number */ | ||
| 130 | fdstate_close(sock); | ||
| 131 | event_del((int)sock); | ||
| 132 | close((int)sock); | ||
| 133 | } | ||
| 134 | |||
| 135 | static void handle_read(const int64_t sock, struct ot_workstruct *ws) { | 118 | static void handle_read(const int64_t sock, struct ot_workstruct *ws) { |
| 136 | struct http_data *cookie = fdstate_cookie(sock); | 119 | struct http_data *cookie = fdstate_cookie(sock); |
| 137 | ssize_t byte_count = read((int)sock, ws->inbuf, G_INBUF_SIZE); | 120 | ssize_t byte_count = read((int)sock, ws->inbuf, G_INBUF_SIZE); |
| 138 | 121 | ||
| 139 | if (byte_count == 0 || (byte_count == -1 && errno != EAGAIN && errno != EWOULDBLOCK && errno != EINTR)) { | 122 | if (byte_count == 0 || (byte_count == -1 && errno != EAGAIN && errno != EWOULDBLOCK && errno != EINTR)) { |
| 140 | handle_dead(sock); | 123 | http_close(sock); |
| 141 | return; | 124 | return; |
| 142 | } | 125 | } |
| 143 | 126 | ||
| @@ -156,7 +139,7 @@ static void handle_read(const int64_t sock, struct ot_workstruct *ws) { | |||
| 156 | ws->request_size = byte_count; | 139 | ws->request_size = byte_count; |
| 157 | http_handle_request(sock, ws); | 140 | http_handle_request(sock, ws); |
| 158 | } else if (buf_cat(&cookie->request, ws->inbuf, (size_t)byte_count)) | 141 | } else if (buf_cat(&cookie->request, ws->inbuf, (size_t)byte_count)) |
| 159 | handle_dead(sock); | 142 | http_close(sock); |
| 160 | return; | 143 | return; |
| 161 | } | 144 | } |
| 162 | 145 | ||
| @@ -187,7 +170,7 @@ static void handle_write(const int64_t sock) { | |||
| 187 | 170 | ||
| 188 | if (cookie->batch) { | 171 | if (cookie->batch) { |
| 189 | if (batch_send(sock, cookie->batch) == BATCH_FAILED) { | 172 | if (batch_send(sock, cookie->batch) == BATCH_FAILED) { |
| 190 | handle_dead(sock); | 173 | http_close(sock); |
| 191 | return; | 174 | return; |
| 192 | } | 175 | } |
| 193 | if (batch_pending(cookie->batch)) | 176 | if (batch_pending(cookie->batch)) |
| @@ -205,7 +188,7 @@ static void handle_write(const int64_t sock) { | |||
| 205 | http_interest_add(sock, cookie, EVENT_IN); | 188 | http_interest_add(sock, cookie, EVENT_IN); |
| 206 | fdstate_set_expiry(sock, time_future_seconds(OT_CLIENT_TIMEOUT)); | 189 | fdstate_set_expiry(sock, time_future_seconds(OT_CLIENT_TIMEOUT)); |
| 207 | } else | 190 | } else |
| 208 | handle_dead(sock); | 191 | http_close(sock); |
| 209 | } | 192 | } |
| 210 | 193 | ||
| 211 | static void handle_accept(const int64_t serversocket, struct ot_workstruct *ws) { | 194 | static void handle_accept(const int64_t serversocket, struct ot_workstruct *ws) { |
| @@ -303,7 +286,7 @@ static void *server_mainloop(void *args) { | |||
| 303 | int cursor = 0; | 286 | int cursor = 0; |
| 304 | 287 | ||
| 305 | while ((sock = fdstate_next_expired(time_now_seconds(), &cursor)) != -1) | 288 | while ((sock = fdstate_next_expired(time_now_seconds(), &cursor)) != -1) |
| 306 | handle_dead(sock); | 289 | http_close(sock); |
| 307 | next_timeout_check = time_future_seconds(OT_CLIENT_TIMEOUT_CHECKINTERVAL); | 290 | next_timeout_check = time_future_seconds(OT_CLIENT_TIMEOUT_CHECKINTERVAL); |
| 308 | } | 291 | } |
| 309 | 292 | ||
