diff options
15 files changed, 979 insertions, 34 deletions
diff --git a/documentation/content/en/books/porters-handbook/makefiles/_index.adoc b/documentation/content/en/books/porters-handbook/makefiles/_index.adoc index bce34cc330..45218f712b 100644 --- a/documentation/content/en/books/porters-handbook/makefiles/_index.adoc +++ b/documentation/content/en/books/porters-handbook/makefiles/_index.adoc @@ -1384,7 +1384,7 @@ MASTER_SITE_SUBDIR= stardict/WyabdcRealPeopleTTS/${PORTVERSION} |`BERLIOS` |`${PORTNAME:tl}.berlios` -|`CHEESESHOP` +|`PYPI` |`source/${DISTNAME:C/(.).\*/\1/}/${DISTNAME:C/(.*)-[0-9].*/\1/}` |`CPAN` diff --git a/website/content/en/releases/13.5R/errata.adoc b/website/content/en/releases/13.5R/errata.adoc index 2afe7f2778..2318705407 100644 --- a/website/content/en/releases/13.5R/errata.adoc +++ b/website/content/en/releases/13.5R/errata.adoc @@ -44,6 +44,7 @@ For a list of all FreeBSD CERT security advisories, see https://www.FreeBSD.org/ |link:https://www.FreeBSD.org/security/advisories/FreeBSD-SA-25:06.xz.asc[FreeBSD-SA-25:06.xz] |2 July 2025 |Use-after-free in multi-threaded xz decoder |link:https://www.FreeBSD.org/security/advisories/FreeBSD-SA-25:07.libarchive.asc[FreeBSD-SA-25:07.libarchive] |8 August 2025 |Integer overflow in libarchive leading to double free |link:https://www.FreeBSD.org/security/advisories/FreeBSD-SA-25:08.openssl.asc[FreeBSD-SA-25:08.openssl] |30 September 2025 |Multiple vulnerabilities in OpenSSL +|link:https://www.FreeBSD.org/security/advisories/FreeBSD-SA-25:09.netinet.asc[FreeBSD-SA-25:09.netinet] |22 October 2025 |SO_REUSEPORT_LB breaks connect(2) for UDP sockets |=== [[errata]] diff --git a/website/content/en/releases/14.3R/errata.adoc b/website/content/en/releases/14.3R/errata.adoc index facd1e4f7f..c89921d04d 100644 --- a/website/content/en/releases/14.3R/errata.adoc +++ b/website/content/en/releases/14.3R/errata.adoc @@ -46,6 +46,7 @@ For a list of all FreeBSD CERT security advisories, see https://www.FreeBSD.org/ |Advisory |Date |Topic |link:https://www.FreeBSD.org/security/advisories/FreeBSD-SA-25:07.libarchive.asc[FreeBSD-SA-25:07.libarchive] |8 August 2025 |Integer overflow in libarchive leading to double free |link:https://www.FreeBSD.org/security/advisories/FreeBSD-SA-25:08.openssl.asc[FreeBSD-SA-25:08.openssl] |30 September 2025 |Multiple vulnerabilities in OpenSSL +|link:https://www.FreeBSD.org/security/advisories/FreeBSD-SA-25:09.netinet.asc[FreeBSD-SA-25:09.netinet] |22 October 2025 |SO_REUSEPORT_LB breaks connect(2) for UDP sockets |=== [[errata]] diff --git a/website/content/en/status/report-2025-07-2025-09/alpha-omega-beach-cleaning.adoc b/website/content/en/status/report-2025-07-2025-09/alpha-omega-beach-cleaning.adoc new file mode 100644 index 0000000000..470eac52f1 --- /dev/null +++ b/website/content/en/status/report-2025-07-2025-09/alpha-omega-beach-cleaning.adoc @@ -0,0 +1,37 @@ +=== Alpha-Omega Beach Cleaning project + +Links: + +link:https://alpha-omega.dev[Alpha-Omega - Linux Foundation Project] URL: link:https://alpha-omega.dev[] + +link:https://github.com/ossf/alpha-omega[Alpha-Omega on GitHub] URL: link:https://github.com/ossf/alpha-omega[] + +link:https://freebsdfoundation.org[FreeBSD Foundation] URL: link:https://freebsdfoundation.org[] + +link:https://github.com/FreeBSDFoundation/alpha-omega-beach-cleaning[Project repository from the FreeBSD Foundation] URL: link:https://github.com/FreeBSDFoundation/alpha-omega-beach-cleaning[] + +Contact: Pierre Pronchery <pierre@freebsdfoundation.org> + +Alpha-Omega's mission is to catalyze sustainable security improvements to critical open source projects and ecosystems. +After a successful project with the FreeBSD Foundation in 2024 -- auditing the bhyve hypervisor and the Capsicum sandboxing framework -- Alpha-Omega has selected FreeBSD again, for the Alpha Omega Beach Cleaning project this time. +This new grant consists in generally improving the security and maintenance of third-party software within the FreeBSD base system. +The FreeBSD Foundation received the grant and is managing and executing the project. + +The list of tasks has been determined as follows: + +* Inventory of dependencies +* Security risk assessments +* Propose list of priorities +* Plan the respective actions +* Formalize code owners +* Integrate review methodologies +* Plan execution & coordination +* Final report + +The first deliverables have been issued on the dedicated GitHub repository: + +* Machine-readable link:https://github.com/FreeBSDFoundation/alpha-omega-beach-cleaning/blob/main/database.yml[database] +* link:https://github.com/FreeBSDFoundation/alpha-omega-beach-cleaning/blob/main/dependencies.md[List of dependencies] +* link:https://github.com/FreeBSDFoundation/alpha-omega-beach-cleaning/blob/main/security.md[Security risk assessments] + +Help is welcome to complete the information collected, and to improve on any other aspect of the project! + +Finally, monthly reporting is submitted and available link:https://github.com/ossf/alpha-omega/tree/main/alpha/engagements/2025/FreeBSD[on GitHub]. + +Sponsor: Alpha-Omega, The FreeBSD Foundation diff --git a/website/content/en/status/report-2025-07-2025-09/framework.adoc b/website/content/en/status/report-2025-07-2025-09/framework.adoc new file mode 100644 index 0000000000..0d3234cf4a --- /dev/null +++ b/website/content/en/status/report-2025-07-2025-09/framework.adoc @@ -0,0 +1,27 @@ +=== Framework Laptop support + +Links: + +link:https://wiki.freebsd.org/Laptops/Framework_Laptop/[Framework Laptop page on FreeBSD Wiki] URL: https://wiki.freebsd.org/Laptops/Framework_Laptop/[] + +link:https://github.com/FrameworkComputer/freebsd-on-framework[Guide on installing and using FreeBSD on Framework systems] URL: https://github.com/FrameworkComputer/freebsd-on-framework[] + +link:https://bugs.freebsd.org/262152[Tracking ticket: Framework Laptop: Feature support, bugs and improvements] URL: https://bugs.freebsd.org/262152[] + +Contact: Daniel Schaefer <dhs@frame.work> + +Contact: Li-Wen Hsu <lwhsu@FreeBSD.org> + +Contact: ShengYi Hong <aokblast@FreeBSD.org> + +Framework Computer Inc. is very supportive of the FreeBSD project in many ways, including providing engineering samples to the Foundation for testing and working on compatibility. + +The Foundation continues to work on improving overall laptop support, and Framework laptops are one of the link:https://github.com/FreeBSDFoundation/proj-laptop/blob/main/supported/laptops.md[target platforms] for the link:https://github.com/FreeBSDFoundation/proj-laptop/[Laptop Support and Usability Project]. + +In the 2nd and 3rd quarter of 2025, there were two hackathons held in Framework's Taipei office to test FreeBSD on the products newly released and in development. + +In April, we continued testing Framework Laptop 12 and Framework Desktop for the support of the in-development 15.0, including the ethernet support, serial console access, etc. + +In September, we worked on testing Framework Laptop 16 AMD Ryzen AI 300 Series, including the NVIDIA Graphics Module. +ShengYi link:https://cgit.freebsd.org/src/commit/?id=7f81b2519aebcf90d7e027122ca99b628ca81ed9[fixed the sound support] for this model. + +Daniel has fixed fwupd on FreeBSD (link:https://github.com/fwupd/fwupd/pull/9220[#9220], link:https://github.com/fwupd/fwupd/pull/9221[#9221], link:https://github.com/fwupd/fwupd/pull/9223[#9223]) and link:https://github.com/fwupd/fwupd/pull/9245[revived the FreeBSD CI]. +This work is included in the link:https://github.com/fwupd/fwupd/releases/tag/2.0.16[fwupd 2.0.16] release. + +Sponsor: The FreeBSD Foundation for Li-Wen and ShengYi's work + +Sponsor: Framework Computer Inc for Daniel's work, hardware and space support diff --git a/website/content/ru/platforms/_index.adoc b/website/content/ru/platforms/_index.adoc index 0e4ba4056c..26c016ef97 100644 --- a/website/content/ru/platforms/_index.adoc +++ b/website/content/ru/platforms/_index.adoc @@ -1,39 +1,56 @@ --- -title: "Поддерживаемые платформы" +title: "Платформы" sidenav: developers --- include::shared/ru/urls.adoc[] -= Поддерживаемые платформы - -== Введение - -Здесь вы можете найти список платформ, на которые портирована FreeBSD, или ведутся работы по портированию. - -== Содержание - -* link:amd64/[Проект FreeBSD/amd64] -* link:arm/[Проект FreeBSD/ARM] -* link:i386/[Проект FreeBSD/i386] -* link:ia64/[Проект FreeBSD/ia64] -* link:mips/[Проект FreeBSD/MIPS] -* link:pc98/[Проект FreeBSD/pc98] -* link:ppc/[Проект FreeBSD/ppc] -* link:sparc/[Проект FreeBSD/sparc64] -* link:xbox/[Проект FreeBSD/xbox] - -== Комментарии и контакты - -Если у вас есть замечания, связанные с портом, или вы хотите связаться с разработчиками, пошлите письмо в соответствующий список рассылки. Доступны следующие списки: - -* Для порта FreeBSD/amd64: freebsd-amd64@FreeBSD.org -* Для порта FreeBSD/ARM: freebsd-arm@FreeBSD.org -* Для порта FreeBSD/i386: freebsd-current@FreeBSD.org -* Для порта FreeBSD/ia64: freebsd-ia64@FreeBSD.org -* Для порта FreeBSD/MIPS: freebsd-mips@FreeBSD.org -* Для порта FreeBSD/pc98: re-pc98@FreeBSD.org -* Для порта FreeBSD/ppc: freebsd-ppc@FreeBSD.org -* Для порта FreeBSD/sparc64: freebsd-sparc@FreeBSD.org -* Для порта FreeBSD/xbox: freebsd-current@FreeBSD.org -* Для общих вопросов, связанных с архитектурой, freebsd-arch@FreeBSD.org +// +// The FreeBSD Russian Documentation Project +// +// Original EN revision (20.11.2023): 96d6c43f19c20c0e3322e38ffbef4a134aa9df08 +// + += Платформы + +== Поддерживаемые платформы + +Вот список платформ, которые поддерживает FreeBSD. + +[.tblbasic] +[cols=",,,,",options="header",] +|=== +|Название платформы |TARGET_ARCH |link:{committers-guide}#archs[Уровень поддержки] в 13.x |link:{committers-guide}#archs[Уровень поддержки] в 14.x |link:{committers-guide}#archs[Уровень поддержки] в 15.x (прогнозный) +|64-разрядная x86 |link:amd64[amd64] |Уровень 1 |Уровень 1 |Уровень 1 +|32-разрядная x86 |link:i386[i386] |Уровень 2 |Уровень 2 |Не поддерживается +|64-разрядная ARMv8 |link:arm[aarch64] |Уровень 1 |Уровень 1 |Уровень 1 +|32-разрядная ARMv6 |link:arm[armv6] |Уровень 2 |Уровень 3 |Не поддерживается +|32-разрядная ARMv7 |link:arm[armv7] |Уровень 2 |Уровень 2 |Уровень 2 +|32-разрядная MIPS без математического модуля |link:mips[mips, mipsel] |Уровень 2 |Не поддерживается |Не поддерживается +|32-разрядная MIPS с математическим модулем |link:mips[mipshf, mipselhf] |Уровень 2 |Не поддерживается |Не поддерживается +|32-разрядная MIPS n32 |link:mips[mipsn32] |Уровень 2 |Не поддерживается |Не поддерживается +|64-разрядная MIPS без математического модуля |link:mips[mips64, mips64el] |Уровень 2 |Не поддерживается |Не поддерживается +|64-разрядная MIPS с математическим модулем |link:mips[mips64hf, mips64elhf] |Уровень 2 |Не поддерживается |Не поддерживается +|32-разрядная PowerPC |link:ppc[powerpc] |Уровень 2 |Уровень 2 |Не поддерживается +|32-разрядная PowerPC с SPE |link:ppc[powerpcspe] |Уровень 2 |Уровень 2 |Не поддерживается +|64-разрядная PowerPC с прямым порядком байтов |link:ppc[powerpc64] |Уровень 2 |Уровень 2 |Уровень 2 +|64-разрядная PowerPC с обратным порядком байтов |link:ppc[powerpc64le] |Уровень 2 |Уровень 2 |Уровень 2 +|64-разрядная RISC-V |https://wiki.freebsd.org/riscv[riscv64] |Уровень 2 |Уровень 2 |Уровень 2 +|64-разрядная RISC-V без математического модуля |https://wiki.freebsd.org/riscv[riscv64sf] |Уровень 2 |Не поддерживается |Не поддерживается +|=== + +== Неподдерживаемые платформы + +Следующие платформы поддерживались более старыми версиями FreeBSD. + +[.tblbasic] +[cols=",,",options="header",] +|=== +|Название платформы |TARGET_ARCH |Последний поддерживающий релиз +|Alpha |alpha |link:../releases/#rel6-4[6.4] +|32-разрядная ARM v4/v5 с обратным порядком байтов|arm |link:../releases/#rel12-4[12.4] +|32-разрядная ARM с прямым порядком байтов |armeb |link:../releases/#rel11-4[11.4] +|Intel IA-64 |ia64 |link:../releases/#rel10-4[10.4] +|PC98 |pc98 |link:../releases/#rel11-4[11.4] +|64-разрядная SPARCv9 |sparc64 |link:../releases/#rel12-4[12.4] +|=== diff --git a/website/data/security/advisories.toml b/website/data/security/advisories.toml index dfcfa583b1..ad0f58dfe3 100644 --- a/website/data/security/advisories.toml +++ b/website/data/security/advisories.toml @@ -2,6 +2,10 @@ # $FreeBSD$ [[advisories]] +name = "FreeBSD-SA-25:09.netinet" +date = "2025-10-22" + +[[advisories]] name = "FreeBSD-SA-25:08.openssl" date = "2025-09-30" diff --git a/website/data/zh-tw/news/news.toml b/website/data/zh-tw/news/news.toml index b7aaf4789c..fe1034e65a 100644 --- a/website/data/zh-tw/news/news.toml +++ b/website/data/zh-tw/news/news.toml @@ -1,6 +1,11 @@ # Sort news by year, month and day # $FreeBSD$ [[news]] +date = "2025-10-18" +title = "FreeBSD 15.0-BETA2 發布了" +description = "FreeBSD 15.0 的第二個 BETA 版本現已發布。用於 amd64、armv7、powerpc64、powerpc64le和 riscv64 的 ISO 映像檔案已經 <a href=\"https://lists.freebsd.org/archives/freebsd-stable/2025-October/003466.html\">發布</a>,可以在多數的 <a href=\"https://docs.freebsd.org/en/books/handbook/mirrors/#mirrors-ftp\">FreeBSD 鏡像站</a>取得。" + +[[news]] date = "2025-10-12" title = "FreeBSD 15.0-BETA1 發布了" description = "FreeBSD 15.0 的第一個 BETA 版本現已發布。用於 amd64、armv7、powerpc64、powerpc64le和 riscv64 的 ISO 映像檔案已經 <a href=\"https://lists.freebsd.org/archives/freebsd-stable/2025-October/003383.html\">發布</a>,可以在多數的 <a href=\"https://docs.freebsd.org/en/books/handbook/mirrors/#mirrors-ftp\">FreeBSD 鏡像站</a>取得。" diff --git a/website/static/security/advisories/FreeBSD-SA-25:09.netinet.asc b/website/static/security/advisories/FreeBSD-SA-25:09.netinet.asc new file mode 100644 index 0000000000..49fe1c653f --- /dev/null +++ b/website/static/security/advisories/FreeBSD-SA-25:09.netinet.asc @@ -0,0 +1,162 @@ +-----BEGIN PGP SIGNED MESSAGE----- +Hash: SHA512 + +============================================================================= +FreeBSD-SA-25:09.netinet Security Advisory + The FreeBSD Project + +Topic: SO_REUSEPORT_LB breaks connect(2) for UDP sockets + +Category: core +Module: netinet +Announced: 2025-10-22 +Credits: MSc. student Omer Ben Simhon and Prof. Amit Klein, + both from the Hebrew University School of Computer + Science and Engineering +Affects: All supported versions of FreeBSD. +Corrected: 2025-10-22 15:48:25 UTC (stable/15, 15.0-STABLE) + 2025-10-22 15:50:30 UTC (releng/15.0, 15.0-BETA2-p1) + 2025-10-22 15:48:51 UTC (stable/14, 14.3-STABLE) + 2025-10-22 15:51:57 UTC (releng/14.3, 14.3-RELEASE-p5) + 2025-10-22 15:49:32 UTC (stable/13, 13.4-STABLE) + 2025-10-22 15:53:35 UTC (releng/13.5, 13.5-RELEASE-p6) +CVE Name: CVE-2025-24934 + +For general information regarding FreeBSD Security Advisories, +including descriptions of the fields above, security branches, and the +following sections, please visit <URL:https://security.FreeBSD.org/>. + +I. Background + +SO_REUSEPORT_LB is a socket option, set by setsockopt(2), which allows multiple +TCP or UDP sockets to bind to the same socket address, creating a +load-balancing group. Incoming packets and connections are distributed evenly +among sockets in a group. This helps network services avoid scalability +bottlenecks caused by having a single TCP listening socket. In particular, it +is expected that sockets belonging to a load-balancing group will accept +packets from any source address. + +II. Problem Description + +Connected sockets are not intended to belong to load-balancing groups. +However, the kernel failed to check the connection state of sockets when adding +them to load-balancing groups. Furthermore, when looking up the destination +socket for an incoming packet, the kernel will match a socket belonging to a +load-balancing group even if it is connected. + +Connected sockets are only supposed to receive packets originating from the +connected host. The above behavior violates this contract. + +III. Impact + +Software which sets SO_REUSEPORT_LB on a socket and then connects it to a host +will not observe any problems. However, due to its membership in a +load-balancing group, that socket will receive packets originating from any +host. This breaks the contract of the connect(2) and implied connect via +sendto(2), and may leave the application vulnerable to spoofing attacks. + +IV. Workaround + +No workaround is available. Software which does not use SO_REUSEPORT_LB is +not affected. + +V. Solution + +Upgrade your vulnerable 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 vulnerable system via a binary patch: + +Systems running a RELEASE version of FreeBSD on the amd64 or arm64 platforms, +or the i386 platform on FreeBSD 13, can be updated via the freebsd-update(8) +utility: + +# freebsd-update fetch +# freebsd-update install +# shutdown -r +10min "Rebooting for a security update" + +2) To update your vulnerable 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. + +[FreeBSD 15.x] +# fetch https://security.FreeBSD.org/patches/SA-25:09/netinet-15.patch +# fetch https://security.FreeBSD.org/patches/SA-25:09/netinet-15.patch.asc +# gpg --verify netinet-15.patch.asc + +[FreeBSD 14.x] +# fetch https://security.FreeBSD.org/patches/SA-25:09/netinet-14.patch +# fetch https://security.FreeBSD.org/patches/SA-25:09/netinet-14.patch.asc +# gpg --verify netinet-14.patch.asc + +[FreeBSD 13.x] +# fetch https://security.FreeBSD.org/patches/SA-25:09/netinet-13.patch +# fetch https://security.FreeBSD.org/patches/SA-25:09/netinet-13.patch.asc +# gpg --verify netinet-13.patch.asc + +b) Apply the patch. Execute the following commands as root: + +# cd /usr/src +# patch < /path/to/patch + +c) Recompile your kernel as described in +<URL:https://www.FreeBSD.org/handbook/kernelconfig.html> and 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/ ef159100ec2b stable/15-n280782 +releng/15.0/ 98c539667881 releng/15.0-n280723 +stable/14/ e276759b3687 stable/14-n272700 +releng/14.3/ 058bcb57cd4b releng/14.3-n271448 +stable/13/ df888c8f41f6 stable/13-n259508 +releng/13.5/ 90e14aa082d3 releng/13.5-n259180 +- ------------------------------------------------------------------------- + +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://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2025-24934> + +The latest revision of this advisory is available at +<URL:https://security.FreeBSD.org/advisories/FreeBSD-SA-25:09.netinet.asc> +-----BEGIN PGP SIGNATURE----- + +iQIzBAEBCgAdFiEEthUnfoEIffdcgYM7bljekB8AGu8FAmj5CrEACgkQbljekB8A +Gu98YQ//dMMpEdKapK6bBM++8HoSWeydnoUifFqu3LiDXcDTgQ6jVsmwQ/QOUPll +bOB7etdtu+FQEI4yl8d9w98TrXC8Mvl6p+dZ3SkIglLNeVmouiot+VDBpoOr/EPq +xXf6dGlkDneYTsAFXwDKe48vmisdWd1trtYhVuE6qWq54AH4Y3dv0+DOMIdlKbPc +GHFLRoJ/eEJH+3QAhL8Ozdp2WySUWHPMsScBRldcrhariXzEQ9KcM6TJx8mYGKta +DYeezna1DQ87wU8Zs5fKfhUS6q/YJcXr9Te5P1xirmcmgr2frJW1DjfWKI8oQ9ru +2mn6oedSu6nRFjpYzO9tS/7svC8Hkyyr1rsZujRkC5cMRwY2DovU653GoaOwadMc +gig8CvOeb1srD1kMnFyGfa54VTbGZCZ261bnGdUc9BCL8ARtv6q4KNTRofkYrCLP +YwGTxEsCVdNbtDGv5nLJ/V7RfAUMnp9YuYpHc0Auttt6cUW6DI3nGQg+LlfoCJ0n +JESXa3Fry0GcFWiPB6oigyFSH6c3Ml+E7TiUYAZOtQ4cqJG1v9x1Lv5BQ1dz5vah +J24oGW2uI6Xp0TbvIFBd6KCFZSa/dS9sq486norj17X7ktZ7EeVVpm4vRBtDEo4N +k2WdkjcWfSM5uLnYLZR+rp+1rhtSIxw3gZaoJLl18p+9NMOFBH4= +=RgID +-----END PGP SIGNATURE----- diff --git a/website/static/security/patches/SA-25:09/netinet-13.patch b/website/static/security/patches/SA-25:09/netinet-13.patch new file mode 100644 index 0000000000..49031737eb --- /dev/null +++ b/website/static/security/patches/SA-25:09/netinet-13.patch @@ -0,0 +1,244 @@ +--- sys/netinet/in_pcb.c.orig ++++ sys/netinet/in_pcb.c +@@ -2668,6 +2668,7 @@ + struct inpcbinfo *pcbinfo = inp->inp_pcbinfo; + struct inpcbport *phd; + u_int32_t hashkey_faddr; ++ bool connected; + + INP_WLOCK_ASSERT(inp); + INP_HASH_WLOCK_ASSERT(pcbinfo); +@@ -2676,11 +2677,15 @@ + ("in_pcbinshash: INP_INHASHLIST")); + + #ifdef INET6 +- if (inp->inp_vflag & INP_IPV6) ++ if (inp->inp_vflag & INP_IPV6) { + hashkey_faddr = INP6_PCBHASHKEY(&inp->in6p_faddr); +- else ++ connected = !IN6_IS_ADDR_UNSPECIFIED(&inp->in6p_faddr); ++ } else + #endif +- hashkey_faddr = inp->inp_faddr.s_addr; ++ { ++ hashkey_faddr = inp->inp_faddr.s_addr; ++ connected = inp->inp_faddr.s_addr != INADDR_ANY; ++ } + + pcbhash = &pcbinfo->ipi_hashbase[INP_PCBHASH(hashkey_faddr, + inp->inp_lport, inp->inp_fport, pcbinfo->ipi_hashmask)]; +@@ -2689,10 +2694,12 @@ + INP_PCBPORTHASH(inp->inp_lport, pcbinfo->ipi_porthashmask)]; + + /* +- * Add entry to load balance group. +- * Only do this if SO_REUSEPORT_LB is set. ++ * Ignore SO_REUSEPORT_LB if the socket is connected. Really this case ++ * should be an error, but for UDP sockets it is not, and some ++ * applications erroneously set it on connected UDP sockets, so we can't ++ * change this without breaking compatibility. + */ +- if ((inp->inp_flags2 & INP_REUSEPORT_LB) != 0) { ++ if (!connected && (inp->inp_flags2 & INP_REUSEPORT_LB) != 0) { + int error = in_pcbinslbgrouphash(inp, M_NODOM); + if (error != 0) + return (error); +@@ -2761,6 +2768,7 @@ + struct inpcbinfo *pcbinfo = inp->inp_pcbinfo; + struct inpcbhead *head; + u_int32_t hashkey_faddr; ++ bool connected; + + INP_WLOCK_ASSERT(inp); + INP_HASH_WLOCK_ASSERT(pcbinfo); +@@ -2769,11 +2777,19 @@ + ("in_pcbrehash: !INP_INHASHLIST")); + + #ifdef INET6 +- if (inp->inp_vflag & INP_IPV6) ++ if (inp->inp_vflag & INP_IPV6) { + hashkey_faddr = INP6_PCBHASHKEY(&inp->in6p_faddr); +- else ++ connected = !IN6_IS_ADDR_UNSPECIFIED(&inp->in6p_faddr); ++ } else + #endif +- hashkey_faddr = inp->inp_faddr.s_addr; ++ { ++ hashkey_faddr = inp->inp_faddr.s_addr; ++ connected = inp->inp_faddr.s_addr != INADDR_ANY; ++ } ++ ++ /* See the comment in in_pcbinshash(). */ ++ if (connected && (inp->inp_flags2 & INP_REUSEPORT_LB) != 0) ++ in_pcbremlbgrouphash(inp); + + head = &pcbinfo->ipi_hashbase[INP_PCBHASH(hashkey_faddr, + inp->inp_lport, inp->inp_fport, pcbinfo->ipi_hashmask)]; +--- tests/sys/netinet/so_reuseport_lb_test.c.orig ++++ tests/sys/netinet/so_reuseport_lb_test.c +@@ -29,6 +29,8 @@ + + #include <sys/cdefs.h> + #include <sys/param.h> ++#include <sys/filio.h> ++#include <sys/ioccom.h> + #include <sys/socket.h> + + #include <netinet/in.h> +@@ -236,10 +238,156 @@ + } + } + ++/* ++ * The kernel erroneously permits calling connect() on a UDP socket with ++ * SO_REUSEPORT_LB set. Verify that packets sent to the bound address are ++ * dropped unless they come from the connected address. ++ */ ++ATF_TC_WITHOUT_HEAD(connect_udp); ++ATF_TC_BODY(connect_udp, tc) ++{ ++ struct sockaddr_in sin = { ++ .sin_family = AF_INET, ++ .sin_len = sizeof(sin), ++ .sin_addr = { htonl(INADDR_LOOPBACK) }, ++ }; ++ ssize_t n; ++ int error, len, s1, s2, s3; ++ char ch; ++ ++ s1 = socket(PF_INET, SOCK_DGRAM, 0); ++ ATF_REQUIRE(s1 >= 0); ++ s2 = socket(PF_INET, SOCK_DGRAM, 0); ++ ATF_REQUIRE(s2 >= 0); ++ s3 = socket(PF_INET, SOCK_DGRAM, 0); ++ ATF_REQUIRE(s3 >= 0); ++ ++ error = setsockopt(s1, SOL_SOCKET, SO_REUSEPORT_LB, (int[]){1}, ++ sizeof(int)); ++ ATF_REQUIRE_MSG(error == 0, ++ "setsockopt(SO_REUSEPORT_LB) failed: %s", strerror(errno)); ++ error = bind(s1, (struct sockaddr *)&sin, sizeof(sin)); ++ ATF_REQUIRE_MSG(error == 0, "bind() failed: %s", strerror(errno)); ++ ++ error = bind(s2, (struct sockaddr *)&sin, sizeof(sin)); ++ ATF_REQUIRE_MSG(error == 0, "bind() failed: %s", strerror(errno)); ++ ++ error = bind(s3, (struct sockaddr *)&sin, sizeof(sin)); ++ ATF_REQUIRE_MSG(error == 0, "bind() failed: %s", strerror(errno)); ++ ++ /* Connect to an address not owned by s2. */ ++ error = getsockname(s3, (struct sockaddr *)&sin, ++ (socklen_t[]){sizeof(sin)}); ++ ATF_REQUIRE(error == 0); ++ error = connect(s1, (struct sockaddr *)&sin, sizeof(sin)); ++ ATF_REQUIRE_MSG(error == 0, "connect() failed: %s", strerror(errno)); ++ ++ /* Try to send a packet to s1 from s2. */ ++ error = getsockname(s1, (struct sockaddr *)&sin, ++ (socklen_t[]){sizeof(sin)}); ++ ATF_REQUIRE(error == 0); ++ ++ ch = 42; ++ n = sendto(s2, &ch, sizeof(ch), 0, (struct sockaddr *)&sin, ++ sizeof(sin)); ++ ATF_REQUIRE(n == 1); ++ ++ /* Give the packet some time to arrive. */ ++ usleep(100000); ++ ++ /* s1 is connected to s3 and shouldn't receive from s2. */ ++ error = ioctl(s1, FIONREAD, &len); ++ ATF_REQUIRE(error == 0); ++ ATF_REQUIRE_MSG(len == 0, "unexpected data available"); ++ ++ /* ... but s3 can of course send to s1. */ ++ n = sendto(s3, &ch, sizeof(ch), 0, (struct sockaddr *)&sin, ++ sizeof(sin)); ++ ATF_REQUIRE(n == 1); ++ usleep(100000); ++ error = ioctl(s1, FIONREAD, &len); ++ ATF_REQUIRE(error == 0); ++ ATF_REQUIRE_MSG(len >= 1, "expected data available"); ++} ++ ++/* ++ * The kernel erroneously permits calling connect() on a UDP socket with ++ * SO_REUSEPORT_LB set. Verify that packets sent to the bound address are ++ * dropped unless they come from the connected address. ++ */ ++ATF_TC_WITHOUT_HEAD(connect_udp6); ++ATF_TC_BODY(connect_udp6, tc) ++{ ++ struct sockaddr_in6 sin6 = { ++ .sin6_family = AF_INET6, ++ .sin6_len = sizeof(sin6), ++ .sin6_addr = IN6ADDR_LOOPBACK_INIT, ++ }; ++ ssize_t n; ++ int error, len, s1, s2, s3; ++ char ch; ++ ++ s1 = socket(PF_INET6, SOCK_DGRAM, 0); ++ ATF_REQUIRE(s1 >= 0); ++ s2 = socket(PF_INET6, SOCK_DGRAM, 0); ++ ATF_REQUIRE(s2 >= 0); ++ s3 = socket(PF_INET6, SOCK_DGRAM, 0); ++ ATF_REQUIRE(s3 >= 0); ++ ++ error = setsockopt(s1, SOL_SOCKET, SO_REUSEPORT_LB, (int[]){1}, ++ sizeof(int)); ++ ATF_REQUIRE_MSG(error == 0, ++ "setsockopt(SO_REUSEPORT_LB) failed: %s", strerror(errno)); ++ error = bind(s1, (struct sockaddr *)&sin6, sizeof(sin6)); ++ ATF_REQUIRE_MSG(error == 0, "bind() failed: %s", strerror(errno)); ++ ++ error = bind(s2, (struct sockaddr *)&sin6, sizeof(sin6)); ++ ATF_REQUIRE_MSG(error == 0, "bind() failed: %s", strerror(errno)); ++ ++ error = bind(s3, (struct sockaddr *)&sin6, sizeof(sin6)); ++ ATF_REQUIRE_MSG(error == 0, "bind() failed: %s", strerror(errno)); ++ ++ /* Connect to an address not owned by s2. */ ++ error = getsockname(s3, (struct sockaddr *)&sin6, ++ (socklen_t[]){sizeof(sin6)}); ++ ATF_REQUIRE(error == 0); ++ error = connect(s1, (struct sockaddr *)&sin6, sizeof(sin6)); ++ ATF_REQUIRE_MSG(error == 0, "connect() failed: %s", strerror(errno)); ++ ++ /* Try to send a packet to s1 from s2. */ ++ error = getsockname(s1, (struct sockaddr *)&sin6, ++ (socklen_t[]){sizeof(sin6)}); ++ ATF_REQUIRE(error == 0); ++ ++ ch = 42; ++ n = sendto(s2, &ch, sizeof(ch), 0, (struct sockaddr *)&sin6, ++ sizeof(sin6)); ++ ATF_REQUIRE(n == 1); ++ ++ /* Give the packet some time to arrive. */ ++ usleep(100000); ++ ++ /* s1 is connected to s3 and shouldn't receive from s2. */ ++ error = ioctl(s1, FIONREAD, &len); ++ ATF_REQUIRE(error == 0); ++ ATF_REQUIRE_MSG(len >= 0, "unexpected data available"); ++ ++ /* ... but s3 can of course send to s1. */ ++ n = sendto(s3, &ch, sizeof(ch), 0, (struct sockaddr *)&sin6, ++ sizeof(sin6)); ++ ATF_REQUIRE(n == 1); ++ usleep(100000); ++ error = ioctl(s1, FIONREAD, &len); ++ ATF_REQUIRE(error == 0); ++ ATF_REQUIRE_MSG(len >= 1, "expected data available"); ++} ++ + ATF_TP_ADD_TCS(tp) + { + ATF_TP_ADD_TC(tp, basic_ipv4); + ATF_TP_ADD_TC(tp, basic_ipv6); ++ ATF_TP_ADD_TC(tp, connect_udp); ++ ATF_TP_ADD_TC(tp, connect_udp6); + + return (atf_no_error()); + } diff --git a/website/static/security/patches/SA-25:09/netinet-13.patch.asc b/website/static/security/patches/SA-25:09/netinet-13.patch.asc new file mode 100644 index 0000000000..4767da0d8d --- /dev/null +++ b/website/static/security/patches/SA-25:09/netinet-13.patch.asc @@ -0,0 +1,16 @@ +-----BEGIN PGP SIGNATURE----- + +iQIzBAABCgAdFiEEthUnfoEIffdcgYM7bljekB8AGu8FAmj5CrcACgkQbljekB8A +Gu+Aqg/8CJPC1rYA+WwpTlAFbQ4HbNrWWptKQvnvvc9qZ6I74p4B4g5tXTsarJaw +Y5fEX4o+SU1aM2x3jLEEKXvjm+BHjeI8OFWDIXsSwg6SH9CkXiiqVeFsgYl7ld0R +W1YU+1QN8/4co/QLOgbRAPFcTm8z6FX6yzWcWRnwrHksT6lSu6q0FTTm//2T+upN +QdW8L19dV0zvL36aA47P7WR5aiaRuyDj9K8gpQnD/rlCPjMpwmuVXdlvQDs7m0uE +4fbrNULAk+2QXUMqWG8qUbpLgAK5oNrI5dGVXzWwJ98pOm5gO7rozWlAE4bn46nk +9/4cMWVZoYHp4Ui0iHqb9nvdJQq21jFS1408Bxsi4sT+nztRsbO8plD3ihSiG+XL +VVcauVUxxf8ezbJmTSji5HTnSIs16kHPiVGCgEuX0bBeItyqrT9p6v379Jw2pSgH +FQHNGoFYJQ0KDlEFxpxChpZyyH7DMKYF0ckwd9apsD8HCUvw1w6y89UjahPpb7Gj +2p3O8NvEFpy0ODL0/h5G7Wc6hzs++i/gaiXiRZXhMtXY0rlpcH6N5SrTso2jY2SA +yEOM1AZV9v9hzS6st4R+Tot/e3j4OlxMjhSKJu9F3VyGyNbIhXFW8pMvjTD06CWM +YSLX4qyBoHhkrMpsj53acGif0hlikN59tuAuVRjGeXRgrbQudkU= +=4UW4 +-----END PGP SIGNATURE----- diff --git a/website/static/security/patches/SA-25:09/netinet-14.patch b/website/static/security/patches/SA-25:09/netinet-14.patch new file mode 100644 index 0000000000..0c022135e8 --- /dev/null +++ b/website/static/security/patches/SA-25:09/netinet-14.patch @@ -0,0 +1,198 @@ +--- sys/netinet/in_pcb.c.orig ++++ sys/netinet/in_pcb.c +@@ -2702,10 +2702,13 @@ + INP_PCBPORTHASH(inp->inp_lport, pcbinfo->ipi_porthashmask)]; + + /* +- * Add entry to load balance group. +- * Only do this if SO_REUSEPORT_LB is set. ++ * Ignore SO_REUSEPORT_LB if the socket is connected. Really this case ++ * should be an error, but for UDP sockets it is not, and some ++ * applications erroneously set it on connected UDP sockets, so we can't ++ * change this without breaking compatibility. + */ +- if ((inp->inp_socket->so_options & SO_REUSEPORT_LB) != 0) { ++ if (!connected && ++ (inp->inp_socket->so_options & SO_REUSEPORT_LB) != 0) { + int error = in_pcbinslbgrouphash(inp, M_NODOM); + if (error != 0) + return (error); +@@ -2836,6 +2839,10 @@ + connected = !in_nullhost(inp->inp_faddr); + } + ++ /* See the comment in in_pcbinshash(). */ ++ if (connected && (inp->inp_flags & INP_INLBGROUP) != 0) ++ in_pcbremlbgrouphash(inp); ++ + /* + * When rehashing, the caller must ensure that either the new or the old + * foreign address was unspecified. +--- tests/sys/netinet/so_reuseport_lb_test.c.orig ++++ tests/sys/netinet/so_reuseport_lb_test.c +@@ -29,6 +29,8 @@ + + #include <sys/cdefs.h> + #include <sys/param.h> ++#include <sys/filio.h> ++#include <sys/ioccom.h> + #include <sys/socket.h> + + #include <netinet/in.h> +@@ -236,10 +238,156 @@ + } + } + ++/* ++ * The kernel erroneously permits calling connect() on a UDP socket with ++ * SO_REUSEPORT_LB set. Verify that packets sent to the bound address are ++ * dropped unless they come from the connected address. ++ */ ++ATF_TC_WITHOUT_HEAD(connect_udp); ++ATF_TC_BODY(connect_udp, tc) ++{ ++ struct sockaddr_in sin = { ++ .sin_family = AF_INET, ++ .sin_len = sizeof(sin), ++ .sin_addr = { htonl(INADDR_LOOPBACK) }, ++ }; ++ ssize_t n; ++ int error, len, s1, s2, s3; ++ char ch; ++ ++ s1 = socket(PF_INET, SOCK_DGRAM, 0); ++ ATF_REQUIRE(s1 >= 0); ++ s2 = socket(PF_INET, SOCK_DGRAM, 0); ++ ATF_REQUIRE(s2 >= 0); ++ s3 = socket(PF_INET, SOCK_DGRAM, 0); ++ ATF_REQUIRE(s3 >= 0); ++ ++ error = setsockopt(s1, SOL_SOCKET, SO_REUSEPORT_LB, (int[]){1}, ++ sizeof(int)); ++ ATF_REQUIRE_MSG(error == 0, ++ "setsockopt(SO_REUSEPORT_LB) failed: %s", strerror(errno)); ++ error = bind(s1, (struct sockaddr *)&sin, sizeof(sin)); ++ ATF_REQUIRE_MSG(error == 0, "bind() failed: %s", strerror(errno)); ++ ++ error = bind(s2, (struct sockaddr *)&sin, sizeof(sin)); ++ ATF_REQUIRE_MSG(error == 0, "bind() failed: %s", strerror(errno)); ++ ++ error = bind(s3, (struct sockaddr *)&sin, sizeof(sin)); ++ ATF_REQUIRE_MSG(error == 0, "bind() failed: %s", strerror(errno)); ++ ++ /* Connect to an address not owned by s2. */ ++ error = getsockname(s3, (struct sockaddr *)&sin, ++ (socklen_t[]){sizeof(sin)}); ++ ATF_REQUIRE(error == 0); ++ error = connect(s1, (struct sockaddr *)&sin, sizeof(sin)); ++ ATF_REQUIRE_MSG(error == 0, "connect() failed: %s", strerror(errno)); ++ ++ /* Try to send a packet to s1 from s2. */ ++ error = getsockname(s1, (struct sockaddr *)&sin, ++ (socklen_t[]){sizeof(sin)}); ++ ATF_REQUIRE(error == 0); ++ ++ ch = 42; ++ n = sendto(s2, &ch, sizeof(ch), 0, (struct sockaddr *)&sin, ++ sizeof(sin)); ++ ATF_REQUIRE(n == 1); ++ ++ /* Give the packet some time to arrive. */ ++ usleep(100000); ++ ++ /* s1 is connected to s3 and shouldn't receive from s2. */ ++ error = ioctl(s1, FIONREAD, &len); ++ ATF_REQUIRE(error == 0); ++ ATF_REQUIRE_MSG(len == 0, "unexpected data available"); ++ ++ /* ... but s3 can of course send to s1. */ ++ n = sendto(s3, &ch, sizeof(ch), 0, (struct sockaddr *)&sin, ++ sizeof(sin)); ++ ATF_REQUIRE(n == 1); ++ usleep(100000); ++ error = ioctl(s1, FIONREAD, &len); ++ ATF_REQUIRE(error == 0); ++ ATF_REQUIRE_MSG(len == 1, "unexpected data available"); ++} ++ ++/* ++ * The kernel erroneously permits calling connect() on a UDP socket with ++ * SO_REUSEPORT_LB set. Verify that packets sent to the bound address are ++ * dropped unless they come from the connected address. ++ */ ++ATF_TC_WITHOUT_HEAD(connect_udp6); ++ATF_TC_BODY(connect_udp6, tc) ++{ ++ struct sockaddr_in6 sin6 = { ++ .sin6_family = AF_INET6, ++ .sin6_len = sizeof(sin6), ++ .sin6_addr = IN6ADDR_LOOPBACK_INIT, ++ }; ++ ssize_t n; ++ int error, len, s1, s2, s3; ++ char ch; ++ ++ s1 = socket(PF_INET6, SOCK_DGRAM, 0); ++ ATF_REQUIRE(s1 >= 0); ++ s2 = socket(PF_INET6, SOCK_DGRAM, 0); ++ ATF_REQUIRE(s2 >= 0); ++ s3 = socket(PF_INET6, SOCK_DGRAM, 0); ++ ATF_REQUIRE(s3 >= 0); ++ ++ error = setsockopt(s1, SOL_SOCKET, SO_REUSEPORT_LB, (int[]){1}, ++ sizeof(int)); ++ ATF_REQUIRE_MSG(error == 0, ++ "setsockopt(SO_REUSEPORT_LB) failed: %s", strerror(errno)); ++ error = bind(s1, (struct sockaddr *)&sin6, sizeof(sin6)); ++ ATF_REQUIRE_MSG(error == 0, "bind() failed: %s", strerror(errno)); ++ ++ error = bind(s2, (struct sockaddr *)&sin6, sizeof(sin6)); ++ ATF_REQUIRE_MSG(error == 0, "bind() failed: %s", strerror(errno)); ++ ++ error = bind(s3, (struct sockaddr *)&sin6, sizeof(sin6)); ++ ATF_REQUIRE_MSG(error == 0, "bind() failed: %s", strerror(errno)); ++ ++ /* Connect to an address not owned by s2. */ ++ error = getsockname(s3, (struct sockaddr *)&sin6, ++ (socklen_t[]){sizeof(sin6)}); ++ ATF_REQUIRE(error == 0); ++ error = connect(s1, (struct sockaddr *)&sin6, sizeof(sin6)); ++ ATF_REQUIRE_MSG(error == 0, "connect() failed: %s", strerror(errno)); ++ ++ /* Try to send a packet to s1 from s2. */ ++ error = getsockname(s1, (struct sockaddr *)&sin6, ++ (socklen_t[]){sizeof(sin6)}); ++ ATF_REQUIRE(error == 0); ++ ++ ch = 42; ++ n = sendto(s2, &ch, sizeof(ch), 0, (struct sockaddr *)&sin6, ++ sizeof(sin6)); ++ ATF_REQUIRE(n == 1); ++ ++ /* Give the packet some time to arrive. */ ++ usleep(100000); ++ ++ /* s1 is connected to s3 and shouldn't receive from s2. */ ++ error = ioctl(s1, FIONREAD, &len); ++ ATF_REQUIRE(error == 0); ++ ATF_REQUIRE_MSG(len == 0, "unexpected data available"); ++ ++ /* ... but s3 can of course send to s1. */ ++ n = sendto(s3, &ch, sizeof(ch), 0, (struct sockaddr *)&sin6, ++ sizeof(sin6)); ++ ATF_REQUIRE(n == 1); ++ usleep(100000); ++ error = ioctl(s1, FIONREAD, &len); ++ ATF_REQUIRE(error == 0); ++ ATF_REQUIRE_MSG(len == 1, "unexpected data available"); ++} ++ + ATF_TP_ADD_TCS(tp) + { + ATF_TP_ADD_TC(tp, basic_ipv4); + ATF_TP_ADD_TC(tp, basic_ipv6); ++ ATF_TP_ADD_TC(tp, connect_udp); ++ ATF_TP_ADD_TC(tp, connect_udp6); + + return (atf_no_error()); + } diff --git a/website/static/security/patches/SA-25:09/netinet-14.patch.asc b/website/static/security/patches/SA-25:09/netinet-14.patch.asc new file mode 100644 index 0000000000..b0c2e2429c --- /dev/null +++ b/website/static/security/patches/SA-25:09/netinet-14.patch.asc @@ -0,0 +1,16 @@ +-----BEGIN PGP SIGNATURE----- + +iQIzBAABCgAdFiEEthUnfoEIffdcgYM7bljekB8AGu8FAmj5CrgACgkQbljekB8A +Gu+IoRAAlJrsOBxL+/qrj25ehBLzbEmgD3t6xdbz3GboR1Nfwx1ragW11xHR0sCN +Mx73rW8Gvf9vOAThvSPs4ajMq4gEmu5tTz8LR5wZnsiGQJrxgz8OZLIvQPIfiF0X +deaXmWE/QK+7T3zqGM5uQIv2I8XIhx6cyvnm5sXFL/cpjiWwWwo3eMiB4k5ecW0w +HZqF/VclSAnB7VhkyvoVOU45+9DdgG6wVdGTBZbGOm6Y7JKkrrlIH84yb4onNanx +XjPOwD+TNXFGlz1rS3R5KuVsEUx1TR3NCYkrjBZcTVFul3YhnH+Cvn2LxUKv+Brf +1EVywW11lF2FMa+cukIaei6Dnka79UnHdarKaCyBseSFmzmcV+XSb0dsvDoEF4mx +XvaIn7BBoEfcBcH2HB46huUWeVWAVvjC4qpkoKGYbiYnS+iamA+uTrazeP5zkgnz +f1KRpgVvAzFNQqGhUI6AO9m+/DugShjtHN6oT8HmKTNfEo2/nbEWGh1+KNCTWMfr +CtVWBwSCV0UECH5DcKDcbjtgoqnJ2qNkooye2ruSjbLkOr6wyWMcNnhm/y9XlXJc +1meQGpMWTHhPYyi+VK4Z+/E5oj3fNv9ZFKDrEnAq5lzNEhkW+O0tYVTkfj/D2bNy +CR50qzAogqsn73XJJ++y2mGa18hs0BNhwAOV8jy4clR4HCRP65c= +=lJlP +-----END PGP SIGNATURE----- diff --git a/website/static/security/patches/SA-25:09/netinet-15.patch b/website/static/security/patches/SA-25:09/netinet-15.patch new file mode 100644 index 0000000000..7083189c9a --- /dev/null +++ b/website/static/security/patches/SA-25:09/netinet-15.patch @@ -0,0 +1,201 @@ +--- sys/netinet/in_pcb.c.orig ++++ sys/netinet/in_pcb.c +@@ -2665,10 +2665,13 @@ + INP_PCBPORTHASH(inp->inp_lport, pcbinfo->ipi_porthashmask)]; + + /* +- * Add entry to load balance group. +- * Only do this if SO_REUSEPORT_LB is set. ++ * Ignore SO_REUSEPORT_LB if the socket is connected. Really this case ++ * should be an error, but for UDP sockets it is not, and some ++ * applications erroneously set it on connected UDP sockets, so we can't ++ * change this without breaking compatibility. + */ +- if ((inp->inp_socket->so_options & SO_REUSEPORT_LB) != 0) { ++ if (!connected && ++ (inp->inp_socket->so_options & SO_REUSEPORT_LB) != 0) { + int error = in_pcbinslbgrouphash(inp, M_NODOM); + if (error != 0) + return (error); +@@ -2770,6 +2773,10 @@ + connected = !in_nullhost(inp->inp_faddr); + } + ++ /* See the comment in in_pcbinshash(). */ ++ if (connected && (inp->inp_flags & INP_INLBGROUP) != 0) ++ in_pcbremlbgrouphash(inp); ++ + /* + * When rehashing, the caller must ensure that either the new or the old + * foreign address was unspecified. +--- tests/sys/netinet/so_reuseport_lb_test.c.orig ++++ tests/sys/netinet/so_reuseport_lb_test.c +@@ -29,6 +29,8 @@ + + #include <sys/param.h> + #include <sys/event.h> ++#include <sys/filio.h> ++#include <sys/ioccom.h> + #include <sys/socket.h> + + #include <netinet/in.h> +@@ -551,6 +553,150 @@ + close(s); + } + ++/* ++ * The kernel erroneously permits calling connect() on a UDP socket with ++ * SO_REUSEPORT_LB set. Verify that packets sent to the bound address are ++ * dropped unless they come from the connected address. ++ */ ++ATF_TC_WITHOUT_HEAD(connect_udp); ++ATF_TC_BODY(connect_udp, tc) ++{ ++ struct sockaddr_in sin = { ++ .sin_family = AF_INET, ++ .sin_len = sizeof(sin), ++ .sin_addr = { htonl(INADDR_LOOPBACK) }, ++ }; ++ ssize_t n; ++ int error, len, s1, s2, s3; ++ char ch; ++ ++ s1 = socket(PF_INET, SOCK_DGRAM, 0); ++ ATF_REQUIRE(s1 >= 0); ++ s2 = socket(PF_INET, SOCK_DGRAM, 0); ++ ATF_REQUIRE(s2 >= 0); ++ s3 = socket(PF_INET, SOCK_DGRAM, 0); ++ ATF_REQUIRE(s3 >= 0); ++ ++ error = setsockopt(s1, SOL_SOCKET, SO_REUSEPORT_LB, (int[]){1}, ++ sizeof(int)); ++ ATF_REQUIRE_MSG(error == 0, ++ "setsockopt(SO_REUSEPORT_LB) failed: %s", strerror(errno)); ++ error = bind(s1, (struct sockaddr *)&sin, sizeof(sin)); ++ ATF_REQUIRE_MSG(error == 0, "bind() failed: %s", strerror(errno)); ++ ++ error = bind(s2, (struct sockaddr *)&sin, sizeof(sin)); ++ ATF_REQUIRE_MSG(error == 0, "bind() failed: %s", strerror(errno)); ++ ++ error = bind(s3, (struct sockaddr *)&sin, sizeof(sin)); ++ ATF_REQUIRE_MSG(error == 0, "bind() failed: %s", strerror(errno)); ++ ++ /* Connect to an address not owned by s2. */ ++ error = getsockname(s3, (struct sockaddr *)&sin, ++ (socklen_t[]){sizeof(sin)}); ++ ATF_REQUIRE(error == 0); ++ error = connect(s1, (struct sockaddr *)&sin, sizeof(sin)); ++ ATF_REQUIRE_MSG(error == 0, "connect() failed: %s", strerror(errno)); ++ ++ /* Try to send a packet to s1 from s2. */ ++ error = getsockname(s1, (struct sockaddr *)&sin, ++ (socklen_t[]){sizeof(sin)}); ++ ATF_REQUIRE(error == 0); ++ ++ ch = 42; ++ n = sendto(s2, &ch, sizeof(ch), 0, (struct sockaddr *)&sin, ++ sizeof(sin)); ++ ATF_REQUIRE(n == 1); ++ ++ /* Give the packet some time to arrive. */ ++ usleep(100000); ++ ++ /* s1 is connected to s3 and shouldn't receive from s2. */ ++ error = ioctl(s1, FIONREAD, &len); ++ ATF_REQUIRE(error == 0); ++ ATF_REQUIRE_MSG(len == 0, "unexpected data available"); ++ ++ /* ... but s3 can of course send to s1. */ ++ n = sendto(s3, &ch, sizeof(ch), 0, (struct sockaddr *)&sin, ++ sizeof(sin)); ++ ATF_REQUIRE(n == 1); ++ usleep(100000); ++ error = ioctl(s1, FIONREAD, &len); ++ ATF_REQUIRE(error == 0); ++ ATF_REQUIRE_MSG(len == 1, "unexpected data available"); ++} ++ ++/* ++ * The kernel erroneously permits calling connect() on a UDP socket with ++ * SO_REUSEPORT_LB set. Verify that packets sent to the bound address are ++ * dropped unless they come from the connected address. ++ */ ++ATF_TC_WITHOUT_HEAD(connect_udp6); ++ATF_TC_BODY(connect_udp6, tc) ++{ ++ struct sockaddr_in6 sin6 = { ++ .sin6_family = AF_INET6, ++ .sin6_len = sizeof(sin6), ++ .sin6_addr = IN6ADDR_LOOPBACK_INIT, ++ }; ++ ssize_t n; ++ int error, len, s1, s2, s3; ++ char ch; ++ ++ s1 = socket(PF_INET6, SOCK_DGRAM, 0); ++ ATF_REQUIRE(s1 >= 0); ++ s2 = socket(PF_INET6, SOCK_DGRAM, 0); ++ ATF_REQUIRE(s2 >= 0); ++ s3 = socket(PF_INET6, SOCK_DGRAM, 0); ++ ATF_REQUIRE(s3 >= 0); ++ ++ error = setsockopt(s1, SOL_SOCKET, SO_REUSEPORT_LB, (int[]){1}, ++ sizeof(int)); ++ ATF_REQUIRE_MSG(error == 0, ++ "setsockopt(SO_REUSEPORT_LB) failed: %s", strerror(errno)); ++ error = bind(s1, (struct sockaddr *)&sin6, sizeof(sin6)); ++ ATF_REQUIRE_MSG(error == 0, "bind() failed: %s", strerror(errno)); ++ ++ error = bind(s2, (struct sockaddr *)&sin6, sizeof(sin6)); ++ ATF_REQUIRE_MSG(error == 0, "bind() failed: %s", strerror(errno)); ++ ++ error = bind(s3, (struct sockaddr *)&sin6, sizeof(sin6)); ++ ATF_REQUIRE_MSG(error == 0, "bind() failed: %s", strerror(errno)); ++ ++ /* Connect to an address not owned by s2. */ ++ error = getsockname(s3, (struct sockaddr *)&sin6, ++ (socklen_t[]){sizeof(sin6)}); ++ ATF_REQUIRE(error == 0); ++ error = connect(s1, (struct sockaddr *)&sin6, sizeof(sin6)); ++ ATF_REQUIRE_MSG(error == 0, "connect() failed: %s", strerror(errno)); ++ ++ /* Try to send a packet to s1 from s2. */ ++ error = getsockname(s1, (struct sockaddr *)&sin6, ++ (socklen_t[]){sizeof(sin6)}); ++ ATF_REQUIRE(error == 0); ++ ++ ch = 42; ++ n = sendto(s2, &ch, sizeof(ch), 0, (struct sockaddr *)&sin6, ++ sizeof(sin6)); ++ ATF_REQUIRE(n == 1); ++ ++ /* Give the packet some time to arrive. */ ++ usleep(100000); ++ ++ /* s1 is connected to s3 and shouldn't receive from s2. */ ++ error = ioctl(s1, FIONREAD, &len); ++ ATF_REQUIRE(error == 0); ++ ATF_REQUIRE_MSG(len == 0, "unexpected data available"); ++ ++ /* ... but s3 can of course send to s1. */ ++ n = sendto(s3, &ch, sizeof(ch), 0, (struct sockaddr *)&sin6, ++ sizeof(sin6)); ++ ATF_REQUIRE(n == 1); ++ usleep(100000); ++ error = ioctl(s1, FIONREAD, &len); ++ ATF_REQUIRE(error == 0); ++ ATF_REQUIRE_MSG(len == 1, "unexpected data available"); ++} ++ + ATF_TP_ADD_TCS(tp) + { + ATF_TP_ADD_TC(tp, basic_ipv4); +@@ -561,6 +707,8 @@ + ATF_TP_ADD_TC(tp, bind_without_listen); + ATF_TP_ADD_TC(tp, connect_not_bound); + ATF_TP_ADD_TC(tp, connect_bound); ++ ATF_TP_ADD_TC(tp, connect_udp); ++ ATF_TP_ADD_TC(tp, connect_udp6); + + return (atf_no_error()); + } diff --git a/website/static/security/patches/SA-25:09/netinet-15.patch.asc b/website/static/security/patches/SA-25:09/netinet-15.patch.asc new file mode 100644 index 0000000000..380b5aba55 --- /dev/null +++ b/website/static/security/patches/SA-25:09/netinet-15.patch.asc @@ -0,0 +1,16 @@ +-----BEGIN PGP SIGNATURE----- + +iQIzBAABCgAdFiEEthUnfoEIffdcgYM7bljekB8AGu8FAmj5CrkACgkQbljekB8A +Gu9urA//d3+X7bwSN9niBanoXBIRFsxr7+im0rHelA5UtPJ9OQ160IAbDdu2H9Cn +76HavCQ+bpytDZxVTWplm9lK9NskFq71ChMosgH7rqDPVcgqyNPqDuGWNbH28dBq +sBydMzY7ZkiDurLlUaesQCKopBES8I4s9DXmO9lWLXm0VI2CkiCYkf3HPZeyxJp5 +7NLXNZQWz+/Osnd1HYb/HlxEiX/DjDgnvbtD11ho2kzlO9wDy4jKwOwAgM49+UP9 +HapQh+1nrRPiX/dqZ5bAVLnztTjSVXq58V/kejpHHlbht8OxAqkGfSoeHB6emSyl +gH5fPSnBd9/IwpBUR79f0+BuHkkibhoVOrSqNl95C3VyuUNPhy/fhrChEQbET1vs +NfbsGO7pNaaTjg5zjEGXJK8x8q+S9R9Q31M1Lts5FMiKdjGIHNzWPu+ZLPMSXBdy +3iJ0OAaLLo5GJ6mefJWCTyUGbegaaxjBrJD+No12sjgXkcogvMm0VvmA7wNxnBXW +Fevs5++9hR8NU4eIhCx3mZQaQDwFOgoV6zKcPtir52jZd+txKnkw3fC01RKE86FW +opINfUTA/W4sZCG2DaSuU7USo2vMKG3m//HBvbO5eSBq+qnavFOWTvQUc16hfMxa +7+pd8VXtdEiZkwqR2Dj58Gt9D3xqoh4fbHQ+AbqvoN3lPJmnNsA= +=/zfq +-----END PGP SIGNATURE----- |