untrusted comment: verify with openbsd-74-base.pub
RWRoyQmAD08ajfhE3n3+C7wEVHk7urK0MrIoBIrcnxZYFAqJi1DkZWgRT9Qa+RHOE19TMmHtjO1atS0BmFcLPHBHx5KMXtdvgwE=
OpenBSD 7.4 errata 006, November 21, 2023:
httpd(8): Avoid a NULL dereference when handling a malformed fastcgi request.
Apply by doing:
signify -Vep /etc/signify/openbsd-74-base.pub -x 006_httpd.patch.sig \
-m - | (cd /usr/src && patch -p0)
And then rebuild and install httpd(8):
cd /usr/src/usr.sbin/httpd
make obj
make
make install
Index: usr.sbin/httpd/httpd.h
===================================================================
RCS file: /cvs/src/usr.sbin/httpd/httpd.h,v
diff -u -p -r1.163 httpd.h
--- usr.sbin/httpd/httpd.h 12 Jul 2023 12:37:27 -0000 1.163
+++ usr.sbin/httpd/httpd.h 16 Nov 2023 17:28:00 -0000
@@ -350,6 +350,7 @@ struct client {
int clt_done;
int clt_chunk;
int clt_inflight;
+ int clt_fcgi_count;
struct range_data clt_ranges;
struct fcgi_data clt_fcgi;
const char *clt_fcgi_error;
Index: usr.sbin/httpd/server.c
===================================================================
RCS file: /cvs/src/usr.sbin/httpd/server.c,v
diff -u -p -r1.128 server.c
--- usr.sbin/httpd/server.c 3 Sep 2023 10:18:18 -0000 1.128
+++ usr.sbin/httpd/server.c 16 Nov 2023 17:28:00 -0000
@@ -1300,7 +1300,7 @@ server_close(struct client *clt, const c
{
struct server *srv = clt->clt_srv;
- if (clt->clt_fcgi_error != NULL) {
+ if (clt->clt_fcgi_count-- > 0) {
clt->clt_fcgi_error = msg;
return;
}
Index: usr.sbin/httpd/server_fcgi.c
===================================================================
RCS file: /cvs/src/usr.sbin/httpd/server_fcgi.c,v
diff -u -p -r1.96 server_fcgi.c
--- usr.sbin/httpd/server_fcgi.c 12 Jul 2023 12:37:28 -0000 1.96
+++ usr.sbin/httpd/server_fcgi.c 16 Nov 2023 17:28:00 -0000
@@ -374,16 +374,15 @@ server_fcgi(struct httpd *env, struct cl
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().
+ * server_close(), normally freeing clt. If clt->clt_fcgi_count
+ * reaches 0, call server_close() via server_abort_http().
*/
- clt->clt_fcgi_error = "";
+ clt->clt_fcgi_count++;
server_read_httpcontent(clt->clt_bev, clt);
- errstr = clt->clt_fcgi_error;
- clt->clt_fcgi_error = NULL;
- if (errstr[0] != '\0')
+ if (clt->clt_fcgi_count-- <= 0) {
+ errstr = clt->clt_fcgi_error;
goto fail;
- errstr = NULL;
+ }
bufferevent_enable(clt->clt_bev, EV_READ);
} else {
bufferevent_disable(clt->clt_bev, EV_READ);