summaryrefslogtreecommitdiff
path: root/usr.sbin
diff options
context:
space:
mode:
Diffstat (limited to 'usr.sbin')
-rw-r--r--usr.sbin/httpd/httpd.h3
-rw-r--r--usr.sbin/httpd/server.c7
-rw-r--r--usr.sbin/httpd/server_fcgi.c13
3 files changed, 20 insertions, 3 deletions
diff --git a/usr.sbin/httpd/httpd.h b/usr.sbin/httpd/httpd.h
index 6cef91ade8b..1e2ccb9d296 100644
--- a/usr.sbin/httpd/httpd.h
+++ b/usr.sbin/httpd/httpd.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: httpd.h,v 1.162 2022/10/24 15:02:01 jmc Exp $ */
+/* $OpenBSD: httpd.h,v 1.163 2023/07/12 12:37:27 tb Exp $ */
/*
* Copyright (c) 2006 - 2015 Reyk Floeter <reyk@openbsd.org>
@@ -352,6 +352,7 @@ struct client {
int clt_inflight;
struct range_data clt_ranges;
struct fcgi_data clt_fcgi;
+ const char *clt_fcgi_error;
char *clt_remote_user;
struct evbuffer *clt_srvevb;
diff --git a/usr.sbin/httpd/server.c b/usr.sbin/httpd/server.c
index 90a47d67c80..6999b08cfae 100644
--- a/usr.sbin/httpd/server.c
+++ b/usr.sbin/httpd/server.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: server.c,v 1.126 2021/07/14 13:33:57 kn Exp $ */
+/* $OpenBSD: server.c,v 1.127 2023/07/12 12:37:27 tb Exp $ */
/*
* Copyright (c) 2006 - 2015 Reyk Floeter <reyk@openbsd.org>
@@ -1300,6 +1300,11 @@ server_close(struct client *clt, const char *msg)
{
struct server *srv = clt->clt_srv;
+ if (clt->clt_fcgi_error != NULL) {
+ clt->clt_fcgi_error = msg;
+ return;
+ }
+
SPLAY_REMOVE(client_tree, &srv->srv_clients, clt);
/* free the HTTP descriptors incl. headers */
diff --git a/usr.sbin/httpd/server_fcgi.c b/usr.sbin/httpd/server_fcgi.c
index 073ab344079..d2c7d8a2076 100644
--- a/usr.sbin/httpd/server_fcgi.c
+++ b/usr.sbin/httpd/server_fcgi.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: server_fcgi.c,v 1.95 2022/08/15 12:29:17 claudio Exp $ */
+/* $OpenBSD: server_fcgi.c,v 1.96 2023/07/12 12:37:28 tb Exp $ */
/*
* Copyright (c) 2014 Florian Obser <florian@openbsd.org>
@@ -372,7 +372,18 @@ server_fcgi(struct httpd *env, struct client *clt)
srv_conf->timeout.tv_sec, srv_conf->timeout.tv_sec);
bufferevent_enable(clt->clt_srvbev, EV_READ|EV_WRITE);
if (clt->clt_toread != 0) {
+ /*
+ * XXX - Work around UAF: server_read_httpcontent() can call
+ * server_close(), normally freeing clt. If clt->clt_fcgi_error
+ * changed, call server_close() via server_abort_http().
+ */
+ clt->clt_fcgi_error = "";
server_read_httpcontent(clt->clt_bev, clt);
+ errstr = clt->clt_fcgi_error;
+ clt->clt_fcgi_error = NULL;
+ if (errstr[0] != '\0')
+ goto fail;
+ errstr = NULL;
bufferevent_enable(clt->clt_bev, EV_READ);
} else {
bufferevent_disable(clt->clt_bev, EV_READ);