git: f1a8ad76e1 - main - Add EN-26:11 and EN-26:12.
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Fri, 01 May 2026 15:28:13 UTC
The branch main has been updated by gordon:
URL: https://cgit.FreeBSD.org/doc/commit/?id=f1a8ad76e18d71c388af8dd9ee0a0310be1be0b1
commit f1a8ad76e18d71c388af8dd9ee0a0310be1be0b1
Author: Gordon Tetlow <gordon@FreeBSD.org>
AuthorDate: 2026-05-01 15:27:36 +0000
Commit: Gordon Tetlow <gordon@FreeBSD.org>
CommitDate: 2026-05-01 15:27:36 +0000
Add EN-26:11 and EN-26:12.
Approved by: so
---
website/data/security/errata.toml | 8 +
.../advisories/FreeBSD-EN-26:11.dhclient.asc | 156 +++++++
.../advisories/FreeBSD-EN-26:12.freebsd-update.asc | 177 ++++++++
.../security/patches/EN-26:11/dhclient.patch | 112 +++++
.../security/patches/EN-26:11/dhclient.patch.asc | 17 +
.../security/patches/EN-26:12/ensa-135.patch | 56 +++
.../security/patches/EN-26:12/ensa-135.patch.asc | 17 +
.../security/patches/EN-26:12/ensa-143.patch | 487 +++++++++++++++++++++
.../security/patches/EN-26:12/ensa-143.patch.asc | 17 +
.../security/patches/EN-26:12/ensa-144.patch | 487 +++++++++++++++++++++
.../security/patches/EN-26:12/ensa-144.patch.asc | 17 +
.../security/patches/EN-26:12/ensa-150.patch | 166 +++++++
.../security/patches/EN-26:12/ensa-150.patch.asc | 17 +
13 files changed, 1734 insertions(+)
diff --git a/website/data/security/errata.toml b/website/data/security/errata.toml
index 1614ad90a8..494f54d35d 100644
--- a/website/data/security/errata.toml
+++ b/website/data/security/errata.toml
@@ -1,6 +1,14 @@
# Sort errata notices by year, month and day
# $FreeBSD$
+[[notices]]
+name = "FreeBSD-EN-26:12.freebsd-update"
+date = "2026-05-01"
+
+[[notices]]
+name = "FreeBSD-EN-26:11.dhclient"
+date = "2026-05-01"
+
[[notices]]
name = "FreeBSD-EN-26:10.amd64"
date = "2026-04-29"
diff --git a/website/static/security/advisories/FreeBSD-EN-26:11.dhclient.asc b/website/static/security/advisories/FreeBSD-EN-26:11.dhclient.asc
new file mode 100644
index 0000000000..153379010a
--- /dev/null
+++ b/website/static/security/advisories/FreeBSD-EN-26:11.dhclient.asc
@@ -0,0 +1,156 @@
+-----BEGIN PGP SIGNED MESSAGE-----
+Hash: SHA512
+
+=============================================================================
+FreeBSD-EN-26:11.dhclient Errata Notice
+ The FreeBSD Project
+
+Topic: dhclient(8) lease validation is too strict
+
+Category: core
+Module: dhclient
+Announced: 2026-05-01
+Affects: All supported versions of FreeBSD.
+Corrected: 2026-04-30 21:07:00 UTC (stable/15, 15.0-STABLE)
+ 2026-05-01 15:08:46 UTC (releng/15.0, 15.0-RELEASE-p8)
+ 2026-04-30 21:07:11 UTC (stable/14, 14.4-STABLE)
+ 2026-05-01 15:08:37 UTC (releng/14.4, 14.4-RELEASE-p4)
+ 2026-05-01 15:08:30 UTC (releng/14.3, 14.3-RELEASE-p13)
+ 2026-04-30 21:07:24 UTC (stable/13, 13.5-STABLE)
+ 2026-05-01 15:08:19 UTC (releng/13.5, 13.5-RELEASE-p14)
+
+For general information regarding FreeBSD Errata Notices and Security
+Advisories, including descriptions of the fields above, security
+branches, and the following sections, please visit
+<URL:https://security.FreeBSD.org/>.
+
+Note: While FreeBSD 13.5 is end of life (EOL) as of May 1st, 2026, the
+Security Team has decided to patch this issue as it was identified and a fix
+was in-flight before the EOL date.
+
+I. Background
+
+dhclient(8) is the default IPv4 DHCP client used on FreeBSD. It is
+responsible for contacting DHCP servers on a network segment and for
+initialising and configuring network interfaces based on received
+information.
+
+When processing a DHCP offer, dhclient passes various parameters provided by
+the server to dhclient-script(8). DHCP options, as documented in
+dhcp-options(5), are passed via the environment.
+
+II. Problem Description
+
+The patch for FreeBSD-SA-26:15.dhclient introduced some validation of the
+boot file DHCP option to prevent unescaped values from being written to the
+stored lease file. This validation is overly strict and rejects Windows
+paths.
+
+III. Impact
+
+The overly strict validation may cause dhclient(8) to reject valid leases.
+
+IV. Workaround
+
+No workaround is available. Systems not running dhclient(8) are not
+affected.
+
+V. Solution
+
+Upgrade your system to a supported FreeBSD stable or release / security
+branch (releng) dated after the correction date.
+
+Perform one of the following:
+
+1) To update your system installed from base system packages:
+
+Systems running a 15.0-RELEASE version of FreeBSD on the amd64 or arm64
+platforms, which were installed using base system packages, can be updated
+via the pkg(8) utility:
+
+# pkg upgrade -r FreeBSD-base
+
+2) To update your system installed from binary distribution sets:
+
+Systems running a RELEASE version of FreeBSD on the amd64 or arm64 platforms,
+or the i386 platform on FreeBSD 13, which were not installed using base
+system packages, can be updated via the freebsd-update(8) utility:
+
+# freebsd-update fetch
+# freebsd-update install
+
+3) To update your system via a source code patch:
+
+The following patches have been verified to apply to the applicable
+FreeBSD release branches.
+
+a) Download the relevant patch from the location below, and verify the
+detached PGP signature using your PGP utility.
+
+# fetch https://security.FreeBSD.org/patches/EN-26:11/dhclient.patch
+# fetch https://security.FreeBSD.org/patches/EN-26:11/dhclient.patch.asc
+# gpg --verify dhclient.patch.asc
+
+b) Apply the patch. Execute the following commands as root:
+
+# cd /usr/src
+# patch < /path/to/patch
+
+c) Recompile the operating system using buildworld and installworld as
+described in <URL:https://www.FreeBSD.org/handbook/makeworld.html>.
+
+Restart the applicable daemons, or reboot the system.
+
+VI. Correction details
+
+This issue is corrected as of the corresponding Git commit hash in the
+following stable and release branches:
+
+Branch/path Hash Revision
+- -------------------------------------------------------------------------
+stable/15/ 252f603d1704 stable/15-n283453
+releng/15.0/ dc8762cfb6e2 releng/15.0-n281035
+stable/14/ 2f9478ad42c4 stable/14-n274094
+releng/14.4/ dfcb69cdb07e releng/14.4-n273699
+releng/14.3/ 5bad905eb37f releng/14.3-n271499
+stable/13/ b1ece85741db stable/13-n259871
+releng/13.5/ b362b6b6c8f2 releng/13.5-n259221
+- -------------------------------------------------------------------------
+
+Run the following command to see which files were modified by a
+particular commit:
+
+# git show --stat <commit hash>
+
+Or visit the following URL, replacing NNNNNN with the hash:
+
+<URL:https://cgit.freebsd.org/src/commit/?id=NNNNNN>
+
+To determine the commit count in a working tree (for comparison against
+nNNNNNN in the table above), run:
+
+# git rev-list --count --first-parent HEAD
+
+VII. References
+
+<URL:https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=294886>
+
+The latest revision of this advisory is available at
+<URL:https://security.FreeBSD.org/advisories/FreeBSD-EN-26:11.dhclient.asc>
+-----BEGIN PGP SIGNATURE-----
+
+iQJPBAEBCgA5FiEEthUnfoEIffdcgYM7bljekB8AGu8FAmn0xiAbFIAAAAAABAAO
+bWFudTIsMi41KzEuMTIsMCwzAAoJEG5Y3pAfABrvJnEQAJ8ZYWjGt7iYjMkOZiM1
+I7NLl7RygvIWU25ThAOXlA7zPA7LbS23+nca4QlNdvTVkpcfsCrmxhJYY4ymkZh7
+QuEVDEp20n02S7362S9kCpmp3NDXQvuCPNt8zRel4ek3u/b8/9KCASL1jN+1eSgR
+G8ZVWVheRzKgsaYJsDIyX0AjNk41gQk8ASYoWjeIk5F14kFk3ozlfJTrBL2XlOuL
+J28P47d5lEgU2x04xLSZF9xQrF1I13XZa8pMtogF3aveTXXVzHDJFZIcppu0uQYY
+tp9uvyQ6NnzNPBXWztVCJ+eRdxS4RLp3Dp3U9/3GrqVuCfG8BO7kE5OhcjO0EPVC
+lmvXBJLqQnsodEQA0BysAsMxlMcw+n6z0np2DFdFCkyLrPCx3Bm+D/WRLngRcp4s
++FBIgoF+ywUXVwLRkVJeCsQJTNzVhneq8rtcfE6LdJoIgW/oOUyNEJTBpgvhXmz6
+/pmW47cmNY+CFWCXAL/7fLZVX1dYvEpSn+Iqqs8Efr2OFfQqRXZunJXNXnKuMtfT
+p82Hl////cHObQSqlI95J5yJmdBzOxlpzHTwSLVTD5SfvAcN3PzN3hRhFFqG8lg5
+HV64Fu1xPqLX1mthTw1Sbng5mTUL+MJ5BN26M+UevYZBi02m5nMUyjWH+D4Bn3RS
+gajZ9Z16VPgdlPsNPihqsx7k
+=Ro3y
+-----END PGP SIGNATURE-----
diff --git a/website/static/security/advisories/FreeBSD-EN-26:12.freebsd-update.asc b/website/static/security/advisories/FreeBSD-EN-26:12.freebsd-update.asc
new file mode 100644
index 0000000000..53fc1f3c48
--- /dev/null
+++ b/website/static/security/advisories/FreeBSD-EN-26:12.freebsd-update.asc
@@ -0,0 +1,177 @@
+-----BEGIN PGP SIGNED MESSAGE-----
+Hash: SHA512
+
+=============================================================================
+FreeBSD-EN-26:12.freebsd-update Errata Notice
+ The FreeBSD Project
+
+Topic: Source inconsistency between freebsd-update, EN/SAs, and git
+
+Category: core
+Module: freebsd-update
+Announced: 2026-05-01
+Affects: All supported versions of FreeBSD.
+Corrected: 2026-05-01 15:08:47 UTC (releng/15.0, 15.0-RELEASE-p8)
+ 2026-05-01 15:08:38 UTC (releng/14.4, 14.4-RELEASE-p4)
+ 2026-05-01 15:08:31 UTC (releng/14.3, 14.3-RELEASE-p13)
+ 2026-05-01 15:08:20 UTC (releng/13.5, 13.5-RELEASE-p14)
+
+For general information regarding FreeBSD Errata Notices and Security
+Advisories, including descriptions of the fields above, security
+branches, and the following sections, please visit
+<URL:https://security.FreeBSD.org/>.
+
+Note: While FreeBSD 13.5 is end of life (EOL) as of May 1st, 2026, the
+Security Team has decided to patch this issue as it was identified and a fix
+was in-flight before the EOL date.
+
+I. Background
+
+The FreeBSD Security Team distributes patches for supported releases via the
+git version control system, as patches link through errata and advisories,
+and through the freebsd-update binary update system.
+
+Both freebsd-update and the errata/advisories do not directly use the
+authoritative git repo but instead rely on individual patch files.
+
+II. Problem Description
+
+Due to the manual nature of patch file development and management, there are
+instances where either a freebsd-update maintained machine or a patched
+source tree from errata/advisories have become out of sync with the
+authoritative git repository.
+
+Specifically, an earlier version of the patch associated with SA-26:11.amd64
+was distributed via freebsd-update. The source patch linked in the advisory
+did match the source in git.
+
+Additionally, patches distributed via freebsd-update and errata/advisories
+are occasionally missing test or non-material ancillary files to minimize
+patch size and improve compatibility across releases, causing an additional
+source of drift from the authoritative git respository.
+
+Pkgbase is unaffected as it directly builds from the authoritative git
+repository.
+
+III. Impact
+
+As a result of this drift, the FreeBSD Security Team has changed the
+freebsd-update build mechanism to retrieve source directly from the
+authoritative git respository. This has caused a binary update to rectify the
+SA-26:11.amd64 issue as well as alter a few additional files that have been
+updated in git but were not distributed via freebsd-update.
+
+IV. Workaround
+
+No workaround is available. Systems using pkgbase or building directly from
+source obtained from the authoritative git repository are unaffected.
+
+V. Solution
+
+Upgrade your system to a supported FreeBSD stable or release / security
+branch (releng) dated after the correction date and reboot the system.
+
+Perform one of the following:
+
+1) If your system is installed from base system packages:
+
+No update is needed as pkgbase is not affected by this issue.
+
+2) To update your system installed from binary distribution sets:
+
+Systems running a RELEASE version of FreeBSD on the amd64 or arm64 platforms,
+or the i386 platform on FreeBSD 13, which were not installed using base
+system packages, can be updated via the freebsd-update(8) utility:
+
+# freebsd-update fetch
+# freebsd-update install
+# shutdown -r +10min "Rebooting for a system update"
+
+3) To update your system via a source code patch:
+
+The following patches are only intended to be used for source trees have been
+maintained with patches linked by previous EN/SAs.
+
+a) Download the relevant patch from the location below, and verify the
+detached PGP signature using your PGP utility.
+
+[FreeBSD 15.0]
+# fetch https://security.FreeBSD.org/patches/EN-26:12/ensa-150.patch
+# fetch https://security.FreeBSD.org/patches/EN-26:12/ensa-150.patch.asc
+# gpg --verify ensa-150.patch.asc
+
+[FreeBSD 14.4]
+# fetch https://security.FreeBSD.org/patches/EN-26:12/ensa-144.patch
+# fetch https://security.FreeBSD.org/patches/EN-26:12/ensa-144.patch.asc
+# gpg --verify ensa-144.patch.asc
+
+[FreeBSD 14.3]
+# fetch https://security.FreeBSD.org/patches/EN-26:12/ensa-143.patch
+# fetch https://security.FreeBSD.org/patches/EN-26:12/ensa-143.patch.asc
+# gpg --verify ensa-143.patch.asc
+
+[FreeBSD 13.5]
+# fetch https://security.FreeBSD.org/patches/EN-26:12/ensa-135.patch
+# fetch https://security.FreeBSD.org/patches/EN-26:12/ensa-135.patch.asc
+# gpg --verify ensa-135.patch.asc
+
+b) Apply the patch. Execute the following commands as root:
+
+# cd /usr/src
+# patch < /path/to/patch
+
+c) Recompile the operating system using buildworld and installworld as
+described in <URL:https://www.FreeBSD.org/handbook/makeworld.html>.
+
+Reboot the system.
+
+VI. Correction details
+
+This issue is corrected as of the corresponding Git commit hash in the
+following stable and release branches:
+
+Branch/path Hash Revision
+- -------------------------------------------------------------------------
+releng/15.0/ 53054229dcb3 releng/15.0-n281036
+releng/14.4/ 49be56ed6fea releng/14.4-n273700
+releng/14.3/ 4f4b48e8a547 releng/14.3-n271500
+releng/13.5/ 2e6399fe39b3 releng/13.5-n259222
+- -------------------------------------------------------------------------
+
+Run the following command to see which files were modified by a
+particular commit:
+
+# git show --stat <commit hash>
+
+Or visit the following URL, replacing NNNNNN with the hash:
+
+<URL:https://cgit.freebsd.org/src/commit/?id=NNNNNN>
+
+To determine the commit count in a working tree (for comparison against
+nNNNNNN in the table above), run:
+
+# git rev-list --count --first-parent HEAD
+
+VII. References
+
+<URL:https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=270166>
+
+The latest revision of this advisory is available at
+<URL:https://security.FreeBSD.org/advisories/FreeBSD-EN-26:12.freebsd-update.asc>
+-----BEGIN PGP SIGNATURE-----
+
+iQJPBAEBCgA5FiEEthUnfoEIffdcgYM7bljekB8AGu8FAmn0xicbFIAAAAAABAAO
+bWFudTIsMi41KzEuMTIsMCwzAAoJEG5Y3pAfABrv//EP/jc0GG1wu9K9TdzGWn4m
+F74a1Gstl13HdTilFhNbF+iQtcuEui4QyBNgy2O7XG1kRsbCYQDN32BzbZl+VhmY
+kBzUO+jRANPQ3J8cReMeyE2sg2jTAqtioKrbMtXqCNB7peC2AekWLSXrWQA99+qO
+qQ/rWW6zCnYWhsiX4fPfVbxw8PS4jdBriOxeBU7gBAQ8lQmdHW5A1hnW2ZzKWWDF
+8m6MuyI4yiA+eDGzkHHn8WetWOgZrbbpFa5H7upYmpSX8jcIlivHqW0j+RMpWG9Z
+UPIcD26dmbw423BNXXxy9SSUWF6fwlNaWzAaPxT9rpVE2kgeP8QbEhPRvTxQ95CJ
+PwVASKSfJ5tMSzZpxl5Vp3U5OyanvpBoFVIj/2tlsAcRm9ywXiqS4HLS1CY67uwb
+G7NkMO8oteO0ZPgXS5sLLGnMlfl/tkhG440tH8UKtWMRXzrXP6sLBwuk3v7RQxN0
+XZHPM4sBA7b8aIi0VKcNR5yby1xDFnI+fdRUT9ILmG8OCijmowFE0fknY78kzmr7
+HF1CRelNU3Wy5hlt6Q5MAY87E5Piw2TU0QY7AZU6eZeb0qLIFsUwVawDATvsqias
+C3RJ9OWSwJTCaUNjwCvwX+1miwfjqLCE30ze0qzZ6NcF67qQBc1pIMUg0HCWkS3E
+rhVyscH7IOUNqCLG9uBCXKL5
+=TZ6g
+-----END PGP SIGNATURE-----
diff --git a/website/static/security/patches/EN-26:11/dhclient.patch b/website/static/security/patches/EN-26:11/dhclient.patch
new file mode 100644
index 0000000000..c4f4a88d9a
--- /dev/null
+++ b/website/static/security/patches/EN-26:11/dhclient.patch
@@ -0,0 +1,112 @@
+--- sbin/dhclient/dhclient.c.orig
++++ sbin/dhclient/dhclient.c
+@@ -1161,7 +1161,7 @@
+ lease = malloc(sizeof(struct client_lease));
+
+ if (!lease) {
+- warning("dhcpoffer: no memory to record lease.");
++ warning("dhcpoffer: no memory to record lease");
+ return (NULL);
+ }
+
+@@ -1211,7 +1211,7 @@
+
+ /* If the server name was filled out, copy it.
+ Do not attempt to validate the server name as a host name.
+- RFC 2131 merely states that sname is NUL-terminated (which do
++ RFC 2131 merely states that sname is NUL-terminated (which we
+ do not assume) and that it is the server's host name. Since
+ the ISC client and server allow arbitrary characters, we do
+ as well. */
+@@ -1219,39 +1219,72 @@
+ !(packet->options[DHO_DHCP_OPTION_OVERLOAD].data[0] & 2)) &&
+ packet->raw->sname[0]) {
+ lease->server_name = malloc(DHCP_SNAME_LEN + 1);
+- if (!lease->server_name) {
+- warning("dhcpoffer: no memory for server name.");
++ if (lease->server_name == NULL) {
++ warning("dhcpoffer: no memory for server name");
+ free_client_lease(lease);
+ return (NULL);
+ }
+- memcpy(lease->server_name, packet->raw->sname, DHCP_SNAME_LEN);
+- lease->server_name[DHCP_SNAME_LEN]='\0';
+- if (strchr(lease->server_name, '"') != NULL ||
+- strchr(lease->server_name, '\\') != NULL) {
+- warning("dhcpoffer: server name contains invalid characters.");
+- free_client_lease(lease);
+- return (NULL);
++ for (i = 0; i < DHCP_SNAME_LEN; i++) {
++ if (packet->raw->sname[i] == '\0') {
++ break;
++ }
++ if (packet->raw->sname[i] < ' ' ||
++ packet->raw->sname[i] == '"' ||
++ packet->raw->sname[i] == '\\') {
++ warning("dhcpoffer: server name contains "
++ "unsafe characters");
++ free(lease->server_name);
++ lease->server_name = NULL;
++ break;
++ }
++ lease->server_name[i] = packet->raw->sname[i];
++ }
++ /* Terminate and zero-pad */
++ if (lease->server_name != NULL) {
++ while (i < DHCP_SNAME_LEN + 1) {
++ lease->server_name[i++] = '\0';
++ }
+ }
+ }
+
+- /* Ditto for the filename. */
++ /* Ditto for the file name. */
+ if ((!packet->options[DHO_DHCP_OPTION_OVERLOAD].len ||
+ !(packet->options[DHO_DHCP_OPTION_OVERLOAD].data[0] & 1)) &&
+ packet->raw->file[0]) {
+ /* Don't count on the NUL terminator. */
+ lease->filename = malloc(DHCP_FILE_LEN + 1);
+- if (!lease->filename) {
+- warning("dhcpoffer: no memory for filename.");
++ if (lease->filename == NULL) {
++ warning("dhcpoffer: no memory for file name");
+ free_client_lease(lease);
+ return (NULL);
+ }
+- memcpy(lease->filename, packet->raw->file, DHCP_FILE_LEN);
+- lease->filename[DHCP_FILE_LEN]='\0';
+- if (strchr(lease->filename, '"') != NULL ||
+- strchr(lease->filename, '\\') != NULL) {
+- warning("dhcpoffer: filename contains invalid characters.");
+- free_client_lease(lease);
+- return (NULL);
++ for (i = 0; i < DHCP_FILE_LEN; i++) {
++ if (packet->raw->file[i] == '\0') {
++ break;
++ }
++ if (packet->raw->file[i] < ' ' ||
++ packet->raw->file[i] == '"') {
++ warning("dhcpoffer: file name contains "
++ "unsafe characters");
++ free(lease->filename);
++ lease->filename = NULL;
++ break;
++ }
++ if (packet->raw->file[i] == '\\') {
++ /*
++ * This is common in Windows-centric
++ * environments. Instead of rejecting,
++ * silently convert to forward slash.
++ */
++ packet->raw->file[i] = '/';
++ }
++ lease->filename[i] = packet->raw->file[i];
++ }
++ /* Terminate and zero-pad */
++ if (lease->filename != NULL) {
++ while (i < DHCP_FILE_LEN + 1) {
++ lease->filename[i++] = '\0';
++ }
+ }
+ }
+ return lease;
diff --git a/website/static/security/patches/EN-26:11/dhclient.patch.asc b/website/static/security/patches/EN-26:11/dhclient.patch.asc
new file mode 100644
index 0000000000..e663d9bde6
--- /dev/null
+++ b/website/static/security/patches/EN-26:11/dhclient.patch.asc
@@ -0,0 +1,17 @@
+-----BEGIN PGP SIGNATURE-----
+
+iQJPBAABCgA5FiEEthUnfoEIffdcgYM7bljekB8AGu8FAmn0xiUbFIAAAAAABAAO
+bWFudTIsMi41KzEuMTIsMCwzAAoJEG5Y3pAfABrvP3IP/jxonX89dJSBsH0i12F0
+dVgVOeCYMf9dhEnd9Oyw/KY6p8OMWkNHg2D3rRR0wDzEf8k7RAVNoD87uKzOHfQk
+IeKE6n5LubG3WdLbEnWSMScHjvJ7+8+vDbU2brkXdWaBQxqdZRJ/QReRvLvLHR/8
+2xomS4l3uS1He+xxCPXk5G116zaDfEZWnYL1rHEbBI81Nxnktb/mSNwHLxf41E3A
+QdGOaPKCbuKKkq98Bo5zaTu9B/68iXq9yDGnPHJoUhZnpCSXA/21PNkUP+G4N1VG
+6bzCgl7e0tWL048nBv7V8A0cyZ8K0rCSjurlPNF82QxGGUD/Z6qKaclpwuQO/X50
+t3gzh0nJ1g6/F/FmywVjZEDAUIIpgHkyMGlWdzqlzLZ1jymSRXnZGGJVGU1tpcPF
+AZC/avfvGAZNrSXVaM5IoduzW7xLzlF4XyJt3aT2GbmegnVmfWD2hgIVzktq/bWj
+5UfalA/T/+2dusWLtbnUVQrZLppQBe5XfH1uNUONwguV4YDQ0ndP9hGUV5UM40Os
+RvrMnHGPjszURPWKN01V5GQRoMZkur/vIglOkFPLcKfr6rYRP4yxpJN70E1xV/pK
+AIjKUxIflDtAUdcgL0uaJHGJX6O8R4eXrl2RjdPv8EGDJcz/Y+zULSDbujCbcLys
+BT3xt7JyKXIB92PonZo28Xn5
+=2BEv
+-----END PGP SIGNATURE-----
diff --git a/website/static/security/patches/EN-26:12/ensa-135.patch b/website/static/security/patches/EN-26:12/ensa-135.patch
new file mode 100644
index 0000000000..e01596907a
--- /dev/null
+++ b/website/static/security/patches/EN-26:12/ensa-135.patch
@@ -0,0 +1,56 @@
+--- tests/sys/netpfil/pf/sctp.py.orig
++++ tests/sys/netpfil/pf/sctp.py
+@@ -448,53 +448,6 @@
+
+ @pytest.mark.require_user("root")
+ @pytest.mark.require_progs(["scapy"])
+- def test_initiate_tag_check(self):
+- # Ensure we don't send ABORTs in response to the other end's INIT_ACK
+- # That'd interfere with our test.
+- ToolsHelper.print_output("/sbin/sysctl net.inet.sctp.blackhole=2")
+-
+- import scapy.all as sp
+-
+- packet = sp.IP(src="192.0.2.1", dst="192.0.2.2") \
+- / sp.SCTP(sport=1234, dport=1234) \
+- / sp.SCTPChunkInit(init_tag=1, n_in_streams=1, n_out_streams=1, a_rwnd=1500)
+- packet.show()
+-
+- r = sp.sr1(packet, timeout=3)
+- assert r
+- r.show()
+- assert r.getlayer(sp.SCTP)
+- assert r.getlayer(sp.SCTPChunkInitAck)
+- assert r.getlayer(sp.SCTP).tag == 1
+-
+- # Send another INIT with the same initiate tag, expect another init ack
+- packet = sp.IP(src="192.0.2.1", dst="192.0.2.2") \
+- / sp.SCTP(sport=1234, dport=1234) \
+- / sp.SCTPChunkInit(init_tag=1, n_in_streams=1, n_out_streams=1, a_rwnd=1500)
+- packet.show()
+-
+- r = sp.sr1(packet, timeout=3)
+- assert r
+- r.show()
+- assert r.getlayer(sp.SCTP)
+- assert r.getlayer(sp.SCTPChunkInitAck)
+- assert r.getlayer(sp.SCTP).tag == 1
+-
+- # Send an INIT with a different initiate tag, expect another init ack
+- packet = sp.IP(src="192.0.2.1", dst="192.0.2.2") \
+- / sp.SCTP(sport=1234, dport=1234) \
+- / sp.SCTPChunkInit(init_tag=42, n_in_streams=1, n_out_streams=1, a_rwnd=1500)
+- packet.show()
+-
+- r = sp.sr1(packet, timeout=3)
+- assert r
+- r.show()
+- assert r.getlayer(sp.SCTP)
+- assert r.getlayer(sp.SCTPChunkInitAck)
+- assert r.getlayer(sp.SCTP).tag == 42
+-
+- @pytest.mark.require_user("root")
+- @pytest.mark.require_progs(["scapy"])
+ def test_too_many_add_ip(self):
+ import scapy.all as sp
+ DEPTH=90
diff --git a/website/static/security/patches/EN-26:12/ensa-135.patch.asc b/website/static/security/patches/EN-26:12/ensa-135.patch.asc
new file mode 100644
index 0000000000..b9015d82dd
--- /dev/null
+++ b/website/static/security/patches/EN-26:12/ensa-135.patch.asc
@@ -0,0 +1,17 @@
+-----BEGIN PGP SIGNATURE-----
+
+iQJPBAABCgA5FiEEthUnfoEIffdcgYM7bljekB8AGu8FAmn0xigbFIAAAAAABAAO
+bWFudTIsMi41KzEuMTIsMCwzAAoJEG5Y3pAfABrvKRoQAOoQG727h+K+Ggup1bPR
+abGWXO72V+ouikfjx34bFYoZkti0/beAnH0/C8KhFCql23kdWVAk576nLz6a1TYe
+6XAkw+MbsL/TN07xexstUfZzBlO6oZGvOed1fkGsK7FNdN47NvTn5bAaSDOIwyvr
+c35FsjD2+ojqc+KdlyaNMidSlS58SbKtcZ1OrcJD3VMB3FJZ6D+ko0adCoXgyfPN
+noaWId+aANmFTksykWsDAgMKEdlyE8d+/dAec9m9qDY6Yza1IgU3bi2jh91lAx/y
+/n3QRfvdllFh1gJ+YTe0B1SpIimqjBnvGjUNNcDrpgbVrc5Yp9fPiPKSnxSit6eP
+dcLNNs3o4yLBScG9R5raZ184H64Uv1boD69I1MFEGWi2qkGxlc0hREj5G5v2NOny
+oGIOzA0yXEb9aXAAH1fP+WV9eADYheCQy3OJqZeJAEOda5actOKFfdoAOpNMNFAm
+2gUlOZO2hrR6RNJiAAJO0vzusuo66Wx97FPJUez/SoQSHriNY/e+yOnnGWe1Fjp+
+2EYa/cUcfHTs5nGy+cUXCjYKL0AL7HD7kiEiOoTG2TT438RtcMNLDH29gjPsnY6F
+nRBF7Sm994wwCKlWW1cmgxyZczpBVByHI8/mAT3i7wEyZsuBij0fkyIJZlHAxJQb
+XPcrcVNqkzLQzucFwGQ1jczC
+=Mn9N
+-----END PGP SIGNATURE-----
diff --git a/website/static/security/patches/EN-26:12/ensa-143.patch b/website/static/security/patches/EN-26:12/ensa-143.patch
new file mode 100644
index 0000000000..8b87835c4a
--- /dev/null
+++ b/website/static/security/patches/EN-26:12/ensa-143.patch
@@ -0,0 +1,487 @@
+--- lib/libnv/tests/Makefile.orig
++++ lib/libnv/tests/Makefile
+@@ -1,6 +1,15 @@
++.include <src.opts.mk>
+
+ ATF_TESTS_C= \
+ nvlist_send_recv_test
++
++.PATH: ${SRCTOP}/lib/libnv
++SRCS.nvlist_send_recv_test= msgio.c nvlist_send_recv_test.c
++CFLAGS.nvlist_send_recv_test+=-I${SRCTOP}/sys/contrib/libnv
++CFLAGS.nvlist_send_recv_test+=-I${SRCTOP}/lib/libnv
++.if ${MK_ASAN} != "yes"
++CFLAGS.nvlist_send_recv_test+=-DNO_ASAN
++.endif
+
+ ATF_TESTS_CXX= \
+ cnv_tests \
+--- lib/libnv/tests/nv_array_tests.cc.orig
++++ lib/libnv/tests/nv_array_tests.cc
+@@ -1,6 +1,5 @@
+ /*-
+- * Copyright (c) 2015 Mariusz Zaborski <oshogbo@FreeBSD.org>
+- * All rights reserved.
++ * Copyright (c) 2015-2024 Mariusz Zaborski <oshogbo@FreeBSD.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+@@ -28,6 +27,7 @@
+ #include <sys/param.h>
+ #include <sys/types.h>
+ #include <sys/nv.h>
++#include <sys/mman.h>
+ #include <sys/socket.h>
+
+ #include <atf-c++.hpp>
+@@ -1162,6 +1162,58 @@
+ free(packed);
+ }
+
++
++ATF_TEST_CASE_WITHOUT_HEAD(nvlist_string_array_nonull__pack);
++ATF_TEST_CASE_BODY(nvlist_string_array_nonull__pack)
++{
++ nvlist_t *testnvl, *unpacked;
++ const char *somestr[3] = { "a", "b", "XXX" };
++ uint8_t *packed, *twopages, *dataptr, *secondpage;
++ size_t packed_size, page_size;
++ bool found;
++
++ page_size = sysconf(_SC_PAGESIZE);
++ testnvl = nvlist_create(0);
++ ATF_REQUIRE(testnvl != NULL);
++ ATF_REQUIRE_EQ(nvlist_error(testnvl), 0);
++ nvlist_add_string_array(testnvl, "nvl/string", somestr,
++ nitems(somestr));
++ ATF_REQUIRE_EQ(nvlist_error(testnvl), 0);
++
++ packed = (uint8_t *)nvlist_pack(testnvl, &packed_size);
++ ATF_REQUIRE(packed != NULL);
++
++ twopages = (uint8_t *)mmap(NULL, page_size * 2, PROT_READ | PROT_WRITE,
++ MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
++ ATF_REQUIRE(twopages != MAP_FAILED);
++ dataptr = &twopages[page_size - packed_size];
++ secondpage = &twopages[page_size];
++
++ memset(twopages, 'A', page_size * 2);
++
++ mprotect(secondpage, page_size, PROT_NONE);
++ memcpy(dataptr, packed, packed_size);
++
++ found = false;
++ for (size_t i = 0; i < packed_size - 3; i++) {
++ if (dataptr[i] == 'X' && dataptr[i + 1] == 'X' &&
++ dataptr[i + 2] == 'X' && dataptr[i + 3] == '\0') {
++ dataptr[i + 3] = 'X';
++ found = true;
++ break;
++ }
++ }
++ ATF_REQUIRE(found == true);
++
++ unpacked = nvlist_unpack(dataptr, packed_size, 0);
++ ATF_REQUIRE(unpacked == NULL);
++
++ nvlist_destroy(testnvl);
++ free(packed);
++ munmap(twopages, page_size * 2);
++}
++
++
+ ATF_INIT_TEST_CASES(tp)
+ {
+
+@@ -1191,5 +1243,7 @@
+ ATF_ADD_TEST_CASE(tp, nvlist_descriptor_array__pack)
+ ATF_ADD_TEST_CASE(tp, nvlist_string_array__pack)
+ ATF_ADD_TEST_CASE(tp, nvlist_nvlist_array__pack)
++
++ ATF_ADD_TEST_CASE(tp, nvlist_string_array_nonull__pack)
+ }
+
+--- lib/libnv/tests/nvlist_send_recv_test.c.orig
++++ lib/libnv/tests/nvlist_send_recv_test.c
+@@ -1,5 +1,8 @@
+ /*-
++ * SPDX-License-Identifier: BSD-2-Clause
++ *
+ * Copyright (c) 2013 The FreeBSD Foundation
++ * Copyright (c) 2024-2026 Mariusz Zaborski <oshogbo@FreeBSD.org>
+ *
+ * This software was developed by Pawel Jakub Dawidek under sponsorship from
+ * the FreeBSD Foundation.
+@@ -28,6 +31,8 @@
+
+ #include <sys/cdefs.h>
+ #include <sys/param.h>
++#include <sys/resource.h>
++#include <sys/select.h>
+ #include <sys/socket.h>
+ #include <sys/sysctl.h>
+ #include <sys/wait.h>
+@@ -44,6 +49,9 @@
+
+ #include <atf-c.h>
+
++#include <nv_impl.h>
++#include <msgio.h>
++
+ #define ALPHABET "abcdefghijklmnopqrstuvwxyz"
+ #define fd_is_valid(fd) (fcntl((fd), F_GETFL) != -1 || errno != EBADF)
+
+@@ -531,6 +539,59 @@
+ nvlist_send_recv__send_nvlist(SOCK_STREAM);
+ }
+
++/*
++ * Regression test for fd_wait(): the previous select(2)-based implementation
++ * called FD_SET() unconditionally, which is an out-of-bounds stack write when
++ * the socket fd is >= FD_SETSIZE. Force the socketpair fds above FD_SETSIZE
++ * and verify a full nvlist round-trip still works.
++ */
++ATF_TC_WITHOUT_HEAD(nvlist_send_recv__highfd);
++ATF_TC_BODY(nvlist_send_recv__highfd, tc)
++{
++ struct rlimit rl;
++ nvlist_t *nvl;
++ int socks[2], hi_send, hi_recv, status;
++ pid_t pid;
++
++ hi_send = FD_SETSIZE + 5;
++ hi_recv = FD_SETSIZE + 6;
++
++ rl.rlim_cur = rl.rlim_max = hi_recv + 1;
++ if (setrlimit(RLIMIT_NOFILE, &rl) != 0)
++ atf_tc_skip("cannot raise RLIMIT_NOFILE: %s", strerror(errno));
++
++ ATF_REQUIRE(socketpair(PF_UNIX, SOCK_STREAM, 0, socks) == 0);
++ ATF_REQUIRE(dup2(socks[0], hi_recv) == hi_recv);
++ ATF_REQUIRE(dup2(socks[1], hi_send) == hi_send);
++ (void)close(socks[0]);
++ (void)close(socks[1]);
++
++ pid = fork();
++ ATF_REQUIRE(pid >= 0);
++ if (pid == 0) {
++ /* Child: send. */
++ (void)close(hi_recv);
++ nvl = nvlist_create(0);
++ nvlist_add_string(nvl, "key", "value");
++ if (nvlist_send(hi_send, nvl) != 0)
++ err(EXIT_FAILURE, "nvlist_send");
++ nvlist_destroy(nvl);
++ _exit(0);
++ }
++
++ (void)close(hi_send);
++ nvl = nvlist_recv(hi_recv, 0);
++ ATF_REQUIRE(nvl != NULL);
++ ATF_REQUIRE(nvlist_error(nvl) == 0);
++ ATF_REQUIRE(nvlist_exists_string(nvl, "key"));
++ ATF_REQUIRE(strcmp(nvlist_get_string(nvl, "key"), "value") == 0);
++ nvlist_destroy(nvl);
++
++ ATF_REQUIRE(waitpid(pid, &status, 0) == pid);
++ ATF_REQUIRE(status == 0);
++ (void)close(hi_recv);
++}
++
+ ATF_TC_WITHOUT_HEAD(nvlist_send_recv__send_closed_fd__dgram);
+ ATF_TC_BODY(nvlist_send_recv__send_closed_fd__dgram, tc)
+ {
+@@ -543,15 +604,260 @@
+ nvlist_send_recv__send_closed_fd(SOCK_STREAM);
+ }
+
++ATF_TC_WITHOUT_HEAD(nvlist_send_recv__overflow_header_size);
++ATF_TC_BODY(nvlist_send_recv__overflow_header_size, tc)
++{
++ nvlist_t *nvl;
++ void *packed;
++ size_t packed_size;
++ struct nvlist_header *header;
++ int fd, socks[2], status;
++ pid_t pid;
++
++#ifdef NO_ASAN
++ atf_tc_skip("This test requires ASAN");
++#endif
++
++ ATF_REQUIRE_EQ(socketpair(PF_UNIX, SOCK_STREAM, 0, socks), 0);
++
++ pid = fork();
++ ATF_REQUIRE(pid >= 0);
++
++ if (pid == 0) {
++ /* Child. */
++ fd = socks[0];
++ close(socks[1]);
++
++ nvl = nvlist_create(0);
++ ATF_REQUIRE(nvl != NULL);
++ ATF_REQUIRE(nvlist_empty(nvl));
++
++ packed = nvlist_pack(nvl, &packed_size);
++ ATF_REQUIRE(packed != NULL);
++ ATF_REQUIRE(packed_size >= sizeof(struct nvlist_header));
++
++ header = (struct nvlist_header *)packed;
++ header->nvlh_size = SIZE_MAX - sizeof(struct nvlist_header) + 2;
++
++ ATF_REQUIRE_EQ(write(fd, packed, packed_size),
++ (ssize_t)sizeof(struct nvlist_header));
++
++ nvlist_destroy(nvl);
++ free(packed);
++
++ exit(0);
++ } else {
++ /* Parent */
++ fd = socks[1];
++ close(socks[0]);
++
++ errno = 0;
++ nvl = nvlist_recv(fd, 0);
++ ATF_REQUIRE(nvl == NULL);
++
++ /*
++ * Make sure it has failed on EINVAL, and not on
++ * errors returned by malloc or recv.
++ */
++ ATF_REQUIRE(errno == EINVAL);
++
++ ATF_REQUIRE(waitpid(pid, &status, 0) == pid);
++ ATF_REQUIRE(status == 0);
++ close(fd);
++ }
++}
++
++ATF_TC_WITHOUT_HEAD(nvlist_send_recv__overflow_big_endian_size);
++ATF_TC_BODY(nvlist_send_recv__overflow_big_endian_size, tc)
++{
++ static const unsigned char payload[] = {
++ 0x6c, /* magic */
++ 0x00, /* version */
++ 0x80, /* flags: NV_FLAG_BIG_ENDIAN */
++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf5,
++ };
++ nvlist_t *nvl;
++ int sv[2];
++
++ ATF_REQUIRE_EQ(socketpair(AF_UNIX, SOCK_STREAM, 0, sv), 0);
++ ATF_REQUIRE_EQ(write(sv[1], payload, sizeof(payload)),
++ (ssize_t)sizeof(payload));
++ ATF_REQUIRE_EQ(close(sv[1]), 0);
++
++ errno = 0;
++ nvl = nvlist_recv(sv[0], 0);
++ ATF_REQUIRE(nvl == NULL);
++ ATF_REQUIRE_EQ(errno, EINVAL);
++
++ ATF_REQUIRE_EQ(close(sv[0]), 0);
++}
++
++ATF_TC_WITHOUT_HEAD(nvlist_send_recv__overflow_little_endian_size);
++ATF_TC_BODY(nvlist_send_recv__overflow_little_endian_size, tc)
++{
++ static const unsigned char payload[] = {
++ 0x6c, /* magic */
++ 0x00, /* version */
++ 0x00, /* flags */
++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++ 0xf5, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
++ };
++ nvlist_t *nvl;
++ int sv[2];
++
++ ATF_REQUIRE_EQ(socketpair(AF_UNIX, SOCK_STREAM, 0, sv), 0);
++ ATF_REQUIRE_EQ(write(sv[1], payload, sizeof(payload)),
++ (ssize_t)sizeof(payload));
++ ATF_REQUIRE_EQ(close(sv[1]), 0);
++
++ errno = 0;
++ nvl = nvlist_recv(sv[0], 0);
++ ATF_REQUIRE(nvl == NULL);
++ ATF_REQUIRE_EQ(errno, EINVAL);
++
++ ATF_REQUIRE_EQ(close(sv[0]), 0);
++}
++
++ATF_TC_WITHOUT_HEAD(nvlist_send_recv__invalid_fd_size);
++ATF_TC_BODY(nvlist_send_recv__invalid_fd_size, tc)
++{
++ nvlist_t *nvl;
++ void *packed;
++ size_t packed_size;
++ struct nvlist_header *header;
++ int fd, socks[2], status;
++ pid_t pid;
++
++ ATF_REQUIRE_EQ(socketpair(PF_UNIX, SOCK_STREAM, 0, socks), 0);
++
++ pid = fork();
++ ATF_REQUIRE(pid >= 0);
++
++ if (pid == 0) {
++ /* Child. */
++ fd = socks[0];
++ close(socks[1]);
++
++ nvl = nvlist_create(0);
++ ATF_REQUIRE(nvl != NULL);
++ ATF_REQUIRE(nvlist_empty(nvl));
++
++ nvlist_add_string(nvl, "nvl/string", "test");
++ ATF_REQUIRE_EQ(nvlist_error(nvl), 0);
++
++ packed = nvlist_pack(nvl, &packed_size);
++ ATF_REQUIRE(packed != NULL);
++ ATF_REQUIRE(packed_size >= sizeof(struct nvlist_header));
++
++ header = (struct nvlist_header *)packed;
++ header->nvlh_descriptors = 0x20;
++
++ ATF_REQUIRE_EQ(write(fd, packed, packed_size),
++ (ssize_t)packed_size);
++
++ nvlist_destroy(nvl);
++ free(packed);
++
++ exit(0);
++ } else {
++ /* Parent */
++ fd = socks[1];
++ close(socks[0]);
++
++ nvl = nvlist_recv(fd, 0);
++ ATF_REQUIRE(nvl == NULL);
++
++ ATF_REQUIRE(waitpid(pid, &status, 0) == pid);
*** 859 LINES SKIPPED ***