Commit Diff


commit - 8dcab0e2df9c42f05eed6ffb1422d251ca15cb71
commit + afc41fe08300310c8fc6ef0007438e5a8b5907fe
blob - b4a8e734d614e15488d6d70d4f26c72cce07fb48
blob + cdb04f1eb0e6eb9a341ed47e3194baaca28fb0d0
--- config.c
+++ config.c
@@ -1,4 +1,4 @@
-/*	$OpenBSD: config.c,v 1.65 2024/01/17 08:22:40 claudio Exp $	*/
+/*	$OpenBSD: config.c,v 1.66 2025/11/12 11:24:04 deraadt Exp $	*/
 
 /*
  * Copyright (c) 2011 - 2015 Reyk Floeter <reyk@openbsd.org>
@@ -158,6 +158,49 @@ config_getcfg(struct httpd *env, struct imsg *imsg)
 	return (0);
 }
 
+/*
+ * struct server_config is an internal data structure
+ * in privileged compartment containing both data and
+ * pointers, which is dangerously copied as a whole.
+ *
+ * This helper function clears all the pointer
+ * fields in struct server_config while preserving
+ * other data, avoiding pointers being accidentally
+ * send to unprivileged compartments, breaking
+ * inter-compartment ASLR.
+ */
+static void
+clear_config_server_ptrs(struct server_config *cfg)
+{
+	cfg->default_type.media_encoding = NULL;
+
+	/* clear all fields expanded from RB_ENTRY */
+	memset(&cfg->default_type.media_entry, 0,
+	    sizeof(cfg->default_type.media_entry));
+
+	cfg->tls_ca = NULL;
+	cfg->tls_ca_file = NULL;
+	cfg->tls_cert = NULL;
+	cfg->tls_cert_file = NULL;
+	cfg->tls_crl = NULL;
+	cfg->tls_crl_file = NULL;
+	cfg->tls_key = NULL;
+	cfg->tls_key_file = NULL;
+	cfg->tls_ocsp_staple = NULL;
+	cfg->tls_ocsp_staple_file = NULL;
+
+	cfg->logaccess = NULL;
+	cfg->logerror = NULL;
+	cfg->auth = NULL;
+	cfg->return_uri = NULL;
+
+	/* clear TAILQ_HEAD */
+	memset(&cfg->fcgiparams, 0, sizeof(cfg->fcgiparams));
+
+	/* clear TAILQ_ENTRY */
+	memset(&cfg->entry, 0, sizeof(cfg->entry));
+}
+
 int
 config_setserver(struct httpd *env, struct server *srv)
 {
@@ -187,6 +230,9 @@ config_setserver(struct httpd *env, struct server *srv
 
 		memcpy(&s, &srv->srv_conf, sizeof(s));
 
+		/* since s is a local, it is safe to clear its pointers directly */
+		clear_config_server_ptrs(&s); 
+
 		c = 0;
 		iov[c].iov_base = &s;
 		iov[c++].iov_len = sizeof(s);
@@ -821,6 +867,7 @@ config_setmedia(struct httpd *env, struct media_type *
 	struct privsep		*ps = env->sc_ps;
 	int			 id;
 	unsigned int		 what;
+	struct media_type	 mt;
 
 	for (id = 0; id < PROC_MAX; id++) {
 		what = ps->ps_what[id];
@@ -831,7 +878,12 @@ config_setmedia(struct httpd *env, struct media_type *
 		DPRINTF("%s: sending media \"%s\" to %s", __func__,
 		    media->media_name, ps->ps_title[id]);
 
-		proc_compose(ps, id, IMSG_CFG_MEDIA, media, sizeof(*media));
+		/* Send a cleaned-up copy */
+		memcpy(&mt, media, sizeof(*media)); 
+		mt.media_encoding = NULL;
+		memset(&mt.media_entry, 0, sizeof(mt.media_entry));
+
+		proc_compose(ps, id, IMSG_CFG_MEDIA, &mt, sizeof(mt));
 	}
 
 	return (0);
@@ -866,6 +918,7 @@ int
 config_setauth(struct httpd *env, struct auth *auth)
 {
 	struct privsep		*ps = env->sc_ps;
+	struct auth		 auth_payload;	/* pointer-free payload */
 	int			 id;
 	unsigned int		 what;
 
@@ -878,7 +931,14 @@ config_setauth(struct httpd *env, struct auth *auth)
 		DPRINTF("%s: sending auth \"%s[%u]\" to %s", __func__,
 		    auth->auth_htpasswd, auth->auth_id, ps->ps_title[id]);
 
-		proc_compose(ps, id, IMSG_CFG_AUTH, auth, sizeof(*auth));
+
+		/* memcpy to avoid modifying auth directly */
+		memcpy(&auth_payload, auth, sizeof(*auth)); 
+
+		/* clear pointers */
+		memset(&auth_payload.auth_entry, 0, sizeof(auth_payload.auth_entry)); 
+
+		proc_compose(ps, id, IMSG_CFG_AUTH, &auth_payload, sizeof(auth_payload));
 	}
 
 	return (0);
blob - 686f41c88d033c81bd8971bf6344ee84a6524e82
blob + ab78dd9d1d1e1cf0212ac7877e018d79dd9c8ab9
--- httpd.c
+++ httpd.c
@@ -1,4 +1,4 @@
-/*	$OpenBSD: httpd.c,v 1.74 2024/04/08 12:45:18 tobhe Exp $	*/
+/*	$OpenBSD: httpd.c,v 1.75 2025/11/12 11:24:04 deraadt Exp $	*/
 
 /*
  * Copyright (c) 2014 Reyk Floeter <reyk@openbsd.org>
@@ -278,6 +278,8 @@ parent_configure(struct httpd *env)
 	struct media_type	*media;
 	struct auth		*auth;
 
+	memset(&cf, 0, sizeof(cf));
+
 	RB_FOREACH(media, mediatypes, env->sc_mediatypes) {
 		if (config_setmedia(env, media) == -1)
 			fatal("send media");
blob - 302a4e63ed69fe989e4f6e0e3b326ed0f775d7a1
blob + d565e61d727d98a0d09ed2a19fd08e608aff3298
--- parse.y
+++ parse.y
@@ -1,4 +1,4 @@
-/*	$OpenBSD: parse.y,v 1.128 2022/02/27 20:30:30 bluhm Exp $	*/
+/*	$OpenBSD: parse.y,v 1.129 2025/11/12 11:24:04 deraadt Exp $	*/
 
 /*
  * Copyright (c) 2020 Matthias Pressfreund <mpfr@fn.de>
@@ -1896,6 +1896,7 @@ load_config(const char *filename, struct httpd *x_conf
 	struct media_type	 m;
 	int			 i;
 
+	memset(&m, 0, sizeof(m));
 	conf = x_conf;
 	conf->sc_flags = 0;