commit - 8dcab0e2df9c42f05eed6ffb1422d251ca15cb71
commit + afc41fe08300310c8fc6ef0007438e5a8b5907fe
blob - b4a8e734d614e15488d6d70d4f26c72cce07fb48
blob + cdb04f1eb0e6eb9a341ed47e3194baaca28fb0d0
--- config.c
+++ config.c
-/* $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>
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)
{
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);
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];
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);
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;
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
-/* $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>
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
-/* $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>
struct media_type m;
int i;
+ memset(&m, 0, sizeof(m));
conf = x_conf;
conf->sc_flags = 0;