From nobody Fri Aug 14 14:35:59 2026 X-Original-To: dev-commits-src-main@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4hM4Xb70ptz6nwQT for ; Fri, 14 Aug 2026 14:35:59 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "YR1" (not verified)) by mx1.freebsd.org (Postfix) with ESMTPS id 4hM4Xb5Zwgz3gwc for ; Fri, 14 Aug 2026 14:35:59 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1786718159; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=pH0Df1hc8ezKBq4l2pa5eUK4rE2XhEFLlBJ3Qj3g+Ok=; b=L62kGs1MLvuRvq6r3nmY3YeJEe5zwsinbdeAKW9dN+KF5h2CvQ5rmofJsniwSTN7tH5433 e3tyabdYdUa9H/0ThP2h49Yr0vCN0hJJQBtb7aAEvRq5GgF+jhk2BegGix1pZx1TbKdX+6 us0NyvbKzjPnupCYwZyVFhW6pF6jRq/cFWvgkWIqiVE14x1hh7viwUjF1POvQyePbG//6E 2z/BPmmhbjZqQe28frE9rxWwnTxXCWvllbjlOow0CbYC3zbB3276kV+Ab2E0OgH5XX6hZj IsJIqyngsJuWihxAE11MBEVF7lsOBR0Kx1mbqutmAEFWPt0I7Kxhg+YNOCfLig== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1786718159; a=rsa-sha256; cv=none; b=TRQj2lP43VPOeB5iObj2hCVBKpKcRtGFiQLeJ99O1EnRM8jaeB3xQZfGn67SoV8E++j1oX 7jvnNTgUQxwmaOifuuhccqDAOQlQ+povuI3/jUbkDNFtmfQQ7UZzc++TLbegyaA53ovdKW CgxicOlxI6bZuTZvgJlpJmTYrX4R0SnjSecvn6HVeNJZi4WklpMgkD/YvdUFoHwf69DdWN 0xV4NYx1K36AuvSlUmw5Eb4HWNJva9KkC2gnmJtSPdLoojgvFT/uEpFG+leuqU2D/jM/ge 8DgOhkv+UnP6tUqdfqmiC8mepbE6xNRnfi+uWCRO/q7rLnv41JYccLtmZ+e30g== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1786718159; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=pH0Df1hc8ezKBq4l2pa5eUK4rE2XhEFLlBJ3Qj3g+Ok=; b=vCqtD6qgjz6QsIjMbrb5WmsDH3/TgOY0av873/Ct623ZiodKUEFaBKGzZ0JXGnoAtCEDD3 AMBFTG4xYnEid7E5LN94B3FL4K2FyEHSgNy7eFYfXafrB3zeWzHxRH8R7KGOV4r/FEpG4o XdZlfOt8GRtde0MGx7i5/sVRJ2Z1Qb/qRbFvRK7hxVuxg/Ac8bVXSaXfLzZKEF2xjbY4nV XXBu/tZs/dkH0PnXqCbSUhL8NzaRuzr4QKz6icc7j64lGAnaifL0ygqdu0+2ZFjbEDc8xN r5gVpPZNQ3abkGMmjeahVAmM6VLqzCWSeaT0V49LSFd7E6V8JDvObezHvbqXyQ== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) by mxrelay.nyi.freebsd.org (Postfix) with ESMTP id 4hM4Xb4bq3z11Zm for ; Fri, 14 Aug 2026 14:35:59 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from git (uid 1279) (envelope-from git@FreeBSD.org) id 3d2d7 by gitrepo.freebsd.org (DragonFly Mail Agent v0.13+ on gitrepo.freebsd.org); Fri, 14 Aug 2026 14:35:59 +0000 To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Konstantin Belousov Subject: git: cba481a7bff2 - main - PF_KEY socket: limit the length of copied socket address List-Id: Commit messages for the main branch of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-main List-Help: List-Post: List-Subscribe: List-Unsubscribe: X-BeenThere: dev-commits-src-main@freebsd.org Sender: owner-dev-commits-src-main@FreeBSD.org List-Id: List-Post: List-Help: List-Subscribe: List-Unsubscribe: List-Owner: Precedence: list MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: kib X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: cba481a7bff2fcf31420ee8b2714660e2666452b Auto-Submitted: auto-generated Date: Fri, 14 Aug 2026 14:35:59 +0000 Message-Id: <6a7f27cf.3d2d7.517d06e1@gitrepo.freebsd.org> The branch main has been updated by kib: URL: https://cgit.FreeBSD.org/src/commit/?id=cba481a7bff2fcf31420ee8b2714660e2666452b commit cba481a7bff2fcf31420ee8b2714660e2666452b Author: Konstantin Belousov AuthorDate: 2026-08-04 15:52:53 +0000 Commit: Konstantin Belousov CommitDate: 2026-08-14 14:35:38 +0000 PF_KEY socket: limit the length of copied socket address for SADB_UPDATE op SADB_X_EXT_NEW_ADDRESS_SRC/DST extensions, by checking the sa_len matching the address family requirements before doing the copy. Also convert KEY_SETSECASIDX() and KEY_SETSECSPIDX() to functions and apply the sa_len clamping there. See https://github.com/0xdeadbeefnetwork/pfkey-sadb-overflow PR: 297264 Tested by: Wafa Hamzah (previous version) Reviewed by: markj Sponsored by: The FreeBSD Foundation MFC after: 1 week Differential revision: https://reviews.freebsd.org/D58646 --- sys/netipsec/key.c | 128 +++++++++++++++++++++++++++++------------------------ 1 file changed, 69 insertions(+), 59 deletions(-) diff --git a/sys/netipsec/key.c b/sys/netipsec/key.c index 3cab8b4b6738..de1481ba4725 100644 --- a/sys/netipsec/key.c +++ b/sys/netipsec/key.c @@ -574,32 +574,42 @@ static int key_checksockaddrs(const struct sockaddr *src, * set parameters into secpolicyindex buffer. * Must allocate secpolicyindex buffer passed to this function. */ -#define KEY_SETSECSPIDX(_dir, s, d, ps, pd, ulp, idx) \ -do { \ - bzero((idx), sizeof(struct secpolicyindex)); \ - (idx)->dir = (_dir); \ - (idx)->prefs = (ps); \ - (idx)->prefd = (pd); \ - (idx)->ul_proto = (ulp); \ - bcopy((s), &(idx)->src, ((const struct sockaddr *)(s))->sa_len); \ - bcopy((d), &(idx)->dst, ((const struct sockaddr *)(d))->sa_len); \ -} while (0) +static void +key_setsecspidx(uint8_t dir, const void *s, const void *d, uint8_t prefs, + uint8_t prefd, uint8_t ul_proto, struct secpolicyindex *idx) +{ + MPASS(key_checksockaddrs((const struct sockaddr *)s, + (const struct sockaddr *)d) == 0); + + memset(idx, 0, sizeof(*idx)); + idx->dir = dir; + idx->prefs = prefs; + idx->prefd = prefd; + idx->ul_proto = ul_proto; + memcpy(&idx->src, s, ((const struct sockaddr *)s)->sa_len); + memcpy(&idx->dst, d, ((const struct sockaddr *)d)->sa_len); +} /* * set parameters into secasindex buffer. * Must allocate secasindex buffer before calling this function. */ -#define KEY_SETSECASIDX(p, m, r, s, d, idx) \ -do { \ - bzero((idx), sizeof(struct secasindex)); \ - (idx)->proto = (p); \ - (idx)->mode = (m); \ - (idx)->reqid = (r); \ - bcopy((s), &(idx)->src, ((const struct sockaddr *)(s))->sa_len); \ - bcopy((d), &(idx)->dst, ((const struct sockaddr *)(d))->sa_len); \ - key_porttosaddr(&(idx)->src.sa, 0); \ - key_porttosaddr(&(idx)->dst.sa, 0); \ -} while (0) +static void +key_setsecasidx(uint8_t proto, uint8_t mode, uint32_t reqid, + const void *s, const void *d, struct secasindex *idx) +{ + MPASS(key_checksockaddrs((const struct sockaddr *)s, + (const struct sockaddr *)d) == 0); + + memset(idx, 0, sizeof(*idx)); + idx->proto = proto; + idx->mode = mode; + idx->reqid = reqid; + memcpy(&idx->src, s, ((const struct sockaddr *)s)->sa_len); + memcpy(&idx->dst, d, ((const struct sockaddr *)d)->sa_len); + key_porttosaddr(&idx->src.sa, 0); + key_porttosaddr(&idx->dst.sa, 0); +} /* key statistics */ struct _keystat { @@ -1209,7 +1219,7 @@ key_allocsa_tunnel(union sockaddr_union *src, union sockaddr_union *dst, IPSEC_ASSERT(src != NULL, ("null src address")); IPSEC_ASSERT(dst != NULL, ("null dst address")); - KEY_SETSECASIDX(proto, IPSEC_MODE_TUNNEL, 0, &src->sa, + key_setsecasidx(proto, IPSEC_MODE_TUNNEL, 0, &src->sa, &dst->sa, &saidx); sav = NULL; @@ -2110,13 +2120,9 @@ key_spdadd(struct socket *so, struct mbuf *m, const struct sadb_msghdr *mhp) return key_senderror(so, m, error); } /* make secindex */ - KEY_SETSECSPIDX(xpl0->sadb_x_policy_dir, - src0 + 1, - dst0 + 1, - src0->sadb_address_prefixlen, - dst0->sadb_address_prefixlen, - src0->sadb_address_proto, - &spidx); + key_setsecspidx(xpl0->sadb_x_policy_dir, src0 + 1, dst0 + 1, + src0->sadb_address_prefixlen, dst0->sadb_address_prefixlen, + src0->sadb_address_proto, &spidx); /* Checking there is SP already or not. */ oldsp = key_getsp(&spidx); if (oldsp != NULL) { @@ -2351,13 +2357,9 @@ key_spddelete(struct socket *so, struct mbuf *m, return key_senderror(so, m, EINVAL); } /* make secindex */ - KEY_SETSECSPIDX(xpl0->sadb_x_policy_dir, - src0 + 1, - dst0 + 1, - src0->sadb_address_prefixlen, - dst0->sadb_address_prefixlen, - src0->sadb_address_proto, - &spidx); + key_setsecspidx(xpl0->sadb_x_policy_dir, src0 + 1, dst0 + 1, + src0->sadb_address_prefixlen, dst0->sadb_address_prefixlen, + src0->sadb_address_proto, &spidx); /* Is there SP in SPD ? */ if ((sp = key_getsp(&spidx)) == NULL) { @@ -5121,7 +5123,7 @@ key_getspi(struct socket *so, struct mbuf *m, const struct sadb_msghdr *mhp) error = EINVAL; goto fail; } - KEY_SETSECASIDX(proto, mode, reqid, src0 + 1, dst0 + 1, &saidx); + key_setsecasidx(proto, mode, reqid, src0 + 1, dst0 + 1, &saidx); /* SPI allocation */ SPI_ALLOC_LOCK(); @@ -5354,36 +5356,44 @@ key_updateaddresses(struct socket *so, struct mbuf *m, const struct sadb_msghdr *mhp, struct secasvar *sav, struct secasindex *saidx) { - struct sockaddr *newaddr; + struct sockaddr *dnewaddr, *snewaddr; struct secashead *sah; struct secasvar *newsav, *tmp; struct mbuf *n; int error, isnew; + bool newsaidx; + newsaidx = false; /* Check that we need to change SAH */ if (!SADB_CHECKHDR(mhp, SADB_X_EXT_NEW_ADDRESS_SRC)) { - newaddr = (struct sockaddr *)( - ((struct sadb_address *) + snewaddr = (struct sockaddr *)(((struct sadb_address *) mhp->ext[SADB_X_EXT_NEW_ADDRESS_SRC]) + 1); - bcopy(newaddr, &saidx->src, newaddr->sa_len); - key_porttosaddr(&saidx->src.sa, 0); + newsaidx = true; + } else { + snewaddr = &saidx->src.sa; } if (!SADB_CHECKHDR(mhp, SADB_X_EXT_NEW_ADDRESS_DST)) { - newaddr = (struct sockaddr *)( - ((struct sadb_address *) + dnewaddr = (struct sockaddr *)(((struct sadb_address *) mhp->ext[SADB_X_EXT_NEW_ADDRESS_DST]) + 1); - bcopy(newaddr, &saidx->dst, newaddr->sa_len); + newsaidx = true; + } else { + dnewaddr = &saidx->dst.sa; + } + error = key_checksockaddrs(snewaddr, dnewaddr); + if (error != 0) { + ipseclog((LOG_DEBUG, "%s: invalid new sockaddr.\n", + __func__)); + return (error); + } + if (!SADB_CHECKHDR(mhp, SADB_X_EXT_NEW_ADDRESS_SRC)) { + memcpy(&saidx->src, snewaddr, snewaddr->sa_len); + key_porttosaddr(&saidx->src.sa, 0); + } + if (!SADB_CHECKHDR(mhp, SADB_X_EXT_NEW_ADDRESS_DST)) { + memcpy(&saidx->dst, dnewaddr, dnewaddr->sa_len); key_porttosaddr(&saidx->dst.sa, 0); } - if (!SADB_CHECKHDR(mhp, SADB_X_EXT_NEW_ADDRESS_SRC) || - !SADB_CHECKHDR(mhp, SADB_X_EXT_NEW_ADDRESS_DST)) { - error = key_checksockaddrs(&saidx->src.sa, &saidx->dst.sa); - if (error != 0) { - ipseclog((LOG_DEBUG, "%s: invalid new sockaddr.\n", - __func__)); - return (error); - } - + if (newsaidx) { sah = key_getsah(saidx); if (sah == NULL) { /* create a new SA index */ @@ -5640,7 +5650,7 @@ key_update(struct socket *so, struct mbuf *m, const struct sadb_msghdr *mhp) ipseclog((LOG_DEBUG, "%s: invalid sockaddr.\n", __func__)); return key_senderror(so, m, error); } - KEY_SETSECASIDX(proto, mode, reqid, src0 + 1, dst0 + 1, &saidx); + key_setsecasidx(proto, mode, reqid, src0 + 1, dst0 + 1, &saidx); sav = key_getsavbyspi(sa0->sadb_sa_spi); if (sav == NULL) { ipseclog((LOG_DEBUG, "%s: no SA found for SPI %u\n", @@ -5873,7 +5883,7 @@ key_add(struct socket *so, struct mbuf *m, const struct sadb_msghdr *mhp) ipseclog((LOG_DEBUG, "%s: invalid sockaddr.\n", __func__)); return key_senderror(so, m, error); } - KEY_SETSECASIDX(proto, mode, reqid, src0 + 1, dst0 + 1, &saidx); + key_setsecasidx(proto, mode, reqid, src0 + 1, dst0 + 1, &saidx); spi = sa0->sadb_sa_spi; /* * For TCP-MD5 SAs we don't use SPI. Check the uniqueness using @@ -6328,7 +6338,7 @@ key_delete(struct socket *so, struct mbuf *m, const struct sadb_msghdr *mhp) ipseclog((LOG_DEBUG, "%s: invalid sockaddr.\n", __func__)); return (key_senderror(so, m, EINVAL)); } - KEY_SETSECASIDX(proto, IPSEC_MODE_ANY, 0, src0 + 1, dst0 + 1, &saidx); + key_setsecasidx(proto, IPSEC_MODE_ANY, 0, src0 + 1, dst0 + 1, &saidx); if (SADB_CHECKHDR(mhp, SADB_EXT_SA)) { /* * Caller wants us to delete all non-LARVAL SAs @@ -6559,7 +6569,7 @@ key_get(struct socket *so, struct mbuf *m, const struct sadb_msghdr *mhp) ipseclog((LOG_DEBUG, "%s: invalid sockaddr.\n", __func__)); return key_senderror(so, m, EINVAL); } - KEY_SETSECASIDX(proto, IPSEC_MODE_ANY, 0, src0 + 1, dst0 + 1, &saidx); + key_setsecasidx(proto, IPSEC_MODE_ANY, 0, src0 + 1, dst0 + 1, &saidx); SPI_ALLOC_LOCK(); if (proto == IPPROTO_TCP) @@ -7376,7 +7386,7 @@ key_acquire2(struct socket *so, struct mbuf *m, const struct sadb_msghdr *mhp) ipseclog((LOG_DEBUG, "%s: invalid sockaddr.\n", __func__)); return key_senderror(so, m, EINVAL); } - KEY_SETSECASIDX(proto, mode, reqid, src0 + 1, dst0 + 1, &saidx); + key_setsecasidx(proto, mode, reqid, src0 + 1, dst0 + 1, &saidx); /* get a SA index */ SAHTREE_RLOCK();