diff --git a/website/data/security/advisories.toml b/website/data/security/advisories.toml index 6558eefda7..3dee86a4c6 100644 --- a/website/data/security/advisories.toml +++ b/website/data/security/advisories.toml @@ -1,2963 +1,3015 @@ # Sort advisories by year, month and day # $FreeBSD$ +[[advisories]] +name = "FreeBSD-SA-26:49.iconv" +date = "2026-06-30" + +[[advisories]] +name = "FreeBSD-SA-26:48.compat32" +date = "2026-06-30" + +[[advisories]] +name = "FreeBSD-SA-26:47.linux" +date = "2026-06-30" + +[[advisories]] +name = "FreeBSD-SA-26:46.ktls" +date = "2026-06-30" + +[[advisories]] +name = "FreeBSD-SA-26:45.audit" +date = "2026-06-30" + +[[advisories]] +name = "FreeBSD-SA-26:44.posixshm" +date = "2026-06-30" + +[[advisories]] +name = "FreeBSD-SA-26:43.tcp" +date = "2026-06-30" + +[[advisories]] +name = "FreeBSD-SA-26:42.unlinkat" +date = "2026-06-30" + +[[advisories]] +name = "FreeBSD-SA-26:41.libalias" +date = "2026-06-30" + +[[advisories]] +name = "FreeBSD-SA-26:40.zfs" +date = "2026-06-30" + +[[advisories]] +name = "FreeBSD-SA-26:39.execve" +date = "2026-06-30" + +[[advisories]] +name = "FreeBSD-SA-26:38.jail" +date = "2026-06-30" + +[[advisories]] +name = "FreeBSD-SA-26:37.vm" +date = "2026-06-30" + [[advisories]] name = "FreeBSD-SA-26:36.ldns" date = "2026-06-09" [[advisories]] name = "FreeBSD-SA-26:35.openssl" date = "2026-06-09" [[advisories]] name = "FreeBSD-SA-26:34.vt" date = "2026-06-09" [[advisories]] name = "FreeBSD-SA-26:33.unbound" date = "2026-06-09" [[advisories]] name = "FreeBSD-SA-26:32.elf" date = "2026-06-09" [[advisories]] name = "FreeBSD-SA-26:31.arm64" date = "2026-06-09" [[advisories]] name = "FreeBSD-SA-26:30.linux" date = "2026-06-09" [[advisories]] name = "FreeBSD-SA-26:29.ip6_multicast" date = "2026-06-09" [[advisories]] name = "FreeBSD-SA-26:28.capsicum" date = "2026-06-09" [[advisories]] name = "FreeBSD-SA-26:27.sound" date = "2026-06-09" [[advisories]] name = "FreeBSD-SA-26:26.ktls" date = "2026-06-09" [[advisories]] name = "FreeBSD-SA-26:25.thr" date = "2026-06-09" [[advisories]] name = "FreeBSD-SA-26:24.cap_net" date = "2026-05-20" [[advisories]] name = "FreeBSD-SA-26:23.bsdinstall" date = "2026-05-20" [[advisories]] name = "FreeBSD-SA-26:22.libcasper" date = "2026-05-20" [[advisories]] name = "FreeBSD-SA-26:21.ptrace" date = "2026-05-20" [[advisories]] name = "FreeBSD-SA-26:20.fusefs" date = "2026-05-20" [[advisories]] name = "FreeBSD-SA-26:19.file" date = "2026-05-20" [[advisories]] name = "FreeBSD-SA-26:18.setcred" date = "2026-05-20" [[advisories]] name = "FreeBSD-SA-26:17.libnv" date = "2026-04-29" [[advisories]] name = "FreeBSD-SA-26:16.libnv" date = "2026-04-29" [[advisories]] name = "FreeBSD-SA-26:15.dhclient" date = "2026-04-29" [[advisories]] name = "FreeBSD-SA-26:14.pf" date = "2026-04-29" [[advisories]] name = "FreeBSD-SA-26:13.exec" date = "2026-04-29" [[advisories]] name = "FreeBSD-SA-26:12.dhclient" date = "2026-04-29" [[advisories]] name = "FreeBSD-SA-26:11.amd64" date = "2026-04-21" [[advisories]] name = "FreeBSD-SA-26:10.tty" date = "2026-04-21" [[advisories]] name = "FreeBSD-SA-26:09.pf" date = "2026-03-26" [[advisories]] name = "FreeBSD-SA-26:08.rpcsec_gss" date = "2026-03-26" [[advisories]] name = "FreeBSD-SA-26:07.nvmf" date = "2026-03-26" [[advisories]] name = "FreeBSD-SA-26:06.tcp" date = "2026-03-26" [[advisories]] name = "FreeBSD-SA-26:05.route" date = "2026-02-24" [[advisories]] name = "FreeBSD-SA-26:04.jail" date = "2026-02-24" [[advisories]] name = "FreeBSD-SA-26:03.blocklistd" date = "2026-02-10" [[advisories]] name = "FreeBSD-SA-26:02.jail" date = "2026-01-27" [[advisories]] name = "FreeBSD-SA-26:01.openssl" date = "2026-01-27" [[advisories]] name = "FreeBSD-SA-25:12.rtsold" date = "2025-12-16" [[advisories]] name = "FreeBSD-SA-25:11.ipfw" date = "2025-12-16" [[advisories]] name = "FreeBSD-SA-25:10.unbound" date = "2025-11-26" [[advisories]] name = "FreeBSD-SA-25:09.netinet" date = "2025-10-22" [[advisories]] name = "FreeBSD-SA-25:08.openssl" date = "2025-09-30" [[advisories]] name = "FreeBSD-SA-25:07.libarchive" date = "2025-08-08" [[advisories]] name = "FreeBSD-SA-25:06.xz" date = "2025-07-02" [[advisories]] name = "FreeBSD-SA-25:05.openssh" date = "2025-02-21" [[advisories]] name = "FreeBSD-SA-25:04.ktrace" date = "2025-01-29" [[advisories]] name = "FreeBSD-SA-25:03.etcupdate" date = "2025-01-29" [[advisories]] name = "FreeBSD-SA-25:02.fs" date = "2025-01-29" [[advisories]] name = "FreeBSD-SA-25:01.openssh" date = "2025-01-29" [[advisories]] name = "FreeBSD-SA-24:19.fetch" date = "2024-10-29" [[advisories]] name = "FreeBSD-SA-24:18.ctl" date = "2024-10-29" [[advisories]] name = "FreeBSD-SA-24:17.bhyve" date = "2024-10-29" [[advisories]] name = "FreeBSD-SA-24:16.libnv" date = "2024-09-19" [[advisories]] name = "FreeBSD-SA-24:15.bhyve" date = "2024-09-19" [[advisories]] name = "FreeBSD-SA-24:14.umtx" date = "2024-09-04" [[advisories]] name = "FreeBSD-SA-24:13.openssl" date = "2024-09-04" [[advisories]] name = "FreeBSD-SA-24:12.bhyve" date = "2024-09-04" [[advisories]] name = "FreeBSD-SA-24:11.ctl" date = "2024-09-04" [[advisories]] name = "FreeBSD-SA-24:10.bhyve" date = "2024-09-04" [[advisories]] name = "FreeBSD-SA-24:09.libnv" date = "2024-09-04" [[advisories]] name = "FreeBSD-SA-24:08.openssh" date = "2024-08-07" [[advisories]] name = "FreeBSD-SA-24:07.nfsclient" date = "2024-08-07" [[advisories]] name = "FreeBSD-SA-24:06.ktrace" date = "2024-08-07" [[advisories]] name = "FreeBSD-SA-24:05.pf" date = "2024-08-07" [[advisories]] name = "FreeBSD-SA-24:04.openssh" date = "2024-07-01" [[advisories]] name = "FreeBSD-SA-24:03.unbound" date = "2024-03-28" [[advisories]] name = "FreeBSD-SA-24:02.tty" date = "2024-02-14" [[advisories]] name = "FreeBSD-SA-24:01.bhyveload" date = "2024-02-14" [[advisories]] name = "FreeBSD-SA-23:19.openssh" date = "2023-12-19" [[advisories]] name = "FreeBSD-SA-23:18.nfsclient" date = "2023-12-12" [[advisories]] name = "FreeBSD-SA-23:17.pf" date = "2023-12-05" [[advisories]] name = "FreeBSD-SA-23:16.cap_net" date = "2023-11-08" [[advisories]] name = "FreeBSD-SA-23:15.stdio" date = "2023-11-08" [[advisories]] name = "FreeBSD-SA-23:14.smccc" date = "2023-10-03" [[advisories]] name = "FreeBSD-SA-23:13.capsicum" date = "2023-10-03" [[advisories]] name = "FreeBSD-SA-23:12.msdosfs" date = "2023-10-03" [[advisories]] name = "FreeBSD-SA-23:11.wifi" date = "2023-09-06" [[advisories]] name = "FreeBSD-SA-23:10.pf" date = "2023-09-06" [[advisories]] name = "FreeBSD-SA-23:09.pam_krb5" date = "2023-08-01" [[advisories]] name = "FreeBSD-SA-23:08.ssh" date = "2023-08-01" [[advisories]] name = "FreeBSD-SA-23:07.bhyve" date = "2023-08-01" [[advisories]] name = "FreeBSD-SA-23:06.ipv6" date = "2023-08-01" [[advisories]] name = "FreeBSD-SA-23:05.openssh" date = "2023-06-21" [[advisories]] name = "FreeBSD-SA-23:04.pam_krb5" date = "2023-06-21" [[advisories]] name = "FreeBSD-SA-23:03.openssl" date = "2023-02-16" [[advisories]] name = "FreeBSD-SA-23:02.openssh" date = "2023-02-16" [[advisories]] name = "FreeBSD-SA-23:01.geli" date = "2023-02-08" [[advisories]] name = "FreeBSD-SA-22:15.ping" date = "2022-11-29" [[advisories]] name = "FreeBSD-SA-22:14.heimdal" date = "2022-11-15" [[advisories]] name = "FreeBSD-SA-22:13.zlib" date = "2022-08-30" [[advisories]] name = "FreeBSD-SA-22:12.lib9p" date = "2022-08-09" [[advisories]] name = "FreeBSD-SA-22:11.vm" date = "2022-08-09" [[advisories]] name = "FreeBSD-SA-22:10.aio" date = "2022-08-09" [[advisories]] name = "FreeBSD-SA-22:09.elf" date = "2022-08-09" [[advisories]] name = "FreeBSD-SA-22:08.zlib" date = "2022-04-06" [[advisories]] name = "FreeBSD-SA-22:07.wifi_meshid" date = "2022-04-06" [[advisories]] name = "FreeBSD-SA-22:06.ioctl" date = "2022-04-06" [[advisories]] name = "FreeBSD-SA-22:05.bhyve" date = "2022-04-06" [[advisories]] name = "FreeBSD-SA-22:04.netmap" date = "2022-04-06" [[advisories]] name = "FreeBSD-SA-22:03.openssl" date = "2022-03-15" [[advisories]] name = "FreeBSD-SA-22:02.wifi" date = "2022-03-15" [[advisories]] name = "FreeBSD-SA-22:01.vt" date = "2022-01-11" [[advisories]] name = "FreeBSD-SA-21:17.openssl" date = "2021-08-24" [[advisories]] name = "FreeBSD-SA-21:16.openssl" date = "2021-08-24" [[advisories]] name = "FreeBSD-SA-21:15.libfetch" date = "2021-08-24" [[advisories]] name = "FreeBSD-SA-21:14.ggatec" date = "2021-08-24" [[advisories]] name = "FreeBSD-SA-21:13.bhyve" date = "2021-08-24" [[advisories]] name = "FreeBSD-SA-21:12.libradius" date = "2021-05-26" [[advisories]] name = "FreeBSD-SA-21:11.smap" date = "2021-05-26" [[advisories]] name = "FreeBSD-SA-21:10.jail_mount" date = "2021-04-06" [[advisories]] name = "FreeBSD-SA-21:09.accept_filter" date = "2021-04-06" [[advisories]] name = "FreeBSD-SA-21:08.vm" date = "2021-04-06" [[advisories]] name = "FreeBSD-SA-21:07.openssl" date = "2021-03-25" [[advisories]] name = "FreeBSD-SA-21:06.xen" date = "2021-02-24" [[advisories]] name = "FreeBSD-SA-21:05.jail_chdir" date = "2021-02-24" [[advisories]] name = "FreeBSD-SA-21:04.jail_remove" date = "2021-02-24" [[advisories]] name = "FreeBSD-SA-21:03.pam_login_access" date = "2021-02-24" [[advisories]] name = "FreeBSD-SA-21:02.xenoom" date = "2021-01-29" [[advisories]] name = "FreeBSD-SA-21:01.fsdisclosure" date = "2021-01-29" [[advisories]] name = "FreeBSD-SA-20:33.openssl" date = "2020-12-08" [[advisories]] name = "FreeBSD-SA-20:32.rtsold" date = "2020-12-01" [[advisories]] name = "FreeBSD-SA-20:31.icmp6" date = "2020-12-01" [[advisories]] name = "FreeBSD-SA-20:30.ftpd" date = "2020-09-15" [[advisories]] name = "FreeBSD-SA-20:29.bhyve_svm" date = "2020-09-15" [[advisories]] name = "FreeBSD-SA-20:28.bhyve_vmcs" date = "2020-09-15" [[advisories]] name = "FreeBSD-SA-20:27.ure" date = "2020-09-15" [[advisories]] name = "FreeBSD-SA-20:26.dhclient" date = "2020-09-02" [[advisories]] name = "FreeBSD-SA-20:25.sctp" date = "2020-09-02" [[advisories]] name = "FreeBSD-SA-20:24.ipv6" date = "2020-09-02" [[advisories]] name = "FreeBSD-SA-20:23.sendmsg" date = "2020-08-05" [[advisories]] name = "FreeBSD-SA-20:22.sqlite" date = "2020-08-05" [[advisories]] name = "FreeBSD-SA-20:21.usb_net" date = "2020-08-05" [[advisories]] name = "FreeBSD-SA-20:20.ipv6" date = "2020-07-08" [[advisories]] name = "FreeBSD-SA-20:19.unbound" date = "2020-07-08" [[advisories]] name = "FreeBSD-SA-20:18.posix_spawnp" date = "2020-07-08" [[advisories]] name = "FreeBSD-SA-20:17.usb" date = "2020-06-09" [[advisories]] name = "FreeBSD-SA-20:16.cryptodev" date = "2020-05-12" [[advisories]] name = "FreeBSD-SA-20:15.cryptodev" date = "2020-05-12" [[advisories]] name = "FreeBSD-SA-20:14.sctp" date = "2020-05-12" [[advisories]] name = "FreeBSD-SA-20:13.libalias" date = "2020-05-12" [[advisories]] name = "FreeBSD-SA-20:12.libalias" date = "2020-05-12" [[advisories]] name = "FreeBSD-SA-20:11.openssl" date = "2020-04-21" [[advisories]] name = "FreeBSD-SA-20:10.ipfw" date = "2020-04-21" [[advisories]] name = "FreeBSD-SA-20:09.ntp" date = "2020-03-19" [[advisories]] name = "FreeBSD-SA-20:08.jail" date = "2020-03-19" [[advisories]] name = "FreeBSD-SA-20:07.epair" date = "2020-03-19" [[advisories]] name = "FreeBSD-SA-20:06.if_ixl_ioctl" date = "2020-03-19" [[advisories]] name = "FreeBSD-SA-20:05.if_oce_ioctl" date = "2020-03-19" [[advisories]] name = "FreeBSD-SA-20:04.tcp" date = "2020-03-19" [[advisories]] name = "FreeBSD-SA-20:03.thrmisc" date = "2020-01-28" [[advisories]] name = "FreeBSD-SA-20:02.ipsec" date = "2020-01-28" [[advisories]] name = "FreeBSD-SA-20:01.libfetch" date = "2020-01-28" [[advisories]] name = "FreeBSD-SA-19:26.mcu" date = "2019-11-12" [[advisories]] name = "FreeBSD-SA-19:25.mcepsc" date = "2019-11-12" [[advisories]] name = "FreeBSD-SA-19:24.mqueuefs" date = "2019-08-20" [[advisories]] name = "FreeBSD-SA-19:23.midi" date = "2019-08-20" [[advisories]] name = "FreeBSD-SA-19:22.mbuf" date = "2019-08-20" [[advisories]] name = "FreeBSD-SA-19:21.bhyve" date = "2019-08-06" [[advisories]] name = "FreeBSD-SA-19:20.bsnmp" date = "2019-08-06" [[advisories]] name = "FreeBSD-SA-19:19.mldv2" date = "2019-08-06" [[advisories]] name = "FreeBSD-SA-19:18.bzip2" date = "2019-08-06" [[advisories]] name = "FreeBSD-SA-19:17.fd" date = "2019-07-24" [[advisories]] name = "FreeBSD-SA-19:16.bhyve" date = "2019-07-24" [[advisories]] name = "FreeBSD-SA-19:15.mqueuefs" date = "2019-07-24" [[advisories]] name = "FreeBSD-SA-19:14.freebsd32" date = "2019-07-24" [[advisories]] name = "FreeBSD-SA-19:13.pts" date = "2019-07-24" [[advisories]] name = "FreeBSD-SA-19:12.telnet" date = "2019-07-24" [[advisories]] name = "FreeBSD-SA-19:11.cd_ioctl" date = "2019-07-02" [[advisories]] name = "FreeBSD-SA-19:10.ufs" date = "2019-07-02" [[advisories]] name = "FreeBSD-SA-19:09.iconv" date = "2019-07-02" [[advisories]] name = "FreeBSD-SA-19:08.rack" date = "2019-06-19" [[advisories]] name = "FreeBSD-SA-19:07.mds" date = "2019-05-14" [[advisories]] name = "FreeBSD-SA-19:06.pf" date = "2019-05-14" [[advisories]] name = "FreeBSD-SA-19:05.pf" date = "2019-05-14" [[advisories]] name = "FreeBSD-SA-19:04.ntp" date = "2019-05-14" [[advisories]] name = "FreeBSD-SA-19:03.wpa" date = "2019-05-14" [[advisories]] name = "FreeBSD-SA-19:02.fd" date = "2019-02-05" [[advisories]] name = "FreeBSD-SA-19:01.syscall" date = "2019-02-05" [[advisories]] name = "FreeBSD-SA-18:15.bootpd" date = "2018-12-19" [[advisories]] name = "FreeBSD-SA-18:14.bhyve" date = "2018-12-04" [[advisories]] name = "FreeBSD-SA-18:13.nfs" date = "2018-11-27" [[advisories]] name = "FreeBSD-SA-18:12.elf" date = "2018-09-12" [[advisories]] name = "FreeBSD-SA-18:11.hostapd" date = "2018-08-14" [[advisories]] name = "FreeBSD-SA-18:10.ip" date = "2018-08-14" [[advisories]] name = "FreeBSD-SA-18:09.l1tf" date = "2018-08-14" [[advisories]] name = "FreeBSD-SA-18:08.tcp" date = "2018-08-06" [[advisories]] name = "FreeBSD-SA-18:07.lazyfpu" date = "2018-06-21" [[advisories]] name = "FreeBSD-SA-18:06.debugreg" date = "2018-05-08" [[advisories]] name = "FreeBSD-SA-18:05.ipsec" date = "2018-04-04" [[advisories]] name = "FreeBSD-SA-18:04.vt" date = "2018-04-04" [[advisories]] name = "FreeBSD-SA-18:03.speculative_execution" date = "2018-03-14" [[advisories]] name = "FreeBSD-SA-18:02.ntp" date = "2018-03-07" [[advisories]] name = "FreeBSD-SA-18:01.ipsec" date = "2018-03-07" [[advisories]] name = "FreeBSD-SA-17:12.openssl" date = "2017-12-09" [[advisories]] name = "FreeBSD-SA-17:11.openssl" date = "2017-11-29" [[advisories]] name = "FreeBSD-SA-17:10.kldstat" date = "2017-11-15" [[advisories]] name = "FreeBSD-SA-17:09.shm" date = "2017-11-15" [[advisories]] name = "FreeBSD-SA-17:08.ptrace" date = "2017-11-15" [[advisories]] name = "FreeBSD-SA-17:07.wpa" date = "2017-10-17" [[advisories]] name = "FreeBSD-SA-17:06.openssh" date = "2017-08-10" [[advisories]] name = "FreeBSD-SA-17:05.heimdal" date = "2017-07-12" [[advisories]] name = "FreeBSD-SA-17:04.ipfilter" date = "2017-04-27" [[advisories]] name = "FreeBSD-SA-17:03.ntp" date = "2017-04-12" [[advisories]] name = "FreeBSD-SA-17:02.openssl" date = "2017-02-23" [[advisories]] name = "FreeBSD-SA-17:01.openssh" date = "2017-01-11" [[advisories]] name = "FreeBSD-SA-16:39.ntp" date = "2016-12-22" [[advisories]] name = "FreeBSD-SA-16:38.bhyve" date = "2016-12-06" [[advisories]] name = "FreeBSD-SA-16:37.libc" date = "2016-12-06" [[advisories]] name = "FreeBSD-SA-16:36.telnetd" date = "2016-12-06" [[advisories]] name = "FreeBSD-SA-16:35.openssl" date = "2016-11-02" [[advisories]] name = "FreeBSD-SA-16:34.bind" date = "2016-11-02" [[advisories]] name = "FreeBSD-SA-16:33.openssh" date = "2016-11-02" [[advisories]] name = "FreeBSD-SA-16:32.bhyve" date = "2016-10-25" [[advisories]] name = "FreeBSD-SA-16:31.libarchive" date = "2016-10-10" [[advisories]] name = "FreeBSD-SA-16:30.portsnap" date = "2016-10-10" [[advisories]] name = "FreeBSD-SA-16:29.bspatch" date = "2016-10-10" [[advisories]] name = "FreeBSD-SA-16:28.bind" date = "2016-10-10" [[advisories]] name = "FreeBSD-SA-16:27.openssl" date = "2016-10-10" [[advisories]] name = "FreeBSD-SA-16:26.openssl" date = "2016-09-23" [[advisories]] name = "FreeBSD-SA-16:25.bspatch" date = "2016-07-25" [[advisories]] name = "FreeBSD-SA-16:24.ntp" date = "2016-06-04" [[advisories]] name = "FreeBSD-SA-16:23.libarchive" date = "2016-05-31" [[advisories]] name = "FreeBSD-SA-16:22.libarchive" date = "2016-05-31" [[advisories]] name = "FreeBSD-SA-16:21.43bsd" date = "2016-05-31" [[advisories]] name = "FreeBSD-SA-16:20.linux" date = "2016-05-31" [[advisories]] name = "FreeBSD-SA-16:19.sendmsg" date = "2016-05-17" [[advisories]] name = "FreeBSD-SA-16:18.atkbd" date = "2016-05-17" [[advisories]] name = "FreeBSD-SA-16:17.openssl" date = "2016-05-04" [[advisories]] name = "FreeBSD-SA-16:16.ntp" date = "2016-04-29" [[advisories]] name = "FreeBSD-SA-16:15.sysarch" date = "2016-03-16" [[advisories]] name = "FreeBSD-SA-16:14.openssh" date = "2016-03-16" [[advisories]] name = "FreeBSD-SA-16:13.bind" date = "2016-03-10" [[advisories]] name = "FreeBSD-SA-16:12.openssl" date = "2016-03-10" [[advisories]] name = "FreeBSD-SA-16:11.openssl" date = "2016-01-30" [[advisories]] name = "FreeBSD-SA-16:10.linux" date = "2016-01-27" [[advisories]] name = "FreeBSD-SA-16:09.ntp" date = "2016-01-27" [[advisories]] name = "FreeBSD-SA-16:08.bind" date = "2016-01-27" [[advisories]] name = "FreeBSD-SA-16:07.openssh" date = "2016-01-14" [[advisories]] name = "FreeBSD-SA-16:06.bsnmpd" date = "2016-01-14" [[advisories]] name = "FreeBSD-SA-16:05.tcp" date = "2016-01-14" [[advisories]] name = "FreeBSD-SA-16:04.linux" date = "2016-01-14" [[advisories]] name = "FreeBSD-SA-16:03.linux" date = "2016-01-14" [[advisories]] name = "FreeBSD-SA-16:02.ntp" date = "2016-01-14" [[advisories]] name = "FreeBSD-SA-16:01.sctp" date = "2016-01-14" [[advisories]] name = "FreeBSD-SA-15:27.bind" date = "2015-12-16" [[advisories]] name = "FreeBSD-SA-15:26.openssl" date = "2015-12-06" [[advisories]] name = "FreeBSD-SA-15:25.ntp" date = "2015-10-26" [[advisories]] name = "FreeBSD-SA-15:24.rpcbind" date = "2015-09-29" [[advisories]] name = "FreeBSD-SA-15:23.bind" date = "2015-09-02" [[advisories]] name = "FreeBSD-SA-15:22.openssh" date = "2015-08-25" [[advisories]] name = "FreeBSD-SA-15:21.amd64" date = "2015-08-25" [[advisories]] name = "FreeBSD-SA-15:20.expat" date = "2015-08-18" [[advisories]] name = "FreeBSD-SA-15:19.routed" date = "2015-08-05" [[advisories]] name = "FreeBSD-SA-15:18.bsdpatch" date = "2015-08-05" [[advisories]] name = "FreeBSD-SA-15:17.bind" date = "2015-07-28" [[advisories]] name = "FreeBSD-SA-15:16.openssh" date = "2015-07-28" [[advisories]] name = "FreeBSD-SA-15:15.tcp" date = "2015-07-28" [[advisories]] name = "FreeBSD-SA-15:14.bsdpatch" date = "2015-07-28" [[advisories]] name = "FreeBSD-SA-15:13.tcp" date = "2015-07-21" [[advisories]] name = "FreeBSD-SA-15:12.openssl" date = "2015-07-09" [[advisories]] name = "FreeBSD-SA-15:11.bind" date = "2015-07-07" [[advisories]] name = "FreeBSD-SA-15:10.openssl" date = "2015-06-12" [[advisories]] name = "FreeBSD-SA-15:09.ipv6" date = "2015-04-07" [[advisories]] name = "FreeBSD-SA-15:08.bsdinstall" date = "2015-04-07" [[advisories]] name = "FreeBSD-SA-15:07.ntp" date = "2015-04-07" [[advisories]] name = "FreeBSD-SA-15:06.openssl" date = "2015-03-19" [[advisories]] name = "FreeBSD-SA-15:05.bind" date = "2015-02-25" [[advisories]] name = "FreeBSD-SA-15:04.igmp" date = "2015-02-25" [[advisories]] name = "FreeBSD-SA-15:03.sctp" date = "2015-01-27" [[advisories]] name = "FreeBSD-SA-15:02.kmem" date = "2015-01-27" [[advisories]] name = "FreeBSD-SA-15:01.openssl" date = "2015-01-14" [[advisories]] name = "FreeBSD-SA-14:31.ntp" date = "2014-12-23" [[advisories]] name = "FreeBSD-SA-14:30.unbound" date = "2014-12-17" [[advisories]] name = "FreeBSD-SA-14:29.bind" date = "2014-12-10" [[advisories]] name = "FreeBSD-SA-14:28.file" date = "2014-12-10" [[advisories]] name = "FreeBSD-SA-14:27.stdio" date = "2014-12-10" [[advisories]] name = "FreeBSD-SA-14:26.ftp" date = "2014-11-04" [[advisories]] name = "FreeBSD-SA-14:25.setlogin" date = "2014-11-04" [[advisories]] name = "FreeBSD-SA-14:24.sshd" date = "2014-11-04" [[advisories]] name = "FreeBSD-SA-14:23.openssl" date = "2014-10-21" [[advisories]] name = "FreeBSD-SA-14:22.namei" date = "2014-10-21" [[advisories]] name = "FreeBSD-SA-14:21.routed" date = "2014-10-21" [[advisories]] name = "FreeBSD-SA-14:20.rtsold" date = "2014-10-21" [[advisories]] name = "FreeBSD-SA-14:19.tcp" date = "2014-09-16" [[advisories]] name = "FreeBSD-SA-14:18.openssl" date = "2014-09-09" [[advisories]] name = "FreeBSD-SA-14:17.kmem" date = "2014-07-08" [[advisories]] name = "FreeBSD-SA-14:16.file" date = "2014-06-24" [[advisories]] name = "FreeBSD-SA-14:15.iconv" date = "2014-06-24" [[advisories]] name = "FreeBSD-SA-14:14.openssl" date = "2014-06-05" [[advisories]] name = "FreeBSD-SA-14:13.pam" date = "2014-06-03" [[advisories]] name = "FreeBSD-SA-14:12.ktrace" date = "2014-06-03" [[advisories]] name = "FreeBSD-SA-14:11.sendmail" date = "2014-06-03" [[advisories]] name = "FreeBSD-SA-14:10.openssl" date = "2014-05-13" [[advisories]] name = "FreeBSD-SA-14:09.openssl" date = "2014-04-30" [[advisories]] name = "FreeBSD-SA-14:08.tcp" date = "2014-04-30" [[advisories]] name = "FreeBSD-SA-14:07.devfs" date = "2014-04-30" [[advisories]] name = "FreeBSD-SA-14:06.openssl" date = "2014-04-08" [[advisories]] name = "FreeBSD-SA-14:05.nfsserver" date = "2014-04-08" [[advisories]] name = "FreeBSD-SA-14:04.bind" date = "2014-01-14" [[advisories]] name = "FreeBSD-SA-14:03.openssl" date = "2014-01-14" [[advisories]] name = "FreeBSD-SA-14:02.ntpd" date = "2014-01-14" [[advisories]] name = "FreeBSD-SA-14:01.bsnmpd" date = "2014-01-14" [[advisories]] name = "FreeBSD-SA-13:14.openssh" date = "2013-11-19" [[advisories]] name = "FreeBSD-SA-13:13.nullfs" date = "2013-09-10" [[advisories]] name = "FreeBSD-SA-13:12.ifioctl" date = "2013-09-10" [[advisories]] name = "FreeBSD-SA-13:11.sendfile" date = "2013-09-10" [[advisories]] name = "FreeBSD-SA-13:10.sctp" date = "2013-08-22" [[advisories]] name = "FreeBSD-SA-13:09.ip_multicast" date = "2013-08-22" [[advisories]] name = "FreeBSD-SA-13:08.nfsserver" date = "2013-07-26" [[advisories]] name = "FreeBSD-SA-13:07.bind" date = "2013-07-26" [[advisories]] name = "FreeBSD-SA-13:06.mmap" date = "2013-06-18" [[advisories]] name = "FreeBSD-SA-13:05.nfsserver" date = "2013-04-29" [[advisories]] name = "FreeBSD-SA-13:04.bind" date = "2013-04-02" [[advisories]] name = "FreeBSD-SA-13:03.openssl" date = "2013-04-02" [[advisories]] name = "FreeBSD-SA-13:02.libc" date = "2013-02-19" [[advisories]] name = "FreeBSD-SA-13:01.bind" date = "2013-02-19" [[advisories]] name = "FreeBSD-SA-12:08.linux" date = "2012-11-22" [[advisories]] name = "FreeBSD-SA-12:07.hostapd" date = "2012-11-22" [[advisories]] name = "FreeBSD-SA-12:06.bind" date = "2012-11-22" [[advisories]] name = "FreeBSD-SA-12:05.bind" date = "2012-08-06" [[advisories]] name = "FreeBSD-SA-12:04.sysret" date = "2012-06-12" [[advisories]] name = "FreeBSD-SA-12:03.bind" date = "2012-06-12" [[advisories]] name = "FreeBSD-SA-12:02.crypt" date = "2012-05-30" [[advisories]] name = "FreeBSD-SA-12:01.openssl" date = "2012-05-30" [[advisories]] name = "FreeBSD-SA-11:10.pam" date = "2011-12-23" [[advisories]] name = "FreeBSD-SA-11:09.pam_ssh" date = "2011-12-23" [[advisories]] name = "FreeBSD-SA-11:08.telnetd" date = "2011-12-23" [[advisories]] name = "FreeBSD-SA-11:07.chroot" date = "2011-12-23" [[advisories]] name = "FreeBSD-SA-11:06.bind" date = "2011-12-23" [[advisories]] name = "FreeBSD-SA-11:05.unix" date = "2011-09-28" [[advisories]] name = "FreeBSD-SA-11:04.compress" date = "2011-09-28" [[advisories]] name = "FreeBSD-SA-11:03.bind" date = "2011-09-28" [[advisories]] name = "FreeBSD-SA-11:02.bind" date = "2011-05-28" [[advisories]] name = "FreeBSD-SA-11:01.mountd" date = "2011-04-20" [[advisories]] name = "FreeBSD-SA-10:10.openssl" date = "2010-11-29" [[advisories]] name = "FreeBSD-SA-10:09.pseudofs" date = "2010-11-10" [[advisories]] name = "FreeBSD-SA-10:08.bzip2" date = "2010-09-20" [[advisories]] name = "FreeBSD-SA-10:07.mbuf" date = "2010-07-13" [[advisories]] name = "FreeBSD-SA-10:06.nfsclient" date = "2010-05-27" [[advisories]] name = "FreeBSD-SA-10:05.opie" date = "2010-05-27" [[advisories]] name = "FreeBSD-SA-10:04.jail" date = "2010-05-27" [[advisories]] name = "FreeBSD-SA-10:03.zfs" date = "2010-01-06" [[advisories]] name = "FreeBSD-SA-10:02.ntpd" date = "2010-01-06" [[advisories]] name = "FreeBSD-SA-10:01.bind" date = "2010-01-06" [[advisories]] name = "FreeBSD-SA-09:17.freebsd-update" date = "2009-12-03" [[advisories]] name = "FreeBSD-SA-09:16.rtld" date = "2009-12-03" [[advisories]] name = "FreeBSD-SA-09:15.ssl" date = "2009-12-03" [[advisories]] name = "FreeBSD-SA-09:14.devfs" date = "2009-10-02" [[advisories]] name = "FreeBSD-SA-09:13.pipe" date = "2009-10-02" [[advisories]] name = "FreeBSD-SA-09:12.bind" date = "2009-07-29" [[advisories]] name = "FreeBSD-SA-09:11.ntpd" date = "2009-06-10" [[advisories]] name = "FreeBSD-SA-09:10.ipv6" date = "2009-06-10" [[advisories]] name = "FreeBSD-SA-09:09.pipe" date = "2009-06-10" [[advisories]] name = "FreeBSD-SA-09:08.openssl" date = "2009-04-22" [[advisories]] name = "FreeBSD-SA-09:07.libc" date = "2009-04-22" [[advisories]] name = "FreeBSD-SA-09:06.ktimer" date = "2009-03-23" [[advisories]] name = "FreeBSD-SA-09:05.telnetd" date = "2009-02-16" [[advisories]] name = "FreeBSD-SA-09:04.bind" date = "2009-01-13" [[advisories]] name = "FreeBSD-SA-09:03.ntpd" date = "2009-01-13" [[advisories]] name = "FreeBSD-SA-09:02.openssl" date = "2009-01-07" [[advisories]] name = "FreeBSD-SA-09:01.lukemftpd" date = "2009-01-07" [[advisories]] name = "FreeBSD-SA-08:13.protosw" date = "2008-12-23" [[advisories]] name = "FreeBSD-SA-08:12.ftpd" date = "2008-12-23" [[advisories]] name = "FreeBSD-SA-08:11.arc4random" date = "2008-11-24" [[advisories]] name = "FreeBSD-SA-08:10.nd6" date = "2008-10-02" [[advisories]] name = "FreeBSD-SA-08:09.icmp6" date = "2008-09-03" [[advisories]] name = "FreeBSD-SA-08:08.nmount" date = "2008-09-03" [[advisories]] name = "FreeBSD-SA-08:07.amd64" date = "2008-09-03" [[advisories]] name = "FreeBSD-SA-08:06.bind" date = "2008-07-13" [[advisories]] name = "FreeBSD-SA-08:05.openssh" date = "2008-04-17" [[advisories]] name = "FreeBSD-SA-08:04.ipsec" date = "2008-02-14" [[advisories]] name = "FreeBSD-SA-08:03.sendfile" date = "2008-02-14" [[advisories]] name = "FreeBSD-SA-08:02.libc" date = "2008-01-14" [[advisories]] name = "FreeBSD-SA-08:01.pty" date = "2008-01-14" [[advisories]] name = "FreeBSD-SA-07:10.gtar" date = "2007-11-29" [[advisories]] name = "FreeBSD-SA-07:09.random" date = "2007-11-29" [[advisories]] name = "FreeBSD-SA-07:08.openssl" date = "2007-10-03" [[advisories]] name = "FreeBSD-SA-07:07.bind" date = "2007-08-01" [[advisories]] name = "FreeBSD-SA-07:06.tcpdump" date = "2007-08-01" [[advisories]] name = "FreeBSD-SA-07:05.libarchive" date = "2007-07-12" [[advisories]] name = "FreeBSD-SA-07:04.file" date = "2007-05-23" [[advisories]] name = "FreeBSD-SA-07:03.ipv6" date = "2007-04-26" [[advisories]] name = "FreeBSD-SA-07:02.bind" date = "2007-02-09" [[advisories]] name = "FreeBSD-SA-07:01.jail" date = "2007-01-11" [[advisories]] name = "FreeBSD-SA-06:26.gtar" date = "2006-12-06" [[advisories]] name = "FreeBSD-SA-06:25.kmem" date = "2006-12-06" [[advisories]] name = "FreeBSD-SA-06:24.libarchive" date = "2006-11-08" [[advisories]] name = "FreeBSD-SA-06:22.openssh" date = "2006-09-30" [[advisories]] name = "FreeBSD-SA-06:23.openssl" date = "2006-09-28" [[advisories]] name = "FreeBSD-SA-06:21.gzip" date = "2006-09-19" [[advisories]] name = "FreeBSD-SA-06:20.bind" date = "2006-09-06" [[advisories]] name = "FreeBSD-SA-06:19.openssl" date = "2006-09-06" [[advisories]] name = "FreeBSD-SA-06:18.ppp" date = "2006-08-23" [[advisories]] name = "FreeBSD-SA-06:17.sendmail" date = "2006-06-14" [[advisories]] name = "FreeBSD-SA-06:16.smbfs" date = "2006-05-31" [[advisories]] name = "FreeBSD-SA-06:15.ypserv" date = "2006-05-31" [[advisories]] name = "FreeBSD-SA-06:14.fpu" date = "2006-04-19" [[advisories]] name = "FreeBSD-SA-06:13.sendmail" date = "2006-03-22" [[advisories]] name = "FreeBSD-SA-06:12.opie" date = "2006-03-22" [[advisories]] name = "FreeBSD-SA-06:11.ipsec" date = "2006-03-22" [[advisories]] name = "FreeBSD-SA-06:10.nfs" date = "2006-03-01" [[advisories]] name = "FreeBSD-SA-06:09.openssh" date = "2006-03-01" [[advisories]] name = "FreeBSD-SA-06:08.sack" date = "2006-02-01" [[advisories]] name = "FreeBSD-SA-06:07.pf" date = "2006-01-25" [[advisories]] name = "FreeBSD-SA-06:06.kmem" date = "2006-01-25" [[advisories]] name = "FreeBSD-SA-06:05.80211" date = "2006-01-18" [[advisories]] name = "FreeBSD-SA-06:04.ipfw" date = "2006-01-11" [[advisories]] name = "FreeBSD-SA-06:03.cpio" date = "2006-01-11" [[advisories]] name = "FreeBSD-SA-06:02.ee" date = "2006-01-11" [[advisories]] name = "FreeBSD-SA-06:01.texindex" date = "2006-01-11" [[advisories]] name = "FreeBSD-SA-05:21.openssl" date = "2005-10-11" [[advisories]] name = "FreeBSD-SA-05:20.cvsbug" date = "2005-09-07" [[advisories]] name = "FreeBSD-SA-05:19.ipsec" date = "2005-07-27" [[advisories]] name = "FreeBSD-SA-05:18.zlib" date = "2005-07-27" [[advisories]] name = "FreeBSD-SA-05:17.devfs" date = "2005-07-20" [[advisories]] name = "FreeBSD-SA-05:16.zlib" date = "2005-07-06" [[advisories]] name = "FreeBSD-SA-05:15.tcp" date = "2005-06-29" [[advisories]] name = "FreeBSD-SA-05:14.bzip2" date = "2005-06-29" [[advisories]] name = "FreeBSD-SA-05:13.ipfw" date = "2005-06-29" [[advisories]] name = "FreeBSD-SA-05:12.bind9" date = "2005-06-09" [[advisories]] name = "FreeBSD-SA-05:11.gzip" date = "2005-06-09" [[advisories]] name = "FreeBSD-SA-05:10.tcpdump" date = "2005-06-09" [[advisories]] name = "FreeBSD-SA-05:09.htt" date = "2005-05-13" [[advisories]] name = "FreeBSD-SA-05:08.kmem" date = "2005-05-06" [[advisories]] name = "FreeBSD-SA-05:07.ldt" date = "2005-05-06" [[advisories]] name = "FreeBSD-SA-05:06.iir" date = "2005-05-06" [[advisories]] name = "FreeBSD-SA-05:05.cvs" date = "2005-04-22" [[advisories]] name = "FreeBSD-SA-05:04.ifconf" date = "2005-04-15" [[advisories]] name = "FreeBSD-SA-05:03.amd64" date = "2005-04-06" [[advisories]] name = "FreeBSD-SA-05:02.sendfile" date = "2005-04-04" [[advisories]] name = "FreeBSD-SA-05:01.telnet" date = "2005-03-28" [[advisories]] name = "FreeBSD-SA-04:17.procfs" date = "2004-12-01" [[advisories]] name = "FreeBSD-SA-04:16.fetch" date = "2004-11-18" [[advisories]] name = "FreeBSD-SA-04:15.syscons" date = "2004-10-04" [[advisories]] name = "FreeBSD-SA-04:14.cvs" date = "2004-09-19" [[advisories]] name = "FreeBSD-SA-04:13.linux" date = "2004-06-30" [[advisories]] name = "FreeBSD-SA-04:12.jailroute" date = "2004-06-07" [[advisories]] name = "FreeBSD-SA-04:11.msync" date = "2004-05-19" [[advisories]] name = "FreeBSD-SA-04:10.cvs" date = "2004-05-19" [[advisories]] name = "FreeBSD-SA-04:09.kadmind" date = "2004-05-05" [[advisories]] name = "FreeBSD-SA-04:08.heimdal" date = "2004-05-05" [[advisories]] name = "FreeBSD-SA-04:07.cvs" date = "2004-04-15" [[advisories]] name = "FreeBSD-SA-04:06.ipv6" date = "2004-03-29" [[advisories]] name = "FreeBSD-SA-04:05.openssl" date = "2004-03-17" [[advisories]] name = "FreeBSD-SA-04:04.tcp" date = "2004-03-02" [[advisories]] name = "FreeBSD-SA-04:03.jail" date = "2004-02-25" [[advisories]] name = "FreeBSD-SA-04:02.shmat" date = "2004-02-05" [[advisories]] name = "FreeBSD-SA-04:01.mksnap_ffs" date = "2004-01-30" [[advisories]] name = "FreeBSD-SA-03:19.bind" date = "2003-11-28" [[advisories]] name = "FreeBSD-SA-03:15.openssh" date = "2003-10-05" [[advisories]] name = "FreeBSD-SA-03:18.openssl" date = "2003-10-03" [[advisories]] name = "FreeBSD-SA-03:17.procfs" date = "2003-10-03" [[advisories]] name = "FreeBSD-SA-03:16.filedesc" date = "2003-10-02" [[advisories]] name = "FreeBSD-SA-03:14.arp" date = "2003-09-23" [[advisories]] name = "FreeBSD-SA-03:13.sendmail" date = "2003-09-17" [[advisories]] name = "FreeBSD-SA-03:12.openssh" date = "2003-09-16" [[advisories]] name = "FreeBSD-SA-03:11.sendmail" date = "2003-08-26" link = "http://home.jp.freebsd.org/cgi-bin/showmail/announce-jp/1170" [[advisories]] name = "FreeBSD-SA-03:10.ibcs2" date = "2003-08-10" link = "http://home.jp.freebsd.org/cgi-bin/showmail/announce-jp/1164" [[advisories]] name = "FreeBSD-SA-03:09.signal" date = "2003-08-10" link = "http://home.jp.freebsd.org/cgi-bin/showmail/announce-jp/1163" [[advisories]] name = "FreeBSD-SA-03:08.realpath" date = "2003-08-03" link = "http://home.jp.freebsd.org/cgi-bin/showmail/announce-jp/1158" [[advisories]] name = "FreeBSD-SN-03:02" date = "2003-04-08" [[advisories]] name = "FreeBSD-SN-03:01" date = "2003-04-07" [[advisories]] name = "FreeBSD-SA-03:07.sendmail" date = "2003-03-30" link = "http://home.jp.freebsd.org/cgi-bin/showmail/announce-jp/1122" [[advisories]] name = "FreeBSD-SA-03:06.openssl" date = "2003-03-21" link = "http://home.jp.freebsd.org/cgi-bin/showmail/announce-jp/1118" [[advisories]] name = "FreeBSD-SA-03:05.xdr" date = "2003-03-20" link = "http://home.jp.freebsd.org/cgi-bin/showmail/announce-jp/1117" [[advisories]] name = "FreeBSD-SA-03:04.sendmail" date = "2003-03-03" link = "http://home.jp.freebsd.org/cgi-bin/showmail/announce-jp/1112" [[advisories]] name = "FreeBSD-SA-03:03.syncookies" date = "2003-02-24" link = "http://home.jp.freebsd.org/cgi-bin/showmail/announce-jp/1106" [[advisories]] name = "FreeBSD-SA-03:02.openssl" date = "2003-02-24" link = "http://home.jp.freebsd.org/cgi-bin/showmail/announce-jp/1105" [[advisories]] name = "FreeBSD-SA-03:01.cvs" date = "2003-02-04" link = "http://home.jp.freebsd.org/cgi-bin/showmail/announce-jp/1100" [[advisories]] name = "FreeBSD-SA-02:44.filedesc" date = "2003-01-07" link = "http://home.jp.freebsd.org/cgi-bin/showmail/announce-jp/1090" [[advisories]] name = "FreeBSD-SA-02:43.bind" date = "2002-11-15" link = "http://home.jp.freebsd.org/cgi-bin/showmail/announce-jp/1084" [[advisories]] name = "FreeBSD-SA-02:41.smrsh" date = "2002-11-15" link = "http://home.jp.freebsd.org/cgi-bin/showmail/announce-jp/1082" [[advisories]] name = "FreeBSD-SA-02:42.resolv" date = "2002-11-12" link = "http://home.jp.freebsd.org/cgi-bin/showmail/announce-jp/1083" [[advisories]] name = "FreeBSD-SA-02:40.kadmind" date = "2002-11-12" link = "http://home.jp.freebsd.org/cgi-bin/showmail/announce-jp/1081" [[advisories]] name = "FreeBSD-SN-02:06" date = "2002-10-10" [[advisories]] name = "FreeBSD-SA-02:39.libkvm" date = "2002-09-16" link = "http://home.jp.freebsd.org/cgi-bin/showmail/announce-jp/1051" [[advisories]] name = "FreeBSD-SN-02:05" date = "2002-08-28" [[advisories]] name = "FreeBSD-SA-02:38.signed-error" date = "2002-08-19" link = "http://home.jp.freebsd.org/cgi-bin/showmail/announce-jp/1041" [[advisories]] name = "FreeBSD-SA-02:37.kqueue" date = "2002-08-05" link = "http://home.jp.freebsd.org/cgi-bin/showmail/announce-jp/1033" [[advisories]] name = "FreeBSD-SA-02:36.nfs" date = "2002-08-05" link = "http://home.jp.freebsd.org/cgi-bin/showmail/announce-jp/1032" [[advisories]] name = "FreeBSD-SA-02:35.ffs" date = "2002-08-05" link = "http://home.jp.freebsd.org/cgi-bin/showmail/announce-jp/1031" [[advisories]] name = "FreeBSD-SA-02:33.openssl" date = "2002-08-05" link = "http://home.jp.freebsd.org/cgi-bin/showmail/announce-jp/1023" [[advisories]] name = "FreeBSD-SA-02:34.rpc" date = "2002-08-01" link = "http://home.jp.freebsd.org/cgi-bin/showmail/announce-jp/1024" [[advisories]] name = "FreeBSD-SA-02:32.pppd" date = "2002-07-31" link = "http://home.jp.freebsd.org/cgi-bin/showmail/announce-jp/1022" [[advisories]] name = "FreeBSD-SA-02:31.openssh" date = "2002-07-15" [[advisories]] name = "FreeBSD-SA-02:30.ktrace" date = "2002-07-12" [[advisories]] name = "FreeBSD-SA-02:29.tcpdump" date = "2002-07-12" [[advisories]] name = "FreeBSD-SA-02:28.resolv" date = "2002-06-26" [[advisories]] name = "FreeBSD-SN-02:04" date = "2002-06-19" [[advisories]] name = "FreeBSD-SA-02:27.rc" date = "2002-05-29" [[advisories]] name = "FreeBSD-SA-02:26.accept" date = "2002-05-29" [[advisories]] name = "FreeBSD-SN-02:03" date = "2002-05-28" [[advisories]] name = "FreeBSD-SA-02:25.bzip2" date = "2002-05-20" [[advisories]] name = "FreeBSD-SA-02:24.k5su" date = "2002-05-20" [[advisories]] name = "FreeBSD-SN-02:02" date = "2002-05-13" [[advisories]] name = "FreeBSD-SA-02:23.stdio" date = "2002-04-22" link = "http://home.jp.freebsd.org/cgi-bin/showmail/announce-jp/1021" [[advisories]] name = "FreeBSD-SA-02:22.mmap" date = "2002-04-18" [[advisories]] name = "FreeBSD-SA-02:21.tcpip" date = "2002-04-17" link = "http://home.jp.freebsd.org/cgi-bin/showmail/announce-jp/980" [[advisories]] name = "FreeBSD-SA-02:20.syncache" date = "2002-04-16" link = "http://home.jp.freebsd.org/cgi-bin/showmail/announce-jp/979" [[advisories]] name = "FreeBSD-SN-02:01" date = "2002-03-30" [[advisories]] name = "FreeBSD-SA-02:19.squid" date = "2002-03-26" link = "http://home.jp.freebsd.org/cgi-bin/showmail/announce-jp/960" [[advisories]] name = "FreeBSD-SA-02:18.zlib" date = "2002-03-18" link = "http://home.jp.freebsd.org/cgi-bin/showmail/announce-jp/978" [[advisories]] name = "FreeBSD-SA-02:17.mod_frontpage" date = "2002-03-12" link = "http://home.jp.freebsd.org/cgi-bin/showmail/announce-jp/954" [[advisories]] name = "FreeBSD-SA-02:16.netscape" date = "2002-03-12" link = "http://home.jp.freebsd.org/cgi-bin/showmail/announce-jp/953" [[advisories]] name = "FreeBSD-SA-02:15.cyrus-sasl" date = "2002-03-12" link = "http://home.jp.freebsd.org/cgi-bin/showmail/announce-jp/952" [[advisories]] name = "FreeBSD-SA-02:14.pam-pgsql" date = "2002-03-12" link = "http://home.jp.freebsd.org/cgi-bin/showmail/announce-jp/951" [[advisories]] name = "FreeBSD-SA-02:13.openssh" date = "2002-03-07" link = "http://home.jp.freebsd.org/cgi-bin/showmail/announce-jp/945" [[advisories]] name = "FreeBSD-SA-02:12.squid" date = "2002-02-21" link = "http://home.jp.freebsd.org/cgi-bin/showmail/announce-jp/938" [[advisories]] name = "FreeBSD-SA-02:11.snmp" date = "2002-02-12" link = "http://home.jp.freebsd.org/cgi-bin/showmail/announce-jp/936" [[advisories]] name = "FreeBSD-SA-02:10.rsync" date = "2002-02-06" link = "http://home.jp.freebsd.org/cgi-bin/showmail/announce-jp/928" [[advisories]] name = "FreeBSD-SA-02:09.fstatfs" date = "2002-02-06" link = "http://home.jp.freebsd.org/cgi-bin/showmail/announce-jp/927" [[advisories]] name = "FreeBSD-SA-02:08.exec" date = "2002-01-24" link = "http://home.jp.freebsd.org/cgi-bin/showmail/announce-jp/923" [[advisories]] name = "FreeBSD-SA-02:07.k5su" date = "2002-01-18" link = "http://home.jp.freebsd.org/cgi-bin/showmail/announce-jp/912" [[advisories]] name = "FreeBSD-SA-02:06.sudo" date = "2002-01-16" link = "http://home.jp.freebsd.org/cgi-bin/showmail/announce-jp/909" [[advisories]] name = "FreeBSD-SA-02:05.pine" date = "2002-01-04" link = "http://home.jp.freebsd.org/cgi-bin/showmail/announce-jp/894" [[advisories]] name = "FreeBSD-SA-02:04.mutt" date = "2002-01-04" link = "http://home.jp.freebsd.org/cgi-bin/showmail/announce-jp/893" [[advisories]] name = "FreeBSD-SA-02:03.mod_auth_pgsql" date = "2002-01-04" link = "http://home.jp.freebsd.org/cgi-bin/showmail/announce-jp/892" [[advisories]] name = "FreeBSD-SA-02:02.pw" date = "2002-01-04" link = "http://home.jp.freebsd.org/cgi-bin/showmail/announce-jp/891" [[advisories]] name = "FreeBSD-SA-02:01.pkg_add" date = "2002-01-04" link = "http://home.jp.freebsd.org/cgi-bin/showmail/announce-jp/898" [[advisories]] name = "FreeBSD-SA-01:64.wu-ftpd" date = "2001-12-04" link = "http://home.jp.freebsd.org/cgi-bin/showmail/announce-jp/870" [[advisories]] name = "FreeBSD-SA-01:63.openssh" date = "2001-12-02" link = "http://home.jp.freebsd.org/cgi-bin/showmail/announce-jp/871" [[advisories]] name = "FreeBSD-SA-01:62.uucp" date = "2001-10-08" [[advisories]] name = "FreeBSD-SA-01:61.squid" date = "2001-10-08" [[advisories]] name = "FreeBSD-SA-01:60.procmail" date = "2001-09-24" [[advisories]] name = "FreeBSD-SA-01:59.rmuser" date = "2001-09-04" [[advisories]] name = "FreeBSD-SA-01:58.lpd" date = "2001-08-30" [[advisories]] name = "FreeBSD-SA-01:57.sendmail" date = "2001-08-27" [[advisories]] name = "FreeBSD-SA-01:56.tcp_wrappers" date = "2001-08-23" [[advisories]] name = "FreeBSD-SA-01:55.procfs" date = "2001-08-21" [[advisories]] name = "FreeBSD-SA-01:54.ports-telnetd" date = "2001-08-20" [[advisories]] name = "FreeBSD-SA-01:53.ipfw" date = "2001-08-17" [[advisories]] name = "FreeBSD-SA-01:52.fragment" date = "2001-08-06" [[advisories]] name = "FreeBSD-SA-01:51.openssl" date = "2001-07-30" [[advisories]] name = "FreeBSD-SA-01:50.windowmaker" date = "2001-07-27" [[advisories]] name = "FreeBSD-SA-01:49.telnetd" date = "2001-07-23" [[advisories]] name = "FreeBSD-SA-01:48.tcpdump" date = "2001-07-17" [[advisories]] name = "FreeBSD-SA-01:47.xinetd" date = "2001-07-10" [[advisories]] name = "FreeBSD-SA-01:46.w3m" date = "2001-07-10" [[advisories]] name = "FreeBSD-SA-01:45.samba" date = "2001-07-10" [[advisories]] name = "FreeBSD-SA-01:44.gnupg" date = "2001-07-10" [[advisories]] name = "FreeBSD-SA-01:43.fetchmail" date = "2001-07-10" [[advisories]] name = "FreeBSD-SA-01:42.signal" date = "2001-07-10" [[advisories]] name = "FreeBSD-SA-01:41.hanterm" date = "2001-07-09" [[advisories]] name = "FreeBSD-SA-01:40.fts" date = "2001-06-04" [[advisories]] name = "FreeBSD-SA-01:39.tcp-isn" date = "2001-05-02" [[advisories]] name = "FreeBSD-SA-01:38.sudo" date = "2001-04-23" [[advisories]] name = "FreeBSD-SA-01:37.slrn" date = "2001-04-23" [[advisories]] name = "FreeBSD-SA-01:36.samba" date = "2001-04-23" [[advisories]] name = "FreeBSD-SA-01:35.licq" date = "2001-04-23" [[advisories]] name = "FreeBSD-SA-01:34.hylafax" date = "2001-04-23" [[advisories]] name = "FreeBSD-SA-01:33.ftpd-glob" date = "2001-04-17" [[advisories]] name = "FreeBSD-SA-01:32.ipfilter" date = "2001-04-16" [[advisories]] name = "FreeBSD-SA-01:31.ntpd" date = "2001-04-06" [[advisories]] name = "FreeBSD-SA-01:30.ufs-ext2fs" date = "2001-03-22" link = "http://home.jp.freebsd.org/cgi-bin/showmail/announce-jp/738" [[advisories]] name = "FreeBSD-SA-01:29.rwhod" date = "2001-03-12" link = "http://home.jp.freebsd.org/cgi-bin/showmail/announce-jp/732" [[advisories]] name = "FreeBSD-SA-01:28.timed" date = "2001-03-12" link = "http://home.jp.freebsd.org/cgi-bin/showmail/announce-jp/731" [[advisories]] name = "FreeBSD-SA-01:27.cfengine" date = "2001-03-12" link = "http://home.jp.freebsd.org/cgi-bin/showmail/announce-jp/730" [[advisories]] name = "FreeBSD-SA-01:26.interbase" date = "2001-03-12" link = "http://home.jp.freebsd.org/cgi-bin/showmail/announce-jp/729" [[advisories]] name = "FreeBSD-SA-01:23.icecast" date = "2001-03-12" link = "http://home.jp.freebsd.org/cgi-bin/showmail/announce-jp/728" [[advisories]] name = "FreeBSD-SA-01:25.kerberosIV" date = "2001-02-14" link = "http://home.jp.freebsd.org/cgi-bin/showmail/announce-jp/716" [[advisories]] name = "FreeBSD-SA-01:24.ssh" date = "2001-02-12" link = "http://home.jp.freebsd.org/cgi-bin/showmail/announce-jp/715" [[advisories]] name = "FreeBSD-SA-01:22.dc20ctrl" date = "2001-02-07" link = "http://home.jp.freebsd.org/cgi-bin/showmail/announce-jp/714" [[advisories]] name = "FreeBSD-SA-01:21.ja-elvis" date = "2001-02-07" link = "http://home.jp.freebsd.org/cgi-bin/showmail/announce-jp/713" [[advisories]] name = "FreeBSD-SA-01:20.mars_nwe" date = "2001-02-07" link = "http://home.jp.freebsd.org/cgi-bin/showmail/announce-jp/712" [[advisories]] name = "FreeBSD-SA-01:19.ja-klock" date = "2001-02-07" link = "http://home.jp.freebsd.org/cgi-bin/showmail/announce-jp/707" [[advisories]] name = "FreeBSD-SA-01:18.bind" date = "2001-01-31" link = "http://home.jp.freebsd.org/cgi-bin/showmail/announce-jp/706" [[advisories]] name = "FreeBSD-SA-01:17.exmh" date = "2001-01-29" link = "http://home.jp.freebsd.org/cgi-bin/showmail/announce-jp/705" [[advisories]] name = "FreeBSD-SA-01:16.mysql" date = "2001-01-29" link = "http://home.jp.freebsd.org/cgi-bin/showmail/announce-jp/704" [[advisories]] name = "FreeBSD-SA-01:15.tinyproxy" date = "2001-01-29" link = "http://home.jp.freebsd.org/cgi-bin/showmail/announce-jp/703" [[advisories]] name = "FreeBSD-SA-01:14.micq" date = "2001-01-29" link = "http://home.jp.freebsd.org/cgi-bin/showmail/announce-jp/702" [[advisories]] name = "FreeBSD-SA-01:13.sort" date = "2001-01-29" link = "http://home.jp.freebsd.org/cgi-bin/showmail/announce-jp/701" [[advisories]] name = "FreeBSD-SA-01:12.periodic" date = "2001-01-29" link = "http://home.jp.freebsd.org/cgi-bin/showmail/announce-jp/700" [[advisories]] name = "FreeBSD-SA-01:11.inetd" date = "2001-01-29" link = "http://home.jp.freebsd.org/cgi-bin/showmail/announce-jp/699" [[advisories]] name = "FreeBSD-SA-01:10.bind" date = "2001-01-23" link = "http://home.jp.freebsd.org/cgi-bin/showmail/announce-jp/698" [[advisories]] name = "FreeBSD-SA-01:09.crontab" date = "2001-01-23" link = "http://home.jp.freebsd.org/cgi-bin/showmail/announce-jp/697" [[advisories]] name = "FreeBSD-SA-01:08.ipfw" date = "2001-01-23" link = "http://home.jp.freebsd.org/cgi-bin/showmail/announce-jp/696" [[advisories]] name = "FreeBSD-SA-01:07.xfree86" date = "2001-01-23" [[advisories]] name = "FreeBSD-SA-01:06.zope" date = "2001-01-15" link = "http://home.jp.freebsd.org/cgi-bin/showmail/announce-jp/669" [[advisories]] name = "FreeBSD-SA-01:05.stunnel" date = "2001-01-15" link = "http://home.jp.freebsd.org/cgi-bin/showmail/announce-jp/668" [[advisories]] name = "FreeBSD-SA-01:04.joe" date = "2001-01-15" link = "http://home.jp.freebsd.org/cgi-bin/showmail/announce-jp/667" [[advisories]] name = "FreeBSD-SA-01:03.bash1" date = "2001-01-15" link = "http://home.jp.freebsd.org/cgi-bin/showmail/announce-jp/666" [[advisories]] name = "FreeBSD-SA-01:02.syslog-ng" date = "2001-01-15" link = "http://home.jp.freebsd.org/cgi-bin/showmail/announce-jp/665" [[advisories]] name = "FreeBSD-SA-01:01.openssh" date = "2001-01-15" link = "http://home.jp.freebsd.org/cgi-bin/showmail/announce-jp/664" [[advisories]] name = "FreeBSD-SA-00:81.ethereal" date = "2000-12-20" link = "http://home.jp.freebsd.org/cgi-bin/showmail/announce-jp/651" [[advisories]] name = "FreeBSD-SA-00:80.halflifeserver" date = "2000-12-20" link = "http://home.jp.freebsd.org/cgi-bin/showmail/announce-jp/650" [[advisories]] name = "FreeBSD-SA-00:79.oops" date = "2000-12-20" link = "http://home.jp.freebsd.org/cgi-bin/showmail/announce-jp/649" [[advisories]] name = "FreeBSD-SA-00:78.bitchx" date = "2000-12-20" link = "http://home.jp.freebsd.org/cgi-bin/showmail/announce-jp/648" [[advisories]] name = "FreeBSD-SA-00:77.procfs" date = "2000-12-18" link = "http://home.jp.freebsd.org/cgi-bin/showmail/announce-jp/647" [[advisories]] name = "FreeBSD-SA-00:76.tcsh-csh" date = "2000-11-20" link = "http://home.jp.freebsd.org/cgi-bin/showmail/announce-jp/628" [[advisories]] name = "FreeBSD-SA-00:75.php" date = "2000-11-20" link = "http://home.jp.freebsd.org/cgi-bin/showmail/announce-jp/627" [[advisories]] name = "FreeBSD-SA-00:74.gaim" date = "2000-11-20" [[advisories]] name = "FreeBSD-SA-00:73.thttpd" date = "2000-11-20" link = "http://home.jp.freebsd.org/cgi-bin/showmail/announce-jp/626" [[advisories]] name = "FreeBSD-SA-00:72.curl" date = "2000-11-20" link = "http://home.jp.freebsd.org/cgi-bin/showmail/announce-jp/625" [[advisories]] name = "FreeBSD-SA-00:71.mgetty" date = "2000-11-20" link = "http://home.jp.freebsd.org/cgi-bin/showmail/announce-jp/624" [[advisories]] name = "FreeBSD-SA-00:70.ppp-nat" date = "2000-11-14" link = "http://home.jp.freebsd.org/cgi-bin/showmail/announce-jp/623" [[advisories]] name = "FreeBSD-SA-00:69.telnetd" date = "2000-11-14" link = "http://home.jp.freebsd.org/cgi-bin/showmail/announce-jp/622" [[advisories]] name = "FreeBSD-SA-00:68.ncurses" date = "2000-11-13" link = "http://home.jp.freebsd.org/cgi-bin/showmail/announce-jp/621" [[advisories]] name = "FreeBSD-SA-00:67.gnupg" date = "2000-11-10" link = "http://home.jp.freebsd.org/cgi-bin/showmail/announce-jp/620" [[advisories]] name = "FreeBSD-SA-00:66.netscape" date = "2000-11-06" link = "http://home.jp.freebsd.org/cgi-bin/showmail/announce-jp/619" [[advisories]] name = "FreeBSD-SA-00:65.xfce" date = "2000-11-06" link = "http://home.jp.freebsd.org/cgi-bin/showmail/announce-jp/618" [[advisories]] name = "FreeBSD-SA-00:64.global" date = "2000-11-06" link = "http://home.jp.freebsd.org/cgi-bin/showmail/announce-jp/617" [[advisories]] name = "FreeBSD-SA-00:63.getnameinfo" date = "2000-11-01" link = "http://home.jp.freebsd.org/cgi-bin/showmail/announce-jp/589" [[advisories]] name = "FreeBSD-SA-00:62.top" date = "2000-11-01" link = "http://home.jp.freebsd.org/cgi-bin/showmail/announce-jp/616" [[advisories]] name = "FreeBSD-SA-00:61.tcpdump" date = "2000-10-31" link = "http://home.jp.freebsd.org/cgi-bin/showmail/announce-jp/615" [[advisories]] name = "FreeBSD-SA-00:60.boa" date = "2000-10-30" link = "http://home.jp.freebsd.org/cgi-bin/showmail/announce-jp/586" [[advisories]] name = "FreeBSD-SA-00:59.pine" date = "2000-10-30" link = "http://home.jp.freebsd.org/cgi-bin/showmail/announce-jp/585" [[advisories]] name = "FreeBSD-SA-00:58.chpass" date = "2000-10-30" link = "http://home.jp.freebsd.org/cgi-bin/showmail/announce-jp/584" [[advisories]] name = "FreeBSD-SA-00:57.muh" date = "2000-10-13" link = "http://home.jp.freebsd.org/cgi-bin/showmail/announce-jp/570" [[advisories]] name = "FreeBSD-SA-00:56.lprng" date = "2000-10-13" link = "http://home.jp.freebsd.org/cgi-bin/showmail/announce-jp/569" [[advisories]] name = "FreeBSD-SA-00:55.xpdf" date = "2000-10-13" link = "http://home.jp.freebsd.org/cgi-bin/showmail/announce-jp/568" [[advisories]] name = "FreeBSD-SA-00:54.fingerd" date = "2000-10-13" link = "http://home.jp.freebsd.org/cgi-bin/showmail/announce-jp/567" [[advisories]] name = "FreeBSD-SA-00:52.tcp-iss" date = "2000-10-06" link = "http://home.jp.freebsd.org/cgi-bin/showmail/announce-jp/561" [[advisories]] name = "FreeBSD-SA-00:53.catopen" date = "2000-09-27" link = "http://home.jp.freebsd.org/cgi-bin/showmail/announce-jp/562" [[advisories]] name = "FreeBSD-SA-00:51.mailman" date = "2000-09-13" link = "http://home.jp.freebsd.org/cgi-bin/showmail/announce-jp/550" [[advisories]] name = "FreeBSD-SA-00:50.listmanager" date = "2000-09-13" link = "http://home.jp.freebsd.org/cgi-bin/showmail/announce-jp/549" [[advisories]] name = "FreeBSD-SA-00:49.eject" date = "2000-09-13" link = "http://home.jp.freebsd.org/cgi-bin/showmail/announce-jp/548" [[advisories]] name = "FreeBSD-SA-00:48.xchat" date = "2000-09-13" link = "http://home.jp.freebsd.org/cgi-bin/showmail/announce-jp/547" [[advisories]] name = "FreeBSD-SA-00:47.pine" date = "2000-09-13" link = "http://home.jp.freebsd.org/cgi-bin/showmail/announce-jp/546" [[advisories]] name = "FreeBSD-SA-00:46.screen" date = "2000-09-13" link = "http://home.jp.freebsd.org/cgi-bin/showmail/announce-jp/545" [[advisories]] name = "FreeBSD-SA-00:45.esound" date = "2000-08-31" link = "http://home.jp.freebsd.org/cgi-bin/showmail/announce-jp/526" [[advisories]] name = "FreeBSD-SA-00:44.xlock" date = "2000-08-28" link = "http://home.jp.freebsd.org/cgi-bin/showmail/announce-jp/523" [[advisories]] name = "FreeBSD-SA-00:43.brouted" date = "2000-08-28" link = "http://home.jp.freebsd.org/cgi-bin/showmail/announce-jp/520" [[advisories]] name = "FreeBSD-SA-00:42.linux" date = "2000-08-28" link = "http://home.jp.freebsd.org/cgi-bin/showmail/announce-jp/530" [[advisories]] name = "FreeBSD-SA-00:41.elf" date = "2000-08-28" link = "http://home.jp.freebsd.org/cgi-bin/showmail/announce-jp/527" [[advisories]] name = "FreeBSD-SA-00:40.mopd" date = "2000-08-28" link = "http://home.jp.freebsd.org/cgi-bin/showmail/announce-jp/521" [[advisories]] name = "FreeBSD-SA-00:39.netscape" date = "2000-08-28" link = "http://home.jp.freebsd.org/cgi-bin/showmail/announce-jp/528" [[advisories]] name = "FreeBSD-SA-00:38.zope" date = "2000-08-14" link = "http://home.jp.freebsd.org/cgi-bin/showmail/announce-jp/525" [[advisories]] name = "FreeBSD-SA-00:37.cvsweb" date = "2000-08-14" link = "http://home.jp.freebsd.org/cgi-bin/showmail/announce-jp/524" [[advisories]] name = "FreeBSD-SA-00:36.ntop" date = "2000-08-14" link = "http://home.jp.freebsd.org/cgi-bin/showmail/announce-jp/531" [[advisories]] name = "FreeBSD-SA-00:35.proftpd" date = "2000-08-14" link = "http://home.jp.freebsd.org/cgi-bin/showmail/announce-jp/522" [[advisories]] name = "FreeBSD-SA-00:34.dhclient" date = "2000-08-14" link = "http://home.jp.freebsd.org/cgi-bin/showmail/announce-jp/529" [[advisories]] name = "FreeBSD-SA-00:33.kerberosIV" date = "2000-07-12" link = "http://home.jp.freebsd.org/cgi-bin/showmail/announce-jp/488" [[advisories]] name = "FreeBSD-SA-00:32.bitchx" date = "2000-07-05" link = "http://home.jp.freebsd.org/cgi-bin/showmail/announce-jp/487" [[advisories]] name = "FreeBSD-SA-00:31.canna" date = "2000-07-05" link = "http://home.jp.freebsd.org/cgi-bin/showmail/announce-jp/486" [[advisories]] name = "FreeBSD-SA-00:30.openssh" date = "2000-07-05" link = "http://home.jp.freebsd.org/cgi-bin/showmail/announce-jp/485" [[advisories]] name = "FreeBSD-SA-00:29.wu-ftpd" date = "2000-07-05" link = "http://home.jp.freebsd.org/cgi-bin/showmail/announce-jp/489" [[advisories]] name = "FreeBSD-SA-00:28.majordomo" date = "2000-07-05" link = "http://home.jp.freebsd.org/cgi-bin/showmail/announce-jp/484" [[advisories]] name = "FreeBSD-SA-00:27.XFree86-4" date = "2000-07-05" link = "http://home.jp.freebsd.org/cgi-bin/showmail/announce-jp/483" [[advisories]] name = "FreeBSD-SA-00:26.popper" date = "2000-07-05" link = "http://home.jp.freebsd.org/cgi-bin/showmail/announce-jp/482" [[advisories]] name = "FreeBSD-SA-00:24.libedit" date = "2000-07-05" link = "http://home.jp.freebsd.org/cgi-bin/showmail/announce-jp/481" [[advisories]] name = "FreeBSD-SA-00:23.ip-options" date = "2000-06-19" link = "http://home.jp.freebsd.org/cgi-bin/showmail/announce-jp/480" [[advisories]] name = "FreeBSD-SA-00:25.alpha-random" date = "2000-06-12" link = "http://home.jp.freebsd.org/cgi-bin/showmail/announce-jp/473" [[advisories]] name = "FreeBSD-SA-00:22.apsfilter" date = "2000-06-07" link = "http://home.jp.freebsd.org/cgi-bin/showmail/announce-jp/461" [[advisories]] name = "FreeBSD-SA-00:21.ssh" date = "2000-06-07" link = "http://home.jp.freebsd.org/cgi-bin/showmail/announce-jp/459" [[advisories]] name = "FreeBSD-SA-00:20.krb5" date = "2000-05-26" link = "http://home.jp.freebsd.org/cgi-bin/showmail/announce-jp/452" [[advisories]] name = "FreeBSD-SA-00:19.semconfig" date = "2000-05-23" link = "http://home.jp.freebsd.org/cgi-bin/showmail/announce-jp/451" [[advisories]] name = "FreeBSD-SA-00:18.gnapster.knapster" date = "2000-05-09" link = "http://home.jp.freebsd.org/cgi-bin/showmail/announce-jp/429" [[advisories]] name = "FreeBSD-SA-00:17.libmytinfo" date = "2000-05-09" link = "http://home.jp.freebsd.org/cgi-bin/showmail/announce-jp/442" [[advisories]] name = "FreeBSD-SA-00:16.golddig" date = "2000-05-09" link = "http://home.jp.freebsd.org/cgi-bin/showmail/announce-jp/439" [[advisories]] name = "FreeBSD-SA-00:15.imap-uw" date = "2000-04-24" link = "http://home.jp.freebsd.org/cgi-bin/showmail/announce-jp/438" [[advisories]] name = "FreeBSD-SA-00:14.imap-uw" date = "2000-04-24" link = "http://home.jp.freebsd.org/cgi-bin/showmail/announce-jp/441" [[advisories]] name = "FreeBSD-SA-00:13.generic-nqs" date = "2000-04-19" link = "http://home.jp.freebsd.org/cgi-bin/showmail/announce-jp/437" [[advisories]] name = "FreeBSD-SA-00:12.healthd" date = "2000-04-10" link = "http://home.jp.freebsd.org/cgi-bin/showmail/announce-jp/436" [[advisories]] name = "FreeBSD-SA-00:11.ircii" date = "2000-04-10" link = "http://home.jp.freebsd.org/cgi-bin/showmail/announce-jp/440" [[advisories]] name = "FreeBSD-SA-00:10.orville-write" date = "2000-03-15" link = "http://home.jp.freebsd.org/cgi-bin/showmail/announce-jp/408" [[advisories]] name = "FreeBSD-SA-00:09.mtr" date = "2000-03-15" link = "http://home.jp.freebsd.org/cgi-bin/showmail/announce-jp/408" [[advisories]] name = "FreeBSD-SA-00:08.lynx" date = "2000-03-15" link = "http://home.jp.freebsd.org/cgi-bin/showmail/announce-jp/407" [[advisories]] name = "FreeBSD-SA-00:07.mh" date = "2000-03-15" link = "http://home.jp.freebsd.org/cgi-bin/showmail/announce-jp/411" [[advisories]] name = "FreeBSD-SA-00:06.htdig" date = "2000-03-01" link = "http://home.jp.freebsd.org/cgi-bin/showmail/announce-jp/403" [[advisories]] name = "FreeBSD-SA-00:05.mysql" date = "2000-02-28" link = "http://home.jp.freebsd.org/cgi-bin/showmail/announce-jp/402" [[advisories]] name = "FreeBSD-SA-00:04.delegate" date = "2000-02-19" link = "http://home.jp.freebsd.org/cgi-bin/showmail/announce-jp/392" [[advisories]] name = "FreeBSD-SA-00:03.asmon" date = "2000-02-19" link = "http://home.jp.freebsd.org/cgi-bin/showmail/announce-jp/391" [[advisories]] name = "FreeBSD-SA-00:02.procfs" date = "2000-01-24" link = "http://home.jp.freebsd.org/cgi-bin/showmail/announce-jp/380" [[advisories]] name = "FreeBSD-SA-00:01.make" date = "2000-01-19" [[advisories]] name = "FreeBSD-SA-99:06.amd" date = "1999-09-16" link = "http://home.jp.freebsd.org/cgi-bin/showmail/announce-jp/318" [[advisories]] name = "FreeBSD-SA-99:05.fts" date = "1999-09-15" link = "http://home.jp.freebsd.org/cgi-bin/showmail/announce-jp/313" [[advisories]] name = "FreeBSD-SA-99:04.core" date = "1999-09-15" link = "http://home.jp.freebsd.org/cgi-bin/showmail/announce-jp/312" [[advisories]] name = "FreeBSD-SA-99:03.ftpd" date = "1999-09-05" link = "http://home.jp.freebsd.org/cgi-bin/showmail/announce-jp/311" [[advisories]] name = "FreeBSD-SA-99:02.profil" date = "1999-09-04" [[advisories]] name = "FreeBSD-SA-99:01.chflags" date = "1999-09-04" [[advisories]] name = "FreeBSD-SA-98:08.fragment" date = "1998-11-04" [[advisories]] name = "FreeBSD-SA-98:07.rst" date = "1998-10-13" [[advisories]] name = "FreeBSD-SA-98:06.icmp" date = "1998-06-10" [[advisories]] name = "FreeBSD-SA-98:05.nfs" date = "1998-06-04" [[advisories]] name = "FreeBSD-SA-98:04.mmap" date = "1998-06-02" [[advisories]] name = "FreeBSD-SA-98:03.ttcp" date = "1998-05-14" [[advisories]] name = "FreeBSD-SA-98:02.mmap" date = "1998-03-12" [[advisories]] name = "FreeBSD-SA-97:06.f00f" date = "1997-12-09" [[advisories]] name = "FreeBSD-SA-98:01.land" date = "1997-12-01" [[advisories]] name = "FreeBSD-SA-97:05.open" date = "1997-10-29" [[advisories]] name = "FreeBSD-SA-97:04.procfs" date = "1997-08-19" [[advisories]] name = "FreeBSD-SA-97:03.sysinstall" date = "1997-04-07" [[advisories]] name = "FreeBSD-SA-97:02.lpd" date = "1997-03-26" [[advisories]] name = "FreeBSD-SA-97:01.setlocale" date = "1997-02-05" [[advisories]] name = "FreeBSD-SA-96:21.talkd" date = "1997-01-18" [[advisories]] name = "FreeBSD-SA-96:20.stack-overflow" date = "1996-12-16" [[advisories]] name = "FreeBSD-SA-96:19.modstat" date = "1996-12-10" [[advisories]] name = "FreeBSD-SA-96:18.lpr" date = "1996-11-25" [[advisories]] name = "FreeBSD-SA-96:17.rzsz" date = "1996-07-16" [[advisories]] name = "FreeBSD-SA-96:16.rdist" date = "1996-07-12" [[advisories]] name = "FreeBSD-SA-96:15.ppp" date = "1996-07-04" [[advisories]] name = "FreeBSD-SA-96:12.perl" date = "1996-06-28" [[advisories]] name = "FreeBSD-SA-96:14.ipfw" date = "1996-06-24" [[advisories]] name = "FreeBSD-SA-96:13.comsat" date = "1996-06-05" [[advisories]] name = "FreeBSD-SA-96:11.man" date = "1996-05-21" [[advisories]] name = "FreeBSD-SA-96:10.mount_union" date = "1996-05-17" [[advisories]] name = "FreeBSD-SA-96:09.vfsload" date = "1996-05-17" [[advisories]] name = "FreeBSD-SA-96:02.apache" date = "1996-04-22" [[advisories]] name = "FreeBSD-SA-96:08.syslog" date = "1996-04-21" [[advisories]] name = "FreeBSD-SA-96:01.sliplogin" date = "1996-04-21" [[advisories]] name = "FreeBSD-SA-96:03.sendmail-suggestion" date = "1996-04-20" diff --git a/website/data/security/errata.toml b/website/data/security/errata.toml index 3ecb2721f7..e6cb101d6d 100644 --- a/website/data/security/errata.toml +++ b/website/data/security/errata.toml @@ -1,1127 +1,1135 @@ # Sort errata notices by year, month and day # $FreeBSD$ +[[notices]] +name = "FreeBSD-EN-26:17.rpcsec_tls" +date = "2026-06-30" + +[[notices]] +name = "FreeBSD-EN-26:16.arm64" +date = "2026-06-30" + [[notices]] name = "FreeBSD-EN-26:15.openssl" date = "2026-06-09" [[notices]] name = "FreeBSD-EN-26:14.syslogd" date = "2026-06-09" [[notices]] name = "FreeBSD-EN-26:13.freebsd-update" date = "2026-05-20" [[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" [[notices]] name = "FreeBSD-EN-26:09.tzdata" date = "2026-04-29" [[notices]] name = "FreeBSD-EN-26:08.pf" date = "2026-04-29" [[notices]] name = "FreeBSD-EN-26:07.pkgbase" date = "2026-04-21" [[notices]] name = "FreeBSD-EN-26:06.timerfd" date = "2026-04-21" [[notices]] name = "FreeBSD-EN-26:05.vm" date = "2026-04-21" [[notices]] name = "FreeBSD-EN-26:04.arm64" date = "2026-02-10" [[notices]] name = "FreeBSD-EN-26:03.vm" date = "2026-01-27" [[notices]] name = "FreeBSD-EN-26:02.arm64" date = "2026-01-27" [[notices]] name = "FreeBSD-EN-26:01.devinfo" date = "2026-01-27" [[notices]] name = "FreeBSD-EN-25:20.vmm" date = "2025-12-16" [[notices]] name = "FreeBSD-EN-25:19.zfs" date = "2025-12-16" [[notices]] name = "FreeBSD-EN-25:18.freebsd-update" date = "2025-09-30" [[notices]] name = "FreeBSD-EN-25:17.bnxt" date = "2025-09-16" [[notices]] name = "FreeBSD-EN-25:16.vfs" date = "2025-09-16" [[notices]] name = "FreeBSD-EN-25:15.arm64" date = "2025-09-16" [[notices]] name = "FreeBSD-EN-25:14.route" date = "2025-08-08" [[notices]] name = "FreeBSD-EN-25:13.wlan_tkip" date = "2025-08-08" [[notices]] name = "FreeBSD-EN-25:12.efi" date = "2025-08-08" [[notices]] name = "FreeBSD-EN-25:11.ena" date = "2025-07-02" [[notices]] name = "FreeBSD-EN-25:10.zfs" date = "2025-07-02" [[notices]] name = "FreeBSD-EN-25:09.libc" date = "2025-07-02" [[notices]] name = "FreeBSD-EN-25:08.caroot" date = "2025-04-10" [[notices]] name = "FreeBSD-EN-25:07.openssl" date = "2025-04-10" [[notices]] name = "FreeBSD-EN-25:06.daemon" date = "2025-04-10" [[notices]] name = "FreeBSD-EN-25:05.expat" date = "2025-04-10" [[notices]] name = "FreeBSD-EN-25:04.tzdata" date = "2025-04-10" [[notices]] name = "FreeBSD-EN-25:03.tzdata" date = "2025-01-29" [[notices]] name = "FreeBSD-EN-25:02.audit" date = "2025-01-29" [[notices]] name = "FreeBSD-EN-25:01.rpc" date = "2025-01-29" [[notices]] name = "FreeBSD-EN-24:17.pam_xdg" date = "2024-10-29" [[notices]] name = "FreeBSD-EN-24:16.pf" date = "2024-09-19" [[notices]] name = "FreeBSD-EN-24:15.calendar" date = "2024-09-04" [[notices]] name = "FreeBSD-EN-24:14.ifconfig" date = "2024-08-07" [[notices]] name = "FreeBSD-EN-24:13.libc++" date = "2024-06-19" [[notices]] name = "FreeBSD-EN-24:12.killpg" date = "2024-06-19" [[notices]] name = "FreeBSD-EN-24:11.ldns" date = "2024-06-19" [[notices]] name = "FreeBSD-EN-24:10.zfs" date = "2024-06-19" [[notices]] name = "FreeBSD-EN-24:09.zfs" date = "2024-04-24" [[notices]] name = "FreeBSD-EN-24:08.kerberos" date = "2024-03-28" [[notices]] name = "FreeBSD-EN-24:07.clang" date = "2024-03-28" [[notices]] name = "FreeBSD-EN-24:06.wireguard" date = "2024-03-28" [[notices]] name = "FreeBSD-EN-24:05.tty" date = "2024-03-28" [[notices]] name = "FreeBSD-EN-24:04.ip" date = "2024-02-14" [[notices]] name = "FreeBSD-EN-24:03.kqueue" date = "2024-02-14" [[notices]] name = "FreeBSD-EN-24:02.libutil" date = "2024-02-14" [[notices]] name = "FreeBSD-EN-24:01.tzdata" date = "2024-02-14" [[notices]] name = "FreeBSD-EN-23:22.vfs" date = "2023-12-05" [[notices]] name = "FreeBSD-EN-23:21.tty" date = "2023-12-05" [[notices]] name = "FreeBSD-EN-23:20.vm" date = "2023-12-05" [[notices]] name = "FreeBSD-EN-23:19.pkgbase" date = "2023-12-05" [[notices]] name = "FreeBSD-EN-23:18.openzfs" date = "2023-12-05" [[notices]] name = "FreeBSD-EN-23:17.ossl" date = "2023-12-05" [[notices]] name = "FreeBSD-EN-23:16.openzfs" date = "2023-12-01" [[notices]] name = "FreeBSD-EN-23:15.sanitizer" date = "2023-12-01" [[notices]] name = "FreeBSD-EN-23:14.regcomp" date = "2023-11-08" [[notices]] name = "FreeBSD-EN-23:13.freebsd-update" date = "2023-11-08" [[notices]] name = "FreeBSD-EN-23:12.freebsd-update" date = "2023-10-03" [[notices]] name = "FreeBSD-EN-23:11.caroot" date = "2023-09-06" [[notices]] name = "FreeBSD-EN-23:10.pci" date = "2023-09-06" [[notices]] name = "FreeBSD-EN-23:09.freebsd-update" date = "2023-09-06" [[notices]] name = "FreeBSD-EN-23:08.vnet" date = "2023-08-01" [[notices]] name = "FreeBSD-EN-23:07.mpr" date = "2023-06-21" [[notices]] name = "FreeBSD-EN-23:06.loader" date = "2023-06-21" [[notices]] name = "FreeBSD-EN-23:05.tzdata" date = "2023-06-21" [[notices]] name = "FreeBSD-EN-23:04.ixgbe" date = "2023-02-08" [[notices]] name = "FreeBSD-EN-23:03.ena" date = "2023-02-08" [[notices]] name = "FreeBSD-EN-23:02.sdhci" date = "2023-02-08" [[notices]] name = "FreeBSD-EN-23:01.tzdata" date = "2023-02-08" [[notices]] name = "FreeBSD-EN-22:28.heimdal" date = "2022-11-29" [[notices]] name = "FreeBSD-EN-22:27.loader" date = "2022-11-01" [[notices]] name = "FreeBSD-EN-22:26.cam" date = "2022-11-01" [[notices]] name = "FreeBSD-EN-22:25.tcp" date = "2022-11-01" [[notices]] name = "FreeBSD-EN-22:24.zfs" date = "2022-11-01" [[notices]] name = "FreeBSD-EN-22:23.vm" date = "2022-11-01" [[notices]] name = "FreeBSD-EN-22:22.tzdata" date = "2022-11-01" [[notices]] name = "FreeBSD-EN-22:21.zfs" date = "2022-11-01" [[notices]] name = "FreeBSD-EN-22:20.tzdata" date = "2022-08-30" [[notices]] name = "FreeBSD-EN-22:19.pam_exec" date = "2022-08-09" [[notices]] name = "FreeBSD-EN-22:18.wifi" date = "2022-08-09" [[notices]] name = "FreeBSD-EN-22:17.cam" date = "2022-08-09" [[notices]] name = "FreeBSD-EN-22:16.kqueue" date = "2022-08-09" [[notices]] name = "FreeBSD-EN-22:15.pf" date = "2022-04-06" [[notices]] name = "FreeBSD-EN-22:14.tzdata" date = "2022-03-22" [[notices]] name = "FreeBSD-EN-22:13.zfs" date = "2022-03-21" [[notices]] name = "FreeBSD-EN-22:12.zfs" date = "2022-03-15" [[notices]] name = "FreeBSD-EN-22:11.zfs" date = "2022-03-15" [[notices]] name = "FreeBSD-EN-22:10.zfs" date = "2022-03-15" [[notices]] name = "FreeBSD-EN-22:09.freebsd-update" date = "2022-03-15" [[notices]] name = "FreeBSD-EN-22:08.i386" date = "2022-02-01" [[notices]] name = "FreeBSD-EN-22:07.la57" date = "2022-02-01" [[notices]] name = "FreeBSD-EN-22:06.libalias" date = "2022-01-11" [[notices]] name = "FreeBSD-EN-22:05.tail" date = "2022-01-11" [[notices]] name = "FreeBSD-EN-22:04.pcid" date = "2022-01-11" [[notices]] name = "FreeBSD-EN-22:03.hyperv" date = "2022-01-11" [[notices]] name = "FreeBSD-EN-22:02.xsave" date = "2022-01-11" [[notices]] name = "FreeBSD-EN-22:01.fsck_ffs" date = "2022-01-11" [[notices]] name = "FreeBSD-EN-21:29.tzdata" date = "2021-11-03" [[notices]] name = "FreeBSD-EN-21:28.vmci" date = "2021-11-03" [[notices]] name = "FreeBSD-EN-21:27.caroot" date = "2021-11-03" [[notices]] name = "FreeBSD-EN-21:26.libevent" date = "2021-11-03" [[notices]] name = "FreeBSD-EN-21:25.bhyve" date = "2021-08-24" [[notices]] name = "FreeBSD-EN-21:24.libcrypto" date = "2021-08-24" [[notices]] name = "FreeBSD-EN-21:23.virtio_blk" date = "2021-08-24" [[notices]] name = "FreeBSD-EN-21:22.linux_futex" date = "2021-06-29" [[notices]] name = "FreeBSD-EN-21:21.ipfw" date = "2021-06-29" [[notices]] name = "FreeBSD-EN-21:20.vlan" date = "2021-06-29" [[notices]] name = "FreeBSD-EN-21:19.libcasper" date = "2021-06-29" [[notices]] name = "FreeBSD-EN-21:18.libc++" date = "2021-06-29" [[notices]] name = "FreeBSD-EN-21:17.libradius" date = "2021-06-01" [[notices]] name = "FreeBSD-EN-21:16.bc" date = "2021-05-26" [[notices]] name = "FreeBSD-EN-21:15.virtio" date = "2021-05-26" [[notices]] name = "FreeBSD-EN-21:14.pms" date = "2021-05-26" [[notices]] name = "FreeBSD-EN-21:13.mpt" date = "2021-05-26" [[notices]] name = "FreeBSD-EN-21:12.divert" date = "2021-05-26" [[notices]] name = "FreeBSD-EN-21:11.aesni" date = "2021-05-26" [[notices]] name = "FreeBSD-EN-21:10.lldb" date = "2021-04-06" [[notices]] name = "FreeBSD-EN-21:09.pf" date = "2021-04-06" [[notices]] name = "FreeBSD-EN-21:08.freebsd-update" date = "2021-02-24" [[notices]] name = "FreeBSD-EN-21:07.caroot" date = "2021-02-24" [[notices]] name = "FreeBSD-EN-21:06.microcode" date = "2021-02-24" [[notices]] name = "FreeBSD-EN-21:05.libatomic" date = "2021-01-29" [[notices]] name = "FreeBSD-EN-21:04.zfs" date = "2021-01-29" [[notices]] name = "FreeBSD-EN-21:03.vnet" date = "2021-01-29" [[notices]] name = "FreeBSD-EN-21:02.extattr" date = "2021-01-29" [[notices]] name = "FreeBSD-EN-21:01.tzdata" date = "2021-01-29" [[notices]] name = "FreeBSD-EN-20:22.callout" date = "2020-12-01" [[notices]] name = "FreeBSD-EN-20:21.ipfw" date = "2020-12-01" [[notices]] name = "FreeBSD-EN-20:20.tzdata" date = "2020-12-01" [[notices]] name = "FreeBSD-EN-20:19.audit" date = "2020-12-01" [[notices]] name = "FreeBSD-EN-20:18.getfsstat" date = "2020-09-02" [[notices]] name = "FreeBSD-EN-20:17.linuxthread" date = "2020-09-02" [[notices]] name = "FreeBSD-EN-20:16.vmx" date = "2020-08-05" [[notices]] name = "FreeBSD-EN-20:15.mps" date = "2020-07-08" [[notices]] name = "FreeBSD-EN-20:14.linuxkpi" date = "2020-07-08" [[notices]] name = "FreeBSD-EN-20:13.bhyve" date = "2020-07-08" [[notices]] name = "FreeBSD-EN-20:12.iflib" date = "2020-06-09" [[notices]] name = "FreeBSD-EN-20:11.ena" date = "2020-06-09" [[notices]] name = "FreeBSD-EN-20:10.build" date = "2020-05-12" [[notices]] name = "FreeBSD-EN-20:09.igb" date = "2020-05-12" [[notices]] name = "FreeBSD-EN-20:08.tzdata" date = "2020-05-12" [[notices]] name = "FreeBSD-EN-20:07.quotad" date = "2020-04-21" [[notices]] name = "FreeBSD-EN-20:06.ipv6" date = "2020-03-19" [[notices]] name = "FreeBSD-EN-20:05.mlx5en" date = "2020-03-19" [[notices]] name = "FreeBSD-EN-20:04.pfctl" date = "2020-03-19" [[notices]] name = "FreeBSD-EN-20:03.sshd" date = "2020-03-19" [[notices]] name = "FreeBSD-EN-20:02.nmount" date = "2020-01-28" [[notices]] name = "FreeBSD-EN-20:01.ssp" date = "2020-01-28" [[notices]] name = "FreeBSD-EN-19:19.loader" date = "2019-11-12" [[notices]] name = "FreeBSD-EN-19:18.tzdata" date = "2019-10-23" [[notices]] name = "FreeBSD-EN-19:17.ipfw" date = "2019-08-20" [[notices]] name = "FreeBSD-EN-19:16.bhyve" date = "2019-08-20" [[notices]] name = "FreeBSD-EN-19:15.libunwind" date = "2019-08-06" [[notices]] name = "FreeBSD-EN-19:14.epoch" date = "2019-08-06" [[notices]] name = "FreeBSD-EN-19:13.mds" date = "2019-07-24" [[notices]] name = "FreeBSD-EN-19:12.tzdata" date = "2019-07-02" [[notices]] name = "FreeBSD-EN-19:11.net" date = "2019-06-19" [[notices]] name = "FreeBSD-EN-19:10.scp" date = "2019-05-14" [[notices]] name = "FreeBSD-EN-19:09.xinstall" date = "2019-05-14" [[notices]] name = "FreeBSD-EN-19:08.tzdata" date = "2019-05-14" [[notices]] name = "FreeBSD-EN-19:07.lle" date = "2019-02-05" [[notices]] name = "FreeBSD-EN-19:06.dtrace" date = "2019-02-05" [[notices]] name = "FreeBSD-EN-19:05.kqueue" date = "2019-01-09" [[notices]] name = "FreeBSD-EN-19:04.tzdata" date = "2019-01-09" [[notices]] name = "FreeBSD-EN-19:03.sqlite" date = "2019-01-09" [[notices]] name = "FreeBSD-EN-19:02.tcp" date = "2019-01-09" [[notices]] name = "FreeBSD-EN-19:01.cc_cubic" date = "2019-01-09" [[notices]] name = "FreeBSD-EN-18:18.zfs" date = "2018-12-19" [[notices]] name = "FreeBSD-EN-18:17.vm" date = "2018-12-19" [[notices]] name = "FreeBSD-EN-18:16.ptrace" date = "2018-12-19" [[notices]] name = "FreeBSD-EN-18:15.loader" date = "2018-11-27" [[notices]] name = "FreeBSD-EN-18:14.tzdata" date = "2018-11-27" [[notices]] name = "FreeBSD-EN-18:13.icmp" date = "2018-11-27" [[notices]] name = "FreeBSD-EN-18:12.mem" date = "2018-09-27" [[notices]] name = "FreeBSD-EN-18:11.listen" date = "2018-09-27" [[notices]] name = "FreeBSD-EN-18:10.syscall" date = "2018-09-27" [[notices]] name = "FreeBSD-EN-18:09.ip" date = "2018-09-27" [[notices]] name = "FreeBSD-EN-18:08.lazyfpu" date = "2018-09-12" [[notices]] name = "FreeBSD-EN-18:07.pmap" date = "2018-06-21" [[notices]] name = "FreeBSD-EN-18:06.tzdata" date = "2018-05-08" [[notices]] name = "FreeBSD-EN-18:05.mem" date = "2018-05-08" [[notices]] name = "FreeBSD-EN-18:04.mem" date = "2018-04-04" [[notices]] name = "FreeBSD-EN-18:03.tzdata" date = "2018-04-04" [[notices]] name = "FreeBSD-EN-18:02.file" date = "2018-03-07" [[notices]] name = "FreeBSD-EN-18:01.tzdata" date = "2018-03-07" [[notices]] name = "FreeBSD-EN-17:09.tzdata" date = "2017-11-02" [[notices]] name = "FreeBSD-EN-17:08.pf" date = "2017-08-10" [[notices]] name = "FreeBSD-EN-17:07.vnet" date = "2017-08-10" [[notices]] name = "FreeBSD-EN-17:06.hyperv" date = "2017-07-12" [[notices]] name = "FreeBSD-EN-17:05.xen" date = "2017-04-12" [[notices]] name = "FreeBSD-EN-17:04.mandoc" date = "2017-02-23" [[notices]] name = "FreeBSD-EN-17:03.hyperv" date = "2017-02-23" [[notices]] name = "FreeBSD-EN-17:02.yp" date = "2017-02-23" [[notices]] name = "FreeBSD-EN-17:01.pcie" date = "2017-02-23" [[notices]] name = "FreeBSD-EN-16:21.localedef" date = "2016-12-06" [[notices]] name = "FreeBSD-EN-16:20.tzdata" date = "2016-12-06" [[notices]] name = "FreeBSD-EN-16:19.tzcode" date = "2016-12-06" [[notices]] name = "FreeBSD-EN-16:18.loader" date = "2016-10-25" [[notices]] name = "FreeBSD-EN-16:17.vm" date = "2016-10-25" [[notices]] name = "FreeBSD-EN-16:16.hv_storvsc" date = "2016-08-12" [[notices]] name = "FreeBSD-EN-16:15.vmbus" date = "2016-08-12" [[notices]] name = "FreeBSD-EN-16:14.hv_storvsc" date = "2016-08-12" [[notices]] name = "FreeBSD-EN-16:13.vmbus" date = "2016-08-12" [[notices]] name = "FreeBSD-EN-16:12.hv_storvsc" date = "2016-08-12" [[notices]] name = "FreeBSD-EN-16:11.vmbus" date = "2016-08-12" [[notices]] name = "FreeBSD-EN-16:10.dhclient" date = "2016-08-12" [[notices]] name = "FreeBSD-EN-16:09.freebsd-update" date = "2016-07-25" [[notices]] name = "FreeBSD-EN-16:08.zfs" date = "2016-05-04" [[notices]] name = "FreeBSD-EN-16:07.ipi" date = "2016-05-04" [[notices]] name = "FreeBSD-EN-16:06.libc" date = "2016-05-04" [[notices]] name = "FreeBSD-EN-16:05.hv_netvsc" date = "2016-03-16" [[notices]] name = "FreeBSD-EN-16:04.hyperv" date = "2016-03-16" [[notices]] name = "FreeBSD-EN-16:03.yplib" date = "2016-01-14" [[notices]] name = "FreeBSD-EN-16:02.pf" date = "2016-01-14" [[notices]] name = "FreeBSD-EN-16:01.filemon" date = "2016-01-14" [[notices]] name = "FreeBSD-EN-15:20.vm" date = "2015-11-04" [[notices]] name = "FreeBSD-EN-15:19.kqueue" date = "2015-11-04" [[notices]] name = "FreeBSD-EN-15:18.pkg" date = "2015-09-16" [[notices]] name = "FreeBSD-EN-15:17.libc" date = "2015-09-16" [[notices]] name = "FreeBSD-EN-15:16.pw" date = "2015-09-16" [[notices]] name = "FreeBSD-EN-15:15.pkg" date = "2015-08-25" [[notices]] name = "FreeBSD-EN-15:14.ixgbe" date = "2015-08-25" [[notices]] name = "FreeBSD-EN-15:13.vidcontrol" date = "2015-08-18" [[notices]] name = "FreeBSD-EN-15:12.netstat" date = "2015-08-18" [[notices]] name = "FreeBSD-EN-15:11.toolchain" date = "2015-08-18" [[notices]] name = "FreeBSD-EN-15:10.iconv" date = "2015-06-30" [[notices]] name = "FreeBSD-EN-15:09.xlocale" date = "2015-06-30" [[notices]] name = "FreeBSD-EN-15:08.sendmail" date = "2015-06-18" [[notices]] name = "FreeBSD-EN-15:07.zfs" date = "2015-06-09" [[notices]] name = "FreeBSD-EN-15:06.file" date = "2015-06-09" [[notices]] name = "FreeBSD-EN-15:05.ufs" date = "2015-05-13" [[notices]] name = "FreeBSD-EN-15:04.freebsd-update" date = "2015-05-13" [[notices]] name = "FreeBSD-EN-15:03.freebsd-update" date = "2015-02-25" [[notices]] name = "FreeBSD-EN-15:02.openssl" date = "2015-02-25" [[notices]] name = "FreeBSD-EN-15:01.vt" date = "2015-02-25" [[notices]] name = "FreeBSD-EN-14:13.freebsd-update" date = "2014-12-23" [[notices]] name = "FreeBSD-EN-14:12.zfs" date = "2014-11-04" [[notices]] name = "FreeBSD-EN-14:11.crypt" date = "2014-10-22" [[notices]] name = "FreeBSD-EN-14:10.tzdata" date = "2014-10-22" [[notices]] name = "FreeBSD-EN-14:09.jail" date = "2014-07-08" [[notices]] name = "FreeBSD-EN-14:08.heimdal" date = "2014-06-24" [[notices]] name = "FreeBSD-EN-14:07.pmap" date = "2014-06-24" [[notices]] name = "FreeBSD-EN-14:06.exec" date = "2014-06-03" [[notices]] name = "FreeBSD-EN-14:05.ciss" date = "2014-05-13" [[notices]] name = "FreeBSD-EN-14:04.kldxref" date = "2014-05-13" [[notices]] name = "FreeBSD-EN-14:03.pkg" date = "2014-05-13" [[notices]] name = "FreeBSD-EN-14:02.mmap" date = "2014-01-14" [[notices]] name = "FreeBSD-EN-14:01.random" date = "2014-01-14" [[notices]] name = "FreeBSD-EN-13:05.freebsd-update" date = "2013-11-28" [[notices]] name = "FreeBSD-EN-13:04.freebsd-update" date = "2013-10-26" [[notices]] name = "FreeBSD-EN-13:03.mfi" date = "2013-08-22" [[notices]] name = "FreeBSD-EN-13:01.fxp" date = "2013-06-28" [[notices]] name = "FreeBSD-EN-13:02.vtnet" date = "2013-06-28" [[notices]] name = "FreeBSD-EN-12:02.ipv6refcount" date = "2012-06-12" [[notices]] name = "FreeBSD-EN-12:01.freebsd-update" date = "2012-01-04" [[notices]] name = "FreeBSD-EN-10:02.sched_ule" date = "2010-02-27" [[notices]] name = "FreeBSD-EN-10:01.freebsd" date = "2010-01-06" [[notices]] name = "FreeBSD-EN-09:05.null" date = "2009-10-02" [[notices]] name = "FreeBSD-EN-09:04.fork" date = "2009-06-24" [[notices]] name = "FreeBSD-EN-09:03.fxp" date = "2009-06-24" [[notices]] name = "FreeBSD-EN-09:02.bce" date = "2009-06-24" [[notices]] name = "FreeBSD-EN-09:01.kenv" date = "2009-03-23" [[notices]] name = "FreeBSD-EN-08:02.tcp" date = "2008-06-19" [[notices]] name = "FreeBSD-EN-08:01.libpthread" date = "2008-04-17" [[notices]] name = "FreeBSD-EN-07:05.freebsd-update" date = "2007-03-15" [[notices]] name = "FreeBSD-EN-07:04.zoneinfo" date = "2007-02-28" [[notices]] name = "FreeBSD-EN-07:03.rc.d_jail" date = "2007-02-28" [[notices]] name = "FreeBSD-EN-07:02.net" date = "2007-02-28" [[notices]] name = "FreeBSD-EN-07:01.nfs" date = "2007-02-14" [[notices]] name = "FreeBSD-EN-06:02.net" date = "2006-08-28" [[notices]] name = "FreeBSD-EN-06:01.jail" date = "2006-07-07" [[notices]] name = "FreeBSD-EN-05:04.nfs" date = "2005-12-19" [[notices]] name = "FreeBSD-EN-05:03.ipi" date = "2005-01-16" [[notices]] name = "FreeBSD-EN-05:02.sk" date = "2005-01-06" [[notices]] name = "FreeBSD-EN-05:01.nfs" date = "2005-01-05" [[notices]] name = "FreeBSD-EN-04:01.twe" date = "2004-06-28" diff --git a/website/static/security/advisories/FreeBSD-EN-26:16.arm64.asc b/website/static/security/advisories/FreeBSD-EN-26:16.arm64.asc new file mode 100644 index 0000000000..df83f21be3 --- /dev/null +++ b/website/static/security/advisories/FreeBSD-EN-26:16.arm64.asc @@ -0,0 +1,148 @@ +-----BEGIN PGP SIGNED MESSAGE----- +Hash: SHA512 + +============================================================================= +FreeBSD-EN-26:16.arm64 Errata Notice + The FreeBSD Project + +Topic: 32-bit setcontext(2) and swapcontext(2) fail on arm64 + +Category: core +Module: arm64 +Announced: 2026-06-30 +Affects: All supported versions of FreeBSD. +Corrected: 2026-06-29 08:11:12 UTC (stable/15, 15.1-STABLE) + 2026-06-30 17:21:50 UTC (releng/15.1, 15.1-RELEASE-p1) + 2026-06-30 17:21:18 UTC (releng/15.0, 15.0-RELEASE-p11) + 2026-06-29 08:14:41 UTC (stable/14, 14.4-STABLE) + 2026-06-30 17:20:53 UTC (releng/14.4, 14.4-RELEASE-p7) + 2026-06-30 17:20:26 UTC (releng/14.3, 14.3-RELEASE-p16) + +For general information regarding FreeBSD Errata Notices and Security +Advisories, including descriptions of the fields above, security +branches, and the following sections, please visit +. + +I. Background + +FreeBSD/arm64 supports running 32-bit (armv7) binaries via its +freebsd32 compatibility layer. + +The setcontext(2) and swapcontext(2) system calls allow a process to +save and restore its execution context. + +II. Problem Description + +The freebsd32 implementations of setcontext(2) and swapcontext(2) on +arm64 returned incorrect values on success, causing the system call to +be treated as though it had failed. + +III. Impact + +32-bit armv7 applications that use setcontext(2) or swapcontext(2) +may crash or behave incorrectly when running on arm64 hosts. This +has been observed to cause random crashes in Ruby applications in +particular. + +IV. Workaround + +No workaround is available. Systems that do not run 32-bit armv7 +binaries on arm64 are not affected. + +V. Solution + +Upgrade your system to a supported FreeBSD stable or release / security +branch (releng) dated after the correction date and reboot. + +Perform one of the following: + +1) To update your system installed from base system packages: + +Systems running a 15.0-RELEASE or later 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 +# shutdown -r now + +2) To update your system installed from binary distribution sets: + +Systems running a RELEASE version of FreeBSD on the amd64 or arm64 platforms +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 now + +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:16/arm64.patch +# fetch https://security.FreeBSD.org/patches/EN-26:16/arm64.patch.asc +# gpg --verify arm64.patch.asc + +b) Apply the patch. Execute the following commands as root: + +# cd /usr/src +# patch -E -p0 < /path/to/patch + +c) Recompile your kernel as described in + 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/ 964215aa1347 stable/15-n284267 +releng/15.1/ a2235baa622b releng/15.1-n283563 +releng/15.0/ b77d19dcc0d5 releng/15.0-n281065 +stable/14/ 58a15fe75cc5 stable/14-n274442 +releng/14.4/ f902821db095 releng/14.4-n273727 +releng/14.3/ e96d0e1fccf5 releng/14.3-n271527 +- ------------------------------------------------------------------------- + +Run the following command to see which files were modified by a +particular commit: + +# git show --stat + +Or visit the following URL, replacing NNNNNN with the hash: + + + +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 + +The latest revision of this advisory is available at + +-----BEGIN PGP SIGNATURE----- + +iQJPBAEBCgA5FiEEthUnfoEIffdcgYM7bljekB8AGu8FAmpEEicbFIAAAAAABAAO +bWFudTIsMi41KzEuMTIsMCwzAAoJEG5Y3pAfABrvs+0P/1v4QrAHy1/m9y7/c4UY +QNrdbnidEFMSzQiAUXaKJyJmIU9kTDlLcrsGgRw7r5KoUCux7DgW9gJ4xX9HgaDM +X4x4a5BueaU5XJtUQ+tiMWm0TRsWpiGhBc6ZvqSiHVGwQHvQrrQ4T2nBl7NdM29G +19sdVRzjj/gvytXZCrQ9FJrkUkrWb24AX9HF6LmtIifphp47uLAdqGSZtDTLyvGZ +U1zYTP0a4PETYaCk2gAfr8qQuZrx+7gDLFLnDJ9YPGIbhFVBv1ig1tMDHuwZed8o +LsLf0pVoStazpnG+G+e8VHbA31I5hN041N9q2fNU79KFcLr1ADm7X6vEniL3pqsA +CvhDq8WyQ9lhM7FLx9kfcFOOat/eWEBxjZN1gDU2asuROhcm1P9pVHlCTA5/96i2 +y/HJSUYdIgScQQ6RVV5K0ZQSfj8gJF73twhmQqRXNXekUypMwVTw0E1wXFWIE80f +kOtQmviV4j9R59efv+CTSZs73XVnx/yv97cayk/pRwxrc0ZNu3cc6B1GY7AZfu02 +jx0bsOSLF/nBz+eQYSr8+jZTT+Qv5RY5ep0uDPmqlN/QBBvT+Mccdd3lWeBbuOah +8+qaGy360hfo3PVjv+e/yMkaXJ3Gmn766TvPn4LeTwSeL+SEzHrpF/Bq4jlBXP+C +bdvDqx+46YN/96VdSl5KpnoK +=+mor +-----END PGP SIGNATURE----- diff --git a/website/static/security/advisories/FreeBSD-EN-26:17.rpcsec_tls.asc b/website/static/security/advisories/FreeBSD-EN-26:17.rpcsec_tls.asc new file mode 100644 index 0000000000..f107650133 --- /dev/null +++ b/website/static/security/advisories/FreeBSD-EN-26:17.rpcsec_tls.asc @@ -0,0 +1,146 @@ +-----BEGIN PGP SIGNED MESSAGE----- +Hash: SHA512 + +============================================================================= +FreeBSD-EN-26:17.rpcsec_tls Errata Notice + The FreeBSD Project + +Topic: Socket refcount underflow in the NFS server + +Category: core +Module: rpcsec_tls +Announced: 2026-06-30 +Affects: FreeBSD 15.0 and later +Corrected: 2026-06-22 13:26:26 UTC (stable/15, 15.1-STABLE) + 2026-06-30 17:21:51 UTC (releng/15.1, 15.1-RELEASE-p1) + 2026-06-30 17:21:19 UTC (releng/15.0, 15.0-RELEASE-p11) + +For general information regarding FreeBSD Errata Notices and Security +Advisories, including descriptions of the fields above, security +branches, and the following sections, please visit +. + +I. Background + +The kernel RPC subsystem implements Transport Layer Security (TLS) for +NFS. TLS handshakes are performed by the userspace daemon +rpc.tlsservd(8) via an upcall mechanism: the kernel inserts a pending +socket into a lookup tree, invokes the daemon, and removes the socket +once the handshake completes or fails. + +II. Problem Description + +When the kernel inserted a socket into the upcall tree, it did not +acquire its own reference on the socket. If the TLS handshake upcall +subsequently failed, the error-handling path closed the socket to +clean up the tree entry, but this effectively released the transport +layer's reference rather than one owned by the upcall tree. + +III. Impact + +A server-side TLS handshake failure, for example because rpc.tlsservd(8) +is not running, can cause a socket reference count underflow in the NFS +server. This results in a kernel panic. + +IV. Workaround + +No workaround is available. Systems that are not running an +NFS server are not affected. + +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) To update your system installed from base system packages: + +Systems running a 15.0-RELEASE or later 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 +# shutdown -r now + +2) To update your system installed from binary distribution sets: + +Systems running a RELEASE version of FreeBSD on the amd64 or arm64 platforms +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 now + +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:17/rpcsec_tls.patch +# fetch https://security.FreeBSD.org/patches/EN-26:17/rpcsec_tls.patch.asc +# gpg --verify rpcsec_tls.patch.asc + +b) Apply the patch. Execute the following commands as root: + +# cd /usr/src +# patch -E -p0 < /path/to/patch + +c) Recompile your kernel as described in + 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/ f3b14134dec1 stable/15-n284051 +releng/15.1/ c04ca8bd36f7 releng/15.1-n283564 +releng/15.0/ 7b3373d4eb5f releng/15.0-n281066 +- ------------------------------------------------------------------------- + +Run the following command to see which files were modified by a +particular commit: + +# git show --stat + +Or visit the following URL, replacing NNNNNN with the hash: + + + +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 + + + +The latest revision of this advisory is available at + +-----BEGIN PGP SIGNATURE----- + +iQJPBAEBCgA5FiEEthUnfoEIffdcgYM7bljekB8AGu8FAmpEEi4bFIAAAAAABAAO +bWFudTIsMi41KzEuMTIsMCwzAAoJEG5Y3pAfABrv6iMP+wfOwos1/WMyrtvqWs7a +u3kbN4H3ricGyNAP4SE1dEWAiFOkG17CaSBgvJMFHm4dOqtoCzSuHrwx6zOzCwbr +xSQE4LKcfimt/hh59cF1Q0701Hwk7kkf8h/hTIgF0gGr3OW+OtdguNj+p3Qx6zMG +0wZxTM5+dTquAwlmi3YUwR5+WOu9/rUoqk88m6HlddqoyGWdbhIR6X2YLD4c1zV9 +ErPckBTcBt2anBZYYwzPhmbnRE4IFfESFPvpkqPaxzga4mbQ2RZRUit2eCFwb+WD +rDhImlpcPLvJm9slvEfJw4y4pjQjIRWuKT0VBv9oobU86+3l2NPnMwU24lL6X0y3 +XEljVwjQ7ODgyGySS9FDoLzGSwnjQ+LnpNWy6yn+GV9a4v7Dp8PBduF+bLSdusrl +8zWU9EGYOv9svF8Z8Wd7uQWsAvHgXoyb2GxRhV7jj4M/BG4+49OSvW0p1u0ZwyXt +2CUiZV59MBaVddzk3Lu5iHmvVkbyNYvChGulea1j3QBn9FyrHWZ6EZ6lSXT9k5gv +RF4sT/tnx2xf/mBz2wz2yfBviprkfQwoGhBJ7txiPFsrvLIwcW+pegrRYcJ9Bx21 +GagSCWTKp7MBP1TX6L8JWiVj283m0PV48fH3Cztoa5cj5zr97USNWiCJhdDxQH52 +3RRPzqVEk2s3HPdMGoz5zwus +=LLkf +-----END PGP SIGNATURE----- diff --git a/website/static/security/advisories/FreeBSD-SA-26:37.vm.asc b/website/static/security/advisories/FreeBSD-SA-26:37.vm.asc new file mode 100644 index 0000000000..53e86f2bd3 --- /dev/null +++ b/website/static/security/advisories/FreeBSD-SA-26:37.vm.asc @@ -0,0 +1,159 @@ +-----BEGIN PGP SIGNED MESSAGE----- +Hash: SHA512 + +============================================================================= +FreeBSD-SA-26:37.vm Security Advisory + The FreeBSD Project + +Topic: Use-after-free in device pager page list + +Category: core +Module: vm +Announced: 2026-06-30 +Credits: slidybat +Affects: All supported versions of FreeBSD. +Corrected: 2026-06-30 17:20:07 UTC (stable/15, 15.1-STABLE) + 2026-06-30 17:21:52 UTC (releng/15.1, 15.1-RELEASE-p1) + 2026-06-30 17:21:20 UTC (releng/15.0, 15.0-RELEASE-p11) + 2026-06-30 17:19:47 UTC (stable/14, 14.4-STABLE) + 2026-06-30 17:20:54 UTC (releng/14.4, 14.4-RELEASE-p7) + 2026-06-30 17:20:27 UTC (releng/14.3, 14.3-RELEASE-p16) +CVE Name: CVE-2026-49418 + +For general information regarding FreeBSD Security Advisories, +including descriptions of the fields above, security branches, and the +following sections, please visit . + +I. Background + +The FreeBSD virtual memory subsystem uses pager objects to manage +memory-mapped device pages. Unmanaged device pager objects maintain +an internal list of pages allocated by the device fault handler; this +list is used to free the pages when the mapping is destroyed. + +II. Problem Description + +When msync(MS_INVALIDATE) is called on a mapping of an unmanaged device +object, the physical pages in the mapping range are marked invalid but +remain in the pager's page list. A subsequent page fault will cause the +fault handler to re-insert the page into the object's list. This +corrupts the list, and on object destruction the page is freed twice. + +III. Impact + +An unprivileged local user with access to a device that provides +memory-mapped I/O can trigger a use-after-free in the kernel, though +this is limited to a pool of objects ("fictitious pages") that are never +recycled for a different purpose. It may be possible to exploit this to +escalate privileges. + +IV. Workaround + +No workaround is available. + +V. Solution + +Upgrade your vulnerable 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) To update your vulnerable system installed from base system packages: + +Systems running a 15.0-RELEASE or later 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 +# shutdown -r +10min "Rebooting for a security update" + +2) To update your vulnerable system installed from binary distribution sets: + +Systems running a RELEASE version of FreeBSD on the amd64 or arm64 platforms +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 security update" + +3) 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-26:37/vm-15.patch +# fetch https://security.FreeBSD.org/patches/SA-26:37/vm-15.patch.asc +# gpg --verify vm-15.patch.asc + +[FreeBSD 14.x] +# fetch https://security.FreeBSD.org/patches/SA-26:37/vm-14.patch +# fetch https://security.FreeBSD.org/patches/SA-26:37/vm-14.patch.asc +# gpg --verify vm-14.patch.asc + +b) Apply the patch. Execute the following commands as root: + +# cd /usr/src +# patch -E -p0 < /path/to/patch + +c) Recompile your kernel as described in + 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/ 21929fbe1ced stable/15-n284323 +releng/15.1/ 958de92ab2dc releng/15.1-n283565 +releng/15.0/ 2baf56862bfd releng/15.0-n281067 +stable/14/ 715831359fa7 stable/14-n274447 +releng/14.4/ 4c9e89c85d7c releng/14.4-n273728 +releng/14.3/ 78bd098b9f83 releng/14.3-n271528 +- ------------------------------------------------------------------------- + +Run the following command to see which files were modified by a +particular commit: + +# git show --stat + +Or visit the following URL, replacing NNNNNN with the hash: + + + +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 + + + +The latest revision of this advisory is available at + +-----BEGIN PGP SIGNATURE----- + +iQJPBAEBCgA5FiEEthUnfoEIffdcgYM7bljekB8AGu8FAmpEEjAbFIAAAAAABAAO +bWFudTIsMi41KzEuMTIsMCwzAAoJEG5Y3pAfABrvZmgQALulswibuZPW1hUdWD6t +M/k6X1fBPbK8lg1Yj5J5Bnh4n1YyB4YzntGaAfLiq5mjpQqxskWtkpIWVqkVe3qO +TKt9113HEn9bkBBrd1u8D708atb6jAAol+JrWeYRTkkUjBTPE3Oltgv9+ln4VyOJ +agSTKRIgved3hxKr88+ms6yLQ4cymeeecPa1/0Brb+5kqWxOIia/DUbx1IebD9xY +GPzwgR9RGMdrHBQsZMwvKx7P5kdb0lp6DFhFP3y8AUZEbgjUOI3832KWje1PsXpj +wqLTxTuXGgRcARm0hl41GQO5FemrRm6sMA699aJ04EMhd+Z453IwNeBzGwsMV1R6 +vEUfqVHUUV3Kzr6MuGSFaaYpvR/99XcK0XYI6aarVfM0JaTn5Wtn80OplD+xbMpr +NN0SHRpM2zOmJ1Cmzv3qBRTGxkbBHR1Evrj8Kdc18xhV2Gn8tEhCd5RZBu7exmVA +RQxuaOD70lOk+7dV2nS+w2OYKLHMhgfWFgQCzmi37F1K7qDDScT0xlgH0rbc6l5W +ntbBim3/FTsLQxzGXcPhteWp1vYeqmMqQqyZ4cPzxqk/20LPbjmB1MSI9YlU0GHm +/e+gouXdyruJK0p4sAsH/HyrgXwqprBF4N5xOY/f/kDWznuO7w6y9yc9OynCAnxA +P8ZqzeJU+9SMnrQxrs0JcNEi +=BnYM +-----END PGP SIGNATURE----- diff --git a/website/static/security/advisories/FreeBSD-SA-26:38.jail.asc b/website/static/security/advisories/FreeBSD-SA-26:38.jail.asc new file mode 100644 index 0000000000..17f5ad3c8f --- /dev/null +++ b/website/static/security/advisories/FreeBSD-SA-26:38.jail.asc @@ -0,0 +1,155 @@ +-----BEGIN PGP SIGNED MESSAGE----- +Hash: SHA512 + +============================================================================= +FreeBSD-SA-26:38.jail Security Advisory + The FreeBSD Project + +Topic: Jail reference count underflow + +Category: core +Module: jail +Announced: 2026-06-30 +Credits: Yuxiang Yang, Yizhou Zhao, Ao Wang, Xuewei Feng, Qi Li, and + Ke Xu from Tsinghua University using GLM-5.1 from Z.ai +Affects: FreeBSD 15.0 and later +Corrected: 2026-06-12 17:59:54 UTC (stable/15, 15.1-STABLE) + 2026-06-30 17:21:54 UTC (releng/15.1, 15.1-RELEASE-p1) + 2026-06-30 17:21:21 UTC (releng/15.0, 15.0-RELEASE-p11) +CVE Name: CVE-2026-49419 + +For general information regarding FreeBSD Security Advisories, +including descriptions of the fields above, security branches, and the +following sections, please visit . + +I. Background + +Jails are an operating system virtualization technology which allow +administrators to confine processes within an environment with limited +ability to affect the system outside of that environment. The +jail_set(2) and jail_get(2) system calls are used to create, modify, +and query jails. + +Starting in FreeBSD 15.0, jails can be referred to using jail +descriptors, a type of file descriptor tied to a particular jail. The +JAIL_AT_DESC flag causes jail_set(2) and jail_get(2) to operate in the +context of the jail identified by the descriptor, rather than the +caller's current jail. + +II. Problem Description + +When the JAIL_AT_DESC flag is specified, kern_jail_set() and +kern_jail_get() released the reference to the caller's current prison +before looking up the jail descriptor. If the descriptor lookup +failed, error-handling paths released the same reference a second +time. + +III. Impact + +An unprivileged local user can trigger a prison reference count +underflow, which may cause the prison structure to be freed while still +in use. When this is done on the jail host, the bug will generally +result in an immediate panic. However, if the user is running in a +jail, then it may be possible to exploit the bug to elevate privileges. + +IV. Workaround + +No workaround is available. + +V. Solution + +Upgrade your vulnerable 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) To update your vulnerable system installed from base system packages: + +Systems running a 15.0-RELEASE or later 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 +# shutdown -r +10min "Rebooting for a security update" + +2) To update your vulnerable system installed from binary distribution sets: + +Systems running a RELEASE version of FreeBSD on the amd64 or arm64 platforms +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 security update" + +3) 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. + +# fetch https://security.FreeBSD.org/patches/SA-26:38/jail.patch +# fetch https://security.FreeBSD.org/patches/SA-26:38/jail.patch.asc +# gpg --verify jail.patch.asc + +b) Apply the patch. Execute the following commands as root: + +# cd /usr/src +# patch -E -p0 < /path/to/patch + +c) Recompile your kernel as described in + 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/ 4938fd9361b4 stable/15-n283929 +releng/15.1/ fc9fe1b9f024 releng/15.1-n283566 +releng/15.0/ 029528221261 releng/15.0-n281068 +- ------------------------------------------------------------------------- + +Run the following command to see which files were modified by a +particular commit: + +# git show --stat + +Or visit the following URL, replacing NNNNNN with the hash: + + + +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 + + + +The latest revision of this advisory is available at + +-----BEGIN PGP SIGNATURE----- + +iQJPBAEBCgA5FiEEthUnfoEIffdcgYM7bljekB8AGu8FAmpEEjQbFIAAAAAABAAO +bWFudTIsMi41KzEuMTIsMCwzAAoJEG5Y3pAfABrvyHIQAJzpVmMYymSw2XqUga4f +DLmFIgbf8rLcZPmcCJ71yFBxC/Je7jEyu5BJo+83sdxaL554UCKYtlADrtvFcb5d +Lyou2mGgchuGB50KPeUtwZw4M6BbhOvWGh4syTv/aKuoKyFRLLyWz9UiDWI32Fjh +OUuEpcsQOoGXPKcItEO+LkDGC90YxAa1ERl+Z7YbKy5oFZ7iiUrgvV+Ethx+FvK5 +WYUDJAbIlrcsF2xyKHag/j/PjNmJNt6oT7i69BHz+9NhXGKFCGqBvUeX4b8TaQM5 +R0nfYL1rBuf7vPmvQRKqXsKfzr4lPIN+g1MnILMvb85dmfukP8r3LqjLHbBoNT5a +lLoFNU7qvR3Mt4bNGxMAZegkWoD+DrgtmQhyB6Tv8EtoCaiOk08EsnKS3BPCwGlv +YYvbn4clZUfTY2bOZR1+rqeTnjgkOlqD4Jaa0c0iTyUOh/+KpfniHSFHdmxXbXjZ +upuWU+pxbfc/cHEWTAXlbJxSUOwuiNoSB4iSMAIwEM2TmrjFvri4CcgY2YJIpUoW +c5w2SLWe8GtNgipuPPQNqLPJ3fooWxrqF+fegHC2tv4lvpSOQbPFDvxOF1b+sCIR +7hxeglpyfCUwvq9k8/LZtdoFSE4HE9sKlvZ0CbabYh8C1bIoozqJlMwRg+VhG1q7 +XWX6sgatGhZHNDndm2p8/YUw +=DzLZ +-----END PGP SIGNATURE----- diff --git a/website/static/security/advisories/FreeBSD-SA-26:39.execve.asc b/website/static/security/advisories/FreeBSD-SA-26:39.execve.asc new file mode 100644 index 0000000000..81dfec2160 --- /dev/null +++ b/website/static/security/advisories/FreeBSD-SA-26:39.execve.asc @@ -0,0 +1,163 @@ +-----BEGIN PGP SIGNED MESSAGE----- +Hash: SHA512 + +============================================================================= +FreeBSD-SA-26:39.execve Security Advisory + The FreeBSD Project + +Topic: Local privilege escalation via execve(2) TOCTOU race + +Category: core +Module: execve +Announced: 2026-06-30 +Credits: Synacktiv +Affects: All supported versions of FreeBSD. +Corrected: 2026-06-26 22:20:44 UTC (stable/15, 15.1-STABLE) + 2026-06-30 17:21:55 UTC (releng/15.1, 15.1-RELEASE-p1) + 2026-06-30 17:21:22 UTC (releng/15.0, 15.0-RELEASE-p11) + 2026-06-28 00:30:18 UTC (stable/14, 14.4-STABLE) + 2026-06-30 17:20:55 UTC (releng/14.4, 14.4-RELEASE-p7) + 2026-06-30 17:20:28 UTC (releng/14.3, 14.3-RELEASE-p16) +CVE Name: CVE-2026-49415 + +For general information regarding FreeBSD Security Advisories, +including descriptions of the fields above, security branches, and the +following sections, please visit . + +I. Background + +The execve(2) system call replaces the calling process's image with a +new executable. When the target binary is set-user-ID (SUID), the +kernel installs a new virtual address space containing the binary's +code and data, then changes the process credentials to those of the +file owner. + +II. Problem Description + +During execve(2) of a SUID binary, the new virtual address space is +installed before the process credentials are updated. During this +window, a process running as the same user can access the target +process's memory via procfs or linprocfs, because the kernel's +debugging permission check still saw the original credentials. + +III. Impact + +An unprivileged local user can exploit this race to modify the +address space of a SUID binary before its credentials are elevated, +potentially gaining full control of the affected system. + +IV. Workaround + +No workaround is available. + +V. Solution + +Upgrade your vulnerable 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) To update your vulnerable system installed from base system packages: + +Systems running a 15.0-RELEASE or later 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 +# shutdown -r +10min "Rebooting for a security update" + +2) To update your vulnerable system installed from binary distribution sets: + +Systems running a RELEASE version of FreeBSD on the amd64 or arm64 platforms +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 security update" + +3) 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-26:39/execve-15.patch +# fetch https://security.FreeBSD.org/patches/SA-26:39/execve-15.patch.asc +# gpg --verify execve-15.patch.asc + +[FreeBSD 14.4] +# fetch https://security.FreeBSD.org/patches/SA-26:39/execve-14.4.patch +# fetch https://security.FreeBSD.org/patches/SA-26:39/execve-14.4.patch.asc +# gpg --verify execve-14.4.patch.asc + +[FreeBSD 14.3] +# fetch https://security.FreeBSD.org/patches/SA-26:39/execve-14.3.patch +# fetch https://security.FreeBSD.org/patches/SA-26:39/execve-14.3.patch.asc +# gpg --verify execve-14.3.patch.asc + +b) Apply the patch. Execute the following commands as root: + +# cd /usr/src +# patch -E -p0 < /path/to/patch + +c) Recompile your kernel as described in + 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/ a80e40ce9ee0 stable/15-n284141 +releng/15.1/ 46f7b5a64048 releng/15.1-n283567 +releng/15.0/ de7144f7c391 releng/15.0-n281069 +stable/14/ bb1154f3ea20 stable/14-n274435 +releng/14.4/ 8fbbc185a3ff releng/14.4-n273729 +releng/14.3/ 6772a8ece2c0 releng/14.3-n271529 +- ------------------------------------------------------------------------- + +Run the following command to see which files were modified by a +particular commit: + +# git show --stat + +Or visit the following URL, replacing NNNNNN with the hash: + + + +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 + + + +The latest revision of this advisory is available at + +-----BEGIN PGP SIGNATURE----- + +iQJPBAEBCgA5FiEEthUnfoEIffdcgYM7bljekB8AGu8FAmpEEjcbFIAAAAAABAAO +bWFudTIsMi41KzEuMTIsMCwzAAoJEG5Y3pAfABrvI88QAI5z9LuCV46PtN5Nxw7f +wv6davrwFt1N/q+hXVXKR0LNU7Q7nB5okGi0ipcjSqIC/9OaTMl9BsT7dA3yxeZi +D1SN0kdrUyTsCNy2jMR/jd21uUMpcMHJYeUEzp9SNtiMwEEWYXNgsr5mX3sqG7/Z +W6RJ5xBXfG0rePsXQ2wRkYsEZzK+sJJWSgPmxqRu+ruQYollVTExjOZfSm7l1ipq +GS150pQ3kw5XNv2+fTnTxphJCXXvB9ZQRYb0ks4D3E/+r/bmY+OZmdnhGzCh6gEh +Es4FmUAAWFbTtu355GcwOR+wy5AG1BxDVL+0D/8mM2EhbKBM5In54Q6JteMl7JeT +DL1kt9nGOG5KXOZmcJdL5vsFg6vbdDvTGD1ufgcddesp6qD5JYh00Gg/2zQTxLjj +EHIc0Oked/eIwObSKypbSYICGQRLC8QdeisdoDgmbWHAxc1OBJY/o+T6emcsDbT8 +qpl3e9CNcGTRAznrrfHS3WJatIHcvLPInxKleXUbXAwcI5IzOWDGuBgOg/GeSdsz +ybPU1NMsT+vqOQ67O7ENjJo/djXxyTQI/ExUR9nFrKZL/ma3EP4G+xyD+1pFW+Pk +HCm1RbMayr75ck7Wb6rjbc6fgPIK/djz1f2rzYMFipt8U1qiiAN552AQ6/mFMjGS +Dp8iGjzGu60Hf9IaLXxTOcYV +=HivV +-----END PGP SIGNATURE----- diff --git a/website/static/security/advisories/FreeBSD-SA-26:40.zfs.asc b/website/static/security/advisories/FreeBSD-SA-26:40.zfs.asc new file mode 100644 index 0000000000..82d21b8c2b --- /dev/null +++ b/website/static/security/advisories/FreeBSD-SA-26:40.zfs.asc @@ -0,0 +1,183 @@ +-----BEGIN PGP SIGNED MESSAGE----- +Hash: SHA512 + +============================================================================= +FreeBSD-SA-26:40.zfs Security Advisory + The FreeBSD Project + +Topic: Multiple vulnerabilities in OpenZFS + +Category: contrib +Module: openzfs +Announced: 2026-06-30 +Credits: Yuxiang Yang, Yizhou Zhao, Ao Wang, Xuewei Feng, Qi Li, + and Ke Xu from Tsinghua University using GLM-5.1 from Z.ai +Credits: Emmanuel Genier at Quarkslab +Affects: All supported versions of FreeBSD. +Corrected: 2026-06-17 07:21:06 UTC (stable/15, 15.1-STABLE) + 2026-06-30 17:21:56 UTC (releng/15.1, 15.1-RELEASE-p1) + 2026-06-30 17:21:23 UTC (releng/15.0, 15.0-RELEASE-p11) + 2026-06-30 17:19:48 UTC (stable/14, 14.4-STABLE) + 2026-06-30 17:20:56 UTC (releng/14.4, 14.4-RELEASE-p7) + 2026-06-30 17:20:29 UTC (releng/14.3, 14.3-RELEASE-p16) +CVE Name: CVE-2026-49429, CVE-2026-49430, CVE-2026-49431 + +For general information regarding FreeBSD Security Advisories, +including descriptions of the fields above, security branches, and the +following sections, please visit . + +I. Background + +ZFS is an advanced and scalable file system originally developed by Sun +Microsystems for its Solaris operating system. ZFS was integrated as +part of FreeBSD starting with FreeBSD 7.0. + +ZFS delegation allows the system administrator to grant unprivileged +users the ability to perform specific administrative operations, such +as creating snapshots or managing properties, on a per-dataset basis. +This is configured using the zfs-allow(8) command. + +II. Problem Description + +The ZFS_IOC_USERSPACE_MANY ioctl, used by zfs-userspace(8), truncated a +64-bit output buffer size to a 32-bit integer for the kernel allocation, +but used the original 64-bit size as the buffer limit when writing +records. + +The ZFS_IOC_RECV_NEW ioctl, in the heal receive path, similarly +truncated a 64-bit payload size to a 32-bit integer for allocation, +then used the original 64-bit size as the length for a byteswap +operation. + +The ZFS_IOC_SET_PROP ioctl, used by zfs-set(8), incorrectly validated +the calling user such that an unprivileged user is able to set metadata +on a dataset indicating that the dataset has received properties from +a zfs-recv(8) stream. + +III. Impact + +A local user with the "userused" delegated ZFS permission can trigger a +kernel heap overflow via the ZFS_IOC_USERSPACE_MANY ioctl, potentially +escalating privileges. [CVE-2026-49429] + +A local user with the "receive" delegated ZFS permission can trigger +kernel memory corruption via ZFS_IOC_RECV_NEW by sending a crafted +receive stream in heal mode. [CVE-2026-49430] + +Any local user can set the internal ZFS metadata flag "$hasrecvd" on +datasets via ZFS_IOC_SET_PROP. [CVE-2026-49431] + +IV. Workaround + +Systems that do not use ZFS are not affected. The first two bugs +are only triggerable by the root user or by a user with delegated +permissions. + +V. Solution + +Upgrade your vulnerable 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) To update your vulnerable system installed from base system packages: + +Systems running a 15.0-RELEASE or later 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 +# shutdown -r +10min "Rebooting for a security update" + +2) To update your vulnerable system installed from binary distribution sets: + +Systems running a RELEASE version of FreeBSD on the amd64 or arm64 platforms +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 security update" + +3) 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-26:40/zfs-15.patch +# fetch https://security.FreeBSD.org/patches/SA-26:40/zfs-15.patch.asc +# gpg --verify zfs-15.patch.asc + +[FreeBSD 14.x] +# fetch https://security.FreeBSD.org/patches/SA-26:40/zfs-14.patch +# fetch https://security.FreeBSD.org/patches/SA-26:40/zfs-14.patch.asc +# gpg --verify zfs-14.patch.asc + +b) Apply the patch. Execute the following commands as root: + +# cd /usr/src +# patch -E -p0 < /path/to/patch + +c) Recompile your kernel as described in + 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/ 25c6e6ed725d stable/15-n284009 +releng/15.1/ 7eeab0afea4d releng/15.1-n283568 +releng/15.0/ 2318d229b76a releng/15.0-n281070 +stable/14/ 6419ed0df139 stable/14-n274448 +releng/14.4/ 62f64d81b50e releng/14.4-n273730 +releng/14.3/ 6503d56e7c63 releng/14.3-n271530 +- ------------------------------------------------------------------------- + +Run the following command to see which files were modified by a +particular commit: + +# git show --stat + +Or visit the following URL, replacing NNNNNN with the hash: + + + +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 + + + + + +The latest revision of this advisory is available at + +-----BEGIN PGP SIGNATURE----- + +iQJPBAEBCgA5FiEEthUnfoEIffdcgYM7bljekB8AGu8FAmpEEjwbFIAAAAAABAAO +bWFudTIsMi41KzEuMTIsMCwzAAoJEG5Y3pAfABrvutcQANSzEdc9r+T+8QZd4M+q +1amnRPldgOo0RVKuIXRxJUisZFXA4/vI03deRulMtVLhqo4OcaDowTs973Y967Ue +yiQwKNY+CpXrJ9gp2dnyx5aN3LnxEtaRRzdfh0ZiRqeDbuV4kjPK2T2tU4iU3Cl3 +2F6pfnY+0vK95pj0QGi6GrQSLA05/RHDUhmzQ9Of/HR75wz7q29cgKufUOE21l40 +lqeoeuhDVwOOx9L9dFASJFTSj1g8FjWHH07DKO0lFVr0z7WyfwuekPnLmcJ1+30N +4EWDLdCA40rgcuugvQMK5/RRPkqBOUOX+xIzS6gNN86uW9SqDcNQAztbcEwPKtie +fcAmRHZrHmCf4Xscbv7G2eRilopaZNxrLnLiDBu3ZPBHlK3ljP5ACRgmMWxJ12T3 +hle+tp/JVNEKcAj74/Cg/WdsPPSXbaf8G3T051FRHEbBVwkZaqZBqfjdVvmfnr5Z +tMAsfFUZkzBXOTw4/7lpuHNIY2ddcn+WWK7MIFv2oKh7NhmS/3bma5KglGhQNvrK +iF7OFkGHZaMBZj+a07qSUvGzAGMlXsNhULruYPGWaA2TsMQMiJR5eT1DA/nRMwA2 +MJ/r7gliPrPzAid5CIbVk8JvgPHwv3/z3VYbrqVbRGhorbBD8F1MkXEqGs94hNuK +L3Gd4s12Y0FYaUnHaOSBqgL6 +=OdNc +-----END PGP SIGNATURE----- diff --git a/website/static/security/advisories/FreeBSD-SA-26:41.libalias.asc b/website/static/security/advisories/FreeBSD-SA-26:41.libalias.asc new file mode 100644 index 0000000000..c1ffbeb83d --- /dev/null +++ b/website/static/security/advisories/FreeBSD-SA-26:41.libalias.asc @@ -0,0 +1,172 @@ +-----BEGIN PGP SIGNED MESSAGE----- +Hash: SHA512 + +============================================================================= +FreeBSD-SA-26:41.libalias Security Advisory + The FreeBSD Project + +Topic: Buffer overflow in libalias RTSP handler + +Category: core +Module: libalias +Announced: 2026-06-30 +Credits: Atuin - Automated Vulnerability Discovery Engine, + Tianchu Chen of Tencent Xuanwu Lab +Credits: UC Berkeley Antiproof +Credits: Stanislav Fort of Aisle Research +Affects: All supported versions of FreeBSD. +Corrected: 2026-06-30 17:20:09 UTC (stable/15, 15.1-STABLE) + 2026-06-30 17:21:58 UTC (releng/15.1, 15.1-RELEASE-p1) + 2026-06-30 17:21:26 UTC (releng/15.0, 15.0-RELEASE-p11) + 2026-06-30 17:19:50 UTC (stable/14, 14.4-STABLE) + 2026-06-30 17:20:58 UTC (releng/14.4, 14.4-RELEASE-p7) + 2026-06-30 17:20:32 UTC (releng/14.3, 14.3-RELEASE-p16) +CVE Name: CVE-2026-49420 + +For general information regarding FreeBSD Security Advisories, +including descriptions of the fields above, security branches, and the +following sections, please visit . + +I. Background + +libalias is a library that performs Network Address Translation (NAT) +for outgoing and incoming IP packets. It includes protocol-specific +handlers for application-layer protocols such as RTSP that embed +addresses or port numbers in their payload. libalias is used by +ipfw(4) to implement in-kernel NAT, and by natd(8). + +II. Problem Description + +The RTSP handler in libalias rewrote outgoing packets into a +fixed-length stack buffer without checking whether the rewritten +data fit in the buffer, or whether the result fit back in the +original packet. + +III. Impact + +A host sending crafted RTSP traffic from inside a NAT gateway using libalias +can overflow a stack buffer, potentially achieving remote code execution +in the kernel (when using ipfw(4) NAT) or in the natd(8) process (which +generally runs as the root user). + +IV. Workaround + +Systems running natd(8) are vulnerable only so long as +libalias_smedia.so is listed in /etc/libalias.conf. Removing it from +that file and restarting natd(8) ensures that the vulnerable code is not +loaded. + +Systems using ipfw(4) to implement NAT are affected only if the +alias_smedia.ko kernel module is loaded. + +The affected code only runs on TCP or UDP packets undergoing outbound +NAT translation, when the source port is 554 or 7070, or the destination +port is 554 or 7070. Dropping such packets before they reach the NAT +rule prevents the bug from being triggered. + +V. Solution + +Upgrade your vulnerable 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) To update your vulnerable system installed from base system packages: + +Systems running a 15.0-RELEASE or later 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 +# shutdown -r +10min "Rebooting for a security update" + +2) To update your vulnerable system installed from binary distribution sets: + +Systems running a RELEASE version of FreeBSD on the amd64 or arm64 platforms +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 security update" + +3) 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-26:41/libalias-15.patch +# fetch https://security.FreeBSD.org/patches/SA-26:41/libalias-15.patch.asc +# gpg --verify libalias-15.patch.asc + +[FreeBSD 14.x] +# fetch https://security.FreeBSD.org/patches/SA-26:41/libalias-14.patch +# fetch https://security.FreeBSD.org/patches/SA-26:41/libalias-14.patch.asc +# gpg --verify libalias-14.patch.asc + +b) Apply the patch. Execute the following commands as root: + +# cd /usr/src +# patch -E -p0 < /path/to/patch + +c) Recompile your kernel as described in + 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/ 1546794142f9 stable/15-n284325 +releng/15.1/ 1b96804ba50d releng/15.1-n283570 +releng/15.0/ 64ce87df6876 releng/15.0-n281072 +stable/14/ 4c0f47666666 stable/14-n274450 +releng/14.4/ 0a7dd3d960c8 releng/14.4-n273732 +releng/14.3/ 935a96aa77be releng/14.3-n271532 +- ------------------------------------------------------------------------- + +Run the following command to see which files were modified by a +particular commit: + +# git show --stat + +Or visit the following URL, replacing NNNNNN with the hash: + + + +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 + + + +The latest revision of this advisory is available at + +-----BEGIN PGP SIGNATURE----- + +iQJPBAEBCgA5FiEEthUnfoEIffdcgYM7bljekB8AGu8FAmpEEkAbFIAAAAAABAAO +bWFudTIsMi41KzEuMTIsMCwzAAoJEG5Y3pAfABrvrg4QAN0ZqVi9f+0/PMb2W+5d +AmlzLM8foU/Po/ZHFgJxdNGEGjmrvJkh7YIg3/+XwnhICtai7Fgbl68PB6SYQNpe +oUQyZiS+pDJEogj7TO0WD4X5XDxmOxQ9LKrgno+jYN4DvpKvXdFs0j6Ad0pD8SNa +qi7GHz0SkEp6mG5Mdr4jr26ZiWiz1pce/buyIDJiHF1gI8munbBJ11OQZBKYCb0C +TE3jBeTPuksIL6o2+Wa8usxdqRUoiFTvRl/ueyDtcDqCasIxgbn8povTgznuPgot +7s4VOc3osXQTkABE42WXa48UzfgsiF8yCUIrYWAA7GLrhTx14gl+XPREkW0c1g/n +n2o7eSRquSQN3eAUgjvqrAmDrJlHeQoLg5w6ojqSIY3yeK8ozJakCU8DT1I/63wF +r7hFMMgVDBe+Gqb3wzq1QTl83UcqbaBYgLbhRkMsRFagMk6toKEtJxXtoBh2G03O +QOSByYug9cgbrbpA7uMZaRHJTsYJDeHFC3b1LhtBAssPq/rHNsrVaL0KQru6odWb +z6dRH4UpQr++pGD5qswBwyxkT1B3lS51sbauoSCbg5Pch3xEqzgGQjcPwaKTebU9 +kbPR8Gt8sC7AZH9tpt+L7m6jWLzP5zdYbC0YVqdaMavZGqk6QR4VwLBSj5ivdrkB +MQFPoDvZ8ua+TPP+0+yOK2hV +=O443 +-----END PGP SIGNATURE----- diff --git a/website/static/security/advisories/FreeBSD-SA-26:42.unlinkat.asc b/website/static/security/advisories/FreeBSD-SA-26:42.unlinkat.asc new file mode 100644 index 0000000000..d3532ec7e2 --- /dev/null +++ b/website/static/security/advisories/FreeBSD-SA-26:42.unlinkat.asc @@ -0,0 +1,160 @@ +-----BEGIN PGP SIGNED MESSAGE----- +Hash: SHA512 + +============================================================================= +FreeBSD-SA-26:42.unlinkat Security Advisory + The FreeBSD Project + +Topic: unlinkat(2) ignores AT_RESOLVE_BENEATH flag + +Category: core +Module: unlinkat +Announced: 2026-06-30 +Credits: Yuxiang Yang, Yizhou Zhao, Ao Wang, Xuewei Feng, Qi Li, + and Ke Xu from Tsinghua University using GLM-5.1 from Z.ai +Affects: All supported versions of FreeBSD. +Corrected: 2026-06-30 17:20:10 UTC (stable/15, 15.1-STABLE) + 2026-06-30 17:21:59 UTC (releng/15.1, 15.1-RELEASE-p1) + 2026-06-30 17:21:27 UTC (releng/15.0, 15.0-RELEASE-p11) + 2026-06-30 17:19:51 UTC (stable/14, 14.4-STABLE) + 2026-06-30 17:20:59 UTC (releng/14.4, 14.4-RELEASE-p7) + 2026-06-30 17:20:33 UTC (releng/14.3, 14.3-RELEASE-p16) +CVE Name: CVE-2026-49421 + +For general information regarding FreeBSD Security Advisories, +including descriptions of the fields above, security branches, and the +following sections, please visit . + +I. Background + +The unlinkat(2) and funlinkat(2) system calls remove directory entries +relative to a given file descriptor. The AT_RESOLVE_BENEATH flag +restricts path resolution so that it cannot ascend above the starting +directory, providing a path-containment guarantee that may be relied upon +when processing paths from an untrusted source. + +II. Problem Description + +The kernel function that implements unlinkat(2) and funlinkat(2) validated +the AT_RESOLVE_BENEATH flag but failed to pass it through to the +underlying path lookup. The flag was silently dropped, so path +resolution was not actually restricted. + +III. Impact + +A process that uses AT_RESOLVE_BENEATH with unlinkat(2) or funlinkat(2) +to confine path resolution can in fact resolve paths above the starting +directory. A caller relying on this flag for path containment may +delete files outside the intended directory tree. + +IV. Workaround + +No workaround is available. Applications that do not use +AT_RESOLVE_BENEATH with unlinkat(2) or funlinkat(2) are not affected. + +V. Solution + +Upgrade your vulnerable 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) To update your vulnerable system installed from base system packages: + +Systems running a 15.0-RELEASE or later 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 +# shutdown -r +10min "Rebooting for a security update" + +2) To update your vulnerable system installed from binary distribution sets: + +Systems running a RELEASE version of FreeBSD on the amd64 or arm64 platforms +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 security update" + +3) 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-26:42/unlinkat-15.patch +# fetch https://security.FreeBSD.org/patches/SA-26:42/unlinkat-15.patch.asc +# gpg --verify unlinkat-15.patch.asc + +[FreeBSD 14.x] +# fetch https://security.FreeBSD.org/patches/SA-26:42/unlinkat-14.patch +# fetch https://security.FreeBSD.org/patches/SA-26:42/unlinkat-14.patch.asc +# gpg --verify unlinkat-14.patch.asc + +b) Apply the patch. Execute the following commands as root: + +# cd /usr/src +# patch -E -p0 < /path/to/patch + +c) Recompile your kernel as described in + 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/ 45f1fcb9d2f7 stable/15-n284326 +releng/15.1/ 63a8e7bc0412 releng/15.1-n283571 +releng/15.0/ 278ebff1ee51 releng/15.0-n281073 +stable/14/ 7982ae91a51a stable/14-n274451 +releng/14.4/ 9a6bccc57c68 releng/14.4-n273733 +releng/14.3/ acfff8b35bfe releng/14.3-n271533 +- ------------------------------------------------------------------------- + +Run the following command to see which files were modified by a +particular commit: + +# git show --stat + +Or visit the following URL, replacing NNNNNN with the hash: + + + +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 + + + +The latest revision of this advisory is available at + +-----BEGIN PGP SIGNATURE----- + +iQJPBAEBCgA5FiEEthUnfoEIffdcgYM7bljekB8AGu8FAmpEEkMbFIAAAAAABAAO +bWFudTIsMi41KzEuMTIsMCwzAAoJEG5Y3pAfABrv7KgP/21qi7igC4TUd2Hjk7l+ +L97zhQeW3TqERBHPTNdeHF2R4dgyGzI/tYUS48btWN6rOUDS3137UE+u1dBkZPIY +MpdTszKSGZQz/wjd6M1utUWIZzGSOa+L60RSzsEucSQHwiBkNXK4hCSW9TIG3Dug +oF8HW6HIv3oZkrSET34+WWcrSWiXvEow3N0B7ICWfFp1b7rzwo7fMqhCL/1SVDtF +3hfUz6OC13HC7MVe44nHKW1LodC9fyekyfY5kD167FZtvgeIy2kn+D+ZOsJIVPsI +tgiJCerS+R9GWIhdeJcCPT+Prq/LO8Vb7x0ggTO2ejJVqwcFWgJTP4aZrtNEC0is +iYuAJPRSCHdRjBQC2ELGZVDHN4ybm8UAlkImKc48pl6ey0xTQb+iaTUKeghbupUW +7/lPpwaOHWObCwn1a5CXcTJ2LwX6vZYdLoCXM69/bTQ9fHI1zI4qo+PUUqwNVg9s +7hsWd9Y/fDXPofDI+vgnXmq87A2EGcQ6iIh5YGEkayfVfpjTJSzZ7wfUtPjRLyqt +QdMtnpFI0mnMIBmKX4ESZh2hB7E6ZG/J2Ky6ll/fA+5ITvE/D2qpzSYljOzu9ZV1 +t3UQvMNWkq4cBjJiHpvVR73Bj5vyEtSrUu70NwV80fVtQqinWalVPlWHm51tkTW+ +6mH3f+G+BExq2ovEvUQqDy6o +=Jjhy +-----END PGP SIGNATURE----- diff --git a/website/static/security/advisories/FreeBSD-SA-26:43.tcp.asc b/website/static/security/advisories/FreeBSD-SA-26:43.tcp.asc new file mode 100644 index 0000000000..f1474fff34 --- /dev/null +++ b/website/static/security/advisories/FreeBSD-SA-26:43.tcp.asc @@ -0,0 +1,157 @@ +-----BEGIN PGP SIGNED MESSAGE----- +Hash: SHA512 + +============================================================================= +FreeBSD-SA-26:43.tcp Security Advisory + The FreeBSD Project + +Topic: Use-after-free in TCP RACK stack option handler + +Category: core +Module: tcp +Announced: 2026-06-30 +Credits: Maik Muench +Affects: All supported versions of FreeBSD. +Corrected: 2026-06-30 17:20:11 UTC (stable/15, 15.1-STABLE) + 2026-06-30 17:22:00 UTC (releng/15.1, 15.1-RELEASE-p1) + 2026-06-30 17:21:28 UTC (releng/15.0, 15.0-RELEASE-p11) + 2026-06-30 17:19:52 UTC (stable/14, 14.4-STABLE) + 2026-06-30 17:21:00 UTC (releng/14.4, 14.4-RELEASE-p7) + 2026-06-30 17:20:34 UTC (releng/14.3, 14.3-RELEASE-p16) +CVE Name: CVE-2026-49422 + +For general information regarding FreeBSD Security Advisories, +including descriptions of the fields above, security branches, and the +following sections, please visit . + +I. Background + +FreeBSD supports multiple pluggable TCP stacks. A given TCP socket can +be configured to use a particular TCP implementation via setsockopt(2). + +The RACK stack implements the Recent ACKnowledgment (RACK) loss +detection algorithm and is provided as the loadable kernel module +tcp_rack.ko. + +II. Problem Description + +The RACK setsockopt(2) handler drops the connection lock in order to +copy option data from userspace, then reacquires the lock. After +reacquiring, it verifies that the TCP stack had not been switched away, +but did not reload its pointer to the stack's per-connection control +block. If userspace switches stacks twice during this window, the +check will succeed but the saved pointer will refer to freed memory. + +III. Impact + +The bug may be exploitable by an unprivileged local user to escalate +privileges. + +IV. Workaround + +Systems that have not loaded the tcp_rack.ko kernel module are not +affected. The module is not loaded by default. To check whether +it is loaded, run: + +# kldstat -m tcp_rack + +V. Solution + +Upgrade your vulnerable 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) To update your vulnerable system installed from base system packages: + +Systems running a 15.0-RELEASE or later 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 +# shutdown -r +10min "Rebooting for a security update" + +2) To update your vulnerable system installed from binary distribution sets: + +Systems running a RELEASE version of FreeBSD on the amd64 or arm64 platforms +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 security update" + +3) 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. + +# fetch https://security.FreeBSD.org/patches/SA-26:43/tcp.patch +# fetch https://security.FreeBSD.org/patches/SA-26:43/tcp.patch.asc +# gpg --verify tcp.patch.asc + +b) Apply the patch. Execute the following commands as root: + +# cd /usr/src +# patch -E -p0 < /path/to/patch + +c) Recompile your kernel as described in + 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/ aed4c4dd9afc stable/15-n284327 +releng/15.1/ 490e506a1ca8 releng/15.1-n283572 +releng/15.0/ 57b3853cc9bb releng/15.0-n281074 +stable/14/ df8885512da5 stable/14-n274452 +releng/14.4/ 800acf75eb80 releng/14.4-n273734 +releng/14.3/ 8845978fec03 releng/14.3-n271534 +- ------------------------------------------------------------------------- + +Run the following command to see which files were modified by a +particular commit: + +# git show --stat + +Or visit the following URL, replacing NNNNNN with the hash: + + + +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 + + + +The latest revision of this advisory is available at + +-----BEGIN PGP SIGNATURE----- + +iQJPBAEBCgA5FiEEthUnfoEIffdcgYM7bljekB8AGu8FAmpEEkcbFIAAAAAABAAO +bWFudTIsMi41KzEuMTIsMCwzAAoJEG5Y3pAfABrv+1AQAMZB1D+dHqyjfENkZer9 +nXE18ljPEZzAO/wZvEls9PbqqAX9eyYK7dChKsQchYiRNQVDekXc9BEgOpFJuJPH +ZbjNpH+xnzt7iMTiU2lQnOqASrtfVsvwWoLOvqeTIKr2O0Sh9v2SfyurQS8zEh6D +JdgVQKrGT6Nw0wQ/Kc/Ul4Wii2gkGP9kIcqhDRNfqMybuxAYJEYlWqKwzLlI36j+ +C7f3d5CNhhXdjuv08Rvyp6Pvh5hd04yQGiI1iN4pCqJlGLOvguPm0DJhr1WOqOcI +jjkPL5envbvOFhEDe69scIsfZnvcXv79IgYyZvz2rKnO/k3Ce7azEUWjMQemb1ZD +ih6FDn1HtOb04zTMFCtdZAd05+qr2B9BsynGcFBdg/KGG1is87VU0SpyYSv5Uj7z +tbFfxb8mPvulMqmG+l29voVBRJB5VqSr3zCBMEc/GrvI0R+d7sHWSSgB898s7XPE +H/QzpHwDmvE0k7sIDQeevjhvj93XrkS6+QOcNiJRmc9G7+UOBssxOzp20GAKD9a1 +/h2fzCpyjS3hJxQ9Y9xUeSiibS2tneZ7d4hoTZm9+5JIq3Y1ORdL0gOFHFdDIfFU +nLKNPguFAGZkd/ASS6/ULvW7UqZJ0UdQrcFS5RIBMsYNYF8uCDramlZ4qWiz2DsT +yqCs7JnSKZzpSqdKKEQSKabq +=oO9/ +-----END PGP SIGNATURE----- diff --git a/website/static/security/advisories/FreeBSD-SA-26:44.posixshm.asc b/website/static/security/advisories/FreeBSD-SA-26:44.posixshm.asc new file mode 100644 index 0000000000..f2493c1034 --- /dev/null +++ b/website/static/security/advisories/FreeBSD-SA-26:44.posixshm.asc @@ -0,0 +1,170 @@ +-----BEGIN PGP SIGNED MESSAGE----- +Hash: SHA512 + +============================================================================= +FreeBSD-SA-26:44.posixshm Security Advisory + The FreeBSD Project + +Topic: Multiple vulnerabilities in POSIX largepage objects + +Category: core +Module: posixshm +Announced: 2026-06-30 +Credits: Chris Jarrett-Davies of the OpenAI Codex Security Team +Affects: All supported versions of FreeBSD. +Corrected: 2026-06-30 17:20:14 UTC (stable/15, 15.1-STABLE) + 2026-06-30 17:22:03 UTC (releng/15.1, 15.1-RELEASE-p1) + 2026-06-30 17:21:31 UTC (releng/15.0, 15.0-RELEASE-p11) + 2026-06-30 17:19:55 UTC (stable/14, 14.4-STABLE) + 2026-06-30 17:21:04 UTC (releng/14.4, 14.4-RELEASE-p7) + 2026-06-30 17:20:37 UTC (releng/14.3, 14.3-RELEASE-p16) +CVE Name: CVE-2026-49427, CVE-2026-49428 + +For general information regarding FreeBSD Security Advisories, +including descriptions of the fields above, security branches, and the +following sections, please visit . + +I. Background + +The POSIX shared memory object module supports "largepage" objects, +which are shared memory objects backed by physically contiguous memory. +Such objects can be accessed more efficiently in some cases. For most +purposes, they behave the same as ordinary POSIX shared memory objects, +but the underlying implementation is quite different, and certain +operations cannot be performed on largepage objects. + +Largepage objects can be created using shm_create_largepage(3). + +II. Problem Description + +Pages belonging to largepage shared memory objects were not explicitly +wired. When sendfile(2) transmitted such an object with the SF_NOCACHE +flag, it freed the underlying pages after transmission even though +existing mappings still referred to them. [CVE-2026-49427] + +Separately, certain system calls, such open(2) with the O_TRUNC flag set, +and fspacectl(2), could incorrectly free memory in largepage objects. +These operations are not permitted on largepage objects, but the +implementation did not verify this. [CVE-2026-49428] + +III. Impact + +An unprivileged local user can abuse the bug to access freed kernel +memory. This can be exploited to escalate privileges. + +IV. Workaround + +No workaround is available. + +V. Solution + +Upgrade your vulnerable 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) To update your vulnerable system installed from base system packages: + +Systems running a 15.0-RELEASE or later 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 +# shutdown -r +10min "Rebooting for a security update" + +2) To update your vulnerable system installed from binary distribution sets: + +Systems running a RELEASE version of FreeBSD on the amd64 or arm64 platforms +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 security update" + +3) 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.1] +# fetch https://security.FreeBSD.org/patches/SA-26:44/posixshm-15.1.patch +# fetch https://security.FreeBSD.org/patches/SA-26:44/posixshm-15.1.patch.asc +# gpg --verify posixshm-15.1.patch.asc + +[FreeBSD 15.0] +# fetch https://security.FreeBSD.org/patches/SA-26:44/posixshm-15.0.patch +# fetch https://security.FreeBSD.org/patches/SA-26:44/posixshm-15.0.patch.asc +# gpg --verify posixshm-15.0.patch.asc + +[FreeBSD 14.x] +# fetch https://security.FreeBSD.org/patches/SA-26:44/posixshm-14.patch +# fetch https://security.FreeBSD.org/patches/SA-26:44/posixshm-14.patch.asc +# gpg --verify posixshm-14.patch.asc + +b) Apply the patch. Execute the following commands as root: + +# cd /usr/src +# patch -E -p0 < /path/to/patch + +c) Recompile your kernel as described in + 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/ 702f4c829c17 stable/15-n284330 +releng/15.1/ b15971f462b6 releng/15.1-n283575 +releng/15.0/ 8d086f03b9be releng/15.0-n281077 +stable/14/ f30052c16dba stable/14-n274455 +releng/14.4/ 0848cdea83fd releng/14.4-n273737 +releng/14.3/ 5272af920126 releng/14.3-n271537 +- ------------------------------------------------------------------------- + +Run the following command to see which files were modified by a +particular commit: + +# git show --stat + +Or visit the following URL, replacing NNNNNN with the hash: + + + +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 + + + + +The latest revision of this advisory is available at + +-----BEGIN PGP SIGNATURE----- + +iQJPBAEBCgA5FiEEthUnfoEIffdcgYM7bljekB8AGu8FAmpEEkobFIAAAAAABAAO +bWFudTIsMi41KzEuMTIsMCwzAAoJEG5Y3pAfABrv0zcP/j01bgGuZ73aAS8U1kMc +cwIZi2tTheS0vEkznQj1gEKKVnMRp9kex3spTuT10U8Ed5dWH6ADAKR0WNEf5O0f +/Uz8twaksMCECr5Nepu/cl/WfB9x7rNq7dFwtYv75gxbhE1i++dQNJictcAT9m/s +I4RtejHRHmSWKun/6k6x6LqKTpbOoueQv1SvgwGMB4gyCX8PBfmpUM068ESI0L2K +L73EICrCDBouSXgKDOvexQkmy57gPx5DfMIsUMg6nw2WmGNfPUxQQGSJ/mT53en9 +QkgrV8GTZDP2PWl8/J6MZ/MjABy5WEmmFQnu0h7ABB/oErZSbYRQj5kdlCM1CHEN +kw9eLoXLUVORV2U1+kAvPaa3qJJrktSeVjXbFPttU60QWxjfdIYOua3WTX5FrJVv +TKNOpmekA6kbqaHQV/4BhGH2teIySCzaIbJi3jG2qechP3SoIi8cpqfHD7rZgOzQ +7xPAre/kO/Ub86DRfjXPHtiDYZ0ubCQc/tSwem5oTlgElDWjH0F5sjLLlk+uGGP/ +C7kkGgPCs5O3U0Ja1wMV5b+pCKu4BDJ8c+ZXCquWi5iqqoXUwgGAQGlu8lJ7/RUH +7FXdEW2jCvk+NR4SDwPF4nq9DMP+HSsLWdrWFbwkxtqOe1vNY5IMVnUqzmHgDVsr +2pZywMqIe2szHqOdRUKwoDvM +=+cdK +-----END PGP SIGNATURE----- diff --git a/website/static/security/advisories/FreeBSD-SA-26:45.audit.asc b/website/static/security/advisories/FreeBSD-SA-26:45.audit.asc new file mode 100644 index 0000000000..9c8d2077d2 --- /dev/null +++ b/website/static/security/advisories/FreeBSD-SA-26:45.audit.asc @@ -0,0 +1,158 @@ +-----BEGIN PGP SIGNED MESSAGE----- +Hash: SHA512 + +============================================================================= +FreeBSD-SA-26:45.audit Security Advisory + The FreeBSD Project + +Topic: Incorrect audit records for ptrace(2) syscall requests + +Category: core +Module: audit +Announced: 2026-06-30 +Credits: Kyle Evans +Affects: All supported versions of FreeBSD. +Corrected: 2026-06-30 17:20:16 UTC (stable/15, 15.1-STABLE) + 2026-06-30 17:22:04 UTC (releng/15.1, 15.1-RELEASE-p1) + 2026-06-30 17:21:32 UTC (releng/15.0, 15.0-RELEASE-p11) + 2026-06-30 17:19:56 UTC (stable/14, 14.4-STABLE) + 2026-06-30 17:21:05 UTC (releng/14.4, 14.4-RELEASE-p7) + 2026-06-30 17:20:38 UTC (releng/14.3, 14.3-RELEASE-p16) +CVE Name: CVE-2026-49426 + +For general information regarding FreeBSD Security Advisories, +including descriptions of the fields above, security branches, and the +following sections, please visit . + +I. Background + +The audit(4) facility allows a system administrator to audit +security-relevant events, including system calls. + +The ptrace(2) system call permits a debugger to execute arbitrary system +calls in a target process via the PT_SC_REMOTE operation, and the +audit(4) facility records the outcome of such remotely executed system +calls. + +II. Problem Description + +When auditing a system call executed via ptrace(PT_SC_REMOTE), the +kernel passed the return value of an internal setup function to +AUDIT_SYSCALL_EXIT() rather than the actual result of the executed +system call. As a result, committed audit records for system calls +which returned an error do not reflect the true outcome of the +operation. That is, they indicate that the operation succeeded when +it in fact failed. + +III. Impact + +Audit records for system calls executed via ptrace(PT_SC_REMOTE) may +show an incorrect error status. An attacker with the ability to debug +a process could use this to produce misleading audit trails, potentially +undermining audit-based Intrusion Detection Systems (IDS). + +IV. Workaround + +No workaround is available. Systems that do not use audit(4) are not +affected. + +V. Solution + +Upgrade your vulnerable 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) To update your vulnerable system installed from base system packages: + +Systems running a 15.0-RELEASE or later 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 +# shutdown -r +10min "Rebooting for a security update" + +2) To update your vulnerable system installed from binary distribution sets: + +Systems running a RELEASE version of FreeBSD on the amd64 or arm64 platforms +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 security update" + +3) 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. + +# fetch https://security.FreeBSD.org/patches/SA-26:45/audit.patch +# fetch https://security.FreeBSD.org/patches/SA-26:45/audit.patch.asc +# gpg --verify audit.patch.asc + +b) Apply the patch. Execute the following commands as root: + +# cd /usr/src +# patch -E -p0 < /path/to/patch + +c) Recompile your kernel as described in + 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/ ec1989960781 stable/15-n284331 +releng/15.1/ 8666a62872de releng/15.1-n283576 +releng/15.0/ f887a2c04c9e releng/15.0-n281078 +stable/14/ 1763deb84ba9 stable/14-n274456 +releng/14.4/ d68c2e77d70c releng/14.4-n273738 +releng/14.3/ 8b11e7df3a62 releng/14.3-n271538 +- ------------------------------------------------------------------------- + +Run the following command to see which files were modified by a +particular commit: + +# git show --stat + +Or visit the following URL, replacing NNNNNN with the hash: + + + +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 + + + +The latest revision of this advisory is available at + +-----BEGIN PGP SIGNATURE----- + +iQJPBAEBCgA5FiEEthUnfoEIffdcgYM7bljekB8AGu8FAmpEEk8bFIAAAAAABAAO +bWFudTIsMi41KzEuMTIsMCwzAAoJEG5Y3pAfABrvrhYQANVoWdJ34ecG1KUeAl/T +2+TdDkWob/ime5tYXbsnyA2u3mbGdl9DMoCa6bbmx5D0KW5hsNIbvpHHguv6Nvss +CeBpipZrrkIQnRI0m1p9EevzrHJ+H31Rz37jYaa3usroMcpquWt28jnS28aykZGr +at/kLU2TXPZfk0/p6G6DK60gIh0l366UGqNYqgoBkSbG0eR7wDjD7KVIndCkN9Js +U+VqJHg8cwgM6O5+Hss7aTrJ8zqug1mbxFqfEabp1jBvNZf/IbiA8oyquKIEtkVl +TRrDdmmNivOQMqi8Q2Jst/gbJYrlMMvYr2UFjtX9YT5K6ayAh97Ti8NzUP8BNV4l +Hl9JMuF6BhADlQONAe4gR6bl2TqTuGnrXxlqalbTvRnix7khXo8iRkS168c8Hi8M +9+fR/bESF5YFEtnTBE3BKyr4dwTltPA3VVzL3VmhnK1HL2hQzSK3GsJloruZRbbj +UxpPiouxhLRfDzSdMp8dNdNLuXtuNQy5V6iX1QXaA3RxJ+IJL2I/K/bngNYzBBkk +4Nk09DDbVDBCgXLDGrBZgj6FAQUbACzzBY9oWOJjy65lA61IAHW4QjsyqirNOg9D +KoJfDAbCtO3C3xZKmA2rGBo6MOFJIqOxIvWXGKknQPZXJthXX/U32ewO96ik2OQl +rR9c1Q1hpdSMHhd8PCE85ZJY +=jxSH +-----END PGP SIGNATURE----- diff --git a/website/static/security/advisories/FreeBSD-SA-26:46.ktls.asc b/website/static/security/advisories/FreeBSD-SA-26:46.ktls.asc new file mode 100644 index 0000000000..0ebae11f8c --- /dev/null +++ b/website/static/security/advisories/FreeBSD-SA-26:46.ktls.asc @@ -0,0 +1,162 @@ +-----BEGIN PGP SIGNED MESSAGE----- +Hash: SHA512 + +============================================================================= +FreeBSD-SA-26:46.ktls Security Advisory + The FreeBSD Project + +Topic: Remote DOS via uninitialized memory access in KTLS receive + +Category: core +Module: ktls +Announced: 2026-06-30 +Credits: Yuxiang Yang, Yizhou Zhao, Ao Wang, Xuewei Feng, Qi Li, and + Ke Xu from Tsinghua University using GLM-5.1 from Z.ai +Affects: All supported versions of FreeBSD. +Corrected: 2026-06-30 17:20:17 UTC (stable/15, 15.1-STABLE) + 2026-06-30 17:22:06 UTC (releng/15.1, 15.1-RELEASE-p1) + 2026-06-30 17:21:33 UTC (releng/15.0, 15.0-RELEASE-p11) + 2026-06-30 17:19:58 UTC (stable/14, 14.4-STABLE) + 2026-06-30 17:21:06 UTC (releng/14.4, 14.4-RELEASE-p7) + 2026-06-30 17:20:39 UTC (releng/14.3, 14.3-RELEASE-p16) +CVE Name: CVE-2026-49423 + +For general information regarding FreeBSD Security Advisories, +including descriptions of the fields above, security branches, and the +following sections, please visit . + +I. Background + +Kernel TLS (KTLS) moves Transport Layer Security (TLS) record processing +into the kernel, allowing applications to encrypt and decrypt socket data +without copying it to and from userspace and to serve TLS data with +sendfile(2). When a connection uses software KTLS on the receive path, +the kernel decrypts each incoming TLS record in place within the socket +buffer. + +II. Problem Description + +When building the iovec array for a received TLS 1.2 CBC record, +ktls_ocf_tls_cbc_decrypt() incremented the iovec index for every +mbuf in the chain, including mbufs that were skipped because they +contained only TLS header bytes. This left uninitialized entries in +the iovec array. The iovec array was allocated without zeroing. + +III. Impact + +A remote TLS peer can cause the kernel to read from uninitialized +iovec entries during HMAC computation, resulting in a kernel panic. +The peer must be able to control TCP segmentation such that the +first mbuf of a CBC record contains only the 5-byte TLS record +header. + +IV. Workaround + +Only users running an application which enables receive-side KTLS +are affected. Systems with the kern.ipc.tls.enable sysctl set to 0 +are unaffected. + +The kern.ipc.tls.cbc_enable sysctl prevents applications from using +AES-CBC with KTLS. Setting it to 0 will prevent applications from +establishing new KTLS sessions using AES-CBC. + +V. Solution + +Upgrade your vulnerable 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) To update your vulnerable system installed from base system packages: + +Systems running a 15.0-RELEASE or later 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 +# shutdown -r +10min "Rebooting for a security update" + +2) To update your vulnerable system installed from binary distribution sets: + +Systems running a RELEASE version of FreeBSD on the amd64 or arm64 platforms +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 security update" + +3) 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. + +# fetch https://security.FreeBSD.org/patches/SA-26:46/ktls.patch +# fetch https://security.FreeBSD.org/patches/SA-26:46/ktls.patch.asc +# gpg --verify ktls.patch.asc + +b) Apply the patch. Execute the following commands as root: + +# cd /usr/src +# patch -E -p0 < /path/to/patch + +c) Recompile your kernel as described in + 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/ e4e6250999aa stable/15-n284332 +releng/15.1/ 54372e3b56b7 releng/15.1-n283577 +releng/15.0/ 5357f822416a releng/15.0-n281079 +stable/14/ a7787f9f8b8e stable/14-n274457 +releng/14.4/ 5f83a1c159a3 releng/14.4-n273739 +releng/14.3/ f769a69b2da3 releng/14.3-n271539 +- ------------------------------------------------------------------------- + +Run the following command to see which files were modified by a +particular commit: + +# git show --stat + +Or visit the following URL, replacing NNNNNN with the hash: + + + +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 + + + +The latest revision of this advisory is available at + +-----BEGIN PGP SIGNATURE----- + +iQJPBAEBCgA5FiEEthUnfoEIffdcgYM7bljekB8AGu8FAmpEElEbFIAAAAAABAAO +bWFudTIsMi41KzEuMTIsMCwzAAoJEG5Y3pAfABrv30sP/iVFbjgTnP8WcG8GwxN7 +DDoO/1HOui5ZbmNNJlgDWxwhmJXEOPlvJeZRy7H4r/+HQ3ri+sUX1cwNyhJx26X6 +TE74fmwj2Q/cC2FOUDUNYEz6VpIHzTgJjZreFwCZV59oxwKVc2tcqZvWaj7yXphq +nfDqr3hQ8xJbdpCH+3Zl7JZh/CQwmzjmXkmHB7PqAlkV8OUpO6WzuOBLPqEVISf7 +nIoasmrYAxRNy1IISCMCufHMGRoSACHdd1LWzJlP+rs0H3GisB3hcFttUf+PY+0B +EGo0D93/RtfnLAiE/6yqbUETwtNpoGT7QcIKmeOWAA8VY3VDdtBkn3Y78VRD4CW1 +iUUO7WoFs72vYr8WVcSKgUFXuWgnNQsOTmJypm1Vh+RjgXa8Jai+vUYRNW3gHUWp +WTKRNmhvrn08owFnAiWeT0Os3dIieRZEcgETiJRt7dqz0+FkOTtPWdOGKjGEkUTM +k8BxI/Uvvxn0uXEPKVQINhjBD5VBlYSehRWzkfGDgWmYQVqsLsuNL0TMOrPvqTsq +y2qS9jcfmzh5LWzfoPPFfAE/vvBCHn+MtSZLcPNPeVWnNzBVKvG1RQ194pOGUxMp +AxrXRGR8/8AcjusG4D/AC7fIEK7POpsYoo95BEoGnqJafZiBp9VRs5bKk7WLYB1t +TSdVgqVBAwCVixX6+dqoX9c4 +=rk8Z +-----END PGP SIGNATURE----- diff --git a/website/static/security/advisories/FreeBSD-SA-26:47.linux.asc b/website/static/security/advisories/FreeBSD-SA-26:47.linux.asc new file mode 100644 index 0000000000..c0c3a3f278 --- /dev/null +++ b/website/static/security/advisories/FreeBSD-SA-26:47.linux.asc @@ -0,0 +1,153 @@ +-----BEGIN PGP SIGNED MESSAGE----- +Hash: SHA512 + +============================================================================= +FreeBSD-SA-26:47.linux Security Advisory + The FreeBSD Project + +Topic: Kernel stack disclosure in Linux compatibility layer + +Category: core +Module: linux(4) +Announced: 2026-06-30 +Credits: Adam Crosser, Praetorian +Affects: FreeBSD 14.3, FreeBSD 14.4 and FreeBSD 15.0 +Corrected: 2026-03-20 13:36:36 UTC (stable/15, 15.0-STABLE) + 2026-06-30 17:21:34 UTC (releng/15.0, 15.0-RELEASE-p11) + 2026-03-20 13:37:14 UTC (stable/14, 14.4-STABLE) + 2026-06-30 17:21:07 UTC (releng/14.4, 14.4-RELEASE-p7) + 2026-06-30 17:20:41 UTC (releng/14.3, 14.3-RELEASE-p16) +CVE Name: CVE-2026-49424 + +For general information regarding FreeBSD Security Advisories, +including descriptions of the fields above, security branches, and the +following sections, please visit . + +I. Background + +The Linux ABI layer (Linuxulator) allows Linux binaries to be executed on a +FreeBSD kernel. This compatibility layer is supported on the amd64, aarch64 +and i386 architectures. + +II. Problem Description + +The Linux waitid() implementation translates a FreeBSD siginfo_t struct +into a stack-declared Linux siginfo_t. It did not first zero the stack +struct. + +III. Impact + +An unprivileged user may observe 104 bytes of uninitialized kernel stack +data, which may contain sensitive information. + +IV. Workaround + +No workaround is available, but systems not using the Linux binary +compatibility layer are not vulnerable. + +The Linux compatibility layer is not included in the default GENERIC kernel. + +The following command can be used to test if the Linux binary compatibility +layer is loaded: + +# kldstat -m linuxelf + +V. Solution + +Upgrade your vulnerable 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) To update your vulnerable system installed from base system packages: + +Systems running a 15.0-RELEASE or later 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 +# shutdown -r +10min "Rebooting for a security update" + +2) To update your vulnerable system installed from binary distribution sets: + +Systems running a RELEASE version of FreeBSD on the amd64 or arm64 platforms +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 security update" + +3) 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. + +# fetch https://security.FreeBSD.org/patches/SA-26:47/linux.patch +# fetch https://security.FreeBSD.org/patches/SA-26:47/linux.patch.asc +# gpg --verify linux.patch.asc + +b) Apply the patch. Execute the following commands as root: + +# cd /usr/src +# patch -E -p0 < /path/to/patch + +c) Recompile your kernel as described in + 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/ 9f8db9cc67fb stable/15-n282671 +releng/15.0/ 008ca5def63b releng/15.0-n281080 +stable/14/ a347e6e20e75 stable/14-n273828 +releng/14.4/ 99d936f98589 releng/14.4-n273740 +releng/14.3/ 6d0438693721 releng/14.3-n271540 +- ------------------------------------------------------------------------- + +Run the following command to see which files were modified by a +particular commit: + +# git show --stat + +Or visit the following URL, replacing NNNNNN with the hash: + + + +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 + + + +The latest revision of this advisory is available at + +-----BEGIN PGP SIGNATURE----- + +iQJPBAEBCgA5FiEEthUnfoEIffdcgYM7bljekB8AGu8FAmpEElQbFIAAAAAABAAO +bWFudTIsMi41KzEuMTIsMCwzAAoJEG5Y3pAfABrveFIQAMbywS1crIKLqntgDjOA +VHkUEsq7B3MGFnx8BfEDLZ/IubBmXpUsqYjA2mGy/4dZhnIKWq280RUAK/fXpTRU +NhXJtaaeRfq/rOOGLdiTozltDohiPWUHZ1ITyZICJsfTbNaFHFGvRNNnVcWTJh3T +15D6/j8tJMbRccAK+Bb3mjWBP5wkxtRvZ8wDFqmem7TYg+em742ZYBxMJyV8DJat +LzsRfOk7WV5lh+h0zLl5qlsYbr8WqYwxY+l2L+qVsmtuLRTy26Fx1qSivxPDjQjg +erQRy/UeudTkzQpKpVHcNmier1TW349ZyQrL+5ZB2A1+UvhBnPMztiAu8ubtxC2j +cZNnK9b/tesd6fubKtSvg+xFFzsAM6/vLwLVoMFkdGCw9hA4Z/+53uGqqaSN+KqJ +n6BaZ7kyQowYxAwvOWnN0h3zrmRBueB+C2zPwwOo6vDptZJNcj5omssjg3KYZ0/3 +bqVbA3VEhWsY4sKjh637h0m/R92fYynjcduRYhSw3pbMXmA0SROKpdTxMgnrHEXG +vViKW0cOHVRZDNZqDcI5YzfvPlXMEdAvrkWrlxvqyQOeTWei7dPLQiPKFxe/6SeQ +3qICnzzVgOkZDdjs44ued+10FacDCB6M1ixU0uPcWfoPaR79rQdNzQ8mpS1p0vbS +ixppeXaxrot6sTGKW4n7V5ek +=xA+Q +-----END PGP SIGNATURE----- diff --git a/website/static/security/advisories/FreeBSD-SA-26:48.compat32.asc b/website/static/security/advisories/FreeBSD-SA-26:48.compat32.asc new file mode 100644 index 0000000000..6603dc4efa --- /dev/null +++ b/website/static/security/advisories/FreeBSD-SA-26:48.compat32.asc @@ -0,0 +1,145 @@ +-----BEGIN PGP SIGNED MESSAGE----- +Hash: SHA512 + +============================================================================= +FreeBSD-SA-26:48.compat32 Security Advisory + The FreeBSD Project + +Topic: Kernel stack disclosure in 32-bit compatibility support + +Category: core +Module: kernel compat32 +Announced: 2026-06-30 +Credits: Adam Crosser, Praetorian +Affects: FreeBSD 14.3, FreeBSD 14.4 and FreeBSD 15.0 +Corrected: 2026-03-20 13:36:44 UTC (stable/15, 15.0-STABLE) + 2026-06-30 17:21:36 UTC (releng/15.0, 15.0-RELEASE-p11) + 2026-03-20 19:35:28 UTC (stable/14, 14.4-STABLE) + 2026-06-30 17:21:08 UTC (releng/14.4, 14.4-RELEASE-p7) + 2026-06-30 17:20:42 UTC (releng/14.3, 14.3-RELEASE-p16) +CVE Name: CVE-2026-49425 + +For general information regarding FreeBSD Security Advisories, +including descriptions of the fields above, security branches, and the +following sections, please visit . + +I. Background + +FreeBSD provides the compat32 subsystem, used to enable execution of 32-bit +binaries on 64-bit platforms. System calls whose parameters require +translation are handled by compat32 before being dispatched to the native +system call handler. + +II. Problem Description + +The compat32 kevent() handler translates a 64-bit kevent struct into a stack- +declared 32-bit struct. It did not first zero the stack struct. + +III. Impact + +An unprivileged user may observe a small amount of uninitialized kernel +stack data, which may contain sensitive information. + +IV. Workaround + +No workaround is available. + +V. Solution + +Upgrade your vulnerable 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) To update your vulnerable system installed from base system packages: + +Systems running a 15.0-RELEASE or later 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 +# shutdown -r +10min "Rebooting for a security update" + +2) To update your vulnerable system installed from binary distribution sets: + +Systems running a RELEASE version of FreeBSD on the amd64 or arm64 platforms +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 security update" + +3) 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. + +# fetch https://security.FreeBSD.org/patches/SA-26:48/compat32.patch +# fetch https://security.FreeBSD.org/patches/SA-26:48/compat32.patch.asc +# gpg --verify compat32.patch.asc + +b) Apply the patch. Execute the following commands as root: + +# cd /usr/src +# patch -E -p0 < /path/to/patch + +c) Recompile your kernel as described in + 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/ 4551ea3b3f04 stable/15-n282670 +releng/15.0/ 760b3f0b86a9 releng/15.0-n281081 +stable/14/ 6a808cd75348 stable/14-n273827 +releng/14.4/ f145e3c02b46 releng/14.4-n273741 +releng/14.3/ 495ee4943cd5 releng/14.3-n271541 +- ------------------------------------------------------------------------- + +Run the following command to see which files were modified by a +particular commit: + +# git show --stat + +Or visit the following URL, replacing NNNNNN with the hash: + + + +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 + + + +The latest revision of this advisory is available at + +-----BEGIN PGP SIGNATURE----- + +iQJPBAEBCgA5FiEEthUnfoEIffdcgYM7bljekB8AGu8FAmpEElYbFIAAAAAABAAO +bWFudTIsMi41KzEuMTIsMCwzAAoJEG5Y3pAfABrv5lMP/2tqpzYyN/2QSC81XID2 +XO3UEpYV6qeSo8barAlApENp+86yhCIo98DfinHqpRjdogFkiMBCJ42x6eBDP4xT +dlf0VAGuNxddb2hR11HWqq+h9v+sOfKmcHBWoPa8S4n2Duq52tq3/n+3y6laXOIh +uVowVNKsrQrFqcaNaLT5RB2bub7g6+a3ebWZxoLnOtJyYMYJbgb6EQBu0wFtR70O +69wl+47jkf5gIzJyHVVjSYzbuO28pkdNT0nPYVFwnxTCxasoANhMkL1hfI9Uv03x +pdjJoJAAKDQ4nfwVH7q6SowR3uk1nyXhNEv22sFzWytz9NnVILA4LS9KtpqHymoN +Ksmsf2lkzm8DZC0hKR9Ez4NhE4OuQGVWQmQ5hZrxf9RnEcPzcFQtxMJkLqGFxz7Q +JIXB1f7y0FxOormmcDIl8Sm8Ov0AkcWfen3hgA8Kf9WEPvW1GCetPGFqp7ju7LV3 +fQQfByS7YTK2kakhvYjskTown1rLKk6ZrL+YRB0DMwbOY0g6pjKUKz3X0+cKU71C +A+HLV/yBPsuKwZFBqkfKp5bVIuNeQ0nsvvlZR6sK2SifhCOzH40EcPFaK72RvP8i +hv3j/dQBWfSCY+fUuQBJBkq+UcbQlnyP18ASzMBA735utyzoWFKw/vAA6hRMKY1O +Jo5LDYRwsp8sxkWGc2nvRAtx +=W3+y +-----END PGP SIGNATURE----- diff --git a/website/static/security/advisories/FreeBSD-SA-26:49.iconv.asc b/website/static/security/advisories/FreeBSD-SA-26:49.iconv.asc new file mode 100644 index 0000000000..cc85d27472 --- /dev/null +++ b/website/static/security/advisories/FreeBSD-SA-26:49.iconv.asc @@ -0,0 +1,154 @@ +-----BEGIN PGP SIGNED MESSAGE----- +Hash: SHA512 + +============================================================================= +FreeBSD-SA-26:49.iconv Security Advisory + The FreeBSD Project + +Topic: Multiple vulnerabilities in iconv(3) + +Category: core +Module: iconv +Announced: 2026-06-30 +Credits: Nick Wellnhofer +Credits: Mark Johnston +Affects: All supported versions of FreeBSD. +Corrected: 2026-06-30 17:20:21 UTC (stable/15, 15.1-STABLE) + 2026-06-30 17:22:10 UTC (releng/15.1, 15.1-RELEASE-p1) + 2026-06-30 17:21:40 UTC (releng/15.0, 15.0-RELEASE-p11) + 2026-06-30 17:20:02 UTC (stable/14, 14.4-STABLE) + 2026-06-30 17:21:12 UTC (releng/14.4, 14.4-RELEASE-p7) + 2026-06-30 17:20:46 UTC (releng/14.3, 14.3-RELEASE-p16) +CVE Name: CVE-2026-58081, CVE-2026-58082 + +For general information regarding FreeBSD Security Advisories, +including descriptions of the fields above, security branches, and the +following sections, please visit . + +I. Background + +iconv(3) converts text between character encodings. It is implemented +as a set of loadable encoding modules in the C library, and is used by +many applications and libraries to process internationalized text. + +II. Problem Description + +Several encoding modules, including HZ, UTF-7, VIQR, and ZW, did not +properly check the size of the caller-supplied output buffer before +writing converted characters. [CVE-2026-58081] + +The ISO-2022 encoding module used a stack buffer sized to MB_LEN_MAX +(6 bytes) for intermediate character output. Some ISO-2022 variants +can require up to 10 bytes per character, in which case conversions +can trigger a stack buffer overflow of up to four bytes. [CVE-2026-58082] + +III. Impact + +An application that uses iconv(3) to convert untrusted input to or +from one of the affected encodings may be vulnerable to buffer overflows +if it uses one of the affected encoding modules. + +IV. Workaround + +No workaround is available. + +V. Solution + +Upgrade your vulnerable system to a supported FreeBSD stable or +release / security branch (releng) dated after the correction date. +Restart all applications that use iconv(3), or reboot the system. + +Perform one of the following: + +1) To update your vulnerable system installed from base system packages: + +Systems running a 15.0-RELEASE or later 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 vulnerable system installed from binary distribution sets: + +Systems running a RELEASE version of FreeBSD on the amd64 or arm64 platforms +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 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. + +# fetch https://security.FreeBSD.org/patches/SA-26:49/iconv.patch +# fetch https://security.FreeBSD.org/patches/SA-26:49/iconv.patch.asc +# gpg --verify iconv.patch.asc + +b) Apply the patch. Execute the following commands as root: + +# cd /usr/src +# patch -E -p0 < /path/to/patch + +c) Recompile the operating system using buildworld and installworld as +described in . + +Restart all daemons that use the library, 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/ 034e21efa19d stable/15-n284336 +releng/15.1/ 6b2dad9fe87d releng/15.1-n283581 +releng/15.0/ 2ac85d131d91 releng/15.0-n281085 +stable/14/ d62d0b6586a8 stable/14-n274461 +releng/14.4/ b819674449de releng/14.4-n273745 +releng/14.3/ 32f296b69571 releng/14.3-n271545 +- ------------------------------------------------------------------------- + +Run the following command to see which files were modified by a +particular commit: + +# git show --stat + +Or visit the following URL, replacing NNNNNN with the hash: + + + +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 + + + + +The latest revision of this advisory is available at + +-----BEGIN PGP SIGNATURE----- + +iQJPBAEBCgA5FiEEthUnfoEIffdcgYM7bljekB8AGu8FAmpEElkbFIAAAAAABAAO +bWFudTIsMi41KzEuMTIsMCwzAAoJEG5Y3pAfABrvlQ0QAIUrLFvc4tG5ODV7cBy/ +1b+aodwSy+bdS2pm7/YtuQ26bpqb8Qy+YVHn5reblXtuhkKcf3UJNqi+tQV2JQYp +2MsRW06fbOADHAPjKygC3I+MtvTJTb9kW2qNK8L3jalrNJQ2guqdFfl1OGyh7dqE +akBGJKMI4nSQQJePwISqp9HUTxdzw8m5V/YiYxRIlbfMjs27E2fKMXGe8Dc7aiwv +31mDg76JsYy0r3BeTEGnRHLOeMNTqxqfaSGOr1E6n93s8sbOMHMqEQogc9E6sBSK +EdSXugXdnCj2OVjnQYptlBOMZ9nVtth7hk0E/zS29DbbPlePcWiyypOKMcP3lh1t +aXTUuO8FsoCrB185k8F5y+Bo0YsgUXtKCj/aQ/cN+guxPhA1EdK+WB5aPn25AipN +UeiWBu2Lm9WdUs68telVgDAxSbXxAq+On5qjv1BTTVzT/yvu78d/CBYSHP3VRqRW +BLgV8W17UKn+0bH3tdpyaxcUN1dmbmi3Htrs/u/gqt+7bjYIxMQceg6E5sV+XIH8 +YOGiMDYSlBHzSJ7gNyN+fvhs6Gcb6NIJgP8+XfU+ov4ZbkFNmoQPxn+0uMTBsCcs +DKO4tSXQjJIg5sldGttuBfMc9+YJd1JAp+qFRadRt6j2Xzy/ntu1EZ42XQt+YGaN +HfQrYuwmrO49ZKaci+WKrWOY +=2Xrt +-----END PGP SIGNATURE----- diff --git a/website/static/security/patches/EN-26:16/arm64.patch b/website/static/security/patches/EN-26:16/arm64.patch new file mode 100644 index 0000000000..893bec2b3a --- /dev/null +++ b/website/static/security/patches/EN-26:16/arm64.patch @@ -0,0 +1,20 @@ +--- sys/arm64/arm64/freebsd32_machdep.c.orig ++++ sys/arm64/arm64/freebsd32_machdep.c +@@ -293,7 +293,7 @@ + NULL, 0); + } + } +- return (ret); ++ return (ret == 0 ? EJUSTRETURN : ret); + } + + int +@@ -341,7 +341,7 @@ + } + } + } +- return (ret); ++ return (ret == 0 ? EJUSTRETURN : ret); + } + + void diff --git a/website/static/security/patches/EN-26:16/arm64.patch.asc b/website/static/security/patches/EN-26:16/arm64.patch.asc new file mode 100644 index 0000000000..67edc30e39 --- /dev/null +++ b/website/static/security/patches/EN-26:16/arm64.patch.asc @@ -0,0 +1,17 @@ +-----BEGIN PGP SIGNATURE----- + +iQJPBAABCgA5FiEEthUnfoEIffdcgYM7bljekB8AGu8FAmpEEi0bFIAAAAAABAAO +bWFudTIsMi41KzEuMTIsMCwzAAoJEG5Y3pAfABrvOdQQANJziDYpoviclsajuzJ9 +pQHXxchrIXVDnF64HQIDWGIgJAJc1vYocNR511x31fTbMaYn9mGWLh4U4y5zhaAY +JyB+JG0BL048arRTc3Dy0hLT+TKt5R+Q0tlAzr6rXyczpFHO9yVH1hJKzIVmblZi +XGONG10Vl0DbYXzKuy3ilRtvn8bRfDrYq1Lb0jM58UFrLCoweCn8i+vT29Pu25wn +ZC8QLJ2uaLAjSKWlaLfioZGXpa0LCfSsrkxRnNgRPA06ggSoIMNHI98+WxjtP3aA +lMZcB5523ZdkFxTdUgphdCDiE+wZb5abgK0NYZehgykdH81nBV/eFY+L8NnAGrGW +32vNZkfwlVhJvE4W5uHcDOeVN85SeeKD1euA/C5iBRqh/4eRWBh8rYY2UQb2PdkY +q2dNkBpAMif/zRdNpOUxqvjeagMUnf0Rd9erlZb6ohSEjoD/vdGoPT/bjM+HzLV+ +91fX7wM/+O8HH5Qgpn54ihXIV/a+4/R79EGY9fMsNoSKjn9YJuD6dGry7BaE+HFB +bvNBdyXwpSqu4TAwiQ4yiSotBnV4mHkE7BwdP8dk+/6kH4OBtTDtlsDcagm7DeWo +MJRajyowuc+QZBbJ0QTn4CJycyKSFaXnF54fER9nDAr5KjEoCP+7wMj8WjhvJ0eQ +sHXtdgyC8ihRAZYqr+LxSdQZ +=8jTb +-----END PGP SIGNATURE----- diff --git a/website/static/security/patches/EN-26:17/rpcsec_tls.patch b/website/static/security/patches/EN-26:17/rpcsec_tls.patch new file mode 100644 index 0000000000..dd2392ffb9 --- /dev/null +++ b/website/static/security/patches/EN-26:17/rpcsec_tls.patch @@ -0,0 +1,64 @@ +--- sys/rpc/rpcsec_tls/rpctls_impl.c.orig ++++ sys/rpc/rpcsec_tls/rpctls_impl.c +@@ -190,7 +190,6 @@ + KRPC_CURVNET_RESTORE(); + return (error); + } +- soref(ups.so); + if (ups.server) { + /* + * Once this file descriptor is associated +@@ -277,6 +276,7 @@ + if (stat != RPC_SUCCESS) + return (RPC_SYSTEMERROR); + ++ soref(so); + mtx_lock(&rpctls_lock); + RB_INSERT(upsock_t, &upcall_sockets, &ups); + mtx_unlock(&rpctls_lock); +@@ -294,9 +294,16 @@ + stat = rpctlscd_connect_2(&arg, &res, rpctls_connect_handle); + if (stat == RPC_SUCCESS) + *reterr = res.reterr; +- else ++ else { + rpctls_rpc_failed(&ups, so); + ++ /* ++ * The socket was closed, make sure the krpc code doesn't close ++ * it a second time. ++ */ ++ CLNT_CONTROL(newclient, CLSET_TLS, &(int){RPCTLS_INHANDSHAKE}); ++ } ++ + /* Unblock reception. */ + CLNT_CONTROL(newclient, CLSET_BLOCKRCV, &(int){0}); + +@@ -388,6 +395,7 @@ + uint32_t *gidv; + int i; + ++ soref(xprt->xp_socket); + mtx_lock(&rpctls_lock); + RB_INSERT(upsock_t, &upcall_sockets, &ups); + mtx_unlock(&rpctls_lock); +@@ -407,9 +415,18 @@ + for (i = 0; i < *ngrps; i++) + *gidp++ = *gidv++; + } +- } else ++ } else { + rpctls_rpc_failed(&ups, xprt->xp_socket); + ++ /* ++ * The socket was closed, make sure the krpc code doesn't close ++ * it a second time. ++ */ ++ sx_xlock(&ups.xp->xp_lock); ++ ups.xp->xp_tls = RPCTLS_FLAGS_HANDSHFAIL; ++ sx_xunlock(&ups.xp->xp_lock); ++ } ++ + mem_free(res.gid.gid_val, 0); + + #ifdef INVARIANTS diff --git a/website/static/security/patches/EN-26:17/rpcsec_tls.patch.asc b/website/static/security/patches/EN-26:17/rpcsec_tls.patch.asc new file mode 100644 index 0000000000..d6aefc43e9 --- /dev/null +++ b/website/static/security/patches/EN-26:17/rpcsec_tls.patch.asc @@ -0,0 +1,17 @@ +-----BEGIN PGP SIGNATURE----- + +iQJPBAABCgA5FiEEthUnfoEIffdcgYM7bljekB8AGu8FAmpEEi8bFIAAAAAABAAO +bWFudTIsMi41KzEuMTIsMCwzAAoJEG5Y3pAfABrvSCsP+wRQQrnsuZzq4bCoupcO +80J+Sn6aT2YQ8DXLi+Exzw1YKZedrqdN9vfZjoPGlcqvT9voeYHmACfSB2YSgy+p ++hvfdLxnsR1cH+bXOApT2kxWO/NOlz3BocpAWxoSl9gXS3Qq9At7mLLhnTBteiro +rOBC/LhJXugybMrp2Szbtb9eeAjTk3HLHjPq4U7zpB3l7xrbNlcm4TbV510POgLa +MpwgOyy0kcw2RJDyH5vjlcYXxOgfSj/6JHyFdFrJK+Tk6FcJYZd/RSe5y7IcFR2y +FW3AMqpQjCKS28cOO/DukjC0TrN6+Q7/QYRObFWjEEe06ewBKnTsSM/FsR6sre2i +ZDk1Ldle1Yatbqz28CSsS1xTN7JMl1VvBNK48Ablsl0aLr9EnDHWQKZ3bV1GAhdl +ZqRRP7mrFrvtTP75kqRPYkgRywzULhTVN0mqxsem6n2z8/iXKCHX9Xvxg9ekPIm4 +ys4kVssJUqc2+cVI/Zj+TR5DO+abH+TuMvLnzPPcyhW/9ut/Aj+5CjqZLkY0uryI +qfV01TmNyWa3ar7R+zS+Atq2RTzz67aNzHFJkhWacWcK9CpWUWX7OmX4XAVhHIvR +6SEHky5BAO1zbKSufTLonGRRU1U9bp8VmC1pqZa5IkuPNqJGdotPdgoWH6AtsNW/ +7GQ4je6XSQY5bUo3zYmUEmXg +=yqlC +-----END PGP SIGNATURE----- diff --git a/website/static/security/patches/SA-26:37/vm-14.patch b/website/static/security/patches/SA-26:37/vm-14.patch new file mode 100644 index 0000000000..843b0c1b86 --- /dev/null +++ b/website/static/security/patches/SA-26:37/vm-14.patch @@ -0,0 +1,142 @@ +--- sys/vm/device_pager.c.orig ++++ sys/vm/device_pager.c +@@ -210,7 +210,8 @@ + object1 = NULL; + object->handle = handle; + object->un_pager.devp.ops = ops; +- TAILQ_INIT(&object->un_pager.devp.devp_pglist); ++ if (object->type == OBJT_DEVICE) ++ vm_object_set_flag(object, OBJ_PG_DTOR); + TAILQ_INSERT_TAIL(&dev_pager_object_list, object, + pager_object_list); + mtx_unlock(&dev_pager_mtx); +@@ -282,15 +283,12 @@ + KASSERT((object->type == OBJT_DEVICE && + (m->oflags & VPO_UNMANAGED) != 0), + ("Managed device or page obj %p m %p", object, m)); +- TAILQ_REMOVE(&object->un_pager.devp.devp_pglist, m, plinks.q); + vm_page_putfake(m); + } + + static void + dev_pager_dealloc(vm_object_t object) + { +- vm_page_t m; +- + VM_OBJECT_WUNLOCK(object); + object->un_pager.devp.ops->cdev_pg_dtor(object->un_pager.devp.handle); + +@@ -300,15 +298,21 @@ + VM_OBJECT_WLOCK(object); + + if (object->type == OBJT_DEVICE) { +- /* +- * Free up our fake pages. +- */ +- while ((m = TAILQ_FIRST(&object->un_pager.devp.devp_pglist)) +- != NULL) { +- if (vm_page_busy_acquire(m, VM_ALLOC_WAITFAIL) == 0) +- continue; +- +- dev_pager_free_page(object, m); ++ vm_page_t m, mtmp; ++ ++restart: ++ TAILQ_FOREACH_SAFE(m, &object->memq, listq, mtmp) { ++ if (!vm_page_busy_acquire(m, VM_ALLOC_WAITFAIL)) ++ goto restart; ++ if (vm_page_remove(m)) { ++ /* ++ * We could end up with invalid pages installed ++ * by the generic page fault handler. Typically ++ * these are replaced by the device pager. ++ */ ++ vm_page_free(m); ++ } else if ((m->flags & PG_FICTITIOUS) != 0) ++ dev_pager_free_page(object, m); + } + } + object->handle = NULL; +@@ -337,10 +341,6 @@ + (object->type == OBJT_MGTDEVICE && + (ma[0]->oflags & VPO_UNMANAGED) == 0), + ("Wrong page type %p %p", ma[0], object)); +- if (object->type == OBJT_DEVICE) { +- TAILQ_INSERT_TAIL(&object->un_pager.devp.devp_pglist, +- ma[0], plinks.q); +- } + if (rbehind) + *rbehind = 0; + if (rahead) +--- sys/vm/vm_object.h.orig ++++ sys/vm/vm_object.h +@@ -137,7 +137,7 @@ + * devp_pglist - list of allocated pages + */ + struct { +- TAILQ_HEAD(, vm_page) devp_pglist; ++ void *spare[2]; + const struct cdev_pager_ops *ops; + void *handle; + } devp; +--- sys/vm/vm_page.c.orig ++++ sys/vm/vm_page.c +@@ -1301,8 +1301,10 @@ + KASSERT((m->oflags & VPO_UNMANAGED) != 0, ("managed %p", m)); + KASSERT((m->flags & PG_FICTITIOUS) != 0, + ("vm_page_putfake: bad page %p", m)); +- vm_page_assert_xbusied(m); +- vm_page_busy_free(m); ++ if (m->object != NULL) { ++ vm_page_assert_xbusied(m); ++ vm_page_busy_free(m); ++ } + uma_zfree(fakepg_zone, m); + } + +--- tests/sys/vm/mmap_test.c.orig ++++ tests/sys/vm/mmap_test.c +@@ -362,6 +362,35 @@ + ATF_REQUIRE(close(fd) == 0); + } + ++/* A regression test for a bug in the device pager. */ ++ATF_TC_WITHOUT_HEAD(mmap__device_reinsert); ++ATF_TC_BODY(mmap__device_reinsert, tc) ++{ ++ void *p; ++ int fd; ++ ++ fd = open("/dev/devstat", O_RDONLY); ++ ATF_REQUIRE(fd >= 0); ++ ++ p = mmap(NULL, getpagesize(), PROT_READ, MAP_SHARED, fd, 0); ++ ATF_REQUIRE(p != MAP_FAILED); ++ ++ /* ++ * Use mlock() to trigger a fault, since msync() will not actually ++ * remove the page from the process page tables. ++ */ ++ ATF_REQUIRE(mlock(p, getpagesize()) == 0); ++ ATF_REQUIRE(munlock(p, getpagesize()) == 0); ++ ATF_REQUIRE(msync(p, getpagesize(), MS_INVALIDATE) == 0); ++ ATF_REQUIRE(mlock(p, getpagesize()) == 0); ++ ATF_REQUIRE(munlock(p, getpagesize()) == 0); ++ ATF_REQUIRE(msync(p, getpagesize(), MS_INVALIDATE) == 0); ++ ATF_REQUIRE(mlock(p, getpagesize()) == 0); ++ ATF_REQUIRE(munlock(p, getpagesize()) == 0); ++ ++ ATF_REQUIRE(munmap(p, getpagesize()) == 0); ++} ++ + ATF_TP_ADD_TCS(tp) + { + ATF_TP_ADD_TC(tp, mmap__map_at_zero); +@@ -371,6 +400,7 @@ + ATF_TP_ADD_TC(tp, mmap__write_only); + ATF_TP_ADD_TC(tp, mmap__maxprot_basic); + ATF_TP_ADD_TC(tp, mmap__maxprot_shm); ++ ATF_TP_ADD_TC(tp, mmap__device_reinsert); + + return (atf_no_error()); + } diff --git a/website/static/security/patches/SA-26:37/vm-14.patch.asc b/website/static/security/patches/SA-26:37/vm-14.patch.asc new file mode 100644 index 0000000000..5739d3208b --- /dev/null +++ b/website/static/security/patches/SA-26:37/vm-14.patch.asc @@ -0,0 +1,17 @@ +-----BEGIN PGP SIGNATURE----- + +iQJPBAABCgA5FiEEthUnfoEIffdcgYM7bljekB8AGu8FAmpEEjIbFIAAAAAABAAO +bWFudTIsMi41KzEuMTIsMCwzAAoJEG5Y3pAfABrvvSQP/0Uvnprz4fHtS8qH5VnY +f5eXQCIvm8q4tV3HawE9bagCmxS7iaAIv1hLccs4hAica3UksI3yo6lOFryDsaJD +qpixdmLawrcL1uquWqKA6TtHo3iQRvZ4wJQVCNOYN4fBD35+Qlirg6s9cBBFgEo0 +deyetRFRRFLyuNUSQQ3Y+dMan5I25wY0TgQHtxB3nNLKuqOPAfrssrgIe2d52t1T +vNtO790XHN0QBkmEyi9q63zUL+LH7R2wsOxbv4JwkNhnvwTBGthUGG5La+8bkZvS +tSZdCGYDaqnx2lzF4doAhXv39si7bYngUL9+5yoxbjazrZDeaPf1zc+WHbJfbifa +H0GjVHkqCxjYg96a6CpwxDYVo44O92HW7Snx6lKOfHrFN9Wjdy9qLcAzyelic+A6 +WquGk1mbUOCzmBe74YO72/Du3A4uTBkzfjf7ppXKpVB9TEfNZw3CRBzga6QnGhVK +0HdUzBFJYmf7JEq4CxTgfsrrks70UL49z5rVp+WNmXzkKngOOQeatelzx0lpyrfy +3y9/OHUhTOo5UOIB/+eCdkBWc4v9G7GsCBirVEdc0ZQ/6K+NyBXqFiKMyQhfp4+l +o2tZ9gC38eWWq999mh2UCWx5pGH7kcQFlo5M69gwJvvdYEIWlBnNCxWyh5xEMrME +T9KkfeXdevqu2NDl5sKDJ4Nl +=3aO6 +-----END PGP SIGNATURE----- diff --git a/website/static/security/patches/SA-26:37/vm-15.patch b/website/static/security/patches/SA-26:37/vm-15.patch new file mode 100644 index 0000000000..517ca1515e --- /dev/null +++ b/website/static/security/patches/SA-26:37/vm-15.patch @@ -0,0 +1,145 @@ +--- sys/vm/device_pager.c.orig ++++ sys/vm/device_pager.c +@@ -213,7 +213,8 @@ + object1 = NULL; + object->handle = handle; + object->un_pager.devp.ops = ops; +- TAILQ_INIT(&object->un_pager.devp.devp_pglist); ++ if (object->type == OBJT_DEVICE) ++ vm_object_set_flag(object, OBJ_PG_DTOR); + TAILQ_INSERT_TAIL(&dev_pager_object_list, object, + pager_object_list); + mtx_unlock(&dev_pager_mtx); +@@ -325,15 +326,12 @@ + KASSERT((object->type == OBJT_DEVICE && + (m->oflags & VPO_UNMANAGED) != 0), + ("Managed device or page obj %p m %p", object, m)); +- TAILQ_REMOVE(&object->un_pager.devp.devp_pglist, m, plinks.q); + vm_page_putfake(m); + } + + static void + dev_pager_dealloc(vm_object_t object) + { +- vm_page_t m; +- + VM_OBJECT_WUNLOCK(object); + object->un_pager.devp.ops->cdev_pg_dtor(object->un_pager.devp.handle); + +@@ -343,15 +341,25 @@ + VM_OBJECT_WLOCK(object); + + if (object->type == OBJT_DEVICE) { +- /* +- * Free up our fake pages. +- */ +- while ((m = TAILQ_FIRST(&object->un_pager.devp.devp_pglist)) +- != NULL) { +- if (vm_page_busy_acquire(m, VM_ALLOC_WAITFAIL) == 0) +- continue; ++ struct pctrie_iter pages; ++ vm_page_t m; + +- dev_pager_free_page(object, m); ++ vm_page_iter_init(&pages, object); ++restart: ++ VM_RADIX_FOREACH(m, &pages) { ++ if (!vm_page_busy_acquire(m, VM_ALLOC_WAITFAIL)) { ++ pctrie_iter_reset(&pages); ++ goto restart; ++ } ++ if (vm_page_iter_remove(&pages, m)) { ++ /* ++ * We could end up with invalid pages installed ++ * by the generic page fault handler. Typically ++ * these are replaced by the device pager. ++ */ ++ vm_page_free(m); ++ } else if ((m->flags & PG_FICTITIOUS) != 0) ++ dev_pager_free_page(object, m); + } + } + object->handle = NULL; +@@ -380,10 +388,6 @@ + (object->type == OBJT_MGTDEVICE && + (ma[0]->oflags & VPO_UNMANAGED) == 0), + ("Wrong page type %p %p", ma[0], object)); +- if (object->type == OBJT_DEVICE) { +- TAILQ_INSERT_TAIL(&object->un_pager.devp.devp_pglist, +- ma[0], plinks.q); +- } + if (rbehind) + *rbehind = 0; + if (rahead) +--- sys/vm/vm_object.h.orig ++++ sys/vm/vm_object.h +@@ -134,7 +134,7 @@ + * devp_pglist - list of allocated pages + */ + struct { +- TAILQ_HEAD(, vm_page) devp_pglist; ++ void *spare[2]; + const struct cdev_pager_ops *ops; + void *handle; + } devp; +--- sys/vm/vm_page.c.orig ++++ sys/vm/vm_page.c +@@ -1363,8 +1363,10 @@ + KASSERT((m->oflags & VPO_UNMANAGED) != 0, ("managed %p", m)); + KASSERT((m->flags & PG_FICTITIOUS) != 0, + ("vm_page_putfake: bad page %p", m)); +- vm_page_assert_xbusied(m); +- vm_page_busy_free(m); ++ if (m->object != NULL) { ++ vm_page_assert_xbusied(m); ++ vm_page_busy_free(m); ++ } + uma_zfree(fakepg_zone, m); + } + +--- tests/sys/vm/mmap_test.c.orig ++++ tests/sys/vm/mmap_test.c +@@ -362,6 +362,35 @@ + ATF_REQUIRE(close(fd) == 0); + } + ++/* A regression test for a bug in the device pager. */ ++ATF_TC_WITHOUT_HEAD(mmap__device_reinsert); ++ATF_TC_BODY(mmap__device_reinsert, tc) ++{ ++ void *p; ++ int fd; ++ ++ fd = open("/dev/devstat", O_RDONLY); ++ ATF_REQUIRE(fd >= 0); ++ ++ p = mmap(NULL, getpagesize(), PROT_READ, MAP_SHARED, fd, 0); ++ ATF_REQUIRE(p != MAP_FAILED); ++ ++ /* ++ * Use mlock() to trigger a fault, since msync() will not actually ++ * remove the page from the process page tables. ++ */ ++ ATF_REQUIRE(mlock(p, getpagesize()) == 0); ++ ATF_REQUIRE(munlock(p, getpagesize()) == 0); ++ ATF_REQUIRE(msync(p, getpagesize(), MS_INVALIDATE) == 0); ++ ATF_REQUIRE(mlock(p, getpagesize()) == 0); ++ ATF_REQUIRE(munlock(p, getpagesize()) == 0); ++ ATF_REQUIRE(msync(p, getpagesize(), MS_INVALIDATE) == 0); ++ ATF_REQUIRE(mlock(p, getpagesize()) == 0); ++ ATF_REQUIRE(munlock(p, getpagesize()) == 0); ++ ++ ATF_REQUIRE(munmap(p, getpagesize()) == 0); ++} ++ + ATF_TP_ADD_TCS(tp) + { + ATF_TP_ADD_TC(tp, mmap__map_at_zero); +@@ -371,6 +400,7 @@ + ATF_TP_ADD_TC(tp, mmap__write_only); + ATF_TP_ADD_TC(tp, mmap__maxprot_basic); + ATF_TP_ADD_TC(tp, mmap__maxprot_shm); ++ ATF_TP_ADD_TC(tp, mmap__device_reinsert); + + return (atf_no_error()); + } diff --git a/website/static/security/patches/SA-26:37/vm-15.patch.asc b/website/static/security/patches/SA-26:37/vm-15.patch.asc new file mode 100644 index 0000000000..a8592736e2 --- /dev/null +++ b/website/static/security/patches/SA-26:37/vm-15.patch.asc @@ -0,0 +1,17 @@ +-----BEGIN PGP SIGNATURE----- + +iQJPBAABCgA5FiEEthUnfoEIffdcgYM7bljekB8AGu8FAmpEEjMbFIAAAAAABAAO +bWFudTIsMi41KzEuMTIsMCwzAAoJEG5Y3pAfABrvux8P/32mEUiInkRV6MN+OFtI +rgS/EMR9cA/l1OQx+aThVmBePd4WSuvszz/AgRq7fOAvWg6HPsecafdr4/McLoA3 +z18zJO6FVQp49RWZ3CZgH+Im+Zq/5FZy8PWAGwkXREvx3+qawIjD/EDEExA3BMkQ +PpEZyLKM4F7h6dIMKW8b7TxSaj5Ik9Kx9LljzfgygQlmtIwZG0d+rVG0kvHOeONk +d8cYpqo2aUcXBvYaxDDOMxzbWDbUbuyFPkOFZen2I9StoZlpbJRjNz6JI9uDAkc5 +ikIM3a9zygDDXrSgt4V4fSUlvghoiuXx1hVgBauSEeKjNuD+1dzsTk6B7IdxPm61 +IH2hnjY02lqRrjMLEtpNAAb9MZprYoDuY7X0/p8XPHn487EQ6Eq3ygginqh6zcFr +aw6m6JR39hRYIJmk+DGDc6Z6NO8pbQ6IeeC5FRxdOr7n1TaIpNHmNt5siZUbRPYa +PjuJ+xOt80IUASGXDJjG8tTYPwip4m34AiGt3rYFKS3wsspAkyZkBk3P+CzSiND0 +/yloh9KDrWfrLNlsPiaaEcKooehCMkg9GAFn+aX1SIt1hfNvS3ks+d6VHot43TVh +2ChPIgS3GNwbTVplXEZsZJu2p0FfHgvCF+v897SDmQIWr7WEtRFf9mSlTO0gAQ7j +RuFI/NZKs+LXXT5aY2MxC7jb +=1gEQ +-----END PGP SIGNATURE----- diff --git a/website/static/security/patches/SA-26:38/jail.patch b/website/static/security/patches/SA-26:38/jail.patch new file mode 100644 index 0000000000..76f8c0d24f --- /dev/null +++ b/website/static/security/patches/SA-26:38/jail.patch @@ -0,0 +1,42 @@ +--- sys/kern/kern_jail.c.orig ++++ sys/kern/kern_jail.c +@@ -1101,14 +1101,17 @@ + * Look up and create jails based on the + * descriptor's prison. + */ +- prison_free(mypr); +- error = jaildesc_find(td, jfd_in, &mypr, NULL); ++ struct prison *jdpr; ++ ++ error = jaildesc_find(td, jfd_in, &jdpr, NULL); + if (error != 0) { + vfs_opterror(opts, error == ENOENT ? + "descriptor to dead jail" : + "not a jail descriptor"); + goto done_errmsg; + } ++ prison_free(mypr); ++ mypr = jdpr; + if ((flags & JAIL_CREATE) && mypr->pr_childmax == 0) { + error = EPERM; + goto done_free; +@@ -2550,14 +2553,17 @@ + } + if (flags & JAIL_AT_DESC) { + /* Look up jails based on the descriptor's prison. */ +- prison_free(mypr); +- error = jaildesc_find(td, jfd_in, &mypr, NULL); ++ struct prison *jdpr; ++ ++ error = jaildesc_find(td, jfd_in, &jdpr, NULL); + if (error != 0) { + vfs_opterror(opts, error == ENOENT ? + "descriptor to dead jail" : + "not a jail descriptor"); + goto done; + } ++ prison_free(mypr); ++ mypr = jdpr; + } + if (flags & (JAIL_GET_DESC | JAIL_OWN_DESC)) { + /* Allocate a jail descriptor to return later. */ diff --git a/website/static/security/patches/SA-26:38/jail.patch.asc b/website/static/security/patches/SA-26:38/jail.patch.asc new file mode 100644 index 0000000000..ee142b7b98 --- /dev/null +++ b/website/static/security/patches/SA-26:38/jail.patch.asc @@ -0,0 +1,17 @@ +-----BEGIN PGP SIGNATURE----- + +iQJPBAABCgA5FiEEthUnfoEIffdcgYM7bljekB8AGu8FAmpEEjYbFIAAAAAABAAO +bWFudTIsMi41KzEuMTIsMCwzAAoJEG5Y3pAfABrv6BMP/20s+harD9JY46gKIl21 +eRthJZz5+hcVfi1bfiMpV+yCWppCrShFGTWykBQTY+fSpq7Pfw8DrzB2H5azeB2j +cLGTu3uqUvrU/uVqAa2LYCXLP26vXaxOtSDqcRh/BreKljdUIelA19qzOt+LP2H9 +PkIgVqL/LfA/cwAQszz96qBWfHahSbH0wyMyfoVFSHIf9p2XB7YCIsFmBnGF2l2s +LvHjKEIUNmhMYKXiJOVrmU84uG2EgCyXbifdaRehrjkM7LyNzPRBaOV7Ezt0EDep +A5hc1RdLVrq9ZlL+cp/vYbgD46TFdEnFFn6zVi7sncyyblp8f/oBD+sdXqKQzQAh +cU0zw/5HwdwRc3whjyQrP9jy8KDga1leKiFq15MFB9DQZvimi5juvfK/ZxDxcCWM +lWL6NqxXnDRWxj1xNj6lDaYkTpYN1dWrTzfA13CWxkjfdRT8yzxacqwQIWrirkKJ +XrZcDJNszwUcfbd1vViYiPv0WiIPa4UYfRZLxCGRcYfyToN2q9bWR2+WsdqtRNsR +yi5CeEcOB6gIWQOrr+fzeC9Ux66bTA1Vc8Ux74IGnlaDtt+K9xtn6xtNIUW+TzND +G41WdbmDaZ8uNSmUPRRqbyLsnNSnbdrEUxpaZBsvzijwwiMDrofuELOZsGcpwkC4 +gvBs14DVojpg21Ge2cKijCaF +=WeSY +-----END PGP SIGNATURE----- diff --git a/website/static/security/patches/SA-26:39/execve-14.3.patch b/website/static/security/patches/SA-26:39/execve-14.3.patch new file mode 100644 index 0000000000..479fb15f9b --- /dev/null +++ b/website/static/security/patches/SA-26:39/execve-14.3.patch @@ -0,0 +1,1526 @@ +--- sys/compat/linprocfs/linprocfs.c.orig ++++ sys/compat/linprocfs/linprocfs.c +@@ -1317,19 +1317,13 @@ + struct vattr vat; + bool private; + +- PROC_LOCK(p); +- error = p_candebug(td, p); +- PROC_UNLOCK(p); +- if (error) +- return (error); +- + if (uio->uio_rw != UIO_READ) + return (EOPNOTSUPP); + +- error = 0; +- vm = vmspace_acquire_ref(p); +- if (vm == NULL) +- return (ESRCH); ++ error = proc_vmspace_ref(td, p, PRVM_BLOCK_EXEC | PRVM_CHECK_DEBUG, ++ &vm); ++ if (error != 0) ++ return (error); + + if (SV_CURPROC_FLAG(SV_LP64)) + l_map_str = l64_map_str; +@@ -1427,7 +1421,7 @@ + } + } + vm_map_unlock_read(map); +- vmspace_free(vm); ++ proc_vmspace_unref(td, p, PRVM_CHECK_DEBUG | PRVM_BLOCK_EXEC, vm); + + return (error); + } +--- sys/compat/linux/linux_misc.c.orig ++++ sys/compat/linux/linux_misc.c +@@ -2007,6 +2007,7 @@ + u_int which; + int flags; + int error; ++ bool exec_blocked; + + if (args->new == NULL && args->old != NULL) { + if (linux_get_dummy_limit(args->resource, &rlim)) { +@@ -2034,6 +2035,7 @@ + return (error); + } + ++ exec_blocked = false; + flags = PGET_HOLD | PGET_NOTWEXIT; + if (args->new != NULL) + flags |= PGET_CANDEBUG; +@@ -2046,6 +2048,14 @@ + error = pget(args->pid, flags, &p); + if (error != 0) + return (error); ++ exec_blocked = true; ++ PROC_LOCK(p); ++ execve_block_wait(td, p); ++ error = args->new != NULL ? p_candebug(td, p) : ++ p_cansee(td, p); ++ PROC_UNLOCK(p); ++ if (error != 0) ++ goto out; + } + if (args->old != NULL) { + PROC_LOCK(p); +@@ -2068,6 +2078,11 @@ + error = kern_proc_setrlimit(td, p, which, &nrlim); + + out: ++ if (exec_blocked) { ++ PROC_LOCK(p); ++ execve_unblock(td, p); ++ PROC_UNLOCK(p); ++ } + PRELE(p); + return (error); + } +--- sys/fs/cuse/cuse.c.orig ++++ sys/fs/cuse/cuse.c +@@ -914,7 +914,7 @@ + }; + + PHOLD(proc_s); +- error = proc_rwmem(proc_s, &uio); ++ error = proc_rwmem(proc_s, &uio, 0); + PRELE(proc_s); + + } else if (proc_cur == proc_s) { +@@ -933,7 +933,7 @@ + }; + + PHOLD(proc_d); +- error = proc_rwmem(proc_d, &uio); ++ error = proc_rwmem(proc_d, &uio, 0); + PRELE(proc_d); + } else { + error = EINVAL; +--- sys/fs/procfs/procfs_map.c.orig ++++ sys/fs/procfs/procfs_map.c +@@ -42,6 +42,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -95,15 +96,14 @@ + bool wrap32; + #endif + +- PROC_LOCK(p); +- error = p_candebug(td, p); +- PROC_UNLOCK(p); +- if (error) +- return (error); +- + if (uio->uio_rw != UIO_READ) + return (EOPNOTSUPP); + ++ error = proc_vmspace_ref(td, p, PRVM_BLOCK_EXEC | PRVM_CHECK_DEBUG, ++ &vm); ++ if (error != 0) ++ return (error); ++ + #ifdef COMPAT_FREEBSD32 + wrap32 = false; + if (SV_CURPROC_FLAG(SV_ILP32)) { +@@ -113,9 +113,6 @@ + } + #endif + +- vm = vmspace_acquire_ref(p); +- if (vm == NULL) +- return (ESRCH); + map = &vm->vm_map; + vm_map_lock_read(map); + VM_MAP_ENTRY_FOREACH(entry, map) { +@@ -240,6 +237,6 @@ + } + } + vm_map_unlock_read(map); +- vmspace_free(vm); ++ proc_vmspace_unref(td, p, PRVM_BLOCK_EXEC | PRVM_CHECK_DEBUG, vm); + return (error); + } +--- sys/fs/procfs/procfs_mem.c.orig ++++ sys/fs/procfs/procfs_mem.c +@@ -61,11 +61,7 @@ + if (uio->uio_resid == 0) + return (0); + +- PROC_LOCK(p); +- error = p_candebug(td, p); +- PROC_UNLOCK(p); +- if (error == 0) +- error = proc_rwmem(p, uio); ++ error = proc_rwmem(p, uio, PRVM_CHECK_DEBUG | PRVM_BLOCK_EXEC); + + return (error); + } +--- sys/fs/pseudofs/pseudofs_vnops.c.orig ++++ sys/fs/pseudofs/pseudofs_vnops.c +@@ -37,6 +37,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -132,6 +133,7 @@ + pfs_lookup_proc(pid_t pid, struct proc **p) + { + struct proc *proc; ++ struct thread *td; + + proc = pfind(pid); + if (proc == NULL) +@@ -141,8 +143,10 @@ + return (0); + } + _PHOLD(proc); +- PROC_UNLOCK(proc); ++ td = curthread; ++ execve_block_wait(td, proc); + *p = proc; ++ PROC_UNLOCK(proc); + return (1); + } + +@@ -672,6 +676,7 @@ + struct pfs_node *pn = pvd->pvd_pn; + struct uio *uio = va->a_uio; + struct proc *proc; ++ struct thread *td; + struct sbuf *sb = NULL; + int error, locked; + off_t buflen, buflim; +@@ -690,21 +695,30 @@ + if (pn->pn_fill == NULL) + PFS_RETURN (EIO); + ++ td = curthread; ++ + /* + * This is necessary because either process' privileges may + * have changed since the open() call. + */ +- if (!pfs_visible(curthread, pn, pvd->pvd_pid, &proc)) ++ if (!pfs_visible(td, pn, pvd->pvd_pid, &proc)) + PFS_RETURN (EIO); +- if (proc != NULL) { +- _PHOLD(proc); +- PROC_UNLOCK(proc); +- } + + vhold(vn); + locked = VOP_ISLOCKED(vn); + VOP_UNLOCK(vn); + ++ if (proc != NULL) { ++ _PHOLD(proc); ++ execve_block_wait(td, proc); ++ if (!pfs_visible_proc(td, pn, proc)) { ++ PROC_UNLOCK(proc); ++ error = EIO; ++ goto ret; ++ } ++ PROC_UNLOCK(proc); ++ } ++ + if (pn->pn_flags & PFS_RAWRD) { + PFS_TRACE(("%zd resid", uio->uio_resid)); + error = pn_fill(curthread, proc, pn, NULL, uio); +@@ -774,8 +788,12 @@ + ret: + vn_lock(vn, locked | LK_RETRY); + vdrop(vn); +- if (proc != NULL) +- PRELE(proc); ++ if (proc != NULL) { ++ PROC_LOCK(proc); ++ execve_unblock(td, proc); ++ _PRELE(proc); ++ PROC_UNLOCK(proc); ++ } + PFS_RETURN (error); + } + +@@ -846,6 +864,7 @@ + struct pfs_node *pd = pvd->pvd_pn; + pid_t pid = pvd->pvd_pid; + struct proc *p, *proc; ++ struct thread *td; + struct pfs_node *pn; + struct uio *uio; + struct pfsentry *pfsent, *pfsent2; +@@ -884,11 +903,13 @@ + KASSERT(pid == NO_PID || proc != NULL, + ("%s(): no process for pid %lu", __func__, (unsigned long)pid)); + ++ td = curthread; + if (pid != NO_PID) { + PROC_LOCK(proc); + + /* check if the directory is visible to the caller */ + if (!pfs_visible_proc(curthread, pd, proc)) { ++ execve_unblock(td, proc); + _PRELE(proc); + PROC_UNLOCK(proc); + pfs_unlock(pd); +@@ -956,6 +977,7 @@ + resid -= PFS_DELEN; + } + if (proc != NULL) { ++ execve_unblock(td, proc); + _PRELE(proc); + PROC_UNLOCK(proc); + } +@@ -1080,6 +1102,7 @@ + struct pfs_node *pn = pvd->pvd_pn; + struct uio *uio = va->a_uio; + struct proc *proc; ++ struct thread *td; + struct sbuf sb; + int error; + +@@ -1099,36 +1122,44 @@ + if (uio->uio_resid > PFS_MAXBUFSIZ) + PFS_RETURN (EIO); + ++ td = curthread; ++ + /* + * This is necessary because either process' privileges may + * have changed since the open() call. + */ +- if (!pfs_visible(curthread, pn, pvd->pvd_pid, &proc)) ++ if (!pfs_visible(td, pn, pvd->pvd_pid, &proc)) + PFS_RETURN (EIO); + if (proc != NULL) { + _PHOLD(proc); ++ execve_block_wait(td, proc); ++ if (!pfs_visible_proc(td, pn, proc)) { ++ PROC_UNLOCK(proc); ++ error = EIO; ++ goto out; ++ } + PROC_UNLOCK(proc); + } + + if (pn->pn_flags & PFS_RAWWR) { + error = pn_fill(curthread, proc, pn, NULL, uio); +- if (proc != NULL) +- PRELE(proc); +- PFS_RETURN (error); ++ goto out; + } + + sbuf_uionew(&sb, uio, &error); +- if (error) { +- if (proc != NULL) +- PRELE(proc); +- PFS_RETURN (error); +- } ++ if (error != 0) ++ goto out; + + error = pn_fill(curthread, proc, pn, &sb, uio); + + sbuf_delete(&sb); +- if (proc != NULL) +- PRELE(proc); ++out: ++ if (proc != NULL) { ++ PROC_LOCK(proc); ++ execve_unblock(td, proc); ++ _PRELE(proc); ++ PROC_UNLOCK(proc); ++ } + PFS_RETURN (error); + } + +--- sys/kern/kern_event.c.orig ++++ sys/kern/kern_event.c +@@ -50,6 +50,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -3028,10 +3029,6 @@ + if ((u_int)arg2 > 2 || (u_int)arg2 == 0) + return (EINVAL); + +- error = pget((pid_t)name[0], PGET_HOLD | PGET_CANDEBUG, &p); +- if (error != 0) +- return (error); +- + td = curthread; + #ifdef FREEBSD_COMPAT32 + compat32 = SV_CURPROC_FLAG(SV_ILP32); +@@ -3039,6 +3036,17 @@ + compat32 = false; + #endif + ++ error = pget((pid_t)name[0], PGET_NOTWEXIT, &p); ++ if (error != 0) ++ return (error); ++ ++ _PHOLD(p); ++ execve_block_wait(td, p); ++ error = p_candebug(td, p); ++ if (error != 0) ++ goto out1; ++ PROC_UNLOCK(p); ++ + s = sbuf_new_for_sysctl(&sm, NULL, 0, req); + if (s == NULL) { + error = ENOMEM; +@@ -3059,7 +3067,11 @@ + sbuf_delete(s); + + out: +- PRELE(p); ++ PROC_LOCK(p); ++out1: ++ execve_unblock(td, p); ++ _PRELE(p); ++ PROC_UNLOCK(p); + return (error); + } + +--- sys/kern/kern_exec.c.orig ++++ sys/kern/kern_exec.c +@@ -26,7 +26,6 @@ + * SUCH DAMAGE. + */ + +-#include + #include "opt_capsicum.h" + #include "opt_hwpmc_hooks.h" + #include "opt_ktrace.h" +@@ -45,6 +44,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -373,6 +373,77 @@ + } + } + ++/* ++ * Returns true if the execblock was obtained, in this case the ++ * process lock is kept. Returns false if the execblock was not ++ * obtained, but the function slept and the lock was dropped. ++ */ ++bool ++execve_block(struct thread *td, struct proc *p) ++{ ++ PROC_LOCK_ASSERT(p, MA_OWNED); ++ MPASS(td == curthread); ++ MPASS(p != td->td_proc || (p->p_flag & P_INEXEC) == 0); ++ ++ if (p != td->td_proc && (p->p_flag & P_INEXEC) != 0) { ++ p->p_flag2 |= P2_INEXEC_WAIT; ++ msleep(&p->p_execblock, &p->p_mtx, PDROP, "inexec", 0); ++ return (false); ++ } ++ MPASS(p->p_execblock < UINT_MAX); ++ p->p_execblock++; ++ return (true); ++} ++ ++/* ++ * Might drop the process lock internally, callers must re-check the ++ * invariants afterward. ++ */ ++void ++execve_block_wait(struct thread *td, struct proc *p) ++{ ++ bool first; ++ ++ PROC_ASSERT_HELD(p); ++ PROC_LOCK_ASSERT(p, MA_OWNED); ++ ++ for (first = true;; first = false) { ++ if (!first) ++ PROC_LOCK(p); ++ if (execve_block(td, p)) ++ return; ++ } ++} ++ ++void ++execve_unblock(struct thread *td, struct proc *p) ++{ ++ PROC_LOCK_ASSERT(p, MA_OWNED); ++ MPASS(td == curthread); ++ ++ MPASS(p->p_execblock > 0); ++ p->p_execblock--; ++ if (p->p_execblock == 0 && (p->p_flag2 & P2_INEXEC_WAIT) != 0) { ++ p->p_flag2 &= ~P2_INEXEC_WAIT; ++ wakeup(&p->p_execblock); ++ } ++} ++ ++void ++execve_block_pass(struct thread *td) ++{ ++ struct proc *p; ++ ++ MPASS(td == curthread); ++ p = td->td_proc; ++ PROC_LOCK_ASSERT(p, MA_OWNED); ++ ++ while (p->p_execblock != 0) { ++ p->p_flag2 |= P2_INEXEC_WAIT; ++ msleep(&p->p_execblock, &p->p_mtx, 0, "exeblk", 0); ++ } ++} ++ + /* + * In-kernel implementation of execve(). All arguments are assumed to be + * userspace pointers from the passed thread. +@@ -428,6 +499,7 @@ + PROC_LOCK(p); + KASSERT((p->p_flag & P_INEXEC) == 0, + ("%s(): process already has P_INEXEC flag", __func__)); ++ execve_block_pass(td); + p->p_flag |= P_INEXEC; + PROC_UNLOCK(p); + +@@ -896,7 +968,11 @@ + * as we're now a bona fide freshly-execed process. + */ + KNOTE_LOCKED(p->p_klist, NOTE_EXEC); ++ MPASS(p->p_execblock == 0); ++ if ((p->p_flag2 & P2_INEXEC_WAIT) != 0) ++ wakeup(&p->p_execblock); + p->p_flag &= ~P_INEXEC; ++ p->p_flag2 &= ~P2_INEXEC_WAIT; + + /* clear "fork but no exec" flag, as we _are_ execing */ + p->p_acflag &= ~AFORK; +@@ -978,7 +1054,10 @@ + exec_fail: + /* we're done here, clear P_INEXEC */ + PROC_LOCK(p); ++ if ((p->p_flag2 & P2_INEXEC_WAIT) != 0) ++ wakeup(&p->p_execblock); + p->p_flag &= ~P_INEXEC; ++ p->p_flag2 &= ~P2_INEXEC_WAIT; + PROC_UNLOCK(p); + + SDT_PROBE1(proc, , , exec__failure, error); +--- sys/kern/kern_exit.c.orig ++++ sys/kern/kern_exit.c +@@ -325,6 +325,7 @@ + while (p->p_lock > 0) + msleep(&p->p_lock, &p->p_mtx, PWAIT, "exithold", 0); + ++ MPASS(p->p_execblock == 0); + PROC_UNLOCK(p); + /* Drain the limit callout while we don't have the proc locked */ + callout_drain(&p->p_limco); +--- sys/kern/kern_fork.c.orig ++++ sys/kern/kern_fork.c +@@ -384,6 +384,7 @@ + + bzero(&p2->p_startzero, + __rangeof(struct proc, p_startzero, p_endzero)); ++ p2->p_execblock = 0; + + /* Tell the prison that we exist. */ + prison_proc_hold(p2->p_ucred->cr_prison); +--- sys/kern/kern_proc.c.orig ++++ sys/kern/kern_proc.c +@@ -45,6 +45,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -1833,8 +1834,8 @@ + } + + static int +-proc_read_string(struct thread *td, struct proc *p, const char *sptr, char *buf, +- size_t len) ++proc_read_string(struct thread *td, struct vmspace *vm, const char *sptr, ++ char *buf, size_t len) + { + ssize_t n; + +@@ -1843,7 +1844,7 @@ + * and is aligned at the end of the page, and the following page is not + * mapped. + */ +- n = proc_readmem(td, p, (vm_offset_t)sptr, buf, len); ++ n = vmspace_iop(td, vm, (vm_offset_t)sptr, buf, len, UIO_READ); + if (n <= 0) + return (ENOMEM); + return (0); +@@ -1859,8 +1860,8 @@ + + #ifdef COMPAT_FREEBSD32 + static int +-get_proc_vector32(struct thread *td, struct proc *p, char ***proc_vectorp, +- size_t *vsizep, enum proc_vector_type type) ++get_proc_vector32(struct thread *td, struct proc *p, struct vmspace *vm, ++ char ***proc_vectorp, size_t *vsizep, enum proc_vector_type type) + { + struct freebsd32_ps_strings pss; + Elf32_Auxinfo aux; +@@ -1871,8 +1872,8 @@ + int i, error; + + error = 0; +- if (proc_readmem(td, p, PROC_PS_STRINGS(p), &pss, sizeof(pss)) != +- sizeof(pss)) ++ if (vmspace_iop(td, vm, PROC_PS_STRINGS(p), &pss, sizeof(pss), ++ UIO_READ) != sizeof(pss)) + return (ENOMEM); + switch (type) { + case PROC_ARG: +@@ -1895,8 +1896,8 @@ + if (vptr % 4 != 0) + return (ENOEXEC); + for (ptr = vptr, i = 0; i < PROC_AUXV_MAX; i++) { +- if (proc_readmem(td, p, ptr, &aux, sizeof(aux)) != +- sizeof(aux)) ++ if (vmspace_iop(td, vm, ptr, &aux, sizeof(aux), ++ UIO_READ) != sizeof(aux)) + return (ENOMEM); + if (aux.a_type == AT_NULL) + break; +@@ -1912,7 +1913,7 @@ + return (EINVAL); + } + proc_vector32 = malloc(size, M_TEMP, M_WAITOK); +- if (proc_readmem(td, p, vptr, proc_vector32, size) != size) { ++ if (vmspace_iop(td, vm, vptr, proc_vector32, size, UIO_READ) != size) { + error = ENOMEM; + goto done; + } +@@ -1933,8 +1934,8 @@ + #endif + + static int +-get_proc_vector(struct thread *td, struct proc *p, char ***proc_vectorp, +- size_t *vsizep, enum proc_vector_type type) ++get_proc_vector(struct thread *td, struct proc *p, struct vmspace *vm, ++ char ***proc_vectorp, size_t *vsizep, enum proc_vector_type type) + { + struct ps_strings pss; + Elf_Auxinfo aux; +@@ -1944,11 +1945,13 @@ + int i; + + #ifdef COMPAT_FREEBSD32 +- if (SV_PROC_FLAG(p, SV_ILP32) != 0) +- return (get_proc_vector32(td, p, proc_vectorp, vsizep, type)); ++ if (SV_PROC_FLAG(p, SV_ILP32) != 0) { ++ return (get_proc_vector32(td, p, vm, proc_vectorp, ++ vsizep, type)); ++ } + #endif +- if (proc_readmem(td, p, PROC_PS_STRINGS(p), &pss, sizeof(pss)) != +- sizeof(pss)) ++ if (vmspace_iop(td, vm, PROC_PS_STRINGS(p), &pss, sizeof(pss), ++ UIO_READ) != sizeof(pss)) + return (ENOMEM); + switch (type) { + case PROC_ARG: +@@ -1986,8 +1989,8 @@ + * to the allocated proc_vector. + */ + for (ptr = vptr, i = 0; i < PROC_AUXV_MAX; i++) { +- if (proc_readmem(td, p, ptr, &aux, sizeof(aux)) != +- sizeof(aux)) ++ if (vmspace_iop(td, vm, ptr, &aux, sizeof(aux), ++ UIO_READ) != sizeof(aux)) + return (ENOMEM); + if (aux.a_type == AT_NULL) + break; +@@ -2009,7 +2012,7 @@ + return (EINVAL); /* In case we are built without INVARIANTS. */ + } + proc_vector = malloc(size, M_TEMP, M_WAITOK); +- if (proc_readmem(td, p, vptr, proc_vector, size) != size) { ++ if (vmspace_iop(td, vm, vptr, proc_vector, size, UIO_READ) != size) { + free(proc_vector, M_TEMP); + return (ENOMEM); + } +@@ -2025,6 +2028,7 @@ + get_ps_strings(struct thread *td, struct proc *p, struct sbuf *sb, + enum proc_vector_type type) + { ++ struct vmspace *vm; + size_t done, len, nchr, vsize; + int error, i; + char **proc_vector, *sptr; +@@ -2037,9 +2041,14 @@ + */ + nchr = 2 * (PATH_MAX + ARG_MAX); + +- error = get_proc_vector(td, p, &proc_vector, &vsize, type); ++ error = proc_vmspace_ref(td, p, PRVM_BLOCK_EXEC | ++ PRVM_CHECK_VISIBILITY, &vm); + if (error != 0) + return (error); ++ ++ error = get_proc_vector(td, p, vm, &proc_vector, &vsize, type); ++ if (error != 0) ++ goto out; + for (done = 0, i = 0; i < (int)vsize && done < nchr; i++) { + /* + * The program may have scribbled into its argv array, e.g. to +@@ -2049,7 +2058,7 @@ + if (proc_vector[i] == NULL) + break; + for (sptr = proc_vector[i]; ; sptr += GET_PS_STRINGS_CHUNK_SZ) { +- error = proc_read_string(td, p, sptr, pss_string, ++ error = proc_read_string(td, vm, sptr, pss_string, + sizeof(pss_string)); + if (error != 0) + goto done; +@@ -2066,6 +2075,8 @@ + } + done: + free(proc_vector, M_TEMP); ++out: ++ proc_vmspace_unref(td, p, PRVM_BLOCK_EXEC | PRVM_CHECK_VISIBILITY, vm); + return (error); + } + +@@ -2086,11 +2097,17 @@ + int + proc_getauxv(struct thread *td, struct proc *p, struct sbuf *sb) + { ++ struct vmspace *vm; + size_t vsize, size; + char **auxv; + int error; + +- error = get_proc_vector(td, p, &auxv, &vsize, PROC_AUX); ++ error = proc_vmspace_ref(td, p, PRVM_BLOCK_EXEC | PRVM_CHECK_DEBUG, ++ &vm); ++ if (error != 0) ++ return (error); ++ error = get_proc_vector(td, p, vm, &auxv, &vsize, PROC_AUX); ++ proc_vmspace_unref(td, p, PRVM_BLOCK_EXEC | PRVM_CHECK_DEBUG, vm); + if (error == 0) { + #ifdef COMPAT_FREEBSD32 + if (SV_PROC_FLAG(p, SV_ILP32) != 0) +@@ -2403,6 +2420,7 @@ + int error, *name; + struct vnode *vp; + struct proc *p; ++ struct thread *td; + vm_map_t map; + struct vmspace *vm; + +@@ -2411,11 +2429,12 @@ + return (EINVAL); + + name = (int *)arg1; ++ td = curthread; + error = pget((pid_t)name[0], PGET_WANTREAD, &p); + if (error != 0) + return (error); +- vm = vmspace_acquire_ref(p); +- if (vm == NULL) { ++ error = proc_vmspace_ref(td, p, PRVM_CHECK_DEBUG, &vm); ++ if (error != 0) { + PRELE(p); + return (ESRCH); + } +@@ -2527,7 +2546,7 @@ + } + } + vm_map_unlock_read(map); +- vmspace_free(vm); ++ proc_vmspace_unref(td, p, PRVM_CHECK_DEBUG, vm); + PRELE(p); + free(kve, M_TEMP); + return (error); +@@ -2618,6 +2637,7 @@ + struct vmspace *vm; + struct cdev *cdev; + struct cdevsw *csw; ++ struct thread *td; + vm_offset_t addr; + unsigned int last_timestamp; + int error, ref; +@@ -2629,10 +2649,11 @@ + + _PHOLD(p); + PROC_UNLOCK(p); +- vm = vmspace_acquire_ref(p); +- if (vm == NULL) { ++ td = curthread; ++ error = proc_vmspace_ref(td, p, PRVM_CHECK_DEBUG, &vm); ++ if (error != 0) { + PRELE(p); +- return (ESRCH); ++ return (error); + } + kve = malloc(sizeof(*kve), M_TEMP, M_WAITOK | M_ZERO); + +@@ -2747,7 +2768,7 @@ + if (vp != NULL) { + vn_fullpath(vp, &fullpath, &freepath); + kve->kve_vn_type = vntype_to_kinfo(vp->v_type); +- cred = curthread->td_ucred; ++ cred = td->td_ucred; + vn_lock(vp, LK_SHARED | LK_RETRY); + if (VOP_GETATTR(vp, &va, cred) == 0) { + kve->kve_vn_fileid = va.va_fileid; +@@ -2803,7 +2824,7 @@ + } + } + vm_map_unlock_read(map); +- vmspace_free(vm); ++ proc_vmspace_unref(td, p, PRVM_CHECK_DEBUG, vm); + PRELE(p); + free(kve, M_TEMP); + return (error); +@@ -2842,7 +2863,7 @@ + struct kinfo_kstack *kkstp; + int error, i, *name, numthreads; + lwpid_t *lwpidarray; +- struct thread *td; ++ struct thread *td, *ctd; + struct stack *st; + struct sbuf sb; + struct proc *p; +@@ -2853,7 +2874,8 @@ + return (EINVAL); + + name = (int *)arg1; +- error = pget((pid_t)name[0], PGET_NOTINEXEC | PGET_WANTREAD, &p); ++ ctd = curthread; ++ error = pget((pid_t)name[0], PGET_WANTREAD, &p); + if (error != 0) + return (error); + +@@ -2862,6 +2884,14 @@ + + lwpidarray = NULL; + PROC_LOCK(p); ++ execve_block_wait(ctd, p); ++ error = p_candebug(ctd, p); ++ if (error != 0) { ++ execve_unblock(ctd, p); ++ _PRELE(p); ++ PROC_UNLOCK(p); ++ return (error); ++ } + do { + if (lwpidarray != NULL) { + free(lwpidarray, M_TEMP); +@@ -2874,15 +2904,6 @@ + PROC_LOCK(p); + } while (numthreads < p->p_numthreads); + +- /* +- * XXXRW: During the below loop, execve(2) and countless other sorts +- * of changes could have taken place. Should we check to see if the +- * vmspace has been replaced, or the like, in order to prevent +- * giving a snapshot that spans, say, execve(2), with some threads +- * before and some after? Among other things, the credentials could +- * have changed, in which case the right to extract debug info might +- * no longer be assured. +- */ + i = 0; + FOREACH_THREAD_IN_PROC(p, td) { + KASSERT(i < numthreads, +@@ -2917,7 +2938,10 @@ + if (error) + break; + } +- PRELE(p); ++ PROC_LOCK(p); ++ execve_unblock(ctd, p); ++ _PRELE(p); ++ PROC_UNLOCK(p); + if (lwpidarray != NULL) + free(lwpidarray, M_TEMP); + stack_destroy(st); +@@ -2970,8 +2994,9 @@ + u_int namelen = arg2; + struct rlimit rlim; + struct proc *p; ++ struct thread *td; + u_int which; +- int flags, error; ++ int error; + + if (namelen != 2) + return (EINVAL); +@@ -2983,23 +3008,24 @@ + if (req->newptr != NULL && req->newlen != sizeof(rlim)) + return (EINVAL); + +- flags = PGET_HOLD | PGET_NOTWEXIT; +- if (req->newptr != NULL) +- flags |= PGET_CANDEBUG; +- else +- flags |= PGET_CANSEE; +- error = pget((pid_t)name[0], flags, &p); ++ td = curthread; ++ error = pget((pid_t)name[0], PGET_NOTWEXIT, &p); + if (error != 0) + return (error); ++ _PHOLD(p); ++ execve_block_wait(td, p); ++ error = req->newptr != NULL ? p_candebug(td, p) : p_cansee(td, p); ++ if (error != 0) ++ goto errout1; + + /* + * Retrieve limit. + */ + if (req->oldptr != NULL) { +- PROC_LOCK(p); + lim_rlimit_proc(p, which, &rlim); +- PROC_UNLOCK(p); + } ++ PROC_UNLOCK(p); ++ + error = SYSCTL_OUT(req, &rlim, sizeof(rlim)); + if (error != 0) + goto errout; +@@ -3014,7 +3040,11 @@ + } + + errout: +- PRELE(p); ++ PROC_LOCK(p); ++errout1: ++ _PRELE(p); ++ execve_unblock(td, p); ++ PROC_UNLOCK(p); + return (error); + } + +@@ -3103,39 +3133,38 @@ + int *name = (int *)arg1; + u_int namelen = arg2; + struct proc *p; +- int flags, error, osrel; ++ int flags, error, old_osrel, osrel; + + if (namelen != 1) + return (EINVAL); + +- if (req->newptr != NULL && req->newlen != sizeof(osrel)) +- return (EINVAL); +- +- flags = PGET_HOLD | PGET_NOTWEXIT; +- if (req->newptr != NULL) ++ flags = PGET_NOTWEXIT; ++ if (req->newptr != NULL) { ++ if (req->newlen != sizeof(osrel)) ++ return (EINVAL); ++ error = SYSCTL_IN(req, &osrel, sizeof(osrel)); ++ if (error != 0) ++ return (error); ++ if (osrel < 0) ++ return (EINVAL); + flags |= PGET_CANDEBUG; +- else ++ } else { + flags |= PGET_CANSEE; ++ } + error = pget((pid_t)name[0], flags, &p); + if (error != 0) + return (error); +- +- error = SYSCTL_OUT(req, &p->p_osrel, sizeof(p->p_osrel)); +- if (error != 0) +- goto errout; +- +- if (req->newptr != NULL) { +- error = SYSCTL_IN(req, &osrel, sizeof(osrel)); +- if (error != 0) +- goto errout; +- if (osrel < 0) { +- error = EINVAL; +- goto errout; +- } +- p->p_osrel = osrel; ++ if ((p->p_flag & P_INEXEC) != 0) { ++ error = EBUSY; ++ } else { ++ old_osrel = p->p_osrel; ++ if (req->newptr != NULL) ++ p->p_osrel = osrel; + } +-errout: +- PRELE(p); ++ PROC_UNLOCK(p); ++ ++ if (error == 0) ++ error = SYSCTL_OUT(req, &old_osrel, sizeof(old_osrel)); + return (error); + } + +@@ -3272,6 +3301,7 @@ + { + struct kinfo_vm_layout kvm; + struct proc *p; ++ struct thread *td; + struct vmspace *vmspace; + int error, *name; + +@@ -3279,6 +3309,7 @@ + if ((u_int)arg2 != 1) + return (EINVAL); + ++ td = curthread; + error = pget((pid_t)name[0], PGET_CANDEBUG, &p); + if (error != 0) + return (error); +@@ -3290,8 +3321,13 @@ + } + } + #endif +- vmspace = vmspace_acquire_ref(p); ++ _PHOLD(p); + PROC_UNLOCK(p); ++ error = proc_vmspace_ref(td, p, PRVM_CHECK_DEBUG, &vmspace); ++ if (error != 0) { ++ PRELE(p); ++ return (error); ++ } + + memset(&kvm, 0, sizeof(kvm)); + kvm.kvm_min_user_addr = vm_map_min(&vmspace->vm_map); +@@ -3343,7 +3379,8 @@ + #ifdef COMPAT_FREEBSD32 + out: + #endif +- vmspace_free(vmspace); ++ proc_vmspace_unref(td, p, PRVM_CHECK_DEBUG, vmspace); ++ PRELE(p); + return (error); + } + +--- sys/kern/kern_procctl.c.orig ++++ sys/kern/kern_procctl.c +@@ -40,6 +40,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -872,37 +873,41 @@ + { + struct vmspace *vm; + vm_map_t map; +- int state; ++ int error, state; + + PROC_LOCK_ASSERT(p, MA_OWNED); + if ((p->p_flag & P_WEXIT) != 0) + return (ESRCH); + state = *(int *)data; ++ error = 0; + + switch (state) { + case PROC_WX_MAPPINGS_PERMIT: +- p->p_flag2 |= P2_WXORX_DISABLE; +- _PHOLD(p); + PROC_UNLOCK(p); +- vm = vmspace_acquire_ref(p); +- if (vm != NULL) { ++ error = proc_vmspace_ref(td, p, PRVM_BLOCK_EXEC | ++ PRVM_CHECK_DEBUG, &vm); ++ if (error == 0) { + map = &vm->vm_map; + vm_map_lock(map); + map->flags &= ~MAP_WXORX; + vm_map_unlock(map); +- vmspace_free(vm); ++ PROC_LOCK(p); ++ p->p_flag2 |= P2_WXORX_DISABLE; ++ PROC_UNLOCK(p); ++ proc_vmspace_unref(td, p, PRVM_BLOCK_EXEC | ++ PRVM_CHECK_DEBUG, vm); + } + PROC_LOCK(p); +- _PRELE(p); + break; + case PROC_WX_MAPPINGS_DISALLOW_EXEC: + p->p_flag2 |= P2_WXORX_ENABLE_EXEC; + break; + default: +- return (EINVAL); ++ error = EINVAL; ++ break; + } + +- return (0); ++ return (error); + } + + static int +--- sys/kern/kern_prot.c.orig ++++ sys/kern/kern_prot.c +@@ -51,6 +51,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -1002,6 +1003,8 @@ + newcred = crget(); + euip = uifind(euid); + PROC_LOCK(p); ++ execve_block_pass(td); ++ + /* + * Copy credentials so other references do not see our changes. + */ +@@ -1056,6 +1059,7 @@ + AUDIT_ARG_GID(gid); + newcred = crget(); + PROC_LOCK(p); ++ execve_block_pass(td); + oldcred = crcopysafe(p, newcred); + + #ifdef MAC +@@ -1154,6 +1158,7 @@ + AUDIT_ARG_EGID(egid); + newcred = crget(); + PROC_LOCK(p); ++ execve_block_pass(td); + oldcred = crcopysafe(p, newcred); + + #ifdef MAC +@@ -1249,6 +1254,7 @@ + if (ngrp != 0) + crextend(newcred, ngrp); + PROC_LOCK(p); ++ execve_block_pass(td); + oldcred = crcopysafe(p, newcred); + + #ifdef MAC +@@ -1311,6 +1317,7 @@ + euip = uifind(euid); + ruip = uifind(ruid); + PROC_LOCK(p); ++ execve_block_pass(td); + oldcred = crcopysafe(p, newcred); + + #ifdef MAC +@@ -1383,6 +1390,7 @@ + AUDIT_ARG_RGID(rgid); + newcred = crget(); + PROC_LOCK(p); ++ execve_block_pass(td); + oldcred = crcopysafe(p, newcred); + + #ifdef MAC +@@ -1453,6 +1461,7 @@ + euip = uifind(euid); + ruip = uifind(ruid); + PROC_LOCK(p); ++ execve_block_pass(td); + oldcred = crcopysafe(p, newcred); + + #ifdef MAC +@@ -1537,6 +1546,7 @@ + AUDIT_ARG_SGID(sgid); + newcred = crget(); + PROC_LOCK(p); ++ execve_block_pass(td); + oldcred = crcopysafe(p, newcred); + + #ifdef MAC +@@ -2229,11 +2239,11 @@ + } + + /* +- * Can't trace a process that's currently exec'ing. +- * +- * XXX: Note, this is not a security policy decision, it's a +- * basic correctness/functionality decision. Therefore, this check +- * should be moved to the caller's of p_candebug(). ++ * Can't trace a process that's currently exec'ing. Otherwise ++ * the process vmspace might change, and the target might be ++ * loading a setugid image. The execve_block(9) and ++ * proc_vmspace_ref(9) allow to get the stable credentials and ++ * vmspace reference. + */ + if ((p->p_flag & P_INEXEC) != 0) + return (EBUSY); +--- sys/kern/kern_resource.c.orig ++++ sys/kern/kern_resource.c +@@ -48,6 +48,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -810,11 +811,11 @@ + } + + static int +-getrlimitusage_one(struct proc *p, u_int which, int flags, rlim_t *res) ++getrlimitusage_one(struct proc *p, struct vmspace *vm, u_int which, int flags, ++ rlim_t *res) + { + struct thread *td; + struct uidinfo *ui; +- struct vmspace *vm; + uid_t uid; + int error; + +@@ -825,7 +826,6 @@ + PROC_UNLOCK(p); + + ui = uifind(uid); +- vm = vmspace_acquire_ref(p); + + switch (which) { + case RLIMIT_CPU: +@@ -903,7 +903,6 @@ + break; + } + +- vmspace_free(vm); + uifree(ui); + return (error); + } +@@ -911,12 +910,15 @@ + int + sys_getrlimitusage(struct thread *td, struct getrlimitusage_args *uap) + { ++ struct proc *p; + rlim_t res; + int error; + + if ((uap->flags & ~(GETRLIMITUSAGE_EUID)) != 0) + return (EINVAL); +- error = getrlimitusage_one(curproc, uap->which, uap->flags, &res); ++ p = curproc; ++ error = getrlimitusage_one(p, p->p_vmspace, uap->which, uap->flags, ++ &res); + if (error == 0) + error = copyout(&res, uap->res, sizeof(res)); + return (error); +@@ -1750,6 +1752,8 @@ + { + rlim_t resval[RLIM_NLIMITS]; + struct proc *p; ++ struct thread *td; ++ struct vmspace *vm; + size_t len; + int error, *name, i; + +@@ -1759,15 +1763,20 @@ + if (req->newptr != NULL) + return (EINVAL); + +- error = pget((pid_t)name[0], PGET_WANTREAD, &p); ++ td = curthread; ++ error = pget((pid_t)name[0], PGET_HOLD | PGET_NOTWEXIT, &p); + if (error != 0) + return (error); ++ error = proc_vmspace_ref(td, p, PRVM_BLOCK_EXEC | ++ PRVM_CHECK_VISIBILITY, &vm); ++ if (error != 0) ++ goto out; + + if ((u_int)arg2 == 1) { + len = sizeof(resval); + memset(resval, 0, sizeof(resval)); + for (i = 0; i < RLIM_NLIMITS; i++) { +- error = getrlimitusage_one(p, (unsigned)i, 0, ++ error = getrlimitusage_one(p, vm, (unsigned)i, 0, + &resval[i]); + if (error == ENXIO) { + resval[i] = -1; +@@ -1778,7 +1787,7 @@ + } + } else { + len = sizeof(resval[0]); +- error = getrlimitusage_one(p, (unsigned)name[1], 0, ++ error = getrlimitusage_one(p, vm, (unsigned)name[1], 0, + &resval[0]); + if (error == ENXIO) { + resval[0] = -1; +@@ -1787,6 +1796,8 @@ + } + if (error == 0) + error = SYSCTL_OUT(req, resval, len); ++ proc_vmspace_unref(td, p, PRVM_BLOCK_EXEC | PRVM_CHECK_VISIBILITY, vm); ++out: + PRELE(p); + return (error); + } +--- sys/kern/sys_process.c.orig ++++ sys/kern/sys_process.c +@@ -34,6 +34,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -344,25 +345,93 @@ + PROC_ACTION(ptrace_single_step(td)); + } + ++static int ++proc_vmspace_check_access(struct thread *td, struct proc *p, int flags) ++{ ++ PROC_ASSERT_HELD(p); ++ if ((flags & PRVM_CHECK_DEBUG) != 0) ++ return (p_candebug(td, p)); ++ if ((flags & PRVM_CHECK_VISIBILITY) != 0) ++ return (p_cansee(td, p)); ++ return (0); ++} ++ + int +-proc_rwmem(struct proc *p, struct uio *uio) ++proc_vmspace_ref(struct thread *td, struct proc *p, int flags, ++ struct vmspace **vmp) ++{ ++ struct vmspace *vm; ++ int error; ++ ++ MPASS((flags & ~(PRVM_BLOCK_EXEC | PRVM_CHECK_VISIBILITY | ++ PRVM_CHECK_DEBUG)) == 0); ++ MPASS((flags & (PRVM_CHECK_VISIBILITY | PRVM_CHECK_DEBUG)) != ++ (PRVM_CHECK_VISIBILITY | PRVM_CHECK_DEBUG)); ++ ++ PROC_LOCK(p); ++ if (p != td->td_proc) { ++ PROC_ASSERT_HELD(p); ++ ++ /* ++ * Make sure that the vmspace doesn't switch out from ++ * under us. ++ */ ++ if ((flags & PRVM_BLOCK_EXEC) != 0) { ++ for (;;) { ++ if (!execve_block(td, p)) { ++ PROC_LOCK(p); ++ continue; ++ } ++ error = proc_vmspace_check_access(td, p, flags); ++ if (error != 0) { ++ execve_unblock(td, p); ++ PROC_UNLOCK(p); ++ return (error); ++ } ++ break; ++ } ++ } else { ++ error = proc_vmspace_check_access(td, p, flags); ++ if (error != 0) { ++ PROC_UNLOCK(p); ++ return (error); ++ } ++ } ++ } ++ vm = vmspace_acquire_ref(p); ++ if (vm == NULL) { ++ if (p != td->td_proc && (flags & PRVM_BLOCK_EXEC) != 0) ++ execve_unblock(td, p); ++ PROC_UNLOCK(p); ++ return (ESRCH); ++ } ++ PROC_UNLOCK(p); ++ *vmp = vm; ++ return (0); ++} ++ ++void ++proc_vmspace_unref(struct thread *td, struct proc *p, int flags, ++ struct vmspace *vm) ++{ ++ vmspace_free(vm); ++ if (p != td->td_proc && (flags & PRVM_BLOCK_EXEC) != 0) { ++ PROC_LOCK(p); ++ PROC_ASSERT_HELD(p); ++ execve_unblock(td, p); ++ PROC_UNLOCK(p); ++ } ++} ++ ++static int ++vmspace_rwmem(struct vmspace *vm, struct uio *uio) + { + vm_map_t map; + vm_offset_t pageno; /* page number */ + vm_prot_t reqprot; + int error, fault_flags, page_offset, writing; + +- /* +- * Make sure that the process' vmspace remains live. +- */ +- if (p != curproc) +- PROC_ASSERT_HELD(p); +- PROC_LOCK_ASSERT(p, MA_NOTOWNED); +- +- /* +- * The map we want... +- */ +- map = &p->p_vmspace->vm_map; ++ map = &vm->vm_map; + + /* + * If we are writing, then we request vm_fault() to create a private +@@ -431,13 +500,30 @@ + return (error); + } + +-static ssize_t +-proc_iop(struct thread *td, struct proc *p, vm_offset_t va, void *buf, ++int ++proc_rwmem(struct proc *p, struct uio *uio, int flags) ++{ ++ struct vmspace *vm; ++ struct thread *td; ++ int error; ++ ++ td = curthread; ++ error = proc_vmspace_ref(td, p, flags, &vm); ++ if (error != 0) ++ return (error); ++ error = vmspace_rwmem(vm, uio); ++ proc_vmspace_unref(td, p, flags, vm); ++ return (error); ++} ++ ++ssize_t ++vmspace_iop(struct thread *td, struct vmspace *vm, vm_offset_t va, void *buf, + size_t len, enum uio_rw rw) + { + struct iovec iov; + struct uio uio; + ssize_t slen; ++ int error; + + MPASS(len < SSIZE_MAX); + slen = (ssize_t)len; +@@ -451,8 +537,8 @@ + uio.uio_segflg = UIO_SYSSPACE; + uio.uio_rw = rw; + uio.uio_td = td; +- proc_rwmem(p, &uio); +- if (uio.uio_resid == slen) ++ error = vmspace_rwmem(vm, &uio); ++ if (error != 0 || uio.uio_resid == slen) + return (-1); + return (slen - uio.uio_resid); + } +@@ -462,7 +548,7 @@ + size_t len) + { + +- return (proc_iop(td, p, va, buf, len, UIO_READ)); ++ return (vmspace_iop(td, p->p_vmspace, va, buf, len, UIO_READ)); + } + + ssize_t +@@ -470,7 +556,7 @@ + size_t len) + { + +- return (proc_iop(td, p, va, buf, len, UIO_WRITE)); ++ return (vmspace_iop(td, p->p_vmspace, va, buf, len, UIO_WRITE)); + } + + static int +@@ -1419,7 +1505,7 @@ + goto out; + } + PROC_UNLOCK(p); +- error = proc_rwmem(p, &uio); ++ error = proc_rwmem(p, &uio, 0); + piod->piod_len -= uio.uio_resid; + PROC_LOCK(p); + break; +--- sys/sys/imgact.h.orig ++++ sys/sys/imgact.h +@@ -123,6 +123,10 @@ + char **, char **); + int pre_execve(struct thread *td, struct vmspace **oldvmspace); + void post_execve(struct thread *td, int error, struct vmspace *oldvmspace); ++bool execve_block(struct thread *td, struct proc *p); ++void execve_block_wait(struct thread *td, struct proc *p); ++void execve_unblock(struct thread *td, struct proc *p); ++void execve_block_pass(struct thread *td); + #endif + + #endif /* !_SYS_IMGACT_H_ */ +--- sys/sys/proc.h.orig ++++ sys/sys/proc.h +@@ -778,6 +778,7 @@ + + TAILQ_HEAD(, kq_timer_cb_data) p_kqtim_stop; /* (c) */ + LIST_ENTRY(proc) p_jaillist; /* (d) Jail process linkage. */ ++ u_int p_execblock; /* (c) Blockers for execve. */ + }; + + #define p_session p_pgrp->pg_session +@@ -891,6 +892,8 @@ + sync core registered */ + #define P2_MEMBAR_GLOBE 0x00400000 /* membar global expedited + registered */ ++#define P2_INEXEC_WAIT 0x80000000 /* Not same as in HEAD. ++ Waiters for P_INEXEC/p_execblock */ + + /* Flags protected by proctree_lock, kept in p_treeflags. */ + #define P_TREE_ORPHANED 0x00000001 /* Reparented, on orphan list */ +--- sys/sys/ptrace.h.orig ++++ sys/sys/ptrace.h +@@ -241,7 +241,20 @@ + int proc_read_dbregs(struct thread *_td, struct dbreg *_dbreg); + int proc_write_dbregs(struct thread *_td, struct dbreg *_dbreg); + int proc_sstep(struct thread *_td); +-int proc_rwmem(struct proc *_p, struct uio *_uio); ++ ++#define PRVM_BLOCK_EXEC 0x00000001 ++#define PRVM_CHECK_VISIBILITY 0x00000002 ++#define PRVM_CHECK_DEBUG 0x00000004 ++ ++#include ++struct vmspace; ++int proc_vmspace_ref(struct thread *_td, struct proc *_p, int _flags, ++ struct vmspace **_vmp); ++void proc_vmspace_unref(struct thread *_td, struct proc *_p, int _flags, ++ struct vmspace *_vm); ++ssize_t vmspace_iop(struct thread *td, struct vmspace *vm, vm_offset_t va, ++ void *buf, size_t len, enum uio_rw rw); ++int proc_rwmem(struct proc *_p, struct uio *_uio, int _flags); + ssize_t proc_readmem(struct thread *_td, struct proc *_p, vm_offset_t _va, + void *_buf, size_t _len); + ssize_t proc_writemem(struct thread *_td, struct proc *_p, vm_offset_t _va, diff --git a/website/static/security/patches/SA-26:39/execve-14.3.patch.asc b/website/static/security/patches/SA-26:39/execve-14.3.patch.asc new file mode 100644 index 0000000000..feeefb42f3 --- /dev/null +++ b/website/static/security/patches/SA-26:39/execve-14.3.patch.asc @@ -0,0 +1,17 @@ +-----BEGIN PGP SIGNATURE----- + +iQJPBAABCgA5FiEEthUnfoEIffdcgYM7bljekB8AGu8FAmpEEjgbFIAAAAAABAAO +bWFudTIsMi41KzEuMTIsMCwzAAoJEG5Y3pAfABrvspgP/Aqw/u8FL082uXlOyHvb +PNiG71uufftQR+oqN7eD1imNgw4SdxeEkkjdIfRNG3OTRO1tkxnYVaf1wK+VzTmV +ISR+CMPNZcIZBQAXhR7ANncJUQjVOYe2WKwyR8E0R2Bee75Qkq1xgFvxhW+cwahh +fKobqrBwChqEMlr3lY++WREWz2PJQPbnF8GTvKOsiPsVbr4ycp/nN3qTI0/UZtss +27DN49n2tMeWeFQ+Aoj59xyB7Wybw4t16m+00lqbvZjuJLCbC+vPI2wlyyQpGi13 +Tq2PDLGi5TSkwARQ73yJ/PBgvTFwXInXWG7QkdrfbrOUIlwZyVI1rVgUyOcXrVx/ +FR3TgZCbfgYiEmoIMivfaxFYh8pMKK/hLQnoe/VEg5/dY3YNLgfTd5d71Ps7ROwo +2KxfFU9ZDo2oqchVKVAVbtmwVp4uQ+jy2itRxT8+r7oGEbJhUAgvWPTd88MGtDAR +WAWndiNxrGgISOftHLNG38fBSgmHNjjA35EtcHgMTG7C9XR4uIGW3bHNlHVafkKZ +3GX/E+byCMIscuF7XzicHtSchKHAfoSmpeoEv0wuk/6kJf6CaIFEzzQmy41ywgPK +V2sGJRuknwOh6bghWCrycY2LgBfiK9/1FemfgnRasPpX6qLLgDFpSfGiPkf8JmEY +BlUQV6QNlkgO1BksFNJ3Ibtz +=V3Rd +-----END PGP SIGNATURE----- diff --git a/website/static/security/patches/SA-26:39/execve-14.4.patch b/website/static/security/patches/SA-26:39/execve-14.4.patch new file mode 100644 index 0000000000..8c060b0614 --- /dev/null +++ b/website/static/security/patches/SA-26:39/execve-14.4.patch @@ -0,0 +1,1526 @@ +--- sys/compat/linprocfs/linprocfs.c.orig ++++ sys/compat/linprocfs/linprocfs.c +@@ -1317,19 +1317,13 @@ + struct vattr vat; + bool private; + +- PROC_LOCK(p); +- error = p_candebug(td, p); +- PROC_UNLOCK(p); +- if (error) +- return (error); +- + if (uio->uio_rw != UIO_READ) + return (EOPNOTSUPP); + +- error = 0; +- vm = vmspace_acquire_ref(p); +- if (vm == NULL) +- return (ESRCH); ++ error = proc_vmspace_ref(td, p, PRVM_BLOCK_EXEC | PRVM_CHECK_DEBUG, ++ &vm); ++ if (error != 0) ++ return (error); + + if (SV_CURPROC_FLAG(SV_LP64)) + l_map_str = l64_map_str; +@@ -1427,7 +1421,7 @@ + } + } + vm_map_unlock_read(map); +- vmspace_free(vm); ++ proc_vmspace_unref(td, p, PRVM_CHECK_DEBUG | PRVM_BLOCK_EXEC, vm); + + return (error); + } +--- sys/compat/linux/linux_misc.c.orig ++++ sys/compat/linux/linux_misc.c +@@ -2006,6 +2006,7 @@ + u_int which; + int flags; + int error; ++ bool exec_blocked; + + if (args->new == NULL && args->old != NULL) { + if (linux_get_dummy_limit(args->resource, &rlim)) { +@@ -2033,6 +2034,7 @@ + return (error); + } + ++ exec_blocked = false; + flags = PGET_HOLD | PGET_NOTWEXIT; + if (args->new != NULL) + flags |= PGET_CANDEBUG; +@@ -2045,6 +2047,14 @@ + error = pget(args->pid, flags, &p); + if (error != 0) + return (error); ++ exec_blocked = true; ++ PROC_LOCK(p); ++ execve_block_wait(td, p); ++ error = args->new != NULL ? p_candebug(td, p) : ++ p_cansee(td, p); ++ PROC_UNLOCK(p); ++ if (error != 0) ++ goto out; + } + if (args->old != NULL) { + PROC_LOCK(p); +@@ -2067,6 +2077,11 @@ + error = kern_proc_setrlimit(td, p, which, &nrlim); + + out: ++ if (exec_blocked) { ++ PROC_LOCK(p); ++ execve_unblock(td, p); ++ PROC_UNLOCK(p); ++ } + PRELE(p); + return (error); + } +--- sys/fs/cuse/cuse.c.orig ++++ sys/fs/cuse/cuse.c +@@ -914,7 +914,7 @@ + }; + + PHOLD(proc_s); +- error = proc_rwmem(proc_s, &uio); ++ error = proc_rwmem(proc_s, &uio, 0); + PRELE(proc_s); + + } else if (proc_cur == proc_s) { +@@ -933,7 +933,7 @@ + }; + + PHOLD(proc_d); +- error = proc_rwmem(proc_d, &uio); ++ error = proc_rwmem(proc_d, &uio, 0); + PRELE(proc_d); + } else { + error = EINVAL; +--- sys/fs/procfs/procfs_map.c.orig ++++ sys/fs/procfs/procfs_map.c +@@ -42,6 +42,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -95,15 +96,14 @@ + bool wrap32; + #endif + +- PROC_LOCK(p); +- error = p_candebug(td, p); +- PROC_UNLOCK(p); +- if (error) +- return (error); +- + if (uio->uio_rw != UIO_READ) + return (EOPNOTSUPP); + ++ error = proc_vmspace_ref(td, p, PRVM_BLOCK_EXEC | PRVM_CHECK_DEBUG, ++ &vm); ++ if (error != 0) ++ return (error); ++ + #ifdef COMPAT_FREEBSD32 + wrap32 = false; + if (SV_CURPROC_FLAG(SV_ILP32)) { +@@ -113,9 +113,6 @@ + } + #endif + +- vm = vmspace_acquire_ref(p); +- if (vm == NULL) +- return (ESRCH); + map = &vm->vm_map; + vm_map_lock_read(map); + VM_MAP_ENTRY_FOREACH(entry, map) { +@@ -240,6 +237,6 @@ + } + } + vm_map_unlock_read(map); +- vmspace_free(vm); ++ proc_vmspace_unref(td, p, PRVM_BLOCK_EXEC | PRVM_CHECK_DEBUG, vm); + return (error); + } +--- sys/fs/procfs/procfs_mem.c.orig ++++ sys/fs/procfs/procfs_mem.c +@@ -61,11 +61,7 @@ + if (uio->uio_resid == 0) + return (0); + +- PROC_LOCK(p); +- error = p_candebug(td, p); +- PROC_UNLOCK(p); +- if (error == 0) +- error = proc_rwmem(p, uio); ++ error = proc_rwmem(p, uio, PRVM_CHECK_DEBUG | PRVM_BLOCK_EXEC); + + return (error); + } +--- sys/fs/pseudofs/pseudofs_vnops.c.orig ++++ sys/fs/pseudofs/pseudofs_vnops.c +@@ -37,6 +37,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -132,6 +133,7 @@ + pfs_lookup_proc(pid_t pid, struct proc **p) + { + struct proc *proc; ++ struct thread *td; + + proc = pfind(pid); + if (proc == NULL) +@@ -141,8 +143,10 @@ + return (0); + } + _PHOLD(proc); +- PROC_UNLOCK(proc); ++ td = curthread; ++ execve_block_wait(td, proc); + *p = proc; ++ PROC_UNLOCK(proc); + return (1); + } + +@@ -672,6 +676,7 @@ + struct pfs_node *pn = pvd->pvd_pn; + struct uio *uio = va->a_uio; + struct proc *proc; ++ struct thread *td; + struct sbuf *sb = NULL; + int error, locked; + off_t buflen, buflim; +@@ -690,21 +695,30 @@ + if (pn->pn_fill == NULL) + PFS_RETURN (EIO); + ++ td = curthread; ++ + /* + * This is necessary because either process' privileges may + * have changed since the open() call. + */ +- if (!pfs_visible(curthread, pn, pvd->pvd_pid, &proc)) ++ if (!pfs_visible(td, pn, pvd->pvd_pid, &proc)) + PFS_RETURN (EIO); +- if (proc != NULL) { +- _PHOLD(proc); +- PROC_UNLOCK(proc); +- } + + vhold(vn); + locked = VOP_ISLOCKED(vn); + VOP_UNLOCK(vn); + ++ if (proc != NULL) { ++ _PHOLD(proc); ++ execve_block_wait(td, proc); ++ if (!pfs_visible_proc(td, pn, proc)) { ++ PROC_UNLOCK(proc); ++ error = EIO; ++ goto ret; ++ } ++ PROC_UNLOCK(proc); ++ } ++ + if (pn->pn_flags & PFS_RAWRD) { + PFS_TRACE(("%zd resid", uio->uio_resid)); + error = pn_fill(curthread, proc, pn, NULL, uio); +@@ -774,8 +788,12 @@ + ret: + vn_lock(vn, locked | LK_RETRY); + vdrop(vn); +- if (proc != NULL) +- PRELE(proc); ++ if (proc != NULL) { ++ PROC_LOCK(proc); ++ execve_unblock(td, proc); ++ _PRELE(proc); ++ PROC_UNLOCK(proc); ++ } + PFS_RETURN (error); + } + +@@ -846,6 +864,7 @@ + struct pfs_node *pd = pvd->pvd_pn; + pid_t pid = pvd->pvd_pid; + struct proc *p, *proc; ++ struct thread *td; + struct pfs_node *pn; + struct uio *uio; + struct pfsentry *pfsent, *pfsent2; +@@ -891,11 +910,13 @@ + KASSERT(pid == NO_PID || proc != NULL, + ("%s(): no process for pid %lu", __func__, (unsigned long)pid)); + ++ td = curthread; + if (pid != NO_PID) { + PROC_LOCK(proc); + + /* check if the directory is visible to the caller */ + if (!pfs_visible_proc(curthread, pd, proc)) { ++ execve_unblock(td, proc); + _PRELE(proc); + PROC_UNLOCK(proc); + pfs_unlock(pd); +@@ -955,6 +976,7 @@ + resid -= PFS_DELEN; + } + if (proc != NULL) { ++ execve_unblock(td, proc); + _PRELE(proc); + PROC_UNLOCK(proc); + } +@@ -1079,6 +1101,7 @@ + struct pfs_node *pn = pvd->pvd_pn; + struct uio *uio = va->a_uio; + struct proc *proc; ++ struct thread *td; + struct sbuf sb; + int error; + +@@ -1098,36 +1121,44 @@ + if (uio->uio_resid > PFS_MAXBUFSIZ) + PFS_RETURN (EIO); + ++ td = curthread; ++ + /* + * This is necessary because either process' privileges may + * have changed since the open() call. + */ +- if (!pfs_visible(curthread, pn, pvd->pvd_pid, &proc)) ++ if (!pfs_visible(td, pn, pvd->pvd_pid, &proc)) + PFS_RETURN (EIO); + if (proc != NULL) { + _PHOLD(proc); ++ execve_block_wait(td, proc); ++ if (!pfs_visible_proc(td, pn, proc)) { ++ PROC_UNLOCK(proc); ++ error = EIO; ++ goto out; ++ } + PROC_UNLOCK(proc); + } + + if (pn->pn_flags & PFS_RAWWR) { + error = pn_fill(curthread, proc, pn, NULL, uio); +- if (proc != NULL) +- PRELE(proc); +- PFS_RETURN (error); ++ goto out; + } + + sbuf_uionew(&sb, uio, &error); +- if (error) { +- if (proc != NULL) +- PRELE(proc); +- PFS_RETURN (error); +- } ++ if (error != 0) ++ goto out; + + error = pn_fill(curthread, proc, pn, &sb, uio); + + sbuf_delete(&sb); +- if (proc != NULL) +- PRELE(proc); ++out: ++ if (proc != NULL) { ++ PROC_LOCK(proc); ++ execve_unblock(td, proc); ++ _PRELE(proc); ++ PROC_UNLOCK(proc); ++ } + PFS_RETURN (error); + } + +--- sys/kern/kern_event.c.orig ++++ sys/kern/kern_event.c +@@ -50,6 +50,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -3038,10 +3039,6 @@ + if ((u_int)arg2 > 2 || (u_int)arg2 == 0) + return (EINVAL); + +- error = pget((pid_t)name[0], PGET_HOLD | PGET_CANDEBUG, &p); +- if (error != 0) +- return (error); +- + td = curthread; + #ifdef COMPAT_FREEBSD32 + compat32 = SV_CURPROC_FLAG(SV_ILP32); +@@ -3049,6 +3046,17 @@ + compat32 = false; + #endif + ++ error = pget((pid_t)name[0], PGET_NOTWEXIT, &p); ++ if (error != 0) ++ return (error); ++ ++ _PHOLD(p); ++ execve_block_wait(td, p); ++ error = p_candebug(td, p); ++ if (error != 0) ++ goto out1; ++ PROC_UNLOCK(p); ++ + s = sbuf_new_for_sysctl(&sm, NULL, 0, req); + if (s == NULL) { + error = ENOMEM; +@@ -3069,7 +3077,11 @@ + sbuf_delete(s); + + out: +- PRELE(p); ++ PROC_LOCK(p); ++out1: ++ execve_unblock(td, p); ++ _PRELE(p); ++ PROC_UNLOCK(p); + return (error); + } + +--- sys/kern/kern_exec.c.orig ++++ sys/kern/kern_exec.c +@@ -26,7 +26,6 @@ + * SUCH DAMAGE. + */ + +-#include + #include "opt_capsicum.h" + #include "opt_hwpmc_hooks.h" + #include "opt_ktrace.h" +@@ -45,6 +44,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -370,6 +370,77 @@ + } + } + ++/* ++ * Returns true if the execblock was obtained, in this case the ++ * process lock is kept. Returns false if the execblock was not ++ * obtained, but the function slept and the lock was dropped. ++ */ ++bool ++execve_block(struct thread *td, struct proc *p) ++{ ++ PROC_LOCK_ASSERT(p, MA_OWNED); ++ MPASS(td == curthread); ++ MPASS(p != td->td_proc || (p->p_flag & P_INEXEC) == 0); ++ ++ if (p != td->td_proc && (p->p_flag & P_INEXEC) != 0) { ++ p->p_flag2 |= P2_INEXEC_WAIT; ++ msleep(&p->p_execblock, &p->p_mtx, PDROP, "inexec", 0); ++ return (false); ++ } ++ MPASS(p->p_execblock < UINT_MAX); ++ p->p_execblock++; ++ return (true); ++} ++ ++/* ++ * Might drop the process lock internally, callers must re-check the ++ * invariants afterward. ++ */ ++void ++execve_block_wait(struct thread *td, struct proc *p) ++{ ++ bool first; ++ ++ PROC_ASSERT_HELD(p); ++ PROC_LOCK_ASSERT(p, MA_OWNED); ++ ++ for (first = true;; first = false) { ++ if (!first) ++ PROC_LOCK(p); ++ if (execve_block(td, p)) ++ return; ++ } ++} ++ ++void ++execve_unblock(struct thread *td, struct proc *p) ++{ ++ PROC_LOCK_ASSERT(p, MA_OWNED); ++ MPASS(td == curthread); ++ ++ MPASS(p->p_execblock > 0); ++ p->p_execblock--; ++ if (p->p_execblock == 0 && (p->p_flag2 & P2_INEXEC_WAIT) != 0) { ++ p->p_flag2 &= ~P2_INEXEC_WAIT; ++ wakeup(&p->p_execblock); ++ } ++} ++ ++void ++execve_block_pass(struct thread *td) ++{ ++ struct proc *p; ++ ++ MPASS(td == curthread); ++ p = td->td_proc; ++ PROC_LOCK_ASSERT(p, MA_OWNED); ++ ++ while (p->p_execblock != 0) { ++ p->p_flag2 |= P2_INEXEC_WAIT; ++ msleep(&p->p_execblock, &p->p_mtx, 0, "exeblk", 0); ++ } ++} ++ + /* + * In-kernel implementation of execve(). All arguments are assumed to be + * userspace pointers from the passed thread. +@@ -425,6 +496,7 @@ + PROC_LOCK(p); + KASSERT((p->p_flag & P_INEXEC) == 0, + ("%s(): process already has P_INEXEC flag", __func__)); ++ execve_block_pass(td); + p->p_flag |= P_INEXEC; + PROC_UNLOCK(p); + +@@ -893,7 +965,11 @@ + * as we're now a bona fide freshly-execed process. + */ + KNOTE_LOCKED(p->p_klist, NOTE_EXEC); ++ MPASS(p->p_execblock == 0); ++ if ((p->p_flag2 & P2_INEXEC_WAIT) != 0) ++ wakeup(&p->p_execblock); + p->p_flag &= ~P_INEXEC; ++ p->p_flag2 &= ~P2_INEXEC_WAIT; + + /* clear "fork but no exec" flag, as we _are_ execing */ + p->p_acflag &= ~AFORK; +@@ -975,7 +1051,10 @@ + exec_fail: + /* we're done here, clear P_INEXEC */ + PROC_LOCK(p); ++ if ((p->p_flag2 & P2_INEXEC_WAIT) != 0) ++ wakeup(&p->p_execblock); + p->p_flag &= ~P_INEXEC; ++ p->p_flag2 &= ~P2_INEXEC_WAIT; + PROC_UNLOCK(p); + + SDT_PROBE1(proc, , , exec__failure, error); +--- sys/kern/kern_exit.c.orig ++++ sys/kern/kern_exit.c +@@ -325,6 +325,7 @@ + while (p->p_lock > 0) + msleep(&p->p_lock, &p->p_mtx, PWAIT, "exithold", 0); + ++ MPASS(p->p_execblock == 0); + PROC_UNLOCK(p); + /* Drain the limit callout while we don't have the proc locked */ + callout_drain(&p->p_limco); +--- sys/kern/kern_fork.c.orig ++++ sys/kern/kern_fork.c +@@ -384,6 +384,7 @@ + + bzero(&p2->p_startzero, + __rangeof(struct proc, p_startzero, p_endzero)); ++ p2->p_execblock = 0; + + /* Tell the prison that we exist. */ + prison_proc_hold(p2->p_ucred->cr_prison); +--- sys/kern/kern_proc.c.orig ++++ sys/kern/kern_proc.c +@@ -45,6 +45,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -1833,8 +1834,8 @@ + } + + static int +-proc_read_string(struct thread *td, struct proc *p, const char *sptr, char *buf, +- size_t len) ++proc_read_string(struct thread *td, struct vmspace *vm, const char *sptr, ++ char *buf, size_t len) + { + ssize_t n; + +@@ -1843,7 +1844,7 @@ + * and is aligned at the end of the page, and the following page is not + * mapped. + */ +- n = proc_readmem(td, p, (vm_offset_t)sptr, buf, len); ++ n = vmspace_iop(td, vm, (vm_offset_t)sptr, buf, len, UIO_READ); + if (n <= 0) + return (ENOMEM); + return (0); +@@ -1859,8 +1860,8 @@ + + #ifdef COMPAT_FREEBSD32 + static int +-get_proc_vector32(struct thread *td, struct proc *p, char ***proc_vectorp, +- size_t *vsizep, enum proc_vector_type type) ++get_proc_vector32(struct thread *td, struct proc *p, struct vmspace *vm, ++ char ***proc_vectorp, size_t *vsizep, enum proc_vector_type type) + { + struct freebsd32_ps_strings pss; + Elf32_Auxinfo aux; +@@ -1871,8 +1872,8 @@ + int i, error; + + error = 0; +- if (proc_readmem(td, p, PROC_PS_STRINGS(p), &pss, sizeof(pss)) != +- sizeof(pss)) ++ if (vmspace_iop(td, vm, PROC_PS_STRINGS(p), &pss, sizeof(pss), ++ UIO_READ) != sizeof(pss)) + return (ENOMEM); + switch (type) { + case PROC_ARG: +@@ -1895,8 +1896,8 @@ + if (vptr % 4 != 0) + return (ENOEXEC); + for (ptr = vptr, i = 0; i < PROC_AUXV_MAX; i++) { +- if (proc_readmem(td, p, ptr, &aux, sizeof(aux)) != +- sizeof(aux)) ++ if (vmspace_iop(td, vm, ptr, &aux, sizeof(aux), ++ UIO_READ) != sizeof(aux)) + return (ENOMEM); + if (aux.a_type == AT_NULL) + break; +@@ -1912,7 +1913,7 @@ + return (EINVAL); + } + proc_vector32 = malloc(size, M_TEMP, M_WAITOK); +- if (proc_readmem(td, p, vptr, proc_vector32, size) != size) { ++ if (vmspace_iop(td, vm, vptr, proc_vector32, size, UIO_READ) != size) { + error = ENOMEM; + goto done; + } +@@ -1933,8 +1934,8 @@ + #endif + + static int +-get_proc_vector(struct thread *td, struct proc *p, char ***proc_vectorp, +- size_t *vsizep, enum proc_vector_type type) ++get_proc_vector(struct thread *td, struct proc *p, struct vmspace *vm, ++ char ***proc_vectorp, size_t *vsizep, enum proc_vector_type type) + { + struct ps_strings pss; + Elf_Auxinfo aux; +@@ -1944,11 +1945,13 @@ + int i; + + #ifdef COMPAT_FREEBSD32 +- if (SV_PROC_FLAG(p, SV_ILP32) != 0) +- return (get_proc_vector32(td, p, proc_vectorp, vsizep, type)); ++ if (SV_PROC_FLAG(p, SV_ILP32) != 0) { ++ return (get_proc_vector32(td, p, vm, proc_vectorp, ++ vsizep, type)); ++ } + #endif +- if (proc_readmem(td, p, PROC_PS_STRINGS(p), &pss, sizeof(pss)) != +- sizeof(pss)) ++ if (vmspace_iop(td, vm, PROC_PS_STRINGS(p), &pss, sizeof(pss), ++ UIO_READ) != sizeof(pss)) + return (ENOMEM); + switch (type) { + case PROC_ARG: +@@ -1986,8 +1989,8 @@ + * to the allocated proc_vector. + */ + for (ptr = vptr, i = 0; i < PROC_AUXV_MAX; i++) { +- if (proc_readmem(td, p, ptr, &aux, sizeof(aux)) != +- sizeof(aux)) ++ if (vmspace_iop(td, vm, ptr, &aux, sizeof(aux), ++ UIO_READ) != sizeof(aux)) + return (ENOMEM); + if (aux.a_type == AT_NULL) + break; +@@ -2009,7 +2012,7 @@ + return (EINVAL); /* In case we are built without INVARIANTS. */ + } + proc_vector = malloc(size, M_TEMP, M_WAITOK); +- if (proc_readmem(td, p, vptr, proc_vector, size) != size) { ++ if (vmspace_iop(td, vm, vptr, proc_vector, size, UIO_READ) != size) { + free(proc_vector, M_TEMP); + return (ENOMEM); + } +@@ -2025,6 +2028,7 @@ + get_ps_strings(struct thread *td, struct proc *p, struct sbuf *sb, + enum proc_vector_type type) + { ++ struct vmspace *vm; + size_t done, len, nchr, vsize; + int error, i; + char **proc_vector, *sptr; +@@ -2037,9 +2041,14 @@ + */ + nchr = 2 * (PATH_MAX + ARG_MAX); + +- error = get_proc_vector(td, p, &proc_vector, &vsize, type); ++ error = proc_vmspace_ref(td, p, PRVM_BLOCK_EXEC | ++ PRVM_CHECK_VISIBILITY, &vm); + if (error != 0) + return (error); ++ ++ error = get_proc_vector(td, p, vm, &proc_vector, &vsize, type); ++ if (error != 0) ++ goto out; + for (done = 0, i = 0; i < (int)vsize && done < nchr; i++) { + /* + * The program may have scribbled into its argv array, e.g. to +@@ -2049,7 +2058,7 @@ + if (proc_vector[i] == NULL) + break; + for (sptr = proc_vector[i]; ; sptr += GET_PS_STRINGS_CHUNK_SZ) { +- error = proc_read_string(td, p, sptr, pss_string, ++ error = proc_read_string(td, vm, sptr, pss_string, + sizeof(pss_string)); + if (error != 0) + goto done; +@@ -2066,6 +2075,8 @@ + } + done: + free(proc_vector, M_TEMP); ++out: ++ proc_vmspace_unref(td, p, PRVM_BLOCK_EXEC | PRVM_CHECK_VISIBILITY, vm); + return (error); + } + +@@ -2086,11 +2097,17 @@ + int + proc_getauxv(struct thread *td, struct proc *p, struct sbuf *sb) + { ++ struct vmspace *vm; + size_t vsize, size; + char **auxv; + int error; + +- error = get_proc_vector(td, p, &auxv, &vsize, PROC_AUX); ++ error = proc_vmspace_ref(td, p, PRVM_BLOCK_EXEC | PRVM_CHECK_DEBUG, ++ &vm); ++ if (error != 0) ++ return (error); ++ error = get_proc_vector(td, p, vm, &auxv, &vsize, PROC_AUX); ++ proc_vmspace_unref(td, p, PRVM_BLOCK_EXEC | PRVM_CHECK_DEBUG, vm); + if (error == 0) { + #ifdef COMPAT_FREEBSD32 + if (SV_PROC_FLAG(p, SV_ILP32) != 0) +@@ -2403,6 +2420,7 @@ + int error, *name; + struct vnode *vp; + struct proc *p; ++ struct thread *td; + vm_map_t map; + struct vmspace *vm; + +@@ -2411,11 +2429,12 @@ + return (EINVAL); + + name = (int *)arg1; ++ td = curthread; + error = pget((pid_t)name[0], PGET_WANTREAD, &p); + if (error != 0) + return (error); +- vm = vmspace_acquire_ref(p); +- if (vm == NULL) { ++ error = proc_vmspace_ref(td, p, PRVM_CHECK_DEBUG, &vm); ++ if (error != 0) { + PRELE(p); + return (ESRCH); + } +@@ -2527,7 +2546,7 @@ + } + } + vm_map_unlock_read(map); +- vmspace_free(vm); ++ proc_vmspace_unref(td, p, PRVM_CHECK_DEBUG, vm); + PRELE(p); + free(kve, M_TEMP); + return (error); +@@ -2618,6 +2637,7 @@ + struct vmspace *vm; + struct cdev *cdev; + struct cdevsw *csw; ++ struct thread *td; + vm_offset_t addr; + unsigned int last_timestamp; + int error, ref; +@@ -2629,10 +2649,11 @@ + + _PHOLD(p); + PROC_UNLOCK(p); +- vm = vmspace_acquire_ref(p); +- if (vm == NULL) { ++ td = curthread; ++ error = proc_vmspace_ref(td, p, PRVM_CHECK_DEBUG, &vm); ++ if (error != 0) { + PRELE(p); +- return (ESRCH); ++ return (error); + } + kve = malloc(sizeof(*kve), M_TEMP, M_WAITOK | M_ZERO); + +@@ -2747,7 +2768,7 @@ + if (vp != NULL) { + vn_fullpath(vp, &fullpath, &freepath); + kve->kve_vn_type = vntype_to_kinfo(vp->v_type); +- cred = curthread->td_ucred; ++ cred = td->td_ucred; + vn_lock(vp, LK_SHARED | LK_RETRY); + if (VOP_GETATTR(vp, &va, cred) == 0) { + kve->kve_vn_fileid = va.va_fileid; +@@ -2803,7 +2824,7 @@ + } + } + vm_map_unlock_read(map); +- vmspace_free(vm); ++ proc_vmspace_unref(td, p, PRVM_CHECK_DEBUG, vm); + PRELE(p); + free(kve, M_TEMP); + return (error); +@@ -2842,7 +2863,7 @@ + struct kinfo_kstack *kkstp; + int error, i, *name, numthreads; + lwpid_t *lwpidarray; +- struct thread *td; ++ struct thread *td, *ctd; + struct stack *st; + struct sbuf sb; + struct proc *p; +@@ -2853,7 +2874,8 @@ + return (EINVAL); + + name = (int *)arg1; +- error = pget((pid_t)name[0], PGET_NOTINEXEC | PGET_WANTREAD, &p); ++ ctd = curthread; ++ error = pget((pid_t)name[0], PGET_WANTREAD, &p); + if (error != 0) + return (error); + +@@ -2862,6 +2884,14 @@ + + lwpidarray = NULL; + PROC_LOCK(p); ++ execve_block_wait(ctd, p); ++ error = p_candebug(ctd, p); ++ if (error != 0) { ++ execve_unblock(ctd, p); ++ _PRELE(p); ++ PROC_UNLOCK(p); ++ return (error); ++ } + do { + if (lwpidarray != NULL) { + free(lwpidarray, M_TEMP); +@@ -2874,15 +2904,6 @@ + PROC_LOCK(p); + } while (numthreads < p->p_numthreads); + +- /* +- * XXXRW: During the below loop, execve(2) and countless other sorts +- * of changes could have taken place. Should we check to see if the +- * vmspace has been replaced, or the like, in order to prevent +- * giving a snapshot that spans, say, execve(2), with some threads +- * before and some after? Among other things, the credentials could +- * have changed, in which case the right to extract debug info might +- * no longer be assured. +- */ + i = 0; + FOREACH_THREAD_IN_PROC(p, td) { + KASSERT(i < numthreads, +@@ -2917,7 +2938,10 @@ + if (error) + break; + } +- PRELE(p); ++ PROC_LOCK(p); ++ execve_unblock(ctd, p); ++ _PRELE(p); ++ PROC_UNLOCK(p); + if (lwpidarray != NULL) + free(lwpidarray, M_TEMP); + stack_destroy(st); +@@ -2970,8 +2994,9 @@ + u_int namelen = arg2; + struct rlimit rlim; + struct proc *p; ++ struct thread *td; + u_int which; +- int flags, error; ++ int error; + + if (namelen != 2) + return (EINVAL); +@@ -2983,23 +3008,24 @@ + if (req->newptr != NULL && req->newlen != sizeof(rlim)) + return (EINVAL); + +- flags = PGET_HOLD | PGET_NOTWEXIT; +- if (req->newptr != NULL) +- flags |= PGET_CANDEBUG; +- else +- flags |= PGET_CANSEE; +- error = pget((pid_t)name[0], flags, &p); ++ td = curthread; ++ error = pget((pid_t)name[0], PGET_NOTWEXIT, &p); + if (error != 0) + return (error); ++ _PHOLD(p); ++ execve_block_wait(td, p); ++ error = req->newptr != NULL ? p_candebug(td, p) : p_cansee(td, p); ++ if (error != 0) ++ goto errout1; + + /* + * Retrieve limit. + */ + if (req->oldptr != NULL) { +- PROC_LOCK(p); + lim_rlimit_proc(p, which, &rlim); +- PROC_UNLOCK(p); + } ++ PROC_UNLOCK(p); ++ + error = SYSCTL_OUT(req, &rlim, sizeof(rlim)); + if (error != 0) + goto errout; +@@ -3014,7 +3040,11 @@ + } + + errout: +- PRELE(p); ++ PROC_LOCK(p); ++errout1: ++ _PRELE(p); ++ execve_unblock(td, p); ++ PROC_UNLOCK(p); + return (error); + } + +@@ -3103,39 +3133,38 @@ + int *name = (int *)arg1; + u_int namelen = arg2; + struct proc *p; +- int flags, error, osrel; ++ int flags, error, old_osrel, osrel; + + if (namelen != 1) + return (EINVAL); + +- if (req->newptr != NULL && req->newlen != sizeof(osrel)) +- return (EINVAL); +- +- flags = PGET_HOLD | PGET_NOTWEXIT; +- if (req->newptr != NULL) ++ flags = PGET_NOTWEXIT; ++ if (req->newptr != NULL) { ++ if (req->newlen != sizeof(osrel)) ++ return (EINVAL); ++ error = SYSCTL_IN(req, &osrel, sizeof(osrel)); ++ if (error != 0) ++ return (error); ++ if (osrel < 0) ++ return (EINVAL); + flags |= PGET_CANDEBUG; +- else ++ } else { + flags |= PGET_CANSEE; ++ } + error = pget((pid_t)name[0], flags, &p); + if (error != 0) + return (error); +- +- error = SYSCTL_OUT(req, &p->p_osrel, sizeof(p->p_osrel)); +- if (error != 0) +- goto errout; +- +- if (req->newptr != NULL) { +- error = SYSCTL_IN(req, &osrel, sizeof(osrel)); +- if (error != 0) +- goto errout; +- if (osrel < 0) { +- error = EINVAL; +- goto errout; +- } +- p->p_osrel = osrel; ++ if ((p->p_flag & P_INEXEC) != 0) { ++ error = EBUSY; ++ } else { ++ old_osrel = p->p_osrel; ++ if (req->newptr != NULL) ++ p->p_osrel = osrel; + } +-errout: +- PRELE(p); ++ PROC_UNLOCK(p); ++ ++ if (error == 0) ++ error = SYSCTL_OUT(req, &old_osrel, sizeof(old_osrel)); + return (error); + } + +@@ -3272,6 +3301,7 @@ + { + struct kinfo_vm_layout kvm; + struct proc *p; ++ struct thread *td; + struct vmspace *vmspace; + int error, *name; + +@@ -3279,6 +3309,7 @@ + if ((u_int)arg2 != 1) + return (EINVAL); + ++ td = curthread; + error = pget((pid_t)name[0], PGET_CANDEBUG, &p); + if (error != 0) + return (error); +@@ -3290,8 +3321,13 @@ + } + } + #endif +- vmspace = vmspace_acquire_ref(p); ++ _PHOLD(p); + PROC_UNLOCK(p); ++ error = proc_vmspace_ref(td, p, PRVM_CHECK_DEBUG, &vmspace); ++ if (error != 0) { ++ PRELE(p); ++ return (error); ++ } + + memset(&kvm, 0, sizeof(kvm)); + kvm.kvm_min_user_addr = vm_map_min(&vmspace->vm_map); +@@ -3343,7 +3379,8 @@ + #ifdef COMPAT_FREEBSD32 + out: + #endif +- vmspace_free(vmspace); ++ proc_vmspace_unref(td, p, PRVM_CHECK_DEBUG, vmspace); ++ PRELE(p); + return (error); + } + +--- sys/kern/kern_procctl.c.orig ++++ sys/kern/kern_procctl.c +@@ -40,6 +40,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -872,37 +873,41 @@ + { + struct vmspace *vm; + vm_map_t map; +- int state; ++ int error, state; + + PROC_LOCK_ASSERT(p, MA_OWNED); + if ((p->p_flag & P_WEXIT) != 0) + return (ESRCH); + state = *(int *)data; ++ error = 0; + + switch (state) { + case PROC_WX_MAPPINGS_PERMIT: +- p->p_flag2 |= P2_WXORX_DISABLE; +- _PHOLD(p); + PROC_UNLOCK(p); +- vm = vmspace_acquire_ref(p); +- if (vm != NULL) { ++ error = proc_vmspace_ref(td, p, PRVM_BLOCK_EXEC | ++ PRVM_CHECK_DEBUG, &vm); ++ if (error == 0) { + map = &vm->vm_map; + vm_map_lock(map); + map->flags &= ~MAP_WXORX; + vm_map_unlock(map); +- vmspace_free(vm); ++ PROC_LOCK(p); ++ p->p_flag2 |= P2_WXORX_DISABLE; ++ PROC_UNLOCK(p); ++ proc_vmspace_unref(td, p, PRVM_BLOCK_EXEC | ++ PRVM_CHECK_DEBUG, vm); + } + PROC_LOCK(p); +- _PRELE(p); + break; + case PROC_WX_MAPPINGS_DISALLOW_EXEC: + p->p_flag2 |= P2_WXORX_ENABLE_EXEC; + break; + default: +- return (EINVAL); ++ error = EINVAL; ++ break; + } + +- return (0); ++ return (error); + } + + static int +--- sys/kern/kern_prot.c.orig ++++ sys/kern/kern_prot.c +@@ -51,6 +51,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -1010,6 +1011,8 @@ + newcred = crget(); + euip = uifind(euid); + PROC_LOCK(p); ++ execve_block_pass(td); ++ + /* + * Copy credentials so other references do not see our changes. + */ +@@ -1064,6 +1067,7 @@ + AUDIT_ARG_GID(gid); + newcred = crget(); + PROC_LOCK(p); ++ execve_block_pass(td); + oldcred = crcopysafe(p, newcred); + + #ifdef MAC +@@ -1162,6 +1166,7 @@ + AUDIT_ARG_EGID(egid); + newcred = crget(); + PROC_LOCK(p); ++ execve_block_pass(td); + oldcred = crcopysafe(p, newcred); + + #ifdef MAC +@@ -1257,6 +1262,7 @@ + if (ngrp != 0) + crextend(newcred, ngrp); + PROC_LOCK(p); ++ execve_block_pass(td); + oldcred = crcopysafe(p, newcred); + + #ifdef MAC +@@ -1319,6 +1325,7 @@ + euip = uifind(euid); + ruip = uifind(ruid); + PROC_LOCK(p); ++ execve_block_pass(td); + oldcred = crcopysafe(p, newcred); + + #ifdef MAC +@@ -1398,6 +1405,7 @@ + AUDIT_ARG_RGID(rgid); + newcred = crget(); + PROC_LOCK(p); ++ execve_block_pass(td); + oldcred = crcopysafe(p, newcred); + + #ifdef MAC +@@ -1468,6 +1476,7 @@ + euip = uifind(euid); + ruip = uifind(ruid); + PROC_LOCK(p); ++ execve_block_pass(td); + oldcred = crcopysafe(p, newcred); + + #ifdef MAC +@@ -1559,6 +1568,7 @@ + AUDIT_ARG_SGID(sgid); + newcred = crget(); + PROC_LOCK(p); ++ execve_block_pass(td); + oldcred = crcopysafe(p, newcred); + + #ifdef MAC +@@ -2310,11 +2320,11 @@ + } + + /* +- * Can't trace a process that's currently exec'ing. +- * +- * XXX: Note, this is not a security policy decision, it's a +- * basic correctness/functionality decision. Therefore, this check +- * should be moved to the caller's of p_candebug(). ++ * Can't trace a process that's currently exec'ing. Otherwise ++ * the process vmspace might change, and the target might be ++ * loading a setugid image. The execve_block(9) and ++ * proc_vmspace_ref(9) allow to get the stable credentials and ++ * vmspace reference. + */ + if ((p->p_flag & P_INEXEC) != 0) + return (EBUSY); +--- sys/kern/kern_resource.c.orig ++++ sys/kern/kern_resource.c +@@ -48,6 +48,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -810,11 +811,11 @@ + } + + static int +-getrlimitusage_one(struct proc *p, u_int which, int flags, rlim_t *res) ++getrlimitusage_one(struct proc *p, struct vmspace *vm, u_int which, int flags, ++ rlim_t *res) + { + struct thread *td; + struct uidinfo *ui; +- struct vmspace *vm; + uid_t uid; + int error; + +@@ -825,7 +826,6 @@ + PROC_UNLOCK(p); + + ui = uifind(uid); +- vm = vmspace_acquire_ref(p); + + switch (which) { + case RLIMIT_CPU: +@@ -903,7 +903,6 @@ + break; + } + +- vmspace_free(vm); + uifree(ui); + return (error); + } +@@ -911,12 +910,15 @@ + int + sys_getrlimitusage(struct thread *td, struct getrlimitusage_args *uap) + { ++ struct proc *p; + rlim_t res; + int error; + + if ((uap->flags & ~(GETRLIMITUSAGE_EUID)) != 0) + return (EINVAL); +- error = getrlimitusage_one(curproc, uap->which, uap->flags, &res); ++ p = curproc; ++ error = getrlimitusage_one(p, p->p_vmspace, uap->which, uap->flags, ++ &res); + if (error == 0) + error = copyout(&res, uap->res, sizeof(res)); + return (error); +@@ -1750,6 +1752,8 @@ + { + rlim_t resval[RLIM_NLIMITS]; + struct proc *p; ++ struct thread *td; ++ struct vmspace *vm; + size_t len; + int error, *name, i; + +@@ -1759,15 +1763,20 @@ + if (req->newptr != NULL) + return (EINVAL); + +- error = pget((pid_t)name[0], PGET_WANTREAD, &p); ++ td = curthread; ++ error = pget((pid_t)name[0], PGET_HOLD | PGET_NOTWEXIT, &p); + if (error != 0) + return (error); ++ error = proc_vmspace_ref(td, p, PRVM_BLOCK_EXEC | ++ PRVM_CHECK_VISIBILITY, &vm); ++ if (error != 0) ++ goto out; + + if ((u_int)arg2 == 1) { + len = sizeof(resval); + memset(resval, 0, sizeof(resval)); + for (i = 0; i < RLIM_NLIMITS; i++) { +- error = getrlimitusage_one(p, (unsigned)i, 0, ++ error = getrlimitusage_one(p, vm, (unsigned)i, 0, + &resval[i]); + if (error == ENXIO) { + resval[i] = -1; +@@ -1778,7 +1787,7 @@ + } + } else { + len = sizeof(resval[0]); +- error = getrlimitusage_one(p, (unsigned)name[1], 0, ++ error = getrlimitusage_one(p, vm, (unsigned)name[1], 0, + &resval[0]); + if (error == ENXIO) { + resval[0] = -1; +@@ -1787,6 +1796,8 @@ + } + if (error == 0) + error = SYSCTL_OUT(req, resval, len); ++ proc_vmspace_unref(td, p, PRVM_BLOCK_EXEC | PRVM_CHECK_VISIBILITY, vm); ++out: + PRELE(p); + return (error); + } +--- sys/kern/sys_process.c.orig ++++ sys/kern/sys_process.c +@@ -34,6 +34,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -345,25 +346,93 @@ + PROC_ACTION(ptrace_single_step(td)); + } + ++static int ++proc_vmspace_check_access(struct thread *td, struct proc *p, int flags) ++{ ++ PROC_ASSERT_HELD(p); ++ if ((flags & PRVM_CHECK_DEBUG) != 0) ++ return (p_candebug(td, p)); ++ if ((flags & PRVM_CHECK_VISIBILITY) != 0) ++ return (p_cansee(td, p)); ++ return (0); ++} ++ + int +-proc_rwmem(struct proc *p, struct uio *uio) ++proc_vmspace_ref(struct thread *td, struct proc *p, int flags, ++ struct vmspace **vmp) ++{ ++ struct vmspace *vm; ++ int error; ++ ++ MPASS((flags & ~(PRVM_BLOCK_EXEC | PRVM_CHECK_VISIBILITY | ++ PRVM_CHECK_DEBUG)) == 0); ++ MPASS((flags & (PRVM_CHECK_VISIBILITY | PRVM_CHECK_DEBUG)) != ++ (PRVM_CHECK_VISIBILITY | PRVM_CHECK_DEBUG)); ++ ++ PROC_LOCK(p); ++ if (p != td->td_proc) { ++ PROC_ASSERT_HELD(p); ++ ++ /* ++ * Make sure that the vmspace doesn't switch out from ++ * under us. ++ */ ++ if ((flags & PRVM_BLOCK_EXEC) != 0) { ++ for (;;) { ++ if (!execve_block(td, p)) { ++ PROC_LOCK(p); ++ continue; ++ } ++ error = proc_vmspace_check_access(td, p, flags); ++ if (error != 0) { ++ execve_unblock(td, p); ++ PROC_UNLOCK(p); ++ return (error); ++ } ++ break; ++ } ++ } else { ++ error = proc_vmspace_check_access(td, p, flags); ++ if (error != 0) { ++ PROC_UNLOCK(p); ++ return (error); ++ } ++ } ++ } ++ vm = vmspace_acquire_ref(p); ++ if (vm == NULL) { ++ if (p != td->td_proc && (flags & PRVM_BLOCK_EXEC) != 0) ++ execve_unblock(td, p); ++ PROC_UNLOCK(p); ++ return (ESRCH); ++ } ++ PROC_UNLOCK(p); ++ *vmp = vm; ++ return (0); ++} ++ ++void ++proc_vmspace_unref(struct thread *td, struct proc *p, int flags, ++ struct vmspace *vm) ++{ ++ vmspace_free(vm); ++ if (p != td->td_proc && (flags & PRVM_BLOCK_EXEC) != 0) { ++ PROC_LOCK(p); ++ PROC_ASSERT_HELD(p); ++ execve_unblock(td, p); ++ PROC_UNLOCK(p); ++ } ++} ++ ++static int ++vmspace_rwmem(struct vmspace *vm, struct uio *uio) + { + vm_map_t map; + vm_offset_t pageno; /* page number */ + vm_prot_t reqprot; + int error, fault_flags, page_offset, writing; + +- /* +- * Make sure that the process' vmspace remains live. +- */ +- if (p != curproc) +- PROC_ASSERT_HELD(p); +- PROC_LOCK_ASSERT(p, MA_NOTOWNED); +- +- /* +- * The map we want... +- */ +- map = &p->p_vmspace->vm_map; ++ map = &vm->vm_map; + + /* + * If we are writing, then we request vm_fault() to create a private +@@ -432,13 +501,30 @@ + return (error); + } + +-static ssize_t +-proc_iop(struct thread *td, struct proc *p, vm_offset_t va, void *buf, ++int ++proc_rwmem(struct proc *p, struct uio *uio, int flags) ++{ ++ struct vmspace *vm; ++ struct thread *td; ++ int error; ++ ++ td = curthread; ++ error = proc_vmspace_ref(td, p, flags, &vm); ++ if (error != 0) ++ return (error); ++ error = vmspace_rwmem(vm, uio); ++ proc_vmspace_unref(td, p, flags, vm); ++ return (error); ++} ++ ++ssize_t ++vmspace_iop(struct thread *td, struct vmspace *vm, vm_offset_t va, void *buf, + size_t len, enum uio_rw rw) + { + struct iovec iov; + struct uio uio; + ssize_t slen; ++ int error; + + MPASS(len < SSIZE_MAX); + slen = (ssize_t)len; +@@ -452,8 +538,8 @@ + uio.uio_segflg = UIO_SYSSPACE; + uio.uio_rw = rw; + uio.uio_td = td; +- proc_rwmem(p, &uio); +- if (uio.uio_resid == slen) ++ error = vmspace_rwmem(vm, &uio); ++ if (error != 0 || uio.uio_resid == slen) + return (-1); + return (slen - uio.uio_resid); + } +@@ -463,7 +549,7 @@ + size_t len) + { + +- return (proc_iop(td, p, va, buf, len, UIO_READ)); ++ return (vmspace_iop(td, p->p_vmspace, va, buf, len, UIO_READ)); + } + + ssize_t +@@ -471,7 +557,7 @@ + size_t len) + { + +- return (proc_iop(td, p, va, buf, len, UIO_WRITE)); ++ return (vmspace_iop(td, p->p_vmspace, va, buf, len, UIO_WRITE)); + } + + static int +@@ -1465,7 +1551,7 @@ + goto out; + } + PROC_UNLOCK(p); +- error = proc_rwmem(p, &uio); ++ error = proc_rwmem(p, &uio, 0); + piod->piod_len -= uio.uio_resid; + PROC_LOCK(p); + break; +--- sys/sys/imgact.h.orig ++++ sys/sys/imgact.h +@@ -122,6 +122,10 @@ + int exec_copyin_args(struct image_args *, const char *, char **, char **); + int pre_execve(struct thread *td, struct vmspace **oldvmspace); + void post_execve(struct thread *td, int error, struct vmspace *oldvmspace); ++bool execve_block(struct thread *td, struct proc *p); ++void execve_block_wait(struct thread *td, struct proc *p); ++void execve_unblock(struct thread *td, struct proc *p); ++void execve_block_pass(struct thread *td); + #endif + + #endif /* !_SYS_IMGACT_H_ */ +--- sys/sys/proc.h.orig ++++ sys/sys/proc.h +@@ -777,6 +777,7 @@ + + TAILQ_HEAD(, kq_timer_cb_data) p_kqtim_stop; /* (c) */ + LIST_ENTRY(proc) p_jaillist; /* (d) Jail process linkage. */ ++ u_int p_execblock; /* (c) Blockers for execve. */ + }; + + #define p_session p_pgrp->pg_session +@@ -890,6 +891,8 @@ + sync core registered */ + #define P2_MEMBAR_GLOBE 0x00400000 /* membar global expedited + registered */ ++#define P2_INEXEC_WAIT 0x80000000 /* Not same as in HEAD. ++ Waiters for P_INEXEC/p_execblock */ + + /* Flags protected by proctree_lock, kept in p_treeflags. */ + #define P_TREE_ORPHANED 0x00000001 /* Reparented, on orphan list */ +--- sys/sys/ptrace.h.orig ++++ sys/sys/ptrace.h +@@ -249,7 +249,20 @@ + int proc_read_dbregs(struct thread *_td, struct dbreg *_dbreg); + int proc_write_dbregs(struct thread *_td, struct dbreg *_dbreg); + int proc_sstep(struct thread *_td); +-int proc_rwmem(struct proc *_p, struct uio *_uio); ++ ++#define PRVM_BLOCK_EXEC 0x00000001 ++#define PRVM_CHECK_VISIBILITY 0x00000002 ++#define PRVM_CHECK_DEBUG 0x00000004 ++ ++#include ++struct vmspace; ++int proc_vmspace_ref(struct thread *_td, struct proc *_p, int _flags, ++ struct vmspace **_vmp); ++void proc_vmspace_unref(struct thread *_td, struct proc *_p, int _flags, ++ struct vmspace *_vm); ++ssize_t vmspace_iop(struct thread *td, struct vmspace *vm, vm_offset_t va, ++ void *buf, size_t len, enum uio_rw rw); ++int proc_rwmem(struct proc *_p, struct uio *_uio, int _flags); + ssize_t proc_readmem(struct thread *_td, struct proc *_p, vm_offset_t _va, + void *_buf, size_t _len); + ssize_t proc_writemem(struct thread *_td, struct proc *_p, vm_offset_t _va, diff --git a/website/static/security/patches/SA-26:39/execve-14.4.patch.asc b/website/static/security/patches/SA-26:39/execve-14.4.patch.asc new file mode 100644 index 0000000000..af6521ffd0 --- /dev/null +++ b/website/static/security/patches/SA-26:39/execve-14.4.patch.asc @@ -0,0 +1,17 @@ +-----BEGIN PGP SIGNATURE----- + +iQJPBAABCgA5FiEEthUnfoEIffdcgYM7bljekB8AGu8FAmpEEjkbFIAAAAAABAAO +bWFudTIsMi41KzEuMTIsMCwzAAoJEG5Y3pAfABrvvecQAIf1sW3Sva+MwlBtOCxk +B35jGzENP56pE4Hl5/biTtHU8ndT9OuaJTXcbGEaagU8t4MJEP/nwFwFjhSazzXr +CTElIoBBTyNHVM35nyLtr6iOOIS25qtHiQmsHSrIlNIY28PcA23K3kepJxr/8Ut0 +M5RO1G/hlV4bHJxMRtLdLn/ibmDZxJlVU1kOdrXziCCIu8jaF7X9Ac1zfw4J299T +P245rBzGNXgnYTZcin8tTxGrh+thBFNQFAi5uoGaPGxrpOnlaDZiEpEIpNFDJH5N +B5Y92wT8gsKYs5vHq4Ye4+b9SgnraHMPIal+YwFNRVtWOnwiyvImn1RlHJq+uaGz +CTe/mWgPOiqk5yxfBpy8lFfhv9n/ImqCdRxu/JnitAyIG/7TM7/gXPUFUoCQ8AGJ +vBOt9JTrMgnNj5p5BUzkyqWtytnVMYsTsve8xRNXA65WkUIvLo2/2NLEUejtyL6Q +r+3+B+L+GigDv6PmDjBwzfPMJBBL+v11AdcxbbYLY/nXoSM6CpB8XsWDwdQRcAsy +e1Iih9eji8MmoUh5jdaKsw/2vXcnlMDurEga5QvMfuxvb7ijwF/0Wdc0wqF4/BRT +JmTxhjl881Lpm2ilBnxiqd1W7v34EUUCoFF16eL4m08NQZKzkozvpYEmbsx23QWc +rhiWc9nNZiXrXPAWstN2CpPk +=EY+n +-----END PGP SIGNATURE----- diff --git a/website/static/security/patches/SA-26:39/execve-15.patch b/website/static/security/patches/SA-26:39/execve-15.patch new file mode 100644 index 0000000000..cfcfd218c8 --- /dev/null +++ b/website/static/security/patches/SA-26:39/execve-15.patch @@ -0,0 +1,1542 @@ +--- sys/compat/linprocfs/linprocfs.c.orig ++++ sys/compat/linprocfs/linprocfs.c +@@ -1315,19 +1315,13 @@ + struct vattr vat; + bool private; + +- PROC_LOCK(p); +- error = p_candebug(td, p); +- PROC_UNLOCK(p); +- if (error) +- return (error); +- + if (uio->uio_rw != UIO_READ) + return (EOPNOTSUPP); + +- error = 0; +- vm = vmspace_acquire_ref(p); +- if (vm == NULL) +- return (ESRCH); ++ error = proc_vmspace_ref(td, p, PRVM_BLOCK_EXEC | PRVM_CHECK_DEBUG, ++ &vm); ++ if (error != 0) ++ return (error); + + if (SV_CURPROC_FLAG(SV_LP64)) + l_map_str = l64_map_str; +@@ -1425,7 +1419,7 @@ + } + } + vm_map_unlock_read(map); +- vmspace_free(vm); ++ proc_vmspace_unref(td, p, PRVM_CHECK_DEBUG | PRVM_BLOCK_EXEC, vm); + + return (error); + } +--- sys/compat/linux/linux_misc.c.orig ++++ sys/compat/linux/linux_misc.c +@@ -2010,6 +2010,7 @@ + u_int which; + int flags; + int error; ++ bool exec_blocked; + + if (args->new == NULL && args->old != NULL) { + if (linux_get_dummy_limit(td, args->resource, &rlim)) { +@@ -2037,6 +2038,7 @@ + return (error); + } + ++ exec_blocked = false; + flags = PGET_HOLD | PGET_NOTWEXIT; + if (args->new != NULL) + flags |= PGET_CANDEBUG; +@@ -2049,6 +2051,14 @@ + error = pget(args->pid, flags, &p); + if (error != 0) + return (error); ++ exec_blocked = true; ++ PROC_LOCK(p); ++ execve_block_wait(td, p); ++ error = args->new != NULL ? p_candebug(td, p) : ++ p_cansee(td, p); ++ PROC_UNLOCK(p); ++ if (error != 0) ++ goto out; + } + if (args->old != NULL) { + PROC_LOCK(p); +@@ -2071,6 +2081,11 @@ + error = kern_proc_setrlimit(td, p, which, &nrlim); + + out: ++ if (exec_blocked) { ++ PROC_LOCK(p); ++ execve_unblock(td, p); ++ PROC_UNLOCK(p); ++ } + PRELE(p); + return (error); + } +--- sys/fs/cuse/cuse.c.orig ++++ sys/fs/cuse/cuse.c +@@ -916,7 +916,7 @@ + }; + + PHOLD(proc_s); +- error = proc_rwmem(proc_s, &uio); ++ error = proc_rwmem(proc_s, &uio, 0); + PRELE(proc_s); + + } else if (proc_cur == proc_s) { +@@ -935,7 +935,7 @@ + }; + + PHOLD(proc_d); +- error = proc_rwmem(proc_d, &uio); ++ error = proc_rwmem(proc_d, &uio, 0); + PRELE(proc_d); + } else { + error = EINVAL; +--- sys/fs/procfs/procfs_map.c.orig ++++ sys/fs/procfs/procfs_map.c +@@ -40,6 +40,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -93,15 +94,14 @@ + bool wrap32; + #endif + +- PROC_LOCK(p); +- error = p_candebug(td, p); +- PROC_UNLOCK(p); +- if (error) +- return (error); +- + if (uio->uio_rw != UIO_READ) + return (EOPNOTSUPP); + ++ error = proc_vmspace_ref(td, p, PRVM_BLOCK_EXEC | PRVM_CHECK_DEBUG, ++ &vm); ++ if (error != 0) ++ return (error); ++ + #ifdef COMPAT_FREEBSD32 + wrap32 = false; + if (SV_CURPROC_FLAG(SV_ILP32)) { +@@ -111,9 +111,6 @@ + } + #endif + +- vm = vmspace_acquire_ref(p); +- if (vm == NULL) +- return (ESRCH); + map = &vm->vm_map; + vm_map_lock_read(map); + VM_MAP_ENTRY_FOREACH(entry, map) { +@@ -238,6 +235,6 @@ + } + } + vm_map_unlock_read(map); +- vmspace_free(vm); ++ proc_vmspace_unref(td, p, PRVM_BLOCK_EXEC | PRVM_CHECK_DEBUG, vm); + return (error); + } +--- sys/fs/procfs/procfs_mem.c.orig ++++ sys/fs/procfs/procfs_mem.c +@@ -60,11 +60,7 @@ + if (uio->uio_resid == 0) + return (0); + +- PROC_LOCK(p); +- error = p_candebug(td, p); +- PROC_UNLOCK(p); +- if (error == 0) +- error = proc_rwmem(p, uio); ++ error = proc_rwmem(p, uio, PRVM_CHECK_DEBUG | PRVM_BLOCK_EXEC); + + return (error); + } +--- sys/fs/pseudofs/pseudofs_vnops.c.orig ++++ sys/fs/pseudofs/pseudofs_vnops.c +@@ -37,6 +37,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -132,6 +133,7 @@ + pfs_lookup_proc(pid_t pid, struct proc **p) + { + struct proc *proc; ++ struct thread *td; + + proc = pfind(pid); + if (proc == NULL) +@@ -141,8 +143,10 @@ + return (0); + } + _PHOLD(proc); +- PROC_UNLOCK(proc); ++ td = curthread; ++ execve_block_wait(td, proc); + *p = proc; ++ PROC_UNLOCK(proc); + return (1); + } + +@@ -672,6 +676,7 @@ + struct pfs_node *pn = pvd->pvd_pn; + struct uio *uio = va->a_uio; + struct proc *proc; ++ struct thread *td; + struct sbuf *sb = NULL; + int error, locked; + off_t buflen, buflim; +@@ -690,21 +695,30 @@ + if (pn->pn_fill == NULL) + PFS_RETURN (EIO); + ++ td = curthread; ++ + /* + * This is necessary because either process' privileges may + * have changed since the open() call. + */ +- if (!pfs_visible(curthread, pn, pvd->pvd_pid, &proc)) ++ if (!pfs_visible(td, pn, pvd->pvd_pid, &proc)) + PFS_RETURN (EIO); +- if (proc != NULL) { +- _PHOLD(proc); +- PROC_UNLOCK(proc); +- } + + vhold(vn); + locked = VOP_ISLOCKED(vn); + VOP_UNLOCK(vn); + ++ if (proc != NULL) { ++ _PHOLD(proc); ++ execve_block_wait(td, proc); ++ if (!pfs_visible_proc(td, pn, proc)) { ++ PROC_UNLOCK(proc); ++ error = EIO; ++ goto ret; ++ } ++ PROC_UNLOCK(proc); ++ } ++ + if (pn->pn_flags & PFS_RAWRD) { + PFS_TRACE(("%zd resid", uio->uio_resid)); + error = pn_fill(curthread, proc, pn, NULL, uio); +@@ -774,8 +788,12 @@ + ret: + vn_lock(vn, locked | LK_RETRY); + vdrop(vn); +- if (proc != NULL) +- PRELE(proc); ++ if (proc != NULL) { ++ PROC_LOCK(proc); ++ execve_unblock(td, proc); ++ _PRELE(proc); ++ PROC_UNLOCK(proc); ++ } + PFS_RETURN (error); + } + +@@ -846,6 +864,7 @@ + struct pfs_node *pd = pvd->pvd_pn; + pid_t pid = pvd->pvd_pid; + struct proc *p, *proc; ++ struct thread *td; + struct pfs_node *pn; + struct uio *uio; + struct pfsentry *pfsent, *pfsent2; +@@ -891,11 +910,13 @@ + KASSERT(pid == NO_PID || proc != NULL, + ("%s(): no process for pid %lu", __func__, (unsigned long)pid)); + ++ td = curthread; + if (pid != NO_PID) { + PROC_LOCK(proc); + + /* check if the directory is visible to the caller */ + if (!pfs_visible_proc(curthread, pd, proc)) { ++ execve_unblock(td, proc); + _PRELE(proc); + PROC_UNLOCK(proc); + pfs_unlock(pd); +@@ -955,6 +976,7 @@ + resid -= PFS_DELEN; + } + if (proc != NULL) { ++ execve_unblock(td, proc); + _PRELE(proc); + PROC_UNLOCK(proc); + } +@@ -1079,6 +1101,7 @@ + struct pfs_node *pn = pvd->pvd_pn; + struct uio *uio = va->a_uio; + struct proc *proc; ++ struct thread *td; + struct sbuf sb; + int error; + +@@ -1098,36 +1121,44 @@ + if (uio->uio_resid > PFS_MAXBUFSIZ) + PFS_RETURN (EIO); + ++ td = curthread; ++ + /* + * This is necessary because either process' privileges may + * have changed since the open() call. + */ +- if (!pfs_visible(curthread, pn, pvd->pvd_pid, &proc)) ++ if (!pfs_visible(td, pn, pvd->pvd_pid, &proc)) + PFS_RETURN (EIO); + if (proc != NULL) { + _PHOLD(proc); ++ execve_block_wait(td, proc); ++ if (!pfs_visible_proc(td, pn, proc)) { ++ PROC_UNLOCK(proc); ++ error = EIO; ++ goto out; ++ } + PROC_UNLOCK(proc); + } + + if (pn->pn_flags & PFS_RAWWR) { + error = pn_fill(curthread, proc, pn, NULL, uio); +- if (proc != NULL) +- PRELE(proc); +- PFS_RETURN (error); ++ goto out; + } + + sbuf_uionew(&sb, uio, &error); +- if (error) { +- if (proc != NULL) +- PRELE(proc); +- PFS_RETURN (error); +- } ++ if (error != 0) ++ goto out; + + error = pn_fill(curthread, proc, pn, &sb, uio); + + sbuf_delete(&sb); +- if (proc != NULL) +- PRELE(proc); ++out: ++ if (proc != NULL) { ++ PROC_LOCK(proc); ++ execve_unblock(td, proc); ++ _PRELE(proc); ++ PROC_UNLOCK(proc); ++ } + PFS_RETURN (error); + } + +--- sys/kern/kern_event.c.orig ++++ sys/kern/kern_event.c +@@ -49,6 +49,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -3381,10 +3382,6 @@ + if ((u_int)arg2 > 2 || (u_int)arg2 == 0) + return (EINVAL); + +- error = pget((pid_t)name[0], PGET_HOLD | PGET_CANDEBUG, &p); +- if (error != 0) +- return (error); +- + td = curthread; + #ifdef COMPAT_FREEBSD32 + compat32 = SV_CURPROC_FLAG(SV_ILP32); +@@ -3392,6 +3389,17 @@ + compat32 = false; + #endif + ++ error = pget((pid_t)name[0], PGET_NOTWEXIT, &p); ++ if (error != 0) ++ return (error); ++ ++ _PHOLD(p); ++ execve_block_wait(td, p); ++ error = p_candebug(td, p); ++ if (error != 0) ++ goto out1; ++ PROC_UNLOCK(p); ++ + s = sbuf_new_for_sysctl(&sm, NULL, 0, req); + if (s == NULL) { + error = ENOMEM; +@@ -3412,7 +3420,11 @@ + sbuf_delete(s); + + out: +- PRELE(p); ++ PROC_LOCK(p); ++out1: ++ execve_unblock(td, p); ++ _PRELE(p); ++ PROC_UNLOCK(p); + return (error); + } + +--- sys/kern/kern_exec.c.orig ++++ sys/kern/kern_exec.c +@@ -26,7 +26,6 @@ + * SUCH DAMAGE. + */ + +-#include + #include "opt_capsicum.h" + #include "opt_hwpmc_hooks.h" + #include "opt_hwt_hooks.h" +@@ -46,6 +45,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -385,6 +385,77 @@ + } + } + ++/* ++ * Returns true if the execblock was obtained, in this case the ++ * process lock is kept. Returns false if the execblock was not ++ * obtained, but the function slept and the lock was dropped. ++ */ ++bool ++execve_block(struct thread *td, struct proc *p) ++{ ++ PROC_LOCK_ASSERT(p, MA_OWNED); ++ MPASS(td == curthread); ++ MPASS(p != td->td_proc || (p->p_flag & P_INEXEC) == 0); ++ ++ if (p != td->td_proc && (p->p_flag & P_INEXEC) != 0) { ++ p->p_flag |= P_INEXEC_WAIT; ++ msleep(&p->p_execblock, &p->p_mtx, PDROP, "inexec", 0); ++ return (false); ++ } ++ MPASS(p->p_execblock < UINT_MAX); ++ p->p_execblock++; ++ return (true); ++} ++ ++/* ++ * Might drop the process lock internally, callers must re-check the ++ * invariants afterward. ++ */ ++void ++execve_block_wait(struct thread *td, struct proc *p) ++{ ++ bool first; ++ ++ PROC_ASSERT_HELD(p); ++ PROC_LOCK_ASSERT(p, MA_OWNED); ++ ++ for (first = true;; first = false) { ++ if (!first) ++ PROC_LOCK(p); ++ if (execve_block(td, p)) ++ return; ++ } ++} ++ ++void ++execve_unblock(struct thread *td, struct proc *p) ++{ ++ PROC_LOCK_ASSERT(p, MA_OWNED); ++ MPASS(td == curthread); ++ ++ MPASS(p->p_execblock > 0); ++ p->p_execblock--; ++ if (p->p_execblock == 0 && (p->p_flag & P_INEXEC_WAIT) != 0) { ++ p->p_flag &= ~P_INEXEC_WAIT; ++ wakeup(&p->p_execblock); ++ } ++} ++ ++void ++execve_block_pass(struct thread *td) ++{ ++ struct proc *p; ++ ++ MPASS(td == curthread); ++ p = td->td_proc; ++ PROC_LOCK_ASSERT(p, MA_OWNED); ++ ++ while (p->p_execblock != 0) { ++ p->p_flag |= P_INEXEC_WAIT; ++ msleep(&p->p_execblock, &p->p_mtx, 0, "exeblk", 0); ++ } ++} ++ + /* + * In-kernel implementation of execve(). All arguments are assumed to be + * userspace pointers from the passed thread. +@@ -440,6 +511,7 @@ + PROC_LOCK(p); + KASSERT((p->p_flag & P_INEXEC) == 0, + ("%s(): process already has P_INEXEC flag", __func__)); ++ execve_block_pass(td); + p->p_flag |= P_INEXEC; + PROC_UNLOCK(p); + +@@ -909,7 +981,10 @@ + * as we're now a bona fide freshly-execed process. + */ + KNOTE_LOCKED(p->p_klist, NOTE_EXEC); +- p->p_flag &= ~P_INEXEC; ++ MPASS(p->p_execblock == 0); ++ if ((p->p_flag & P_INEXEC_WAIT) != 0) ++ wakeup(&p->p_execblock); ++ p->p_flag &= ~(P_INEXEC | P_INEXEC_WAIT); + + /* clear "fork but no exec" flag, as we _are_ execing */ + p->p_acflag &= ~AFORK; +@@ -1005,7 +1080,9 @@ + exec_fail: + /* we're done here, clear P_INEXEC */ + PROC_LOCK(p); +- p->p_flag &= ~P_INEXEC; ++ if ((p->p_flag & P_INEXEC_WAIT) != 0) ++ wakeup(&p->p_execblock); ++ p->p_flag &= ~(P_INEXEC | P_INEXEC_WAIT); + PROC_UNLOCK(p); + + SDT_PROBE1(proc, , , exec__failure, error); +--- sys/kern/kern_exit.c.orig ++++ sys/kern/kern_exit.c +@@ -323,6 +323,7 @@ + while (p->p_lock > 0) + msleep(&p->p_lock, &p->p_mtx, PWAIT, "exithold", 0); + ++ MPASS(p->p_execblock == 0); + PROC_UNLOCK(p); + /* Drain the limit callout while we don't have the proc locked */ + callout_drain(&p->p_limco); +--- sys/kern/kern_fork.c.orig ++++ sys/kern/kern_fork.c +@@ -430,6 +430,7 @@ + + bzero(&p2->p_startzero, + __rangeof(struct proc, p_startzero, p_endzero)); ++ p2->p_execblock = 0; + + /* Tell the prison that we exist. */ + prison_proc_hold(p2->p_ucred->cr_prison); +--- sys/kern/kern_proc.c.orig ++++ sys/kern/kern_proc.c +@@ -43,6 +43,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -1838,8 +1839,8 @@ + } + + static int +-proc_read_string(struct thread *td, struct proc *p, const char *sptr, char *buf, +- size_t len) ++proc_read_string(struct thread *td, struct vmspace *vm, const char *sptr, ++ char *buf, size_t len) + { + ssize_t n; + +@@ -1848,7 +1849,7 @@ + * and is aligned at the end of the page, and the following page is not + * mapped. + */ +- n = proc_readmem(td, p, (vm_offset_t)sptr, buf, len); ++ n = vmspace_iop(td, vm, (vm_offset_t)sptr, buf, len, UIO_READ); + if (n <= 0) + return (ENOMEM); + return (0); +@@ -1864,8 +1865,8 @@ + + #ifdef COMPAT_FREEBSD32 + static int +-get_proc_vector32(struct thread *td, struct proc *p, char ***proc_vectorp, +- size_t *vsizep, enum proc_vector_type type) ++get_proc_vector32(struct thread *td, struct proc *p, struct vmspace *vm, ++ char ***proc_vectorp, size_t *vsizep, enum proc_vector_type type) + { + struct freebsd32_ps_strings pss; + Elf32_Auxinfo aux; +@@ -1876,8 +1877,8 @@ + int i, error; + + error = 0; +- if (proc_readmem(td, p, PROC_PS_STRINGS(p), &pss, sizeof(pss)) != +- sizeof(pss)) ++ if (vmspace_iop(td, vm, PROC_PS_STRINGS(p), &pss, sizeof(pss), ++ UIO_READ) != sizeof(pss)) + return (ENOMEM); + switch (type) { + case PROC_ARG: +@@ -1900,8 +1901,8 @@ + if (vptr % 4 != 0) + return (ENOEXEC); + for (ptr = vptr, i = 0; i < PROC_AUXV_MAX; i++) { +- if (proc_readmem(td, p, ptr, &aux, sizeof(aux)) != +- sizeof(aux)) ++ if (vmspace_iop(td, vm, ptr, &aux, sizeof(aux), ++ UIO_READ) != sizeof(aux)) + return (ENOMEM); + if (aux.a_type == AT_NULL) + break; +@@ -1917,7 +1918,7 @@ + return (EINVAL); + } + proc_vector32 = malloc(size, M_TEMP, M_WAITOK); +- if (proc_readmem(td, p, vptr, proc_vector32, size) != size) { ++ if (vmspace_iop(td, vm, vptr, proc_vector32, size, UIO_READ) != size) { + error = ENOMEM; + goto done; + } +@@ -1938,8 +1939,8 @@ + #endif + + static int +-get_proc_vector(struct thread *td, struct proc *p, char ***proc_vectorp, +- size_t *vsizep, enum proc_vector_type type) ++get_proc_vector(struct thread *td, struct proc *p, struct vmspace *vm, ++ char ***proc_vectorp, size_t *vsizep, enum proc_vector_type type) + { + struct ps_strings pss; + Elf_Auxinfo aux; +@@ -1949,11 +1950,13 @@ + int i; + + #ifdef COMPAT_FREEBSD32 +- if (SV_PROC_FLAG(p, SV_ILP32) != 0) +- return (get_proc_vector32(td, p, proc_vectorp, vsizep, type)); ++ if (SV_PROC_FLAG(p, SV_ILP32) != 0) { ++ return (get_proc_vector32(td, p, vm, proc_vectorp, ++ vsizep, type)); ++ } + #endif +- if (proc_readmem(td, p, PROC_PS_STRINGS(p), &pss, sizeof(pss)) != +- sizeof(pss)) ++ if (vmspace_iop(td, vm, PROC_PS_STRINGS(p), &pss, sizeof(pss), ++ UIO_READ) != sizeof(pss)) + return (ENOMEM); + switch (type) { + case PROC_ARG: +@@ -1991,8 +1994,8 @@ + * to the allocated proc_vector. + */ + for (ptr = vptr, i = 0; i < PROC_AUXV_MAX; i++) { +- if (proc_readmem(td, p, ptr, &aux, sizeof(aux)) != +- sizeof(aux)) ++ if (vmspace_iop(td, vm, ptr, &aux, sizeof(aux), ++ UIO_READ) != sizeof(aux)) + return (ENOMEM); + if (aux.a_type == AT_NULL) + break; +@@ -2014,7 +2017,7 @@ + return (EINVAL); /* In case we are built without INVARIANTS. */ + } + proc_vector = malloc(size, M_TEMP, M_WAITOK); +- if (proc_readmem(td, p, vptr, proc_vector, size) != size) { ++ if (vmspace_iop(td, vm, vptr, proc_vector, size, UIO_READ) != size) { + free(proc_vector, M_TEMP); + return (ENOMEM); + } +@@ -2030,6 +2033,7 @@ + get_ps_strings(struct thread *td, struct proc *p, struct sbuf *sb, + enum proc_vector_type type) + { ++ struct vmspace *vm; + size_t done, len, nchr, vsize; + int error, i; + char **proc_vector, *sptr; +@@ -2042,9 +2046,14 @@ + */ + nchr = 2 * (PATH_MAX + ARG_MAX); + +- error = get_proc_vector(td, p, &proc_vector, &vsize, type); ++ error = proc_vmspace_ref(td, p, PRVM_BLOCK_EXEC | ++ PRVM_CHECK_VISIBILITY, &vm); + if (error != 0) + return (error); ++ ++ error = get_proc_vector(td, p, vm, &proc_vector, &vsize, type); ++ if (error != 0) ++ goto out; + for (done = 0, i = 0; i < (int)vsize && done < nchr; i++) { + /* + * The program may have scribbled into its argv array, e.g. to +@@ -2054,7 +2063,7 @@ + if (proc_vector[i] == NULL) + break; + for (sptr = proc_vector[i]; ; sptr += GET_PS_STRINGS_CHUNK_SZ) { +- error = proc_read_string(td, p, sptr, pss_string, ++ error = proc_read_string(td, vm, sptr, pss_string, + sizeof(pss_string)); + if (error != 0) + goto done; +@@ -2071,6 +2080,8 @@ + } + done: + free(proc_vector, M_TEMP); ++out: ++ proc_vmspace_unref(td, p, PRVM_BLOCK_EXEC | PRVM_CHECK_VISIBILITY, vm); + return (error); + } + +@@ -2091,11 +2102,17 @@ + int + proc_getauxv(struct thread *td, struct proc *p, struct sbuf *sb) + { ++ struct vmspace *vm; + size_t vsize, size; + char **auxv; + int error; + +- error = get_proc_vector(td, p, &auxv, &vsize, PROC_AUX); ++ error = proc_vmspace_ref(td, p, PRVM_BLOCK_EXEC | PRVM_CHECK_DEBUG, ++ &vm); ++ if (error != 0) ++ return (error); ++ error = get_proc_vector(td, p, vm, &auxv, &vsize, PROC_AUX); ++ proc_vmspace_unref(td, p, PRVM_BLOCK_EXEC | PRVM_CHECK_DEBUG, vm); + if (error == 0) { + #ifdef COMPAT_FREEBSD32 + if (SV_PROC_FLAG(p, SV_ILP32) != 0) +@@ -2408,6 +2425,7 @@ + int error, *name; + struct vnode *vp; + struct proc *p; ++ struct thread *td; + vm_map_t map; + struct vmspace *vm; + +@@ -2416,11 +2434,12 @@ + return (EINVAL); + + name = (int *)arg1; ++ td = curthread; + error = pget((pid_t)name[0], PGET_WANTREAD, &p); + if (error != 0) + return (error); +- vm = vmspace_acquire_ref(p); +- if (vm == NULL) { ++ error = proc_vmspace_ref(td, p, PRVM_CHECK_DEBUG, &vm); ++ if (error != 0) { + PRELE(p); + return (ESRCH); + } +@@ -2532,7 +2551,7 @@ + } + } + vm_map_unlock_read(map); +- vmspace_free(vm); ++ proc_vmspace_unref(td, p, PRVM_CHECK_DEBUG, vm); + PRELE(p); + free(kve, M_TEMP); + return (error); +@@ -2627,6 +2646,7 @@ + struct ucred *cred; + struct vnode *vp; + struct vmspace *vm; ++ struct thread *td; + vm_offset_t addr; + unsigned int last_timestamp; + int error; +@@ -2638,10 +2658,11 @@ + + _PHOLD(p); + PROC_UNLOCK(p); +- vm = vmspace_acquire_ref(p); +- if (vm == NULL) { ++ td = curthread; ++ error = proc_vmspace_ref(td, p, PRVM_CHECK_DEBUG, &vm); ++ if (error != 0) { + PRELE(p); +- return (ESRCH); ++ return (error); + } + kve = malloc(sizeof(*kve), M_TEMP, M_WAITOK | M_ZERO); + +@@ -2745,7 +2766,7 @@ + if (vp != NULL) { + vn_fullpath(vp, &fullpath, &freepath); + kve->kve_vn_type = vntype_to_kinfo(vp->v_type); +- cred = curthread->td_ucred; ++ cred = td->td_ucred; + vn_lock(vp, LK_SHARED | LK_RETRY); + if (VOP_GETATTR(vp, &va, cred) == 0) { + kve->kve_vn_fileid = va.va_fileid; +@@ -2801,7 +2822,7 @@ + } + } + vm_map_unlock_read(map); +- vmspace_free(vm); ++ proc_vmspace_unref(td, p, PRVM_CHECK_DEBUG, vm); + PRELE(p); + free(kve, M_TEMP); + return (error); +@@ -2840,7 +2861,7 @@ + struct kinfo_kstack *kkstp; + int error, i, *name, numthreads; + lwpid_t *lwpidarray; +- struct thread *td; ++ struct thread *td, *ctd; + struct stack *st; + struct sbuf sb; + struct proc *p; +@@ -2851,7 +2872,8 @@ + return (EINVAL); + + name = (int *)arg1; +- error = pget((pid_t)name[0], PGET_NOTINEXEC | PGET_WANTREAD, &p); ++ ctd = curthread; ++ error = pget((pid_t)name[0], PGET_WANTREAD, &p); + if (error != 0) + return (error); + +@@ -2860,6 +2882,14 @@ + + lwpidarray = NULL; + PROC_LOCK(p); ++ execve_block_wait(ctd, p); ++ error = p_candebug(ctd, p); ++ if (error != 0) { ++ execve_unblock(ctd, p); ++ _PRELE(p); ++ PROC_UNLOCK(p); ++ return (error); ++ } + do { + if (lwpidarray != NULL) { + free(lwpidarray, M_TEMP); +@@ -2872,15 +2902,6 @@ + PROC_LOCK(p); + } while (numthreads < p->p_numthreads); + +- /* +- * XXXRW: During the below loop, execve(2) and countless other sorts +- * of changes could have taken place. Should we check to see if the +- * vmspace has been replaced, or the like, in order to prevent +- * giving a snapshot that spans, say, execve(2), with some threads +- * before and some after? Among other things, the credentials could +- * have changed, in which case the right to extract debug info might +- * no longer be assured. +- */ + i = 0; + FOREACH_THREAD_IN_PROC(p, td) { + KASSERT(i < numthreads, +@@ -2913,7 +2934,10 @@ + if (error) + break; + } +- PRELE(p); ++ PROC_LOCK(p); ++ execve_unblock(ctd, p); ++ _PRELE(p); ++ PROC_UNLOCK(p); + if (lwpidarray != NULL) + free(lwpidarray, M_TEMP); + stack_destroy(st); +@@ -2969,8 +2993,9 @@ + u_int namelen = arg2; + struct rlimit rlim; + struct proc *p; ++ struct thread *td; + u_int which; +- int flags, error; ++ int error; + + if (namelen != 2) + return (EINVAL); +@@ -2982,23 +3007,24 @@ + if (req->newptr != NULL && req->newlen != sizeof(rlim)) + return (EINVAL); + +- flags = PGET_HOLD | PGET_NOTWEXIT; +- if (req->newptr != NULL) +- flags |= PGET_CANDEBUG; +- else +- flags |= PGET_CANSEE; +- error = pget((pid_t)name[0], flags, &p); ++ td = curthread; ++ error = pget((pid_t)name[0], PGET_NOTWEXIT, &p); + if (error != 0) + return (error); ++ _PHOLD(p); ++ execve_block_wait(td, p); ++ error = req->newptr != NULL ? p_candebug(td, p) : p_cansee(td, p); ++ if (error != 0) ++ goto errout1; + + /* + * Retrieve limit. + */ + if (req->oldptr != NULL) { +- PROC_LOCK(p); + lim_rlimit_proc(p, which, &rlim); +- PROC_UNLOCK(p); + } ++ PROC_UNLOCK(p); ++ + error = SYSCTL_OUT(req, &rlim, sizeof(rlim)); + if (error != 0) + goto errout; +@@ -3013,7 +3039,11 @@ + } + + errout: +- PRELE(p); ++ PROC_LOCK(p); ++errout1: ++ _PRELE(p); ++ execve_unblock(td, p); ++ PROC_UNLOCK(p); + return (error); + } + +@@ -3102,39 +3132,38 @@ + int *name = (int *)arg1; + u_int namelen = arg2; + struct proc *p; +- int flags, error, osrel; ++ int flags, error, old_osrel, osrel; + + if (namelen != 1) + return (EINVAL); + +- if (req->newptr != NULL && req->newlen != sizeof(osrel)) +- return (EINVAL); +- +- flags = PGET_HOLD | PGET_NOTWEXIT; +- if (req->newptr != NULL) ++ flags = PGET_NOTWEXIT; ++ if (req->newptr != NULL) { ++ if (req->newlen != sizeof(osrel)) ++ return (EINVAL); ++ error = SYSCTL_IN(req, &osrel, sizeof(osrel)); ++ if (error != 0) ++ return (error); ++ if (osrel < 0) ++ return (EINVAL); + flags |= PGET_CANDEBUG; +- else ++ } else { + flags |= PGET_CANSEE; ++ } + error = pget((pid_t)name[0], flags, &p); + if (error != 0) + return (error); +- +- error = SYSCTL_OUT(req, &p->p_osrel, sizeof(p->p_osrel)); +- if (error != 0) +- goto errout; +- +- if (req->newptr != NULL) { +- error = SYSCTL_IN(req, &osrel, sizeof(osrel)); +- if (error != 0) +- goto errout; +- if (osrel < 0) { +- error = EINVAL; +- goto errout; +- } +- p->p_osrel = osrel; ++ if ((p->p_flag & P_INEXEC) != 0) { ++ error = EBUSY; ++ } else { ++ old_osrel = p->p_osrel; ++ if (req->newptr != NULL) ++ p->p_osrel = osrel; + } +-errout: +- PRELE(p); ++ PROC_UNLOCK(p); ++ ++ if (error == 0) ++ error = SYSCTL_OUT(req, &old_osrel, sizeof(old_osrel)); + return (error); + } + +@@ -3271,6 +3300,7 @@ + { + struct kinfo_vm_layout kvm; + struct proc *p; ++ struct thread *td; + struct vmspace *vmspace; + int error, *name; + +@@ -3278,6 +3308,7 @@ + if ((u_int)arg2 != 1) + return (EINVAL); + ++ td = curthread; + error = pget((pid_t)name[0], PGET_CANDEBUG, &p); + if (error != 0) + return (error); +@@ -3289,8 +3320,13 @@ + } + } + #endif +- vmspace = vmspace_acquire_ref(p); ++ _PHOLD(p); + PROC_UNLOCK(p); ++ error = proc_vmspace_ref(td, p, PRVM_CHECK_DEBUG, &vmspace); ++ if (error != 0) { ++ PRELE(p); ++ return (error); ++ } + + memset(&kvm, 0, sizeof(kvm)); + kvm.kvm_min_user_addr = vm_map_min(&vmspace->vm_map); +@@ -3342,7 +3378,8 @@ + #ifdef COMPAT_FREEBSD32 + out: + #endif +- vmspace_free(vmspace); ++ proc_vmspace_unref(td, p, PRVM_CHECK_DEBUG, vmspace); ++ PRELE(p); + return (error); + } + +--- sys/kern/kern_procctl.c.orig ++++ sys/kern/kern_procctl.c +@@ -40,6 +40,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -841,25 +842,30 @@ + { + struct vmspace *vm; + vm_map_t map; +- int state; ++ int error, state; + + PROC_LOCK_ASSERT(p, MA_OWNED); + if ((p->p_flag & P_WEXIT) != 0) + return (ESRCH); + state = *(int *)data; ++ error = 0; + + switch (state) { + case PROC_WX_MAPPINGS_PERMIT: +- p->p_flag2 |= P2_WXORX_DISABLE; + _PHOLD(p); + PROC_UNLOCK(p); +- vm = vmspace_acquire_ref(p); +- if (vm != NULL) { ++ error = proc_vmspace_ref(td, p, PRVM_BLOCK_EXEC | ++ PRVM_CHECK_DEBUG, &vm); ++ if (error == 0) { + map = &vm->vm_map; + vm_map_lock(map); + map->flags &= ~MAP_WXORX; + vm_map_unlock(map); +- vmspace_free(vm); ++ PROC_LOCK(p); ++ p->p_flag2 |= P2_WXORX_DISABLE; ++ PROC_UNLOCK(p); ++ proc_vmspace_unref(td, p, PRVM_BLOCK_EXEC | ++ PRVM_CHECK_DEBUG, vm); + } + PROC_LOCK(p); + _PRELE(p); +@@ -868,10 +874,11 @@ + p->p_flag2 |= P2_WXORX_ENABLE_EXEC; + break; + default: +- return (EINVAL); ++ error = EINVAL; ++ break; + } + +- return (0); ++ return (error); + } + + static int +--- sys/kern/kern_prot.c.orig ++++ sys/kern/kern_prot.c +@@ -49,6 +49,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -1016,6 +1017,8 @@ + newcred = crget(); + euip = uifind(euid); + PROC_LOCK(p); ++ execve_block_pass(td); ++ + /* + * Copy credentials so other references do not see our changes. + */ +@@ -1070,6 +1073,7 @@ + AUDIT_ARG_GID(gid); + newcred = crget(); + PROC_LOCK(p); ++ execve_block_pass(td); + oldcred = crcopysafe(p, newcred); + + #ifdef MAC +@@ -1168,6 +1172,7 @@ + AUDIT_ARG_EGID(egid); + newcred = crget(); + PROC_LOCK(p); ++ execve_block_pass(td); + oldcred = crcopysafe(p, newcred); + + #ifdef MAC +@@ -1299,6 +1304,7 @@ + newcred = crget(); + crextend(newcred, ngrp); + PROC_LOCK(p); ++ execve_block_pass(td); + oldcred = crcopysafe(p, newcred); + + #ifdef MAC +@@ -1355,6 +1361,7 @@ + euip = uifind(euid); + ruip = uifind(ruid); + PROC_LOCK(p); ++ execve_block_pass(td); + oldcred = crcopysafe(p, newcred); + + #ifdef MAC +@@ -1434,6 +1441,7 @@ + AUDIT_ARG_RGID(rgid); + newcred = crget(); + PROC_LOCK(p); ++ execve_block_pass(td); + oldcred = crcopysafe(p, newcred); + + #ifdef MAC +@@ -1504,6 +1512,7 @@ + euip = uifind(euid); + ruip = uifind(ruid); + PROC_LOCK(p); ++ execve_block_pass(td); + oldcred = crcopysafe(p, newcred); + + #ifdef MAC +@@ -1595,6 +1604,7 @@ + AUDIT_ARG_SGID(sgid); + newcred = crget(); + PROC_LOCK(p); ++ execve_block_pass(td); + oldcred = crcopysafe(p, newcred); + + #ifdef MAC +@@ -2355,11 +2365,11 @@ + } + + /* +- * Can't trace a process that's currently exec'ing. +- * +- * XXX: Note, this is not a security policy decision, it's a +- * basic correctness/functionality decision. Therefore, this check +- * should be moved to the caller's of p_candebug(). ++ * Can't trace a process that's currently exec'ing. Otherwise ++ * the process vmspace might change, and the target might be ++ * loading a setugid image. The execve_block(9) and ++ * proc_vmspace_ref(9) allow to get the stable credentials and ++ * vmspace reference. + */ + if ((p->p_flag & P_INEXEC) != 0) + return (EBUSY); +--- sys/kern/kern_resource.c.orig ++++ sys/kern/kern_resource.c +@@ -45,6 +45,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -807,11 +808,11 @@ + } + + static int +-getrlimitusage_one(struct proc *p, u_int which, int flags, rlim_t *res) ++getrlimitusage_one(struct proc *p, struct vmspace *vm, u_int which, int flags, ++ rlim_t *res) + { + struct thread *td; + struct uidinfo *ui; +- struct vmspace *vm; + uid_t uid; + int error; + +@@ -822,7 +823,6 @@ + PROC_UNLOCK(p); + + ui = uifind(uid); +- vm = vmspace_acquire_ref(p); + + switch (which) { + case RLIMIT_CPU: +@@ -900,7 +900,6 @@ + break; + } + +- vmspace_free(vm); + uifree(ui); + return (error); + } +@@ -908,12 +907,15 @@ + int + sys_getrlimitusage(struct thread *td, struct getrlimitusage_args *uap) + { ++ struct proc *p; + rlim_t res; + int error; + + if ((uap->flags & ~(GETRLIMITUSAGE_EUID)) != 0) + return (EINVAL); +- error = getrlimitusage_one(curproc, uap->which, uap->flags, &res); ++ p = curproc; ++ error = getrlimitusage_one(p, p->p_vmspace, uap->which, uap->flags, ++ &res); + if (error == 0) + error = copyout(&res, uap->res, sizeof(res)); + return (error); +@@ -1768,6 +1770,8 @@ + { + rlim_t resval[RLIM_NLIMITS]; + struct proc *p; ++ struct thread *td; ++ struct vmspace *vm; + size_t len; + int error, *name, i; + +@@ -1777,15 +1781,20 @@ + if (req->newptr != NULL) + return (EINVAL); + +- error = pget((pid_t)name[0], PGET_WANTREAD, &p); ++ td = curthread; ++ error = pget((pid_t)name[0], PGET_HOLD | PGET_NOTWEXIT, &p); + if (error != 0) + return (error); ++ error = proc_vmspace_ref(td, p, PRVM_BLOCK_EXEC | ++ PRVM_CHECK_VISIBILITY, &vm); ++ if (error != 0) ++ goto out; + + if ((u_int)arg2 == 1) { + len = sizeof(resval); + memset(resval, 0, sizeof(resval)); + for (i = 0; i < RLIM_NLIMITS; i++) { +- error = getrlimitusage_one(p, (unsigned)i, 0, ++ error = getrlimitusage_one(p, vm, (unsigned)i, 0, + &resval[i]); + if (error == ENXIO) { + resval[i] = -1; +@@ -1796,7 +1805,7 @@ + } + } else { + len = sizeof(resval[0]); +- error = getrlimitusage_one(p, (unsigned)name[1], 0, ++ error = getrlimitusage_one(p, vm, (unsigned)name[1], 0, + &resval[0]); + if (error == ENXIO) { + resval[0] = -1; +@@ -1805,6 +1814,8 @@ + } + if (error == 0) + error = SYSCTL_OUT(req, resval, len); ++ proc_vmspace_unref(td, p, PRVM_BLOCK_EXEC | PRVM_CHECK_VISIBILITY, vm); ++out: + PRELE(p); + return (error); + } +--- sys/kern/sys_process.c.orig ++++ sys/kern/sys_process.c +@@ -33,6 +33,7 @@ + + #include + #include ++#include + #include + #include + #include +@@ -333,25 +334,93 @@ + return (ptrace_single_step(td)); + } + ++static int ++proc_vmspace_check_access(struct thread *td, struct proc *p, int flags) ++{ ++ PROC_ASSERT_HELD(p); ++ if ((flags & PRVM_CHECK_DEBUG) != 0) ++ return (p_candebug(td, p)); ++ if ((flags & PRVM_CHECK_VISIBILITY) != 0) ++ return (p_cansee(td, p)); ++ return (0); ++} ++ + int +-proc_rwmem(struct proc *p, struct uio *uio) ++proc_vmspace_ref(struct thread *td, struct proc *p, int flags, ++ struct vmspace **vmp) ++{ ++ struct vmspace *vm; ++ int error; ++ ++ MPASS((flags & ~(PRVM_BLOCK_EXEC | PRVM_CHECK_VISIBILITY | ++ PRVM_CHECK_DEBUG)) == 0); ++ MPASS((flags & (PRVM_CHECK_VISIBILITY | PRVM_CHECK_DEBUG)) != ++ (PRVM_CHECK_VISIBILITY | PRVM_CHECK_DEBUG)); ++ ++ PROC_LOCK(p); ++ if (p != td->td_proc) { ++ PROC_ASSERT_HELD(p); ++ ++ /* ++ * Make sure that the vmspace doesn't switch out from ++ * under us. ++ */ ++ if ((flags & PRVM_BLOCK_EXEC) != 0) { ++ for (;;) { ++ if (!execve_block(td, p)) { ++ PROC_LOCK(p); ++ continue; ++ } ++ error = proc_vmspace_check_access(td, p, flags); ++ if (error != 0) { ++ execve_unblock(td, p); ++ PROC_UNLOCK(p); ++ return (error); ++ } ++ break; ++ } ++ } else { ++ error = proc_vmspace_check_access(td, p, flags); ++ if (error != 0) { ++ PROC_UNLOCK(p); ++ return (error); ++ } ++ } ++ } ++ vm = vmspace_acquire_ref(p); ++ if (vm == NULL) { ++ if (p != td->td_proc && (flags & PRVM_BLOCK_EXEC) != 0) ++ execve_unblock(td, p); ++ PROC_UNLOCK(p); ++ return (ESRCH); ++ } ++ PROC_UNLOCK(p); ++ *vmp = vm; ++ return (0); ++} ++ ++void ++proc_vmspace_unref(struct thread *td, struct proc *p, int flags, ++ struct vmspace *vm) ++{ ++ vmspace_free(vm); ++ if (p != td->td_proc && (flags & PRVM_BLOCK_EXEC) != 0) { ++ PROC_LOCK(p); ++ PROC_ASSERT_HELD(p); ++ execve_unblock(td, p); ++ PROC_UNLOCK(p); ++ } ++} ++ ++static int ++vmspace_rwmem(struct vmspace *vm, struct uio *uio) + { + vm_map_t map; + vm_offset_t pageno; /* page number */ + vm_prot_t reqprot; + int error, fault_flags, page_offset, writing; + +- /* +- * Make sure that the process' vmspace remains live. +- */ +- if (p != curproc) +- PROC_ASSERT_HELD(p); +- PROC_LOCK_ASSERT(p, MA_NOTOWNED); +- +- /* +- * The map we want... +- */ +- map = &p->p_vmspace->vm_map; ++ map = &vm->vm_map; + + /* + * If we are writing, then we request vm_fault() to create a private +@@ -363,9 +432,9 @@ + fault_flags = writing ? VM_FAULT_DIRTY : VM_FAULT_NORMAL; + + if (writing) { +- error = priv_check_cred(p->p_ucred, PRIV_PROC_MEM_WRITE); +- if (error) +- return (error); ++ error = priv_check(curthread, PRIV_PROC_MEM_WRITE); ++ if (error != 0) ++ goto out; + } + + /* +@@ -423,16 +492,34 @@ + + } while (error == 0 && uio->uio_resid > 0); + ++out: + return (error); + } + +-static ssize_t +-proc_iop(struct thread *td, struct proc *p, vm_offset_t va, void *buf, ++int ++proc_rwmem(struct proc *p, struct uio *uio, int flags) ++{ ++ struct vmspace *vm; ++ struct thread *td; ++ int error; ++ ++ td = curthread; ++ error = proc_vmspace_ref(td, p, flags, &vm); ++ if (error != 0) ++ return (error); ++ error = vmspace_rwmem(vm, uio); ++ proc_vmspace_unref(td, p, flags, vm); ++ return (error); ++} ++ ++ssize_t ++vmspace_iop(struct thread *td, struct vmspace *vm, vm_offset_t va, void *buf, + size_t len, enum uio_rw rw) + { + struct iovec iov; + struct uio uio; + ssize_t slen; ++ int error; + + MPASS(len < SSIZE_MAX); + slen = (ssize_t)len; +@@ -446,8 +533,8 @@ + uio.uio_segflg = UIO_SYSSPACE; + uio.uio_rw = rw; + uio.uio_td = td; +- proc_rwmem(p, &uio); +- if (uio.uio_resid == slen) ++ error = vmspace_rwmem(vm, &uio); ++ if (error != 0 || uio.uio_resid == slen) + return (-1); + return (slen - uio.uio_resid); + } +@@ -457,7 +544,7 @@ + size_t len) + { + +- return (proc_iop(td, p, va, buf, len, UIO_READ)); ++ return (vmspace_iop(td, p->p_vmspace, va, buf, len, UIO_READ)); + } + + ssize_t +@@ -465,7 +552,7 @@ + size_t len) + { + +- return (proc_iop(td, p, va, buf, len, UIO_WRITE)); ++ return (vmspace_iop(td, p->p_vmspace, va, buf, len, UIO_WRITE)); + } + + static int +@@ -1458,7 +1545,7 @@ + goto out; + } + PROC_UNLOCK(p); +- error = proc_rwmem(p, &uio); ++ error = proc_rwmem(p, &uio, 0); + piod->piod_len -= uio.uio_resid; + PROC_LOCK(p); + break; +--- sys/sys/imgact.h.orig ++++ sys/sys/imgact.h +@@ -122,6 +122,10 @@ + int exec_copyin_args(struct image_args *, const char *, char **, char **); + int pre_execve(struct thread *td, struct vmspace **oldvmspace); + void post_execve(struct thread *td, int error, struct vmspace *oldvmspace); ++bool execve_block(struct thread *td, struct proc *p); ++void execve_block_wait(struct thread *td, struct proc *p); ++void execve_unblock(struct thread *td, struct proc *p); ++void execve_block_pass(struct thread *td); + #endif + + #endif /* !_SYS_IMGACT_H_ */ +--- sys/sys/proc.h.orig ++++ sys/sys/proc.h +@@ -777,6 +777,7 @@ + + TAILQ_HEAD(, kq_timer_cb_data) p_kqtim_stop; /* (c) */ + LIST_ENTRY(proc) p_jaillist; /* (d) Jail process linkage. */ ++ u_int p_execblock; /* (c) Blockers for execve. */ + }; + + #define p_session p_pgrp->pg_session +@@ -843,7 +844,7 @@ + #define P_STATCHILD 0x08000000 /* Child process stopped or exited. */ + #define P_INMEM 0x10000000 /* Loaded into memory, always set. */ + #define P_UNUSED1 0x20000000 /* --available-- */ +-#define P_UNUSED2 0x40000000 /* --available-- */ ++#define P_INEXEC_WAIT 0x40000000 /* Waiters for P_INEXEC/p_execblock */ + #define P_PPTRACE 0x80000000 /* PT_TRACEME by vforked child. */ + + #define P_STOPPED (P_STOPPED_SIG|P_STOPPED_SINGLE|P_STOPPED_TRACE) +--- sys/sys/ptrace.h.orig ++++ sys/sys/ptrace.h +@@ -247,7 +247,20 @@ + int proc_read_dbregs(struct thread *_td, struct dbreg *_dbreg); + int proc_write_dbregs(struct thread *_td, struct dbreg *_dbreg); + int proc_sstep(struct thread *_td); +-int proc_rwmem(struct proc *_p, struct uio *_uio); ++ ++#define PRVM_BLOCK_EXEC 0x00000001 ++#define PRVM_CHECK_VISIBILITY 0x00000002 ++#define PRVM_CHECK_DEBUG 0x00000004 ++ ++#include ++struct vmspace; ++int proc_vmspace_ref(struct thread *_td, struct proc *_p, int _flags, ++ struct vmspace **_vmp); ++void proc_vmspace_unref(struct thread *_td, struct proc *_p, int _flags, ++ struct vmspace *_vm); ++ssize_t vmspace_iop(struct thread *td, struct vmspace *vm, vm_offset_t va, ++ void *buf, size_t len, enum uio_rw rw); ++int proc_rwmem(struct proc *_p, struct uio *_uio, int _flags); + ssize_t proc_readmem(struct thread *_td, struct proc *_p, vm_offset_t _va, + void *_buf, size_t _len); + ssize_t proc_writemem(struct thread *_td, struct proc *_p, vm_offset_t _va, diff --git a/website/static/security/patches/SA-26:39/execve-15.patch.asc b/website/static/security/patches/SA-26:39/execve-15.patch.asc new file mode 100644 index 0000000000..2e251a6ee1 --- /dev/null +++ b/website/static/security/patches/SA-26:39/execve-15.patch.asc @@ -0,0 +1,17 @@ +-----BEGIN PGP SIGNATURE----- + +iQJPBAABCgA5FiEEthUnfoEIffdcgYM7bljekB8AGu8FAmpEEjsbFIAAAAAABAAO +bWFudTIsMi41KzEuMTIsMCwzAAoJEG5Y3pAfABrvxYoQAMHtBsQcQhBlsMurZ0e3 +mc8NR/FklwPQ0VyN821caPpHV5HcwFvRdKmnv2z0wyuvDHN2SB9rvD1iixYfcAUI +05mSld/2BG0PLzkGhrNyswdb3e8xUm5RvKmQt4W8TjHB8QCNXtoWIFHSOU7LSZmW +FrLl1B4N8tYmXz28c9ySCvsMojTqhOKRuGV9CrpttpmQ9vuZ6oUZdkleUJKtfjro +/hh9LpIN6iJJJyFXodVxXF+WAd32fPK/BUzkeKf7/tf9H5VdoBm3Mmx8cGbwoLdA +lneDVwVYxVfupvSM7D19/ysU6ydZWBm6vZPmZ+FxkXbBQsVFMHK9iyhBnDYJjOET +LfULSCY2FQBIY0ovWsIyziWBy2YUtNJnk/I5eu8RYEk6d2G02LrOidxeshoTitQI +pbcB5+b7+l4Pu2uQ4qvUoMZzN2gZ5/AjE2YYm0U/AXgwB+ARlTeQrjV3uRf7pLrX +A7kD9b6pjX+RlhDM9VR4BBnHgDWQ7X9J84T72Fw385e1swjqHe5wfYV1KoK5wlMJ +Jh+huILxO8jx1XpbSOtB7PH8iKfUgxNrnel/wmZNdBwqeKpn4vp78DxH7YG7psjM +DG6yPdApJfKADx7nQWFHkk/BNU2yMcjGN4x4wPk4QIHNAnNxbTINOchjIR+dfscK +kQASf5PJ5kWwAU+ClUhSyum8 +=BsaU +-----END PGP SIGNATURE----- diff --git a/website/static/security/patches/SA-26:40/zfs-14.patch b/website/static/security/patches/SA-26:40/zfs-14.patch new file mode 100644 index 0000000000..3b25a4959a --- /dev/null +++ b/website/static/security/patches/SA-26:40/zfs-14.patch @@ -0,0 +1,598 @@ +--- sys/contrib/openzfs/module/nvpair/nvpair.c.orig ++++ sys/contrib/openzfs/module/nvpair/nvpair.c +@@ -134,7 +134,8 @@ + #define NVP_SIZE_CALC(name_len, data_len) \ + (NV_ALIGN((sizeof (nvpair_t)) + name_len) + NV_ALIGN(data_len)) + +-static int i_get_value_size(data_type_t type, const void *data, uint_t nelem); ++static int i_get_value_size(data_type_t type, const void *data, uint_t nelem, ++ size_t max_size); + static int nvlist_add_common(nvlist_t *nvl, const char *name, data_type_t type, + uint_t nelem, const void *data); + +@@ -809,8 +810,10 @@ + * verify nvp_type, nvp_value_elem, and also possibly + * verify string values and get the value size. + */ +- size2 = i_get_value_size(type, NVP_VALUE(nvp), NVP_NELEM(nvp)); + size1 = nvp->nvp_size - NVP_VALOFF(nvp); ++ size2 = i_get_value_size(type, NVP_VALUE(nvp), NVP_NELEM(nvp), ++ size1); ++ + if (size2 < 0 || size1 != NV_ALIGN(size2)) + return (EFAULT); + +@@ -1001,12 +1004,21 @@ + * DATA_TYPE_STRING and + * DATA_TYPE_STRING_ARRAY + * Is data == NULL then the size of the string(s) is excluded. ++ * ++ * If 'max_size' is non-zero, then don't look beyond 'max_size' number of ++ * bytes when calculating a value size. Note that 'max_size' should include ++ * the NULL terminator byte when calculating string size. If 'max_size' is 0, ++ * it is ignored. + */ + static int +-i_get_value_size(data_type_t type, const void *data, uint_t nelem) ++i_get_value_size(data_type_t type, const void *data, uint_t nelem, ++ size_t max_size) + { + uint64_t value_sz; + ++ if (max_size == 0) ++ max_size = INT32_MAX; ++ + if (i_validate_type_nelem(type, nelem) != 0) + return (-1); + +@@ -1051,10 +1063,15 @@ + break; + #endif + case DATA_TYPE_STRING: +- if (data == NULL) ++ if (data == NULL) { + value_sz = 0; +- else +- value_sz = strlen(data) + 1; ++ } else { ++ value_sz = strnlen(data, max_size); ++ if (value_sz >= max_size) { ++ return (-1); /* string not terminated */ ++ } ++ value_sz += 1; ++ } + break; + case DATA_TYPE_BOOLEAN_ARRAY: + value_sz = (uint64_t)nelem * sizeof (boolean_t); +@@ -1088,16 +1105,23 @@ + break; + case DATA_TYPE_STRING_ARRAY: + value_sz = (uint64_t)nelem * sizeof (uint64_t); +- + if (data != NULL) { + char *const *strs = data; + uint_t i; ++ size_t newsize; + + /* no alignment requirement for strings */ + for (i = 0; i < nelem; i++) { + if (strs[i] == NULL) + return (-1); +- value_sz += strlen(strs[i]) + 1; ++ ++ newsize = strnlen(strs[i], max_size); ++ ++ if (newsize == max_size) ++ return (-1); /* not terminated */ ++ ++ value_sz += newsize + 1; /* +1 for NULL */ ++ max_size -= newsize + 1; + } + } + break; +@@ -1162,7 +1186,7 @@ + * In case of data types DATA_TYPE_STRING and DATA_TYPE_STRING_ARRAY + * is the size of the string(s) included. + */ +- if ((value_sz = i_get_value_size(type, data, nelem)) < 0) ++ if ((value_sz = i_get_value_size(type, data, nelem, 0)) < 0) + return (EINVAL); + + if (i_validate_nvpair_value(type, nelem, data) != 0) +@@ -1587,7 +1611,7 @@ + #endif + if (data == NULL) + return (EINVAL); +- if ((value_sz = i_get_value_size(type, NULL, 1)) < 0) ++ if ((value_sz = i_get_value_size(type, NULL, 1, 0)) < 0) + return (EINVAL); + memcpy(data, NVP_VALUE(nvp), (size_t)value_sz); + if (nelem != NULL) +@@ -3017,7 +3041,8 @@ + * In case of data types DATA_TYPE_STRING and DATA_TYPE_STRING_ARRAY + * is the size of the string(s) excluded. + */ +- if ((value_sz = i_get_value_size(type, NULL, NVP_NELEM(nvp))) < 0) ++ if ((value_sz = i_get_value_size(type, NULL, NVP_NELEM(nvp), ++ NVP_SIZE(nvp))) < 0) + return (EFAULT); + + if (NVP_SIZE_CALC(nvp->nvp_name_sz, value_sz) > nvp->nvp_size) +@@ -3332,7 +3357,7 @@ + * In case of data types DATA_TYPE_STRING and DATA_TYPE_STRING_ARRAY + * is the size of the string(s) excluded. + */ +- if ((value_sz = i_get_value_size(type, NULL, nelem)) < 0) ++ if ((value_sz = i_get_value_size(type, NULL, nelem, NVP_SIZE(nvp)) < 0)) + return (EFAULT); + + /* if there is no data to extract then return */ +--- sys/contrib/openzfs/module/zfs/dmu_recv.c.orig ++++ sys/contrib/openzfs/module/zfs/dmu_recv.c +@@ -2834,16 +2834,20 @@ + { + struct drr_object *drro = + &drc->drc_rrd->header.drr_u.drr_object; +- uint32_t size = DRR_OBJECT_PAYLOAD_SIZE(drro); ++ uint32_t size; + void *buf = NULL; + dmu_object_info_t doi; + ++ size = DRR_OBJECT_PAYLOAD_SIZE(drro); ++ if (size > SPA_MAXBLOCKSIZE) ++ return (SET_ERROR(ERANGE)); ++ + if (size != 0) +- buf = kmem_zalloc(size, KM_SLEEP); ++ buf = vmem_zalloc(size, KM_SLEEP); + + err = receive_read_payload_and_next_header(drc, size, buf); + if (err != 0) { +- kmem_free(buf, size); ++ vmem_free(buf, size); + return (err); + } + err = dmu_object_info(drc->drc_os, drro->drr_object, &doi); +@@ -2867,7 +2871,11 @@ + case DRR_WRITE: + { + struct drr_write *drrw = &drc->drc_rrd->header.drr_u.drr_write; +- int size = DRR_WRITE_PAYLOAD_SIZE(drrw); ++ uint64_t size = DRR_WRITE_PAYLOAD_SIZE(drrw); ++ ++ if (size > SPA_MAXBLOCKSIZE) ++ return (SET_ERROR(ERANGE)); ++ + abd_t *abd = abd_alloc_linear(size, B_FALSE); + err = receive_read_payload_and_next_header(drc, size, + abd_to_buf(abd)); +@@ -2884,12 +2892,18 @@ + { + struct drr_write_embedded *drrwe = + &drc->drc_rrd->header.drr_u.drr_write_embedded; +- uint32_t size = P2ROUNDUP(drrwe->drr_psize, 8); +- void *buf = kmem_zalloc(size, KM_SLEEP); ++ uint32_t size; ++ void *buf; ++ ++ size = P2ROUNDUP(drrwe->drr_psize, 8); ++ if (size > SPA_MAXBLOCKSIZE) ++ return (SET_ERROR(ERANGE)); ++ ++ buf = vmem_zalloc(size, KM_SLEEP); + + err = receive_read_payload_and_next_header(drc, size, buf); + if (err != 0) { +- kmem_free(buf, size); ++ vmem_free(buf, size); + return (err); + } + +@@ -2918,7 +2932,11 @@ + case DRR_SPILL: + { + struct drr_spill *drrs = &drc->drc_rrd->header.drr_u.drr_spill; +- int size = DRR_SPILL_PAYLOAD_SIZE(drrs); ++ uint64_t size = DRR_SPILL_PAYLOAD_SIZE(drrs); ++ ++ if (size > SPA_MAXBLOCKSIZE) ++ return (SET_ERROR(ERANGE)); ++ + abd_t *abd = abd_alloc_linear(size, B_FALSE); + err = receive_read_payload_and_next_header(drc, size, + abd_to_buf(abd)); +@@ -3069,7 +3087,7 @@ + abd_free(rrd->abd); + rrd->abd = NULL; + } else if (rrd->payload != NULL) { +- kmem_free(rrd->payload, rrd->payload_size); ++ vmem_free(rrd->payload, rrd->payload_size); + rrd->payload = NULL; + } + return (0); +@@ -3083,7 +3101,7 @@ + rrd->abd = NULL; + rrd->payload = NULL; + } else if (rrd->payload != NULL) { +- kmem_free(rrd->payload, rrd->payload_size); ++ vmem_free(rrd->payload, rrd->payload_size); + rrd->payload = NULL; + } + +@@ -3096,7 +3114,7 @@ + { + struct drr_object *drro = &rrd->header.drr_u.drr_object; + err = receive_object(rwa, drro, rrd->payload); +- kmem_free(rrd->payload, rrd->payload_size); ++ vmem_free(rrd->payload, rrd->payload_size); + rrd->payload = NULL; + break; + } +@@ -3134,7 +3152,7 @@ + struct drr_write_embedded *drrwe = + &rrd->header.drr_u.drr_write_embedded; + err = receive_write_embedded(rwa, drrwe, rrd->payload); +- kmem_free(rrd->payload, rrd->payload_size); ++ vmem_free(rrd->payload, rrd->payload_size); + rrd->payload = NULL; + break; + } +@@ -3203,7 +3221,7 @@ + rrd->abd = NULL; + rrd->payload = NULL; + } else if (rrd->payload != NULL) { +- kmem_free(rrd->payload, rrd->payload_size); ++ vmem_free(rrd->payload, rrd->payload_size); + rrd->payload = NULL; + } + /* +--- sys/contrib/openzfs/module/zfs/vdev_label.c.orig ++++ sys/contrib/openzfs/module/zfs/vdev_label.c +@@ -1362,6 +1362,7 @@ + VB_NVLIST); + break; + } ++ vbe->vbe_bootenv[sizeof (vbe->vbe_bootenv) - 1] = '\0'; + fnvlist_add_string(bootenv, FREEBSD_BOOTONCE, buf); + } + +--- sys/contrib/openzfs/module/zfs/zfs_ioctl.c.orig ++++ sys/contrib/openzfs/module/zfs/zfs_ioctl.c +@@ -913,6 +913,23 @@ + ZFS_DELEG_PERM_CREATE, cr)); + } + ++/* ++ * Policy for dataset set property operations. Individual properties checked by ++ * zfs_check_settable(), additionally require zfs_secpolicy_recv() when setting ++ * properties as part of a receive. ++ */ ++static int ++zfs_secpolicy_setprops(zfs_cmd_t *zc, nvlist_t *innvl, cred_t *cr) ++{ ++ boolean_t received = zc->zc_cookie; ++ int error; ++ ++ if (received && (error = zfs_secpolicy_recv(zc, innvl, cr))) ++ return (error); ++ ++ return (zfs_secpolicy_read(zc, innvl, cr)); ++} ++ + int + zfs_secpolicy_snapshot_perms(const char *name, cred_t *cr) + { +@@ -3642,7 +3659,6 @@ + zfs_ioc_log_history(const char *unused, nvlist_t *innvl, nvlist_t *outnvl) + { + (void) unused, (void) outnvl; +- const char *message; + char *poolname; + spa_t *spa; + int error; +@@ -3663,7 +3679,7 @@ + if (error != 0) + return (error); + +- message = fnvlist_lookup_string(innvl, "message"); ++ const char *message = fnvlist_lookup_string(innvl, "message"); + + if (spa_version(spa) < SPA_VERSION_ZPOOL_HISTORY) { + spa_close(spa, FTAG); +@@ -5994,21 +6010,27 @@ + * outputs: + * zc_nvlist_dst[_size] data buffer (array of zfs_useracct_t) + * zc_cookie zap cursor ++ * ++ * The zc_nvlist_dst output array is limited to 1000 entries. + */ + static int + zfs_ioc_userspace_many(zfs_cmd_t *zc) + { ++ const size_t batch_limit = 1000 * sizeof (zfs_useracct_t); ++ uint64_t bufsize = MIN(zc->zc_nvlist_dst_size, batch_limit); + zfsvfs_t *zfsvfs; +- int bufsize = zc->zc_nvlist_dst_size; + +- if (bufsize <= 0) ++ if (bufsize < sizeof (zfs_useracct_t)) { ++ zc->zc_nvlist_dst_size = sizeof (zfs_useracct_t); + return (SET_ERROR(ENOMEM)); ++ } + + int error = zfsvfs_hold(zc->zc_name, FTAG, &zfsvfs, B_FALSE); + if (error != 0) + return (error); + + void *buf = vmem_alloc(bufsize, KM_SLEEP); ++ zc->zc_nvlist_dst_size = bufsize; + + error = zfs_userspace_many(zfsvfs, zc->zc_objset_type, &zc->zc_cookie, + buf, &zc->zc_nvlist_dst_size); +@@ -6499,7 +6521,7 @@ + dsl_pool_t *dp; + dsl_dataset_t *new, *old; + const char *firstsnap; +- uint64_t used, comp, uncomp; ++ uint64_t used = 0, comp = 0, uncomp = 0; + + firstsnap = fnvlist_lookup_string(innvl, "firstsnap"); + +@@ -7374,7 +7396,7 @@ + zfs_ioc_send, zfs_secpolicy_send); + + zfs_ioctl_register_dataset_modify(ZFS_IOC_SET_PROP, zfs_ioc_set_prop, +- zfs_secpolicy_none); ++ zfs_secpolicy_setprops); + zfs_ioctl_register_dataset_modify(ZFS_IOC_DESTROY, zfs_ioc_destroy, + zfs_secpolicy_destroy); + zfs_ioctl_register_dataset_modify(ZFS_IOC_RENAME, zfs_ioc_rename, +--- sys/contrib/openzfs/module/zfs/zfs_quota.c.orig ++++ sys/contrib/openzfs/module/zfs/zfs_quota.c +@@ -85,10 +85,14 @@ + sa.sa_layout_info = BSWAP_16(sa.sa_layout_info); + swap = B_TRUE; + } +- VERIFY3U(sa.sa_magic, ==, SA_MAGIC); ++ ++ if (unlikely(sa.sa_magic != SA_MAGIC)) ++ return (SET_ERROR(EINVAL)); + + int hdrsize = sa_hdrsize(&sa); +- VERIFY3U(hdrsize, >=, sizeof (sa_hdr_phys_t)); ++ ++ if (unlikely(hdrsize < sizeof (sa_hdr_phys_t))) ++ return (SET_ERROR(EINVAL)); + + uintptr_t data_after_hdr = (uintptr_t)data + hdrsize; + zoi->zfi_user = *((uint64_t *)(data_after_hdr + SA_UID_OFFSET)); +--- sys/contrib/openzfs/tests/zfs-tests/cmd/libzfs_input_check.c.orig ++++ sys/contrib/openzfs/tests/zfs-tests/cmd/libzfs_input_check.c +@@ -84,7 +84,6 @@ + ZFS_IOC_DSOBJ_TO_DSNAME, + ZFS_IOC_OBJ_TO_PATH, + ZFS_IOC_POOL_SET_PROPS, +- ZFS_IOC_POOL_GET_PROPS, + ZFS_IOC_SET_FSACL, + ZFS_IOC_GET_FSACL, + ZFS_IOC_SHARE, +@@ -124,11 +123,136 @@ + lzc_ioctl_test(ioc, name, req, opt, err, wild); \ + } while (0) + ++#define IOC_INPUT_TEST_INJECT(ioc, name, innvl) \ ++ do { \ ++ active_test = __func__ + 5; \ ++ lzc_ioctl_run_impl(ioc, name, innvl, 0, B_TRUE); \ ++ } while (0) ++ ++/* ++ * Given a zfs_cmd_t containing an already packed nvlist in zc->zc_nvlist_src, ++ * and its original innvl, look in innvl for the last string nvpair, or last ++ * string array nvpair, and remove the string terminator. The idea is to ++ * corrupt the nvlist string value so that anyone doing a strlen() on it will ++ * read past the end of the packed nvlist buffer and trigger a crash. ++ */ ++static void ++do_bad_string(zfs_cmd_t *zc, nvlist_t *innvl) ++{ ++ nvpair_t *elem = NULL; ++ nvpair_t *lastseen = NULL; ++ const char *str = NULL; ++ const char **arr; ++ uint_t n; ++ char *off; ++ char *packed; ++ uint64_t size, off_size; ++ ++ while ((elem = nvlist_next_nvpair(innvl, elem)) != NULL) { ++ if ((nvpair_type(elem) == DATA_TYPE_STRING) || ++ (nvpair_type(elem) == DATA_TYPE_STRING_ARRAY)) ++ lastseen = elem; ++ } ++ ++ if (lastseen == NULL) ++ return; /* No strings */ ++ ++ /* ++ * Lookup either the last string, or the last string in the last ++ * string array in the nvlist. We will use this to corrupt from the ++ * string to the end of the nvlist buffer. Any attempts to strlen this ++ * string should run pass the end of the packed buffer. ++ */ ++ if (nvpair_value_string(lastseen, &str) != 0) { ++ if (nvpair_value_string_array(lastseen, &arr, &n) == 0) ++ str = arr[n-1]; ++ } ++ ++ /* ++ * We now have the last string. Corrupt everything from the NULL ++ * terminator byte for the last string to the end of the packed nvlist ++ * buffer. ++ */ ++ packed = (char *)zc->zc_nvlist_src; ++ size = zc->zc_nvlist_src_size; ++ ++ off = memmem(packed, size, str, strlen(str)); ++ off_size = strlen(str); ++ ++ memset(&off[off_size - 1], '!', (packed + size) - ++ (&off[off_size - 1])); ++ ++} ++ ++/* ++ * For each byte in the packed nvlist list in zc, corrupt a single byte, then ++ * try doing the ioctl. This tests how well the kernel handles fuzzed nvlists. ++ * ++ * NOTE - make sure you are doing this with a "safe" ioctl! You don't want to ++ * run this on an ioctl that can potentially corrupt data (like a zpool create). ++ */ ++static void ++do_fuzz(int zfs_fd, zfs_ioc_t ioc, zfs_cmd_t *zc) ++{ ++ uint64_t size; ++ uint64_t i; ++ unsigned char old = 0; ++ unsigned char *pos; ++ zfs_cmd_t orig_zc = *zc; ++ ++ pos = (unsigned char *) zc->zc_nvlist_src; ++ size = zc->zc_nvlist_src_size; ++ ++ /* ++ * Fuzz each byte in the packed nvlist, one byte at a time, and do the ++ * ioctl. If the kernel doesn't crash, then the test passed. ++ */ ++ for (i = 0; i < size; i++) { ++ /* Restore the previously corrupted byte */ ++ if (i > 0) ++ pos[i-1] = old; ++ ++ old = pos[i]; ++ ++ /* Corrupt the new byte */ ++ pos[i]++; ++ ++ /* ++ * Do the ioctl and ignore the return code. We just want to ++ * see if the kernel panics. ++ */ ++ lzc_ioctl_fd(zfs_fd, ioc, zc); ++ ++ /* ++ * Restore 'zc' with original fields since the ioctl may ++ * have modified them. ++ */ ++ *zc = orig_zc; ++ } ++ /* Restore last byte */ ++ if (i > 0) ++ pos[i - 1] = old; ++ ++ /* ++ * Try fuzzing the packed nvlist size field. Test it with one byte ++ * bigger and one byte smaller than the current value. ++ */ ++ zc->zc_nvlist_src_size--; ++ lzc_ioctl_fd(zfs_fd, ioc, zc); ++ ++ zc->zc_nvlist_src_size += 2; ++ lzc_ioctl_fd(zfs_fd, ioc, zc); ++ ++ /* Restore to normal */ ++ zc->zc_nvlist_src_size -= 1; ++} ++ + /* + * run a zfs ioctl command, verify expected results and log failures + */ + static void +-lzc_ioctl_run(zfs_ioc_t ioc, const char *name, nvlist_t *innvl, int expected) ++lzc_ioctl_run_impl(zfs_ioc_t ioc, const char *name, nvlist_t *innvl, ++ int expected, boolean_t do_corrupt) + { + zfs_cmd_t zc = {"\0"}; + char *packed = NULL; +@@ -159,10 +283,30 @@ + zc.zc_nvlist_dst_size = MAX(size * 2, 128 * 1024); + zc.zc_nvlist_dst = (uint64_t)(uintptr_t)malloc(zc.zc_nvlist_dst_size); + ++ if (do_corrupt) { ++ /* ++ * Try changing bytes in the packed nvlist to see if it will ++ * panic the kernel when you do the ioctl. ++ */ ++ do_fuzz(zfs_fd, ioc, &zc); ++ ++ /* ++ * Corrupt the last string in the packed nvlist so it has no ++ * NULL terminator. ++ */ ++ do_bad_string(&zc, innvl); ++ ++ } ++ + if (lzc_ioctl_fd(zfs_fd, ioc, &zc) != 0) + error = errno; + +- if (error != expected) { ++ /* ++ * If we're corrupting the nvlist we don't care about the specific ++ * error code that gets returned, as it could be one of many. We only ++ * care if it panics the kernel. ++ */ ++ if (!do_corrupt && error != expected) { + unexpected_failures = B_TRUE; + (void) fprintf(stderr, "%s: Unexpected result with %s, " + "error %d (expecting %d)\n", +@@ -173,6 +317,12 @@ + free((void *)(uintptr_t)zc.zc_nvlist_dst); + } + ++static void ++lzc_ioctl_run(zfs_ioc_t ioc, const char *name, nvlist_t *innvl, int expected) ++{ ++ return (lzc_ioctl_run_impl(ioc, name, innvl, expected, B_FALSE)); ++} ++ + /* + * Test each ioc for the following ioctl input errors: + * ZFS_ERR_IOC_ARG_UNAVAIL an input argument is not supported by kernel +@@ -309,6 +459,7 @@ + fnvlist_add_string(required, "message", "input check"); + + IOC_INPUT_TEST(ZFS_IOC_LOG_HISTORY, pool, required, NULL, 0); ++ IOC_INPUT_TEST_INJECT(ZFS_IOC_LOG_HISTORY, pool, required); + + nvlist_free(required); + } +@@ -790,6 +941,20 @@ + nvlist_free(required); + } + ++static void ++test_zpool_get(const char *pool) ++{ ++ const char *strs[] = {ZPOOL_DEDUPCACHED_PROP_NAME}; ++ nvlist_t *optional = fnvlist_alloc(); ++ ++ fnvlist_add_string_array(optional, ZPOOL_GET_PROPS_NAMES, strs, 1); ++ ++ IOC_INPUT_TEST(ZFS_IOC_POOL_GET_PROPS, pool, NULL, optional, 0); ++ IOC_INPUT_TEST_INJECT(ZFS_IOC_POOL_GET_PROPS, pool, optional); ++ ++ nvlist_free(optional); ++} ++ + static void + zfs_ioc_input_tests(const char *pool) + { +@@ -884,6 +1049,7 @@ + + test_scrub(pool); + ++ test_zpool_get(pool); + /* + * cleanup + */ diff --git a/website/static/security/patches/SA-26:40/zfs-14.patch.asc b/website/static/security/patches/SA-26:40/zfs-14.patch.asc new file mode 100644 index 0000000000..d0ed095e14 --- /dev/null +++ b/website/static/security/patches/SA-26:40/zfs-14.patch.asc @@ -0,0 +1,17 @@ +-----BEGIN PGP SIGNATURE----- + +iQJPBAABCgA5FiEEthUnfoEIffdcgYM7bljekB8AGu8FAmpEEj0bFIAAAAAABAAO +bWFudTIsMi41KzEuMTIsMCwzAAoJEG5Y3pAfABrvcSkQANk5rPZMRfuXMMGy7P/I +4xjRvkW3waHSc6ECqVzWkV7Z5u9atiF6ByEvNndLwtTSI/VoCyTNYP9OLCUBxJ1q +wCj89p6Azx9IsYcDsE8L9OhdwOvcUCZRGw5Qiz3n+SAgn2CWri995I2NP3Wprpto +x4rAjgNdx9QzJp/1ulYBB70i9F5X4aQv7pLLCvIzca4QgEu4iIHnU6GPb1NFYlL5 +FgtsWyQGq7whDR1hpBrqy5Z4EJbMw7O9MZMHYDpWaD74NXHpjD+hdIzWnFryHGPP +vKW6NH6XCWfJ415ZQI1tp5CSUzsdqBxt6n2aRBxeEdXzrMDJ8UoUGCHzFnqL3vSc +pqL5VmyvJ0a3vRH7ySRXjLMo8aHMF5N7wFAsRxX2qsnjNE0lf2c7IWYbQfVTl+IZ +kHiSyh5upIpWPU+0s3dygPsVtVQfna8KHC1NDRBqLqhCr9z1SCAzjGOEcqoeHLaq +Vq5Xmzl+qJw1zwUgdaDpADDvTHK5VvoePf4J9QTz4tUq349eriLBCUEAE1S9LnS/ +nanqkz97qgDghplSa1vEEGEqqB3PaXm56PYGj4ZQM/6XIETp5Soe89BoEmHDyfH4 +JdRgKwqGrf9dR6qmuQi1H9Z0XZEDbw2mKC67BFn5VoJVLpuBXE84iFBdWOt+sePS +9ivU2kaBHDalIvlkVwNjlUyH +=j2f5 +-----END PGP SIGNATURE----- diff --git a/website/static/security/patches/SA-26:40/zfs-15.patch b/website/static/security/patches/SA-26:40/zfs-15.patch new file mode 100644 index 0000000000..84143bc036 --- /dev/null +++ b/website/static/security/patches/SA-26:40/zfs-15.patch @@ -0,0 +1,598 @@ +--- sys/contrib/openzfs/module/nvpair/nvpair.c.orig ++++ sys/contrib/openzfs/module/nvpair/nvpair.c +@@ -135,7 +135,8 @@ + #define NVP_SIZE_CALC(name_len, data_len) \ + (NV_ALIGN((sizeof (nvpair_t)) + name_len) + NV_ALIGN(data_len)) + +-static int i_get_value_size(data_type_t type, const void *data, uint_t nelem); ++static int i_get_value_size(data_type_t type, const void *data, uint_t nelem, ++ size_t max_size); + static int nvlist_add_common(nvlist_t *nvl, const char *name, data_type_t type, + uint_t nelem, const void *data); + +@@ -810,8 +811,10 @@ + * verify nvp_type, nvp_value_elem, and also possibly + * verify string values and get the value size. + */ +- size2 = i_get_value_size(type, NVP_VALUE(nvp), NVP_NELEM(nvp)); + size1 = nvp->nvp_size - NVP_VALOFF(nvp); ++ size2 = i_get_value_size(type, NVP_VALUE(nvp), NVP_NELEM(nvp), ++ size1); ++ + if (size2 < 0 || size1 != NV_ALIGN(size2)) + return (EFAULT); + +@@ -1002,12 +1005,21 @@ + * DATA_TYPE_STRING and + * DATA_TYPE_STRING_ARRAY + * Is data == NULL then the size of the string(s) is excluded. ++ * ++ * If 'max_size' is non-zero, then don't look beyond 'max_size' number of ++ * bytes when calculating a value size. Note that 'max_size' should include ++ * the NULL terminator byte when calculating string size. If 'max_size' is 0, ++ * it is ignored. + */ + static int +-i_get_value_size(data_type_t type, const void *data, uint_t nelem) ++i_get_value_size(data_type_t type, const void *data, uint_t nelem, ++ size_t max_size) + { + uint64_t value_sz; + ++ if (max_size == 0) ++ max_size = INT32_MAX; ++ + if (i_validate_type_nelem(type, nelem) != 0) + return (-1); + +@@ -1052,10 +1064,15 @@ + break; + #endif + case DATA_TYPE_STRING: +- if (data == NULL) ++ if (data == NULL) { + value_sz = 0; +- else +- value_sz = strlen(data) + 1; ++ } else { ++ value_sz = strnlen(data, max_size); ++ if (value_sz >= max_size) { ++ return (-1); /* string not terminated */ ++ } ++ value_sz += 1; ++ } + break; + case DATA_TYPE_BOOLEAN_ARRAY: + value_sz = (uint64_t)nelem * sizeof (boolean_t); +@@ -1089,16 +1106,23 @@ + break; + case DATA_TYPE_STRING_ARRAY: + value_sz = (uint64_t)nelem * sizeof (uint64_t); +- + if (data != NULL) { + char *const *strs = data; + uint_t i; ++ size_t newsize; + + /* no alignment requirement for strings */ + for (i = 0; i < nelem; i++) { + if (strs[i] == NULL) + return (-1); +- value_sz += strlen(strs[i]) + 1; ++ ++ newsize = strnlen(strs[i], max_size); ++ ++ if (newsize == max_size) ++ return (-1); /* not terminated */ ++ ++ value_sz += newsize + 1; /* +1 for NULL */ ++ max_size -= newsize + 1; + } + } + break; +@@ -1163,7 +1187,7 @@ + * In case of data types DATA_TYPE_STRING and DATA_TYPE_STRING_ARRAY + * is the size of the string(s) included. + */ +- if ((value_sz = i_get_value_size(type, data, nelem)) < 0) ++ if ((value_sz = i_get_value_size(type, data, nelem, 0)) < 0) + return (EINVAL); + + if (i_validate_nvpair_value(type, nelem, data) != 0) +@@ -1588,7 +1612,7 @@ + #endif + if (data == NULL) + return (EINVAL); +- if ((value_sz = i_get_value_size(type, NULL, 1)) < 0) ++ if ((value_sz = i_get_value_size(type, NULL, 1, 0)) < 0) + return (EINVAL); + memcpy(data, NVP_VALUE(nvp), (size_t)value_sz); + if (nelem != NULL) +@@ -3019,7 +3043,8 @@ + * In case of data types DATA_TYPE_STRING and DATA_TYPE_STRING_ARRAY + * is the size of the string(s) excluded. + */ +- if ((value_sz = i_get_value_size(type, NULL, NVP_NELEM(nvp))) < 0) ++ if ((value_sz = i_get_value_size(type, NULL, NVP_NELEM(nvp), ++ NVP_SIZE(nvp))) < 0) + return (EFAULT); + + if (NVP_SIZE_CALC(nvp->nvp_name_sz, value_sz) > nvp->nvp_size) +@@ -3333,7 +3358,7 @@ + * In case of data types DATA_TYPE_STRING and DATA_TYPE_STRING_ARRAY + * is the size of the string(s) excluded. + */ +- if ((value_sz = i_get_value_size(type, NULL, nelem)) < 0) ++ if ((value_sz = i_get_value_size(type, NULL, nelem, NVP_SIZE(nvp)) < 0)) + return (EFAULT); + + /* if there is no data to extract then return */ +--- sys/contrib/openzfs/module/zfs/dmu_recv.c.orig ++++ sys/contrib/openzfs/module/zfs/dmu_recv.c +@@ -2901,16 +2901,20 @@ + { + struct drr_object *drro = + &drc->drc_rrd->header.drr_u.drr_object; +- uint32_t size = DRR_OBJECT_PAYLOAD_SIZE(drro); ++ uint32_t size; + void *buf = NULL; + dmu_object_info_t doi; + ++ size = DRR_OBJECT_PAYLOAD_SIZE(drro); ++ if (size > SPA_MAXBLOCKSIZE) ++ return (SET_ERROR(ERANGE)); ++ + if (size != 0) +- buf = kmem_zalloc(size, KM_SLEEP); ++ buf = vmem_zalloc(size, KM_SLEEP); + + err = receive_read_payload_and_next_header(drc, size, buf); + if (err != 0) { +- kmem_free(buf, size); ++ vmem_free(buf, size); + return (err); + } + err = dmu_object_info(drc->drc_os, drro->drr_object, &doi); +@@ -2934,7 +2938,11 @@ + case DRR_WRITE: + { + struct drr_write *drrw = &drc->drc_rrd->header.drr_u.drr_write; +- int size = DRR_WRITE_PAYLOAD_SIZE(drrw); ++ uint64_t size = DRR_WRITE_PAYLOAD_SIZE(drrw); ++ ++ if (size > SPA_MAXBLOCKSIZE) ++ return (SET_ERROR(ERANGE)); ++ + abd_t *abd = abd_alloc_linear(size, B_FALSE); + err = receive_read_payload_and_next_header(drc, size, + abd_to_buf(abd)); +@@ -2951,12 +2959,18 @@ + { + struct drr_write_embedded *drrwe = + &drc->drc_rrd->header.drr_u.drr_write_embedded; +- uint32_t size = P2ROUNDUP(drrwe->drr_psize, 8); +- void *buf = kmem_zalloc(size, KM_SLEEP); ++ uint32_t size; ++ void *buf; ++ ++ size = P2ROUNDUP(drrwe->drr_psize, 8); ++ if (size > SPA_MAXBLOCKSIZE) ++ return (SET_ERROR(ERANGE)); ++ ++ buf = vmem_zalloc(size, KM_SLEEP); + + err = receive_read_payload_and_next_header(drc, size, buf); + if (err != 0) { +- kmem_free(buf, size); ++ vmem_free(buf, size); + return (err); + } + +@@ -2985,7 +2999,11 @@ + case DRR_SPILL: + { + struct drr_spill *drrs = &drc->drc_rrd->header.drr_u.drr_spill; +- int size = DRR_SPILL_PAYLOAD_SIZE(drrs); ++ uint64_t size = DRR_SPILL_PAYLOAD_SIZE(drrs); ++ ++ if (size > SPA_MAXBLOCKSIZE) ++ return (SET_ERROR(ERANGE)); ++ + abd_t *abd = abd_alloc_linear(size, B_FALSE); + err = receive_read_payload_and_next_header(drc, size, + abd_to_buf(abd)); +@@ -3136,7 +3154,7 @@ + abd_free(rrd->abd); + rrd->abd = NULL; + } else if (rrd->payload != NULL) { +- kmem_free(rrd->payload, rrd->payload_size); ++ vmem_free(rrd->payload, rrd->payload_size); + rrd->payload = NULL; + } + return (0); +@@ -3150,7 +3168,7 @@ + rrd->abd = NULL; + rrd->payload = NULL; + } else if (rrd->payload != NULL) { +- kmem_free(rrd->payload, rrd->payload_size); ++ vmem_free(rrd->payload, rrd->payload_size); + rrd->payload = NULL; + } + +@@ -3163,7 +3181,7 @@ + { + struct drr_object *drro = &rrd->header.drr_u.drr_object; + err = receive_object(rwa, drro, rrd->payload); +- kmem_free(rrd->payload, rrd->payload_size); ++ vmem_free(rrd->payload, rrd->payload_size); + rrd->payload = NULL; + break; + } +@@ -3201,7 +3219,7 @@ + struct drr_write_embedded *drrwe = + &rrd->header.drr_u.drr_write_embedded; + err = receive_write_embedded(rwa, drrwe, rrd->payload); +- kmem_free(rrd->payload, rrd->payload_size); ++ vmem_free(rrd->payload, rrd->payload_size); + rrd->payload = NULL; + break; + } +@@ -3270,7 +3288,7 @@ + rrd->abd = NULL; + rrd->payload = NULL; + } else if (rrd->payload != NULL) { +- kmem_free(rrd->payload, rrd->payload_size); ++ vmem_free(rrd->payload, rrd->payload_size); + rrd->payload = NULL; + } + /* +--- sys/contrib/openzfs/module/zfs/vdev_label.c.orig ++++ sys/contrib/openzfs/module/zfs/vdev_label.c +@@ -1371,6 +1371,7 @@ + VB_NVLIST); + break; + } ++ vbe->vbe_bootenv[sizeof (vbe->vbe_bootenv) - 1] = '\0'; + fnvlist_add_string(bootenv, FREEBSD_BOOTONCE, buf); + } + +--- sys/contrib/openzfs/module/zfs/zfs_ioctl.c.orig ++++ sys/contrib/openzfs/module/zfs/zfs_ioctl.c +@@ -937,6 +937,23 @@ + ZFS_DELEG_PERM_CREATE, cr)); + } + ++/* ++ * Policy for dataset set property operations. Individual properties checked by ++ * zfs_check_settable(), additionally require zfs_secpolicy_recv() when setting ++ * properties as part of a receive. ++ */ ++static int ++zfs_secpolicy_setprops(zfs_cmd_t *zc, nvlist_t *innvl, cred_t *cr) ++{ ++ boolean_t received = zc->zc_cookie; ++ int error; ++ ++ if (received && (error = zfs_secpolicy_recv(zc, innvl, cr))) ++ return (error); ++ ++ return (zfs_secpolicy_read(zc, innvl, cr)); ++} ++ + int + zfs_secpolicy_snapshot_perms(const char *name, cred_t *cr) + { +@@ -3884,7 +3901,6 @@ + zfs_ioc_log_history(const char *unused, nvlist_t *innvl, nvlist_t *outnvl) + { + (void) unused, (void) outnvl; +- const char *message; + char *poolname; + spa_t *spa; + int error; +@@ -3905,7 +3921,7 @@ + if (error != 0) + return (error); + +- message = fnvlist_lookup_string(innvl, "message"); ++ const char *message = fnvlist_lookup_string(innvl, "message"); + + if (spa_version(spa) < SPA_VERSION_ZPOOL_HISTORY) { + spa_close(spa, FTAG); +@@ -6365,21 +6381,27 @@ + * outputs: + * zc_nvlist_dst[_size] data buffer (array of zfs_useracct_t) + * zc_cookie zap cursor ++ * ++ * The zc_nvlist_dst output array is limited to 1000 entries. + */ + static int + zfs_ioc_userspace_many(zfs_cmd_t *zc) + { ++ const size_t batch_limit = 1000 * sizeof (zfs_useracct_t); ++ uint64_t bufsize = MIN(zc->zc_nvlist_dst_size, batch_limit); + zfsvfs_t *zfsvfs; +- int bufsize = zc->zc_nvlist_dst_size; + +- if (bufsize <= 0) ++ if (bufsize < sizeof (zfs_useracct_t)) { ++ zc->zc_nvlist_dst_size = sizeof (zfs_useracct_t); + return (SET_ERROR(ENOMEM)); ++ } + + int error = zfsvfs_hold(zc->zc_name, FTAG, &zfsvfs, B_FALSE); + if (error != 0) + return (error); + + void *buf = vmem_alloc(bufsize, KM_SLEEP); ++ zc->zc_nvlist_dst_size = bufsize; + + error = zfs_userspace_many(zfsvfs, zc->zc_objset_type, &zc->zc_cookie, + buf, &zc->zc_nvlist_dst_size, &zc->zc_guid); +@@ -6870,7 +6892,7 @@ + dsl_pool_t *dp; + dsl_dataset_t *new, *old; + const char *firstsnap; +- uint64_t used, comp, uncomp; ++ uint64_t used = 0, comp = 0, uncomp = 0; + + firstsnap = fnvlist_lookup_string(innvl, "firstsnap"); + +@@ -7757,7 +7779,7 @@ + zfs_ioc_send, zfs_secpolicy_send); + + zfs_ioctl_register_dataset_modify(ZFS_IOC_SET_PROP, zfs_ioc_set_prop, +- zfs_secpolicy_none); ++ zfs_secpolicy_setprops); + zfs_ioctl_register_dataset_modify(ZFS_IOC_DESTROY, zfs_ioc_destroy, + zfs_secpolicy_destroy); + zfs_ioctl_register_dataset_modify(ZFS_IOC_RENAME, zfs_ioc_rename, +--- sys/contrib/openzfs/module/zfs/zfs_quota.c.orig ++++ sys/contrib/openzfs/module/zfs/zfs_quota.c +@@ -86,10 +86,14 @@ + sa.sa_layout_info = BSWAP_16(sa.sa_layout_info); + swap = B_TRUE; + } +- VERIFY3U(sa.sa_magic, ==, SA_MAGIC); ++ ++ if (unlikely(sa.sa_magic != SA_MAGIC)) ++ return (SET_ERROR(EINVAL)); + + int hdrsize = sa_hdrsize(&sa); +- VERIFY3U(hdrsize, >=, sizeof (sa_hdr_phys_t)); ++ ++ if (unlikely(hdrsize < sizeof (sa_hdr_phys_t))) ++ return (SET_ERROR(EINVAL)); + + uintptr_t data_after_hdr = (uintptr_t)data + hdrsize; + zoi->zfi_user = *((uint64_t *)(data_after_hdr + SA_UID_OFFSET)); +--- sys/contrib/openzfs/tests/zfs-tests/cmd/libzfs_input_check.c.orig ++++ sys/contrib/openzfs/tests/zfs-tests/cmd/libzfs_input_check.c +@@ -85,7 +85,6 @@ + ZFS_IOC_DSOBJ_TO_DSNAME, + ZFS_IOC_OBJ_TO_PATH, + ZFS_IOC_POOL_SET_PROPS, +- ZFS_IOC_POOL_GET_PROPS, + ZFS_IOC_SET_FSACL, + ZFS_IOC_GET_FSACL, + ZFS_IOC_SHARE, +@@ -125,11 +124,136 @@ + lzc_ioctl_test(ioc, name, req, opt, err, wild); \ + } while (0) + ++#define IOC_INPUT_TEST_INJECT(ioc, name, innvl) \ ++ do { \ ++ active_test = __func__ + 5; \ ++ lzc_ioctl_run_impl(ioc, name, innvl, 0, B_TRUE); \ ++ } while (0) ++ ++/* ++ * Given a zfs_cmd_t containing an already packed nvlist in zc->zc_nvlist_src, ++ * and its original innvl, look in innvl for the last string nvpair, or last ++ * string array nvpair, and remove the string terminator. The idea is to ++ * corrupt the nvlist string value so that anyone doing a strlen() on it will ++ * read past the end of the packed nvlist buffer and trigger a crash. ++ */ ++static void ++do_bad_string(zfs_cmd_t *zc, nvlist_t *innvl) ++{ ++ nvpair_t *elem = NULL; ++ nvpair_t *lastseen = NULL; ++ const char *str = NULL; ++ const char **arr; ++ uint_t n; ++ char *off; ++ char *packed; ++ uint64_t size, off_size; ++ ++ while ((elem = nvlist_next_nvpair(innvl, elem)) != NULL) { ++ if ((nvpair_type(elem) == DATA_TYPE_STRING) || ++ (nvpair_type(elem) == DATA_TYPE_STRING_ARRAY)) ++ lastseen = elem; ++ } ++ ++ if (lastseen == NULL) ++ return; /* No strings */ ++ ++ /* ++ * Lookup either the last string, or the last string in the last ++ * string array in the nvlist. We will use this to corrupt from the ++ * string to the end of the nvlist buffer. Any attempts to strlen this ++ * string should run pass the end of the packed buffer. ++ */ ++ if (nvpair_value_string(lastseen, &str) != 0) { ++ if (nvpair_value_string_array(lastseen, &arr, &n) == 0) ++ str = arr[n-1]; ++ } ++ ++ /* ++ * We now have the last string. Corrupt everything from the NULL ++ * terminator byte for the last string to the end of the packed nvlist ++ * buffer. ++ */ ++ packed = (char *)zc->zc_nvlist_src; ++ size = zc->zc_nvlist_src_size; ++ ++ off = memmem(packed, size, str, strlen(str)); ++ off_size = strlen(str); ++ ++ memset(&off[off_size - 1], '!', (packed + size) - ++ (&off[off_size - 1])); ++ ++} ++ ++/* ++ * For each byte in the packed nvlist list in zc, corrupt a single byte, then ++ * try doing the ioctl. This tests how well the kernel handles fuzzed nvlists. ++ * ++ * NOTE - make sure you are doing this with a "safe" ioctl! You don't want to ++ * run this on an ioctl that can potentially corrupt data (like a zpool create). ++ */ ++static void ++do_fuzz(int zfs_fd, zfs_ioc_t ioc, zfs_cmd_t *zc) ++{ ++ uint64_t size; ++ uint64_t i; ++ unsigned char old = 0; ++ unsigned char *pos; ++ zfs_cmd_t orig_zc = *zc; ++ ++ pos = (unsigned char *) zc->zc_nvlist_src; ++ size = zc->zc_nvlist_src_size; ++ ++ /* ++ * Fuzz each byte in the packed nvlist, one byte at a time, and do the ++ * ioctl. If the kernel doesn't crash, then the test passed. ++ */ ++ for (i = 0; i < size; i++) { ++ /* Restore the previously corrupted byte */ ++ if (i > 0) ++ pos[i-1] = old; ++ ++ old = pos[i]; ++ ++ /* Corrupt the new byte */ ++ pos[i]++; ++ ++ /* ++ * Do the ioctl and ignore the return code. We just want to ++ * see if the kernel panics. ++ */ ++ lzc_ioctl_fd(zfs_fd, ioc, zc); ++ ++ /* ++ * Restore 'zc' with original fields since the ioctl may ++ * have modified them. ++ */ ++ *zc = orig_zc; ++ } ++ /* Restore last byte */ ++ if (i > 0) ++ pos[i - 1] = old; ++ ++ /* ++ * Try fuzzing the packed nvlist size field. Test it with one byte ++ * bigger and one byte smaller than the current value. ++ */ ++ zc->zc_nvlist_src_size--; ++ lzc_ioctl_fd(zfs_fd, ioc, zc); ++ ++ zc->zc_nvlist_src_size += 2; ++ lzc_ioctl_fd(zfs_fd, ioc, zc); ++ ++ /* Restore to normal */ ++ zc->zc_nvlist_src_size -= 1; ++} ++ + /* + * run a zfs ioctl command, verify expected results and log failures + */ + static void +-lzc_ioctl_run(zfs_ioc_t ioc, const char *name, nvlist_t *innvl, int expected) ++lzc_ioctl_run_impl(zfs_ioc_t ioc, const char *name, nvlist_t *innvl, ++ int expected, boolean_t do_corrupt) + { + zfs_cmd_t zc = {"\0"}; + char *packed = NULL; +@@ -160,10 +284,30 @@ + zc.zc_nvlist_dst_size = MAX(size * 2, 128 * 1024); + zc.zc_nvlist_dst = (uint64_t)(uintptr_t)malloc(zc.zc_nvlist_dst_size); + ++ if (do_corrupt) { ++ /* ++ * Try changing bytes in the packed nvlist to see if it will ++ * panic the kernel when you do the ioctl. ++ */ ++ do_fuzz(zfs_fd, ioc, &zc); ++ ++ /* ++ * Corrupt the last string in the packed nvlist so it has no ++ * NULL terminator. ++ */ ++ do_bad_string(&zc, innvl); ++ ++ } ++ + if (lzc_ioctl_fd(zfs_fd, ioc, &zc) != 0) + error = errno; + +- if (error != expected) { ++ /* ++ * If we're corrupting the nvlist we don't care about the specific ++ * error code that gets returned, as it could be one of many. We only ++ * care if it panics the kernel. ++ */ ++ if (!do_corrupt && error != expected) { + unexpected_failures = B_TRUE; + (void) fprintf(stderr, "%s: Unexpected result with %s, " + "error %d (expecting %d)\n", +@@ -174,6 +318,12 @@ + free((void *)(uintptr_t)zc.zc_nvlist_dst); + } + ++static void ++lzc_ioctl_run(zfs_ioc_t ioc, const char *name, nvlist_t *innvl, int expected) ++{ ++ return (lzc_ioctl_run_impl(ioc, name, innvl, expected, B_FALSE)); ++} ++ + /* + * Test each ioc for the following ioctl input errors: + * ZFS_ERR_IOC_ARG_UNAVAIL an input argument is not supported by kernel +@@ -310,6 +460,7 @@ + fnvlist_add_string(required, "message", "input check"); + + IOC_INPUT_TEST(ZFS_IOC_LOG_HISTORY, pool, required, NULL, 0); ++ IOC_INPUT_TEST_INJECT(ZFS_IOC_LOG_HISTORY, pool, required); + + nvlist_free(required); + } +@@ -791,6 +942,20 @@ + nvlist_free(required); + } + ++static void ++test_zpool_get(const char *pool) ++{ ++ const char *strs[] = {ZPOOL_DEDUPCACHED_PROP_NAME}; ++ nvlist_t *optional = fnvlist_alloc(); ++ ++ fnvlist_add_string_array(optional, ZPOOL_GET_PROPS_NAMES, strs, 1); ++ ++ IOC_INPUT_TEST(ZFS_IOC_POOL_GET_PROPS, pool, NULL, optional, 0); ++ IOC_INPUT_TEST_INJECT(ZFS_IOC_POOL_GET_PROPS, pool, optional); ++ ++ nvlist_free(optional); ++} ++ + static void + zfs_ioc_input_tests(const char *pool) + { +@@ -885,6 +1050,7 @@ + + test_scrub(pool); + ++ test_zpool_get(pool); + /* + * cleanup + */ diff --git a/website/static/security/patches/SA-26:40/zfs-15.patch.asc b/website/static/security/patches/SA-26:40/zfs-15.patch.asc new file mode 100644 index 0000000000..adde5ee97c --- /dev/null +++ b/website/static/security/patches/SA-26:40/zfs-15.patch.asc @@ -0,0 +1,17 @@ +-----BEGIN PGP SIGNATURE----- + +iQJPBAABCgA5FiEEthUnfoEIffdcgYM7bljekB8AGu8FAmpEEj4bFIAAAAAABAAO +bWFudTIsMi41KzEuMTIsMCwzAAoJEG5Y3pAfABrvcYgP/AxdKz23VY//zrhq9WM2 +6GsN+3ZYUQVxy9AZVVe6f7yi5fjFduqrmD5DpKAXuLk69wN5Ov7LwKI25LmrDOCJ +oqAI+5LpKYgXHYZ0RF9v9jW3yoZ61/ib3ETpNm6dhVl0l2QMahvz/FyXdOFVIq4O +BKP6rEFAvx52fZhLfi4VkXq3Zf5CRNzd4eizDptGH/T+ltG/vox1+5gRFwX7y1At +bE8wOjJw67+hTgkA6XWW3ejACEzZnEGmV1MnlVq/254jipCK+4trrHKrt8rIZsi9 +7U5d9JejU6oYVzol23My9d99kkx/J8eqQ6m3maH7CCZu58BILCdXMJ8qRGS9Z/Qf +RWptotH6+5FPIYQxiSgKBnswE0hY3Ox0fD031tRApKt8niDaOTp0ixQuMApCKn+n +aFDYNJ5SWJdsI971QJuEFR6jFyqkvnTPpx3ky2e18kx2DlAhkFlxdcH2iqdUfs4K +F034xM1XHqlSSNlXpJYnDEHZvZqn8b9T2k5njtmeeWWaZuhteCoXNqFwRN/ztWI5 +eaROVTfSvaagPEwFfjv6NcU16IzwusAUA9eQd8XRf6SL7q23vczht5u8LNlJTxqb +Wp2cLBb7YGC+gapur9P3tkDH8UrM7N4al+ksyipKAizd49Y0AdlvjSwMRESSuekd +bY7QzTp/HGg3My2VgHjXjqHM +=LKMH +-----END PGP SIGNATURE----- diff --git a/website/static/security/patches/SA-26:41/libalias-14.patch b/website/static/security/patches/SA-26:41/libalias-14.patch new file mode 100644 index 0000000000..43d8f3e74e --- /dev/null +++ b/website/static/security/patches/SA-26:41/libalias-14.patch @@ -0,0 +1,411 @@ +--- sys/netinet/libalias/alias_smedia.c.orig ++++ sys/netinet/libalias/alias_smedia.c +@@ -104,8 +104,9 @@ + #include + #include + #else +-#include + #include ++#include ++#include + #include + #include + #endif +@@ -128,9 +129,9 @@ + #define RTSP_CONTROL_PORT_NUMBER_2 7070 + #define TFTP_PORT_NUMBER 69 + +-static void +-AliasHandleRtspOut(struct libalias *, struct ip *, struct alias_link *, +- int maxpacketsize); ++static void AliasHandleRtspOut(struct libalias *, struct ip *, ++ struct alias_link *, size_t); ++ + static int + fingerprint(struct libalias *la, struct alias_data *ah) + { +@@ -154,7 +155,8 @@ + if (ntohs(*ah->dport) == TFTP_PORT_NUMBER) + FindRtspOut(la, pip->ip_src, pip->ip_dst, + *ah->sport, *ah->aport, IPPROTO_UDP); +- else AliasHandleRtspOut(la, pip, ah->lnk, ah->maxpktsize); ++ else ++ AliasHandleRtspOut(la, pip, ah->lnk, ah->maxpktsize); + return (0); + } + +@@ -208,13 +210,15 @@ + + #define ISDIGIT(a) (((a) >= '0') && ((a) <= '9')) + +-static int +-search_string(char *data, int dlen, const char *search_str) ++static ssize_t ++search_string(char *data, size_t dlen, const char *search_str) + { +- int i, j, k; +- int search_str_len; ++ size_t i, j, k; ++ size_t search_str_len; + + search_str_len = strlen(search_str); ++ if (search_str_len > dlen) ++ return (-1); + for (i = 0; i < dlen - search_str_len; i++) { + for (j = i, k = 0; j < dlen - search_str_len; j++, k++) { + if (data[j] != search_str[k] && +@@ -230,18 +234,21 @@ + static int + alias_rtsp_out(struct libalias *la, struct ip *pip, + struct alias_link *lnk, +- char *data, ++ char *data, size_t maxlen, + const char *port_str) + { +- int hlen, tlen, dlen; ++ size_t hlen, tlen, dlen; ++ size_t i, j; + struct tcphdr *tc; +- int i, j, pos, state, port_dlen, new_dlen, delta; ++ int delta, state; ++ ssize_t pos, slen; ++ size_t new_dlen, port_dlen, port_slen; + u_short p[2], new_len; + u_short sport, eport, base_port; + u_short salias = 0, ealias = 0, base_alias = 0; + const char *transport_str = "transport:"; +- char newdata[2048], *port_data, *port_newdata, stemp[80]; +- int links_created = 0, pkt_updated = 0; ++ char *newdata, *port_data; ++ bool links_created = false, pkt_updated = false; + struct alias_link *rtsp_lnk = NULL; + struct in_addr null_addr; + +@@ -250,6 +257,9 @@ + hlen = (pip->ip_hl + tc->th_off) << 2; + tlen = ntohs(pip->ip_len); + dlen = tlen - hlen; ++ if (hlen > tlen || tlen > maxlen) ++ return (-1); ++ port_slen = strlen(port_str); + + /* Find keyword, "Transport: " */ + pos = search_string(data, dlen, transport_str); +@@ -259,17 +269,21 @@ + port_data = data + pos; + port_dlen = dlen - pos; + ++ /* Allocate temporary buffer */ ++ maxlen -= hlen; ++ if ((newdata = malloc(maxlen)) == NULL) ++ return (-1); + memcpy(newdata, data, pos); +- port_newdata = newdata + pos; ++ new_dlen = pos; + +- while (port_dlen > (int)strlen(port_str)) { ++ while (port_dlen > port_slen) { + /* Find keyword, appropriate port string */ + pos = search_string(port_data, port_dlen, port_str); +- if (pos < 0) ++ if (pos < 0 || (size_t)pos + 1 > maxlen - new_dlen) + break; + +- memcpy(port_newdata, port_data, pos + 1); +- port_newdata += (pos + 1); ++ memcpy(newdata + new_dlen, port_data, pos + 1); ++ new_dlen += pos + 1; + + p[0] = p[1] = 0; + sport = eport = 0; +@@ -300,7 +314,7 @@ + eport = htons(p[1]); + + if (!links_created) { +- links_created = 1; ++ links_created = true; + /* + * Find an even numbered port + * number base that satisfies the +@@ -349,24 +363,30 @@ + ealias = htons(base_alias + (RTSP_PORT_GROUP - 1)); + } + if (salias && rtsp_lnk) { +- pkt_updated = 1; ++ pkt_updated = true; + + /* Copy into IP packet */ +- sprintf(stemp, "%d", ntohs(salias)); +- memcpy(port_newdata, stemp, strlen(stemp)); +- port_newdata += strlen(stemp); ++ slen = snprintf(newdata + new_dlen, ++ maxlen - new_dlen, "%d", ntohs(salias)); ++ if (slen < 0 || slen >= maxlen - new_dlen) ++ goto fail; ++ new_dlen += slen; + + if (eport != 0) { +- *port_newdata = '-'; +- port_newdata++; ++ if (new_dlen == maxlen) ++ goto fail; ++ newdata[new_dlen++] = '-'; + + /* Copy into IP packet */ +- sprintf(stemp, "%d", ntohs(ealias)); +- memcpy(port_newdata, stemp, strlen(stemp)); +- port_newdata += strlen(stemp); ++ slen = snprintf(newdata + new_dlen, ++ maxlen - new_dlen, "%d", ntohs(ealias)); ++ if (slen < 0 || slen >= maxlen - new_dlen) ++ goto fail; ++ new_dlen += slen; + } +- *port_newdata = ';'; +- port_newdata++; ++ if (new_dlen == maxlen) ++ goto fail; ++ newdata[new_dlen++] = ';'; + } + state++; + break; +@@ -380,20 +400,20 @@ + } + + if (!pkt_updated) +- return (-1); +- +- memcpy(port_newdata, port_data, port_dlen); +- port_newdata += port_dlen; +- *port_newdata = '\0'; ++ goto fail; + + /* Create new packet */ +- new_dlen = port_newdata - newdata; ++ if (new_dlen + port_dlen > maxlen) ++ goto fail; ++ memmove(data + new_dlen, port_data, port_dlen); + memcpy(data, newdata, new_dlen); ++ new_dlen += port_dlen; ++ free(newdata); + + SetAckModified(lnk); + tc = (struct tcphdr *)ip_next(pip); + delta = GetDeltaSeqOut(tc->th_seq, lnk); +- AddSeq(lnk, delta + new_dlen - dlen, pip->ip_hl, pip->ip_len, ++ AddSeq(lnk, delta + (int)(new_dlen - dlen), pip->ip_hl, pip->ip_len, + tc->th_seq, tc->th_off); + + new_len = htons(hlen + new_dlen); +@@ -407,6 +427,9 @@ + tc->th_sum = TcpChecksum(pip); + #endif + return (0); ++fail: ++ free(newdata); ++ return (-1); + } + + /* Support the protocol used by early versions of RealPlayer */ +@@ -415,13 +438,13 @@ + alias_pna_out(struct libalias *la, struct ip *pip, + struct alias_link *lnk, + char *data, +- int dlen) ++ size_t dlen) + { + struct alias_link *pna_links; +- u_short msg_id, msg_len; + char *work; +- u_short alias_port, port; + struct tcphdr *tc; ++ u_short msg_id, msg_len; ++ u_short alias_port, port; + + work = data; + work += 5; +@@ -433,7 +456,7 @@ + if (ntohs(msg_id) == 0) /* end of options */ + return (0); + +- if ((ntohs(msg_id) == 1) || (ntohs(msg_id) == 7)) { ++ if (ntohs(msg_id) == 1 || ntohs(msg_id) == 7) { + memcpy(&port, work, 2); + pna_links = FindUdpTcpOut(la, pip->ip_src, GetDestAddress(lnk), + port, 0, IPPROTO_UDP, 1); +@@ -462,22 +485,23 @@ + } + + static void +-AliasHandleRtspOut(struct libalias *la, struct ip *pip, struct alias_link *lnk, int maxpacketsize) ++AliasHandleRtspOut(struct libalias *la, struct ip *pip, struct alias_link *lnk, ++ size_t maxlen) + { +- int hlen, tlen, dlen; + struct tcphdr *tc; + char *data; + const char *setup = "SETUP", *pna = "PNA", *str200 = "200"; + const char *okstr = "OK", *client_port_str = "client_port"; + const char *server_port_str = "server_port"; +- int i, parseOk; +- +- (void)maxpacketsize; ++ size_t hlen, tlen, dlen; ++ size_t i; + + tc = (struct tcphdr *)ip_next(pip); + hlen = (pip->ip_hl + tc->th_off) << 2; + tlen = ntohs(pip->ip_len); + dlen = tlen - hlen; ++ if (hlen > tlen || tlen > maxlen) ++ return; + + data = (char *)pip; + data += hlen; +@@ -485,13 +509,14 @@ + /* When aliasing a client, check for the SETUP request */ + if ((ntohs(tc->th_dport) == RTSP_CONTROL_PORT_NUMBER_1) || + (ntohs(tc->th_dport) == RTSP_CONTROL_PORT_NUMBER_2)) { +- if (dlen >= (int)strlen(setup) && ++ if (dlen >= strlen(setup) && + memcmp(data, setup, strlen(setup)) == 0) { +- alias_rtsp_out(la, pip, lnk, data, client_port_str); ++ alias_rtsp_out(la, pip, lnk, data, maxlen, ++ client_port_str); + return; + } + +- if (dlen >= (int)strlen(pna) && ++ if (dlen >= strlen(pna) && + memcmp(data, pna, strlen(pna)) == 0) + alias_pna_out(la, pip, lnk, data, dlen); + } else { +@@ -499,24 +524,21 @@ + * When aliasing a server, check for the 200 reply + * Accommodate varying number of blanks between 200 & OK + */ +- +- if (dlen >= (int)strlen(str200)) { +- for (parseOk = 0, i = 0; +- i <= dlen - (int)strlen(str200); +- i++) +- if (memcmp(&data[i], str200, strlen(str200)) == 0) { +- parseOk = 1; +- break; +- } +- +- if (parseOk) { +- i += strlen(str200); /* skip string found */ +- while (data[i] == ' ') /* skip blank(s) */ ++ if (dlen < strlen(str200) + 1 + strlen(okstr)) ++ return; ++ for (i = 0; i <= dlen - strlen(str200) - 1; i++) { ++ if (memcmp(&data[i], str200, strlen(str200)) == 0 && ++ data[i + strlen(str200)] == ' ') { ++ i += strlen(str200); /* skip 200 */ ++ while (i < dlen && data[i] == ' ') /* skip blank(s) */ + i++; +- +- if ((dlen - i) >= (int)strlen(okstr)) +- if (memcmp(&data[i], okstr, strlen(okstr)) == 0) +- alias_rtsp_out(la, pip, lnk, data, server_port_str); ++ if (dlen - i >= strlen(okstr)) { ++ if (memcmp(&data[i], okstr, strlen(okstr)) == 0) { ++ alias_rtsp_out(la, pip, lnk, data, ++ maxlen, server_port_str); ++ break; ++ } ++ } + } + } + } +--- tests/sys/netinet/libalias/Makefile.orig ++++ tests/sys/netinet/libalias/Makefile +@@ -4,6 +4,10 @@ + TESTSDIR= ${TESTSBASE}/sys/netinet/libalias + BINDIR= ${TESTSDIR} + ++PLAIN_TESTS_C+= smedia ++ ++LIBADD.smedia+= sbuf ++ + ATF_TESTS_C+= 1_instance \ + 2_natout \ + 3_natin \ +--- /dev/null ++++ tests/sys/netinet/libalias/smedia.c +@@ -0,0 +1,74 @@ ++/* ++ * Copyright (c) 2026 The FreeBSD Foundation ++ * ++ * This software was developed by Mark Johnston under sponsorship from ++ * the FreeBSD Foundation. ++ * ++ * SPDX-License-Identifier: BSD-2-Clause ++ */ ++ ++/* ++ * A minimal regression test for a buffer overflow in alias_rtsp_out(). ++ */ ++ ++#include ++#include ++ ++#include ++#include ++#include ++#include ++ ++#include ++#include ++ ++#include ++ ++int ++main(void) ++{ ++ uint8_t *packet; ++ struct ip ip; ++ struct tcphdr tcp; ++ struct sbuf sb; ++ struct libalias *la; ++ ++ sbuf_new(&sb, NULL, 0, SBUF_AUTOEXTEND); ++ sbuf_printf(&sb, "SETUP rtsp://example.com/media.mp4 RTSP/1.0\r\n"); ++ sbuf_printf(&sb, "CSeq: 1\r\n"); ++ sbuf_printf(&sb, "Transport: RTP/AVP;unicast;"); ++ for (int i = 0; i < 200; i++) ++ sbuf_printf(&sb, "client_port=%d-%d;", 2 * i, 2 * i + 1); ++ sbuf_printf(&sb, "\r\n\r\n"); ++ sbuf_finish(&sb); ++ ++ memset(&tcp, 0, sizeof(tcp)); ++ tcp.th_sport = htons(1234); ++ tcp.th_dport = htons(554); ++ tcp.th_off = 5; ++ ++ memset(&ip, 0, sizeof(ip)); ++ ip.ip_v = IPVERSION; ++ ip.ip_hl = sizeof(ip) / 4; ++ ip.ip_len = htons(sizeof(ip) + sizeof(tcp) + sbuf_len(&sb)); ++ ip.ip_id = htons(1); ++ ip.ip_ttl = 64; ++ ip.ip_p = IPPROTO_TCP; ++ ip.ip_src.s_addr = inet_addr("127.0.0.1"); ++ ip.ip_dst.s_addr = inet_addr("127.0.0.2"); ++ ++ packet = malloc(sizeof(ip) + sizeof(tcp) + sbuf_len(&sb)); ++ memcpy(packet, &ip, sizeof(ip)); ++ memcpy(packet + sizeof(ip), &tcp, sizeof(tcp)); ++ memcpy(packet + sizeof(ip) + sizeof(tcp), sbuf_data(&sb), ++ sbuf_len(&sb)); ++ ++ la = LibAliasInit(NULL); ++ LibAliasSetAddress(la, ++ (struct in_addr){.s_addr = inet_addr("127.0.0.1")}); ++ if (LibAliasOut(la, packet, sizeof(ip) + sizeof(tcp) + sbuf_len(&sb)) != ++ PKT_ALIAS_OK) ++ return (1); ++ LibAliasUninit(la); ++ return (0); ++} diff --git a/website/static/security/patches/SA-26:41/libalias-14.patch.asc b/website/static/security/patches/SA-26:41/libalias-14.patch.asc new file mode 100644 index 0000000000..cc2176e181 --- /dev/null +++ b/website/static/security/patches/SA-26:41/libalias-14.patch.asc @@ -0,0 +1,17 @@ +-----BEGIN PGP SIGNATURE----- + +iQJPBAABCgA5FiEEthUnfoEIffdcgYM7bljekB8AGu8FAmpEEkEbFIAAAAAABAAO +bWFudTIsMi41KzEuMTIsMCwzAAoJEG5Y3pAfABrv5D8QAIzNGrG5pDIIHRA4vVvJ +I/wR2ufPBBeS2OXZw3cOdLwbskQycj7qDo3S0dK05fbVyORlrYhvKjTIukP0MudF +IzKyXskNSotomiFCNkajBex2OiZWNmMpaOmJLgxJQ+4MbEs0vE9Ln/6R+cOWwFBB +8wYfDyN55VCBB1QwawcaW+qPj/4D5zOA+ue+OpLxYhRk195hUbgLsHNrsbCNrDWV +rUVKRX+rmXHMfCxSS+igXX9g4BY1Bdq/9fjwLVOHtj/ySYQhHpw/rky6iMUc/AMu +tjaIGAVE4lSXM8KcY2n9S8ivdUK2czxFQjEba6TSxRqoD7CKgUG5yqBVogkO1ivj +Un5eI7sQy6IM2GhxGCDuhXguDMTVnE91tHV/DHYUjJSeORhPeiuSFptaAW6AGeut +Z9KcJYE8VbFcZzGE5Swgdt8lQlCCD3sT5ITNE12Miuj4W9jpbrxA/fed/IHgV7mE +3iRQ6w08NZynthf1JiC+qP5l6M5wGZoxQEla68uOaB42vmKz8tBF9XTwB/FOzik4 +2VRRdi4SEp0Fv/2QI0BHQ36Xo52nzwbum0A75tozMszEm+ymuyYknItD7ej+U3lb +gugcqy2jwnoS6FbZBB8ViM3g73C49/ZQNJ/t8GKRC3UVuE/QM6RP5oAmefDYT+NG +fvBu24sQkbVbOU+ktic8iqnL +=uAOH +-----END PGP SIGNATURE----- diff --git a/website/static/security/patches/SA-26:41/libalias-15.patch b/website/static/security/patches/SA-26:41/libalias-15.patch new file mode 100644 index 0000000000..5efae275fb --- /dev/null +++ b/website/static/security/patches/SA-26:41/libalias-15.patch @@ -0,0 +1,411 @@ +--- sys/netinet/libalias/alias_smedia.c.orig ++++ sys/netinet/libalias/alias_smedia.c +@@ -104,8 +104,9 @@ + #include + #include + #else +-#include + #include ++#include ++#include + #include + #include + #endif +@@ -128,9 +129,9 @@ + #define RTSP_CONTROL_PORT_NUMBER_2 7070 + #define TFTP_PORT_NUMBER 69 + +-static void +-AliasHandleRtspOut(struct libalias *, struct ip *, struct alias_link *, +- int maxpacketsize); ++static void AliasHandleRtspOut(struct libalias *, struct ip *, ++ struct alias_link *, size_t); ++ + static int + fingerprint(struct libalias *la, struct alias_data *ah) + { +@@ -154,7 +155,8 @@ + if (ntohs(*ah->dport) == TFTP_PORT_NUMBER) + FindRtspOut(la, pip->ip_src, pip->ip_dst, + *ah->sport, *ah->aport, IPPROTO_UDP); +- else AliasHandleRtspOut(la, pip, ah->lnk, ah->maxpktsize); ++ else ++ AliasHandleRtspOut(la, pip, ah->lnk, ah->maxpktsize); + return (0); + } + +@@ -208,13 +210,15 @@ + + #define ISDIGIT(a) (((a) >= '0') && ((a) <= '9')) + +-static int +-search_string(char *data, int dlen, const char *search_str) ++static ssize_t ++search_string(char *data, size_t dlen, const char *search_str) + { +- int i, j, k; +- int search_str_len; ++ size_t i, j, k; ++ size_t search_str_len; + + search_str_len = strlen(search_str); ++ if (search_str_len > dlen) ++ return (-1); + for (i = 0; i < dlen - search_str_len; i++) { + for (j = i, k = 0; j < dlen - search_str_len; j++, k++) { + if (data[j] != search_str[k] && +@@ -230,18 +234,21 @@ + static int + alias_rtsp_out(struct libalias *la, struct ip *pip, + struct alias_link *lnk, +- char *data, ++ char *data, size_t maxlen, + const char *port_str) + { +- int hlen, tlen, dlen; ++ size_t hlen, tlen, dlen; ++ size_t i, j; + struct tcphdr *tc; +- int i, j, pos, state, port_dlen, new_dlen, delta; ++ int delta, state; ++ ssize_t pos, slen; ++ size_t new_dlen, port_dlen, port_slen; + u_short p[2], new_len; + u_short sport, eport, base_port; + u_short salias = 0, ealias = 0, base_alias = 0; + const char *transport_str = "transport:"; +- char newdata[2048], *port_data, *port_newdata, stemp[80]; +- int links_created = 0, pkt_updated = 0; ++ char *newdata, *port_data; ++ bool links_created = false, pkt_updated = false; + struct alias_link *rtsp_lnk = NULL; + struct in_addr null_addr; + +@@ -250,6 +257,9 @@ + hlen = (pip->ip_hl + tc->th_off) << 2; + tlen = ntohs(pip->ip_len); + dlen = tlen - hlen; ++ if (hlen > tlen || tlen > maxlen) ++ return (-1); ++ port_slen = strlen(port_str); + + /* Find keyword, "Transport: " */ + pos = search_string(data, dlen, transport_str); +@@ -259,17 +269,21 @@ + port_data = data + pos; + port_dlen = dlen - pos; + ++ /* Allocate temporary buffer */ ++ maxlen -= hlen; ++ if ((newdata = malloc(maxlen)) == NULL) ++ return (-1); + memcpy(newdata, data, pos); +- port_newdata = newdata + pos; ++ new_dlen = pos; + +- while (port_dlen > (int)strlen(port_str)) { ++ while (port_dlen > port_slen) { + /* Find keyword, appropriate port string */ + pos = search_string(port_data, port_dlen, port_str); +- if (pos < 0) ++ if (pos < 0 || (size_t)pos + 1 > maxlen - new_dlen) + break; + +- memcpy(port_newdata, port_data, pos + 1); +- port_newdata += (pos + 1); ++ memcpy(newdata + new_dlen, port_data, pos + 1); ++ new_dlen += pos + 1; + + p[0] = p[1] = 0; + sport = eport = 0; +@@ -300,7 +314,7 @@ + eport = htons(p[1]); + + if (!links_created) { +- links_created = 1; ++ links_created = true; + /* + * Find an even numbered port + * number base that satisfies the +@@ -349,24 +363,30 @@ + ealias = htons(base_alias + (RTSP_PORT_GROUP - 1)); + } + if (salias && rtsp_lnk) { +- pkt_updated = 1; ++ pkt_updated = true; + + /* Copy into IP packet */ +- sprintf(stemp, "%d", ntohs(salias)); +- memcpy(port_newdata, stemp, strlen(stemp)); +- port_newdata += strlen(stemp); ++ slen = snprintf(newdata + new_dlen, ++ maxlen - new_dlen, "%d", ntohs(salias)); ++ if (slen < 0 || slen >= maxlen - new_dlen) ++ goto fail; ++ new_dlen += slen; + + if (eport != 0) { +- *port_newdata = '-'; +- port_newdata++; ++ if (new_dlen == maxlen) ++ goto fail; ++ newdata[new_dlen++] = '-'; + + /* Copy into IP packet */ +- sprintf(stemp, "%d", ntohs(ealias)); +- memcpy(port_newdata, stemp, strlen(stemp)); +- port_newdata += strlen(stemp); ++ slen = snprintf(newdata + new_dlen, ++ maxlen - new_dlen, "%d", ntohs(ealias)); ++ if (slen < 0 || slen >= maxlen - new_dlen) ++ goto fail; ++ new_dlen += slen; + } +- *port_newdata = ';'; +- port_newdata++; ++ if (new_dlen == maxlen) ++ goto fail; ++ newdata[new_dlen++] = ';'; + } + state++; + break; +@@ -380,20 +400,20 @@ + } + + if (!pkt_updated) +- return (-1); +- +- memcpy(port_newdata, port_data, port_dlen); +- port_newdata += port_dlen; +- *port_newdata = '\0'; ++ goto fail; + + /* Create new packet */ +- new_dlen = port_newdata - newdata; ++ if (new_dlen + port_dlen > maxlen) ++ goto fail; ++ memmove(data + new_dlen, port_data, port_dlen); + memcpy(data, newdata, new_dlen); ++ new_dlen += port_dlen; ++ free(newdata); + + SetAckModified(lnk); + tc = (struct tcphdr *)ip_next(pip); + delta = GetDeltaSeqOut(tc->th_seq, lnk); +- AddSeq(lnk, delta + new_dlen - dlen, pip->ip_hl, pip->ip_len, ++ AddSeq(lnk, delta + (int)(new_dlen - dlen), pip->ip_hl, pip->ip_len, + tc->th_seq, tc->th_off); + + new_len = htons(hlen + new_dlen); +@@ -407,6 +427,9 @@ + tc->th_sum = TcpChecksum(pip); + #endif + return (0); ++fail: ++ free(newdata); ++ return (-1); + } + + /* Support the protocol used by early versions of RealPlayer */ +@@ -415,13 +438,13 @@ + alias_pna_out(struct libalias *la, struct ip *pip, + struct alias_link *lnk, + char *data, +- int dlen) ++ size_t dlen) + { + struct alias_link *pna_links; +- u_short msg_id, msg_len; + char *work; +- u_short alias_port, port; + struct tcphdr *tc; ++ u_short msg_id, msg_len; ++ u_short alias_port, port; + + work = data; + work += 5; +@@ -433,7 +456,7 @@ + if (ntohs(msg_id) == 0) /* end of options */ + return (0); + +- if ((ntohs(msg_id) == 1) || (ntohs(msg_id) == 7)) { ++ if (ntohs(msg_id) == 1 || ntohs(msg_id) == 7) { + memcpy(&port, work, 2); + (void)FindUdpTcpOut(la, pip->ip_src, GetDestAddress(lnk), + port, 0, IPPROTO_UDP, 1, &pna_links); +@@ -462,22 +485,23 @@ + } + + static void +-AliasHandleRtspOut(struct libalias *la, struct ip *pip, struct alias_link *lnk, int maxpacketsize) ++AliasHandleRtspOut(struct libalias *la, struct ip *pip, struct alias_link *lnk, ++ size_t maxlen) + { +- int hlen, tlen, dlen; + struct tcphdr *tc; + char *data; + const char *setup = "SETUP", *pna = "PNA", *str200 = "200"; + const char *okstr = "OK", *client_port_str = "client_port"; + const char *server_port_str = "server_port"; +- int i, parseOk; +- +- (void)maxpacketsize; ++ size_t hlen, tlen, dlen; ++ size_t i; + + tc = (struct tcphdr *)ip_next(pip); + hlen = (pip->ip_hl + tc->th_off) << 2; + tlen = ntohs(pip->ip_len); + dlen = tlen - hlen; ++ if (hlen > tlen || tlen > maxlen) ++ return; + + data = (char *)pip; + data += hlen; +@@ -485,13 +509,14 @@ + /* When aliasing a client, check for the SETUP request */ + if ((ntohs(tc->th_dport) == RTSP_CONTROL_PORT_NUMBER_1) || + (ntohs(tc->th_dport) == RTSP_CONTROL_PORT_NUMBER_2)) { +- if (dlen >= (int)strlen(setup) && ++ if (dlen >= strlen(setup) && + memcmp(data, setup, strlen(setup)) == 0) { +- alias_rtsp_out(la, pip, lnk, data, client_port_str); ++ alias_rtsp_out(la, pip, lnk, data, maxlen, ++ client_port_str); + return; + } + +- if (dlen >= (int)strlen(pna) && ++ if (dlen >= strlen(pna) && + memcmp(data, pna, strlen(pna)) == 0) + alias_pna_out(la, pip, lnk, data, dlen); + } else { +@@ -499,24 +524,21 @@ + * When aliasing a server, check for the 200 reply + * Accommodate varying number of blanks between 200 & OK + */ +- +- if (dlen >= (int)strlen(str200)) { +- for (parseOk = 0, i = 0; +- i <= dlen - (int)strlen(str200); +- i++) +- if (memcmp(&data[i], str200, strlen(str200)) == 0) { +- parseOk = 1; +- break; +- } +- +- if (parseOk) { +- i += strlen(str200); /* skip string found */ +- while (data[i] == ' ') /* skip blank(s) */ ++ if (dlen < strlen(str200) + 1 + strlen(okstr)) ++ return; ++ for (i = 0; i <= dlen - strlen(str200) - 1; i++) { ++ if (memcmp(&data[i], str200, strlen(str200)) == 0 && ++ data[i + strlen(str200)] == ' ') { ++ i += strlen(str200); /* skip 200 */ ++ while (i < dlen && data[i] == ' ') /* skip blank(s) */ + i++; +- +- if ((dlen - i) >= (int)strlen(okstr)) +- if (memcmp(&data[i], okstr, strlen(okstr)) == 0) +- alias_rtsp_out(la, pip, lnk, data, server_port_str); ++ if (dlen - i >= strlen(okstr)) { ++ if (memcmp(&data[i], okstr, strlen(okstr)) == 0) { ++ alias_rtsp_out(la, pip, lnk, data, ++ maxlen, server_port_str); ++ break; ++ } ++ } + } + } + } +--- tests/sys/netinet/libalias/Makefile.orig ++++ tests/sys/netinet/libalias/Makefile +@@ -3,6 +3,10 @@ + TESTSDIR= ${TESTSBASE}/sys/netinet/libalias + BINDIR= ${TESTSDIR} + ++PLAIN_TESTS_C+= smedia ++ ++LIBADD.smedia+= sbuf ++ + ATF_TESTS_C+= 1_instance \ + 2_natout \ + 3_natin \ +--- /dev/null ++++ tests/sys/netinet/libalias/smedia.c +@@ -0,0 +1,74 @@ ++/* ++ * Copyright (c) 2026 The FreeBSD Foundation ++ * ++ * This software was developed by Mark Johnston under sponsorship from ++ * the FreeBSD Foundation. ++ * ++ * SPDX-License-Identifier: BSD-2-Clause ++ */ ++ ++/* ++ * A minimal regression test for a buffer overflow in alias_rtsp_out(). ++ */ ++ ++#include ++#include ++ ++#include ++#include ++#include ++#include ++ ++#include ++#include ++ ++#include ++ ++int ++main(void) ++{ ++ uint8_t *packet; ++ struct ip ip; ++ struct tcphdr tcp; ++ struct sbuf sb; ++ struct libalias *la; ++ ++ sbuf_new(&sb, NULL, 0, SBUF_AUTOEXTEND); ++ sbuf_printf(&sb, "SETUP rtsp://example.com/media.mp4 RTSP/1.0\r\n"); ++ sbuf_printf(&sb, "CSeq: 1\r\n"); ++ sbuf_printf(&sb, "Transport: RTP/AVP;unicast;"); ++ for (int i = 0; i < 200; i++) ++ sbuf_printf(&sb, "client_port=%d-%d;", 2 * i, 2 * i + 1); ++ sbuf_printf(&sb, "\r\n\r\n"); ++ sbuf_finish(&sb); ++ ++ memset(&tcp, 0, sizeof(tcp)); ++ tcp.th_sport = htons(1234); ++ tcp.th_dport = htons(554); ++ tcp.th_off = 5; ++ ++ memset(&ip, 0, sizeof(ip)); ++ ip.ip_v = IPVERSION; ++ ip.ip_hl = sizeof(ip) / 4; ++ ip.ip_len = htons(sizeof(ip) + sizeof(tcp) + sbuf_len(&sb)); ++ ip.ip_id = htons(1); ++ ip.ip_ttl = 64; ++ ip.ip_p = IPPROTO_TCP; ++ ip.ip_src.s_addr = inet_addr("127.0.0.1"); ++ ip.ip_dst.s_addr = inet_addr("127.0.0.2"); ++ ++ packet = malloc(sizeof(ip) + sizeof(tcp) + sbuf_len(&sb)); ++ memcpy(packet, &ip, sizeof(ip)); ++ memcpy(packet + sizeof(ip), &tcp, sizeof(tcp)); ++ memcpy(packet + sizeof(ip) + sizeof(tcp), sbuf_data(&sb), ++ sbuf_len(&sb)); ++ ++ la = LibAliasInit(NULL); ++ LibAliasSetAddress(la, ++ (struct in_addr){.s_addr = inet_addr("127.0.0.1")}); ++ if (LibAliasOut(la, packet, sizeof(ip) + sizeof(tcp) + sbuf_len(&sb)) != ++ PKT_ALIAS_OK) ++ return (1); ++ LibAliasUninit(la); ++ return (0); ++} diff --git a/website/static/security/patches/SA-26:41/libalias-15.patch.asc b/website/static/security/patches/SA-26:41/libalias-15.patch.asc new file mode 100644 index 0000000000..08a8870be3 --- /dev/null +++ b/website/static/security/patches/SA-26:41/libalias-15.patch.asc @@ -0,0 +1,17 @@ +-----BEGIN PGP SIGNATURE----- + +iQJPBAABCgA5FiEEthUnfoEIffdcgYM7bljekB8AGu8FAmpEEkIbFIAAAAAABAAO +bWFudTIsMi41KzEuMTIsMCwzAAoJEG5Y3pAfABrv0XAQAJsi7O7hJr+x3IGvJfC4 +S37/wJFqgvv8je2NIlu2RI6KiEupYgWOimMzUUC/aAOSs9PmY4iHaQF+kM2dEkUc +0nHOTfdhxiqRuYZL+6lb4TrCJ50W+jXJ6DUFgZOIyf/03+W4yGE/6E2dJ3jSNSl7 +1YVhiVguGyAnAMNrM6kHz2spuDM40SwNjmNCKGcU8/7y6MqSa8eM+HHKo4iPvg9x +oGqVJI/KGyO7+yazhO9hlgqSTEgxwUagEbH1Z2E1zXPJysSJv0q6UlGg9O4VD1LD +NCfLX2BN0Sjd/rIeV0a/qzE+Q0Oe+6F2F5uzII4DkveVHi+wArAdhSGJm1bRPlNi +kNGucmOMjxjpcEFpn0A8jbJs0MewEAgem/v7L7YJ8ZWOpoj82go2PAKPc+qgSo44 +tHNCf8KrYfLyi/L49wWYzO9jkglE5ZIKrtAwy2CQ6xHE+N5cqNw2RD4up0lWzCT2 +MeryQmo9ThABSViUW4nde0YPuwAXrvNwgiG0uzXN+pQUNb/Pxmro/I6ucbNVc4w3 +ZjusbWrwyORHTIdPhwvPj9cTbU5nS294fiQRdIACwrsmL8ZxNBl7zk6KV4POQSY3 +X+c820lw3K7MCW1gz5bnp3qJ403RmuK71MbnyYu/2cWyUG9KG1Xg38xcYoiIOgcG +796DxtVAJnULrNZlPS/zLLRR +=r7tJ +-----END PGP SIGNATURE----- diff --git a/website/static/security/patches/SA-26:42/unlinkat-14.patch b/website/static/security/patches/SA-26:42/unlinkat-14.patch new file mode 100644 index 0000000000..05bafe67c4 --- /dev/null +++ b/website/static/security/patches/SA-26:42/unlinkat-14.patch @@ -0,0 +1,258 @@ +--- sys/kern/vfs_syscalls.c.orig ++++ sys/kern/vfs_syscalls.c +@@ -1889,16 +1889,17 @@ + + static int + kern_funlinkat_ex(struct thread *td, int dfd, const char *path, int fd, +- int flag, enum uio_seg pathseg, ino_t oldinum) ++ int flags, enum uio_seg pathseg, ino_t oldinum) + { + +- if ((flag & ~(AT_REMOVEDIR | AT_RESOLVE_BENEATH)) != 0) ++ if ((flags & ~(AT_REMOVEDIR | AT_RESOLVE_BENEATH)) != 0) + return (EINVAL); + +- if ((flag & AT_REMOVEDIR) != 0) +- return (kern_frmdirat(td, dfd, path, fd, UIO_USERSPACE, 0)); ++ if ((flags & AT_REMOVEDIR) != 0) ++ return (kern_frmdirat(td, dfd, path, fd, pathseg, ++ flags & ~AT_REMOVEDIR)); + +- return (kern_funlinkat(td, dfd, path, fd, UIO_USERSPACE, 0, 0)); ++ return (kern_funlinkat(td, dfd, path, fd, pathseg, flags, 0)); + } + + #ifndef _SYS_SYSPROTO_H_ +--- tests/sys/kern/Makefile.orig ++++ tests/sys/kern/Makefile +@@ -32,6 +32,7 @@ + ATF_TESTS_C+= ptrace_test + TEST_METADATA.ptrace_test+= timeout="15" + ATF_TESTS_C+= reaper ++ATF_TESTS_C+= resolve_beneath_test + ATF_TESTS_C+= sched_affinity + ATF_TESTS_C+= sigaltstack + ATF_TESTS_C+= sigwait +--- /dev/null ++++ tests/sys/kern/resolve_beneath_test.c +@@ -0,0 +1,220 @@ ++/* ++ * Copyright (c) 2026 The FreeBSD Foundation ++ * ++ * This software was written by Mark Johnston under sponsorship from ++ * the FreeBSD Foundation. ++ * ++ * SPDX-License-Identifier: BSD-2-Clause ++ */ ++ ++#include ++#include ++ ++#include ++#include ++#include ++ ++#include ++ ++/* ++ * Verify that AT_RESOLVE_BENEATH is respected by various system calls. ++ */ ++ ++static int ++setup(void) ++{ ++ int fd, tfd; ++ ++ ATF_REQUIRE_EQ(0, mkdir("base", 0755)); ++ ATF_REQUIRE_EQ(0, mkdir("outside", 0755)); ++ ATF_REQUIRE((tfd = open("outside/target", O_CREAT | O_WRONLY, 0644)) >= ++ 0); ++ ATF_REQUIRE(close(tfd) == 0); ++ ATF_REQUIRE_EQ(0, mkdir("outside/dir", 0755)); ++ ATF_REQUIRE((tfd = open("base/file", O_CREAT | O_WRONLY, 0644)) >= 0); ++ ATF_REQUIRE(close(tfd) == 0); ++ ATF_REQUIRE_EQ(0, mkdir("base/subdir", 0755)); ++ ATF_REQUIRE((fd = open("base", O_DIRECTORY | O_RDONLY)) >= 0); ++ return (fd); ++} ++ ++ATF_TC_WITHOUT_HEAD(faccessat_beneath); ++ATF_TC_BODY(faccessat_beneath, tc) ++{ ++ int fd; ++ ++ fd = setup(); ++ ATF_REQUIRE_EQ(0, ++ faccessat(fd, "file", F_OK, AT_RESOLVE_BENEATH)); ++ ATF_REQUIRE_ERRNO(ENOTCAPABLE, ++ faccessat(fd, "../outside/target", F_OK, ++ AT_RESOLVE_BENEATH) == -1); ++ ATF_REQUIRE(close(fd) == 0); ++} ++ ++ATF_TC_WITHOUT_HEAD(chflagsat_beneath); ++ATF_TC_BODY(chflagsat_beneath, tc) ++{ ++ int fd, ret; ++ ++ fd = setup(); ++ ret = chflagsat(fd, "file", UF_NODUMP, AT_RESOLVE_BENEATH); ++ if (ret != 0) ++ ATF_REQUIRE_EQ(EOPNOTSUPP, errno); ++ ATF_REQUIRE_ERRNO(ENOTCAPABLE, ++ chflagsat(fd, "../outside/target", UF_NODUMP, ++ AT_RESOLVE_BENEATH) == -1); ++ ATF_REQUIRE(close(fd) == 0); ++} ++ ++ATF_TC_WITHOUT_HEAD(fchmodat_beneath); ++ATF_TC_BODY(fchmodat_beneath, tc) ++{ ++ int fd; ++ ++ fd = setup(); ++ ATF_REQUIRE_EQ(0, ++ fchmodat(fd, "file", 0644, AT_RESOLVE_BENEATH)); ++ ATF_REQUIRE_ERRNO(ENOTCAPABLE, ++ fchmodat(fd, "../outside/target", 0644, ++ AT_RESOLVE_BENEATH) == -1); ++ ATF_REQUIRE(close(fd) == 0); ++} ++ ++ATF_TC_WITHOUT_HEAD(fchownat_beneath); ++ATF_TC_BODY(fchownat_beneath, tc) ++{ ++ int fd; ++ ++ fd = setup(); ++ ATF_REQUIRE_EQ(0, ++ fchownat(fd, "file", -1, -1, AT_RESOLVE_BENEATH)); ++ ATF_REQUIRE_ERRNO(ENOTCAPABLE, ++ fchownat(fd, "../outside/target", 0, 0, ++ AT_RESOLVE_BENEATH) == -1); ++ ATF_REQUIRE(close(fd) == 0); ++} ++ ++ATF_TC_WITHOUT_HEAD(utimensat_beneath); ++ATF_TC_BODY(utimensat_beneath, tc) ++{ ++ int fd; ++ ++ fd = setup(); ++ ATF_REQUIRE_EQ(0, ++ utimensat(fd, "file", NULL, AT_RESOLVE_BENEATH)); ++ ATF_REQUIRE_ERRNO(ENOTCAPABLE, ++ utimensat(fd, "../outside/target", NULL, ++ AT_RESOLVE_BENEATH) == -1); ++ ATF_REQUIRE(close(fd) == 0); ++} ++ ++ATF_TC_WITHOUT_HEAD(linkat_beneath); ++ATF_TC_BODY(linkat_beneath, tc) ++{ ++ int fd; ++ ++ fd = setup(); ++ ATF_REQUIRE_EQ(0, ++ linkat(fd, "file", fd, "hardlink", AT_RESOLVE_BENEATH)); ++ ATF_REQUIRE_ERRNO(ENOTCAPABLE, ++ linkat(fd, "../outside/target", fd, "hardlink2", ++ AT_RESOLVE_BENEATH) == -1); ++ ATF_REQUIRE(close(fd) == 0); ++} ++ ++ATF_TC_WITHOUT_HEAD(unlinkat_beneath); ++ATF_TC_BODY(unlinkat_beneath, tc) ++{ ++ int fd; ++ ++ fd = setup(); ++ ATF_REQUIRE_EQ(0, ++ unlinkat(fd, "file", AT_RESOLVE_BENEATH)); ++ ATF_REQUIRE_ERRNO(ENOTCAPABLE, ++ unlinkat(fd, "../outside/target", ++ AT_RESOLVE_BENEATH) == -1); ++ ATF_REQUIRE(close(fd) == 0); ++} ++ ++ATF_TC_WITHOUT_HEAD(unlinkat_rmdir_beneath); ++ATF_TC_BODY(unlinkat_rmdir_beneath, tc) ++{ ++ int fd; ++ ++ fd = setup(); ++ ATF_REQUIRE_EQ(0, ++ unlinkat(fd, "subdir", ++ AT_REMOVEDIR | AT_RESOLVE_BENEATH)); ++ ATF_REQUIRE_ERRNO(ENOTCAPABLE, ++ unlinkat(fd, "../outside/dir", ++ AT_REMOVEDIR | AT_RESOLVE_BENEATH) == -1); ++ ATF_REQUIRE_EQ(0, access("outside/dir", F_OK)); ++ ATF_REQUIRE(close(fd) == 0); ++} ++ ++ATF_TC_WITHOUT_HEAD(funlinkat_beneath); ++ATF_TC_BODY(funlinkat_beneath, tc) ++{ ++ int fd; ++ ++ fd = setup(); ++ ATF_REQUIRE_EQ(0, ++ funlinkat(fd, "file", FD_NONE, AT_RESOLVE_BENEATH)); ++ ATF_REQUIRE_ERRNO(ENOTCAPABLE, ++ funlinkat(fd, "../outside/target", FD_NONE, ++ AT_RESOLVE_BENEATH) == -1); ++ ATF_REQUIRE(close(fd) == 0); ++} ++ ++ATF_TC_WITHOUT_HEAD(funlinkat_rmdir_beneath); ++ATF_TC_BODY(funlinkat_rmdir_beneath, tc) ++{ ++ int fd; ++ ++ fd = setup(); ++ ATF_REQUIRE_EQ(0, mkdir("base/subdir2", 0755)); ++ ATF_REQUIRE_EQ(0, ++ funlinkat(fd, "subdir2", FD_NONE, ++ AT_REMOVEDIR | AT_RESOLVE_BENEATH)); ++ ATF_REQUIRE_ERRNO(ENOTCAPABLE, ++ funlinkat(fd, "../outside/dir", FD_NONE, ++ AT_REMOVEDIR | AT_RESOLVE_BENEATH) == -1); ++ ATF_REQUIRE_EQ(0, access("outside/dir", F_OK)); ++ ATF_REQUIRE(close(fd) == 0); ++} ++ ++ATF_TC(getfhat_beneath); ++ATF_TC_HEAD(getfhat_beneath, tc) ++{ ++ atf_tc_set_md_var(tc, "require.user", "root"); ++} ++ATF_TC_BODY(getfhat_beneath, tc) ++{ ++ fhandle_t fh; ++ int fd; ++ ++ fd = setup(); ++ ATF_REQUIRE_EQ(0, ++ getfhat(fd, "file", &fh, AT_RESOLVE_BENEATH)); ++ ATF_REQUIRE_ERRNO(ENOTCAPABLE, ++ getfhat(fd, "../outside/target", &fh, ++ AT_RESOLVE_BENEATH) == -1); ++ ATF_REQUIRE(close(fd) == 0); ++} ++ ++ATF_TP_ADD_TCS(tp) ++{ ++ ATF_TP_ADD_TC(tp, faccessat_beneath); ++ ATF_TP_ADD_TC(tp, chflagsat_beneath); ++ ATF_TP_ADD_TC(tp, fchmodat_beneath); ++ ATF_TP_ADD_TC(tp, fchownat_beneath); ++ ATF_TP_ADD_TC(tp, utimensat_beneath); ++ ATF_TP_ADD_TC(tp, linkat_beneath); ++ ATF_TP_ADD_TC(tp, unlinkat_beneath); ++ ATF_TP_ADD_TC(tp, unlinkat_rmdir_beneath); ++ ATF_TP_ADD_TC(tp, funlinkat_beneath); ++ ATF_TP_ADD_TC(tp, funlinkat_rmdir_beneath); ++ ATF_TP_ADD_TC(tp, getfhat_beneath); ++ return (atf_no_error()); ++} diff --git a/website/static/security/patches/SA-26:42/unlinkat-14.patch.asc b/website/static/security/patches/SA-26:42/unlinkat-14.patch.asc new file mode 100644 index 0000000000..e55a93f361 --- /dev/null +++ b/website/static/security/patches/SA-26:42/unlinkat-14.patch.asc @@ -0,0 +1,17 @@ +-----BEGIN PGP SIGNATURE----- + +iQJPBAABCgA5FiEEthUnfoEIffdcgYM7bljekB8AGu8FAmpEEkUbFIAAAAAABAAO +bWFudTIsMi41KzEuMTIsMCwzAAoJEG5Y3pAfABrvdmYP/3H8TmK89Yd2JalFYJ06 +epLxF6uIXHXYRh8pqRKdT8o/M/OgG0mS81mY5cRmoJxuQ8AZpbHl6qZlq+IYVO4k +vHekRRhN03foemKG7AdMdyFzXUx+9siq4YP1ZclIrXpq/1C8NRFjgUaFS3IDL74p +6DxjHjPEYvxd0u2jEFakwmLPeCWkp1kT3mUA9NWr7BRbHV0x7pDl0sAi4jWIhFoK +bCNbNSiprXCfm/mP+UHsjUEKKXRVQwfQG79JmHa4dLfINFINe7SeIecaYOZBqNQ8 +f/ZrYna96YDZxBaGzTdoMa2sAQ85oQ2ED8O54jukYw7+GR2SdAsaZYTDSuFGfn9C +qMRbdp+FXcYhjOKsBxTI2OoqtKneHNmgrOANwgmTXs0mpRJkp86rCi8UAv12KO+d +R87l5F08WvixDF7QYuzhrBz2bPIJTfY7xDMaM9WKVt8uRsLph2/Ux23OYoCHeIVG +Tvz1uL76QWJexUWWZFB/rmGBqnliQflCeaH2cAOHczALdDXwG13mokEyzaxWfJHa +IQaCIPf0Ei71cRzrAce48pEJ/koIiiTkAtC8o4sbTeMc6VZ92mdBbdRls/DKXFTL +W155cPjorZU37oo4rUg8dT3Xudl+eOgsf2YcAZyHGmZLefxPrkefkR0NCPiZVI/N +2/pLNumu3v6f8NR7vIrFUQ8t +=xt1p +-----END PGP SIGNATURE----- diff --git a/website/static/security/patches/SA-26:42/unlinkat-15.patch b/website/static/security/patches/SA-26:42/unlinkat-15.patch new file mode 100644 index 0000000000..008f9fea29 --- /dev/null +++ b/website/static/security/patches/SA-26:42/unlinkat-15.patch @@ -0,0 +1,258 @@ +--- sys/kern/vfs_syscalls.c.orig ++++ sys/kern/vfs_syscalls.c +@@ -1976,16 +1976,17 @@ + + static int + kern_funlinkat_ex(struct thread *td, int dfd, const char *path, int fd, +- int flag, enum uio_seg pathseg, ino_t oldinum) ++ int flags, enum uio_seg pathseg, ino_t oldinum) + { + +- if ((flag & ~(AT_REMOVEDIR | AT_RESOLVE_BENEATH)) != 0) ++ if ((flags & ~(AT_REMOVEDIR | AT_RESOLVE_BENEATH)) != 0) + return (EINVAL); + +- if ((flag & AT_REMOVEDIR) != 0) +- return (kern_frmdirat(td, dfd, path, fd, UIO_USERSPACE, 0)); ++ if ((flags & AT_REMOVEDIR) != 0) ++ return (kern_frmdirat(td, dfd, path, fd, pathseg, ++ flags & ~AT_REMOVEDIR)); + +- return (kern_funlinkat(td, dfd, path, fd, UIO_USERSPACE, 0, 0)); ++ return (kern_funlinkat(td, dfd, path, fd, pathseg, flags, 0)); + } + + #ifndef _SYS_SYSPROTO_H_ +--- tests/sys/kern/Makefile.orig ++++ tests/sys/kern/Makefile +@@ -39,6 +39,7 @@ + ATF_TESTS_C+= ptrace_test + TEST_METADATA.ptrace_test+= timeout="15" + ATF_TESTS_C+= reaper ++ATF_TESTS_C+= resolve_beneath_test + ATF_TESTS_C+= sched_affinity + ATF_TESTS_C+= shutdown_dgram + ATF_TESTS_C+= sigaltstack +--- /dev/null ++++ tests/sys/kern/resolve_beneath_test.c +@@ -0,0 +1,220 @@ ++/* ++ * Copyright (c) 2026 The FreeBSD Foundation ++ * ++ * This software was written by Mark Johnston under sponsorship from ++ * the FreeBSD Foundation. ++ * ++ * SPDX-License-Identifier: BSD-2-Clause ++ */ ++ ++#include ++#include ++ ++#include ++#include ++#include ++ ++#include ++ ++/* ++ * Verify that AT_RESOLVE_BENEATH is respected by various system calls. ++ */ ++ ++static int ++setup(void) ++{ ++ int fd, tfd; ++ ++ ATF_REQUIRE_EQ(0, mkdir("base", 0755)); ++ ATF_REQUIRE_EQ(0, mkdir("outside", 0755)); ++ ATF_REQUIRE((tfd = open("outside/target", O_CREAT | O_WRONLY, 0644)) >= ++ 0); ++ ATF_REQUIRE(close(tfd) == 0); ++ ATF_REQUIRE_EQ(0, mkdir("outside/dir", 0755)); ++ ATF_REQUIRE((tfd = open("base/file", O_CREAT | O_WRONLY, 0644)) >= 0); ++ ATF_REQUIRE(close(tfd) == 0); ++ ATF_REQUIRE_EQ(0, mkdir("base/subdir", 0755)); ++ ATF_REQUIRE((fd = open("base", O_DIRECTORY | O_RDONLY)) >= 0); ++ return (fd); ++} ++ ++ATF_TC_WITHOUT_HEAD(faccessat_beneath); ++ATF_TC_BODY(faccessat_beneath, tc) ++{ ++ int fd; ++ ++ fd = setup(); ++ ATF_REQUIRE_EQ(0, ++ faccessat(fd, "file", F_OK, AT_RESOLVE_BENEATH)); ++ ATF_REQUIRE_ERRNO(ENOTCAPABLE, ++ faccessat(fd, "../outside/target", F_OK, ++ AT_RESOLVE_BENEATH) == -1); ++ ATF_REQUIRE(close(fd) == 0); ++} ++ ++ATF_TC_WITHOUT_HEAD(chflagsat_beneath); ++ATF_TC_BODY(chflagsat_beneath, tc) ++{ ++ int fd, ret; ++ ++ fd = setup(); ++ ret = chflagsat(fd, "file", UF_NODUMP, AT_RESOLVE_BENEATH); ++ if (ret != 0) ++ ATF_REQUIRE_EQ(EOPNOTSUPP, errno); ++ ATF_REQUIRE_ERRNO(ENOTCAPABLE, ++ chflagsat(fd, "../outside/target", UF_NODUMP, ++ AT_RESOLVE_BENEATH) == -1); ++ ATF_REQUIRE(close(fd) == 0); ++} ++ ++ATF_TC_WITHOUT_HEAD(fchmodat_beneath); ++ATF_TC_BODY(fchmodat_beneath, tc) ++{ ++ int fd; ++ ++ fd = setup(); ++ ATF_REQUIRE_EQ(0, ++ fchmodat(fd, "file", 0644, AT_RESOLVE_BENEATH)); ++ ATF_REQUIRE_ERRNO(ENOTCAPABLE, ++ fchmodat(fd, "../outside/target", 0644, ++ AT_RESOLVE_BENEATH) == -1); ++ ATF_REQUIRE(close(fd) == 0); ++} ++ ++ATF_TC_WITHOUT_HEAD(fchownat_beneath); ++ATF_TC_BODY(fchownat_beneath, tc) ++{ ++ int fd; ++ ++ fd = setup(); ++ ATF_REQUIRE_EQ(0, ++ fchownat(fd, "file", -1, -1, AT_RESOLVE_BENEATH)); ++ ATF_REQUIRE_ERRNO(ENOTCAPABLE, ++ fchownat(fd, "../outside/target", 0, 0, ++ AT_RESOLVE_BENEATH) == -1); ++ ATF_REQUIRE(close(fd) == 0); ++} ++ ++ATF_TC_WITHOUT_HEAD(utimensat_beneath); ++ATF_TC_BODY(utimensat_beneath, tc) ++{ ++ int fd; ++ ++ fd = setup(); ++ ATF_REQUIRE_EQ(0, ++ utimensat(fd, "file", NULL, AT_RESOLVE_BENEATH)); ++ ATF_REQUIRE_ERRNO(ENOTCAPABLE, ++ utimensat(fd, "../outside/target", NULL, ++ AT_RESOLVE_BENEATH) == -1); ++ ATF_REQUIRE(close(fd) == 0); ++} ++ ++ATF_TC_WITHOUT_HEAD(linkat_beneath); ++ATF_TC_BODY(linkat_beneath, tc) ++{ ++ int fd; ++ ++ fd = setup(); ++ ATF_REQUIRE_EQ(0, ++ linkat(fd, "file", fd, "hardlink", AT_RESOLVE_BENEATH)); ++ ATF_REQUIRE_ERRNO(ENOTCAPABLE, ++ linkat(fd, "../outside/target", fd, "hardlink2", ++ AT_RESOLVE_BENEATH) == -1); ++ ATF_REQUIRE(close(fd) == 0); ++} ++ ++ATF_TC_WITHOUT_HEAD(unlinkat_beneath); ++ATF_TC_BODY(unlinkat_beneath, tc) ++{ ++ int fd; ++ ++ fd = setup(); ++ ATF_REQUIRE_EQ(0, ++ unlinkat(fd, "file", AT_RESOLVE_BENEATH)); ++ ATF_REQUIRE_ERRNO(ENOTCAPABLE, ++ unlinkat(fd, "../outside/target", ++ AT_RESOLVE_BENEATH) == -1); ++ ATF_REQUIRE(close(fd) == 0); ++} ++ ++ATF_TC_WITHOUT_HEAD(unlinkat_rmdir_beneath); ++ATF_TC_BODY(unlinkat_rmdir_beneath, tc) ++{ ++ int fd; ++ ++ fd = setup(); ++ ATF_REQUIRE_EQ(0, ++ unlinkat(fd, "subdir", ++ AT_REMOVEDIR | AT_RESOLVE_BENEATH)); ++ ATF_REQUIRE_ERRNO(ENOTCAPABLE, ++ unlinkat(fd, "../outside/dir", ++ AT_REMOVEDIR | AT_RESOLVE_BENEATH) == -1); ++ ATF_REQUIRE_EQ(0, access("outside/dir", F_OK)); ++ ATF_REQUIRE(close(fd) == 0); ++} ++ ++ATF_TC_WITHOUT_HEAD(funlinkat_beneath); ++ATF_TC_BODY(funlinkat_beneath, tc) ++{ ++ int fd; ++ ++ fd = setup(); ++ ATF_REQUIRE_EQ(0, ++ funlinkat(fd, "file", FD_NONE, AT_RESOLVE_BENEATH)); ++ ATF_REQUIRE_ERRNO(ENOTCAPABLE, ++ funlinkat(fd, "../outside/target", FD_NONE, ++ AT_RESOLVE_BENEATH) == -1); ++ ATF_REQUIRE(close(fd) == 0); ++} ++ ++ATF_TC_WITHOUT_HEAD(funlinkat_rmdir_beneath); ++ATF_TC_BODY(funlinkat_rmdir_beneath, tc) ++{ ++ int fd; ++ ++ fd = setup(); ++ ATF_REQUIRE_EQ(0, mkdir("base/subdir2", 0755)); ++ ATF_REQUIRE_EQ(0, ++ funlinkat(fd, "subdir2", FD_NONE, ++ AT_REMOVEDIR | AT_RESOLVE_BENEATH)); ++ ATF_REQUIRE_ERRNO(ENOTCAPABLE, ++ funlinkat(fd, "../outside/dir", FD_NONE, ++ AT_REMOVEDIR | AT_RESOLVE_BENEATH) == -1); ++ ATF_REQUIRE_EQ(0, access("outside/dir", F_OK)); ++ ATF_REQUIRE(close(fd) == 0); ++} ++ ++ATF_TC(getfhat_beneath); ++ATF_TC_HEAD(getfhat_beneath, tc) ++{ ++ atf_tc_set_md_var(tc, "require.user", "root"); ++} ++ATF_TC_BODY(getfhat_beneath, tc) ++{ ++ fhandle_t fh; ++ int fd; ++ ++ fd = setup(); ++ ATF_REQUIRE_EQ(0, ++ getfhat(fd, "file", &fh, AT_RESOLVE_BENEATH)); ++ ATF_REQUIRE_ERRNO(ENOTCAPABLE, ++ getfhat(fd, "../outside/target", &fh, ++ AT_RESOLVE_BENEATH) == -1); ++ ATF_REQUIRE(close(fd) == 0); ++} ++ ++ATF_TP_ADD_TCS(tp) ++{ ++ ATF_TP_ADD_TC(tp, faccessat_beneath); ++ ATF_TP_ADD_TC(tp, chflagsat_beneath); ++ ATF_TP_ADD_TC(tp, fchmodat_beneath); ++ ATF_TP_ADD_TC(tp, fchownat_beneath); ++ ATF_TP_ADD_TC(tp, utimensat_beneath); ++ ATF_TP_ADD_TC(tp, linkat_beneath); ++ ATF_TP_ADD_TC(tp, unlinkat_beneath); ++ ATF_TP_ADD_TC(tp, unlinkat_rmdir_beneath); ++ ATF_TP_ADD_TC(tp, funlinkat_beneath); ++ ATF_TP_ADD_TC(tp, funlinkat_rmdir_beneath); ++ ATF_TP_ADD_TC(tp, getfhat_beneath); ++ return (atf_no_error()); ++} diff --git a/website/static/security/patches/SA-26:42/unlinkat-15.patch.asc b/website/static/security/patches/SA-26:42/unlinkat-15.patch.asc new file mode 100644 index 0000000000..f413835de1 --- /dev/null +++ b/website/static/security/patches/SA-26:42/unlinkat-15.patch.asc @@ -0,0 +1,17 @@ +-----BEGIN PGP SIGNATURE----- + +iQJPBAABCgA5FiEEthUnfoEIffdcgYM7bljekB8AGu8FAmpEEkYbFIAAAAAABAAO +bWFudTIsMi41KzEuMTIsMCwzAAoJEG5Y3pAfABrvkYwQAIZlSngSKUA3rgmlkP3+ +lJvkuKtmM7rTcWLX7AVnr0yov8RPBJbW+UTQil2SYDqZbCHc+fBwFufqe66g8Eo/ +FVBqZUAj5c6jN9k4YJia3LHNI1ur4YECME9sSCxo1RnElSnAeO/D45ftoVS6sKLw +yi7Al4nkNVTs3eQDhqVEocWpT2WQ8hlfjCyQ/zSSuKYpgz92NDvw21dSk//e/gDp +oSQj2xPTBGmNm1jCyN3kLY4RQJSNWcyQ6elXtmf/b0URr9otd3EFSuQO5l98FNQX +cN1vtErOiSbXe5ONBmTzHg+oV6lxcOaFXIS2Bj5mzwsJwzxMilv2YVlcp8QqWe18 +D9PNlP14ZpuRjVm1NGIF6zigo+WXqtJuVDVtJCsxzcFlH3/t+GwDTNHEmWbczQ27 +zKFD7NT4SzAAnzzrWY+PFuB4FQ5N39fYD5TkJMLqMrpWLvvD55VmKB3gi44JqSzP +L0gW33zJTVRjWdYajdfLeo2Uqr3tKt6KgLgSO6Cxn8i3QqqMiYF4ao94z7+dLCJg +1LKiJCq07sIscyk68fyiN5AnDCfMToLxjpcxlWbLitcQKdGePCzVSBbE4CZFF7ws +XKWo6xwn8sKeslfZLcVmQfuxPPe3QdqrxALCeaPn6YfUyd9sPVj6fHm5TGE2Kvcu +TRYZkCwLrMjtAXA8giCh+yQi +=JzW1 +-----END PGP SIGNATURE----- diff --git a/website/static/security/patches/SA-26:43/tcp.patch b/website/static/security/patches/SA-26:43/tcp.patch new file mode 100644 index 0000000000..7fab0d9682 --- /dev/null +++ b/website/static/security/patches/SA-26:43/tcp.patch @@ -0,0 +1,10 @@ +--- sys/netinet/tcp_stacks/rack.c.orig ++++ sys/netinet/tcp_stacks/rack.c +@@ -24136,6 +24136,7 @@ + INP_WUNLOCK(inp); + return (ENOPROTOOPT); + } ++ rack = (struct tcp_rack *)tp->t_fb_ptr; + if (rack->defer_options && (rack->gp_ready == 0) && + (sopt->sopt_name != TCP_DEFER_OPTIONS) && + (sopt->sopt_name != TCP_HYBRID_PACING) && diff --git a/website/static/security/patches/SA-26:43/tcp.patch.asc b/website/static/security/patches/SA-26:43/tcp.patch.asc new file mode 100644 index 0000000000..4d47189553 --- /dev/null +++ b/website/static/security/patches/SA-26:43/tcp.patch.asc @@ -0,0 +1,17 @@ +-----BEGIN PGP SIGNATURE----- + +iQJPBAABCgA5FiEEthUnfoEIffdcgYM7bljekB8AGu8FAmpEEkgbFIAAAAAABAAO +bWFudTIsMi41KzEuMTIsMCwzAAoJEG5Y3pAfABrvbZ8P+gKuaRL0Ukgo6MWFuZHo +D4/5OEFPniFtMwJSYrshtJ9FOT5arGgtAiLq1XBTUbMwAWu05OxjaftxEFFD2FRE +OI1slYTt/BBgmYJ37iBrj3greMyBWbXdqUwPZ3PMRNazpDVBwwT09/zJyo03/CG3 +KbIerFNEwBBoZUT6MMADua0NNj0oxQ3TbuSeHYfem3qY37biepC9dk2lI2JyG9Uw +bWGlP2x15eDob6dAQoB503iJES2ZB/cj68fRyVXNVJQY/TR37TejPrMoOopVjPpR +z9rsuttxSv+N4Pd+1cbJ9ylZlr5qQPX7Y1Y9wup/NhPaLch5/KT8Z3Dc1UY0LUzv +2nkMm849ICqZJPKENjOba8Ef8nlcdsy+avBtHd3+/IKrZRbjM5SfXMWdUu+41nbV +wcvyBSUMqQ8gVfOMpRFC8Cgy9fJK1UsPr0ntgabavxHvKXfQfsWUicCjL45ZU08N +OyoWIZEm3ZCzhEh71n4dhsvVk8c2pokdPhH7dOJoQIfBWCqGhY5KquGUzsGXu+5c +TIDd7xn9UXivsgRO3GBW0ixoDeNpny0KpwjiaLBEJmN2S+WIG/7RWybaUDQ2oP4I +LYsmPoeUvCtYJVXvk+yTY6Dna4P2K+LTh9vBUTEWIEYJGRfkLWqUAdqpBjpYfVqc +AHfB7LlappDJayR/F27r9mJQ +=shFk +-----END PGP SIGNATURE----- diff --git a/website/static/security/patches/SA-26:44/posixshm-14.patch b/website/static/security/patches/SA-26:44/posixshm-14.patch new file mode 100644 index 0000000000..f1a4112398 --- /dev/null +++ b/website/static/security/patches/SA-26:44/posixshm-14.patch @@ -0,0 +1,336 @@ +--- sys/kern/uipc_shm.c.orig ++++ sys/kern/uipc_shm.c +@@ -323,6 +323,7 @@ + shm_largepage_phys_ctor(vm_object_t object, vm_prot_t prot, + vm_ooffset_t foff, struct ucred *cred) + { ++ object->flags |= OBJ_PG_DTOR; + } + + static void +@@ -330,11 +331,24 @@ + { + int psind; + ++ VM_OBJECT_ASSERT_WLOCKED(object); ++ + psind = object->un_pager.phys.data_val; + if (psind != 0) { ++ vm_page_t m, mtmp; ++ bool removed __diagused; ++ ++restart: ++ TAILQ_FOREACH_SAFE(m, &object->memq, listq, mtmp) { ++ if (!vm_page_busy_acquire(m, VM_ALLOC_WAITFAIL)) { ++ goto restart; ++ } ++ removed = vm_page_remove(m); ++ KASSERT(!removed, ("%s: page %p not wired", __func__, m)); ++ vm_page_unwire(m, PQ_NONE); ++ } + atomic_subtract_long(&count_largepages[psind], + object->size / (pagesizes[psind] / PAGE_SIZE)); +- vm_wire_sub(object->size); + } else { + KASSERT(object->size == 0, + ("largepage phys obj %p not initialized bit size %#jx > 0", +@@ -824,7 +838,7 @@ + vm_pindex_t oldobjsz __unused; + int aflags, error, i, psind, try; + +- KASSERT(length >= 0, ("shm_dotruncate: length < 0")); ++ KASSERT(length >= 0, ("shm_dotruncate_largepage: length < 0")); + object = shmfd->shm_object; + VM_OBJECT_ASSERT_WLOCKED(object); + rangelock_cookie_assert(rl_cookie, RA_WLOCKED); +@@ -856,7 +870,7 @@ + if ((shmfd->shm_seals & F_SEAL_GROW) != 0) + return (EPERM); + +- aflags = VM_ALLOC_NORMAL | VM_ALLOC_ZERO; ++ aflags = VM_ALLOC_NORMAL | VM_ALLOC_ZERO | VM_ALLOC_WIRED; + if (shmfd->shm_lp_alloc_policy == SHM_LARGEPAGE_ALLOC_NOWAIT) + aflags |= VM_ALLOC_WAITFAIL; + try = 0; +@@ -904,7 +918,6 @@ + object->size += OFF_TO_IDX(pagesizes[psind]); + shmfd->shm_size += pagesizes[psind]; + atomic_add_long(&count_largepages[psind], 1); +- vm_wire_add(atop(pagesizes[psind])); + } + return (0); + } +@@ -1345,15 +1358,13 @@ + if (error == 0 && + (flags & (O_ACCMODE | O_TRUNC)) == + (O_RDWR | O_TRUNC)) { +- VM_OBJECT_WLOCK(shmfd->shm_object); + #ifdef MAC + error = mac_posixshm_check_truncate( +- td->td_ucred, fp->f_cred, shmfd); ++ td->td_ucred, fp->f_cred, shmfd); + if (error == 0) + #endif +- error = shm_dotruncate_locked(shmfd, 0, ++ error = shm_dotruncate_cookie(shmfd, 0, + rl_cookie); +- VM_OBJECT_WUNLOCK(shmfd->shm_object); + } + if (error == 0) { + /* +@@ -2096,11 +2107,14 @@ + ("shm_fspacectl: non-zero flags")); + KASSERT(*offset >= 0 && *length > 0 && *length <= OFF_MAX - *offset, + ("shm_fspacectl: offset/length overflow or underflow")); +- error = EINVAL; ++ + shmfd = fp->f_data; + off = *offset; + len = *length; + ++ if (shm_largepage(shmfd)) ++ return (ENOTSUP); ++ + rl_cookie = shm_rangelock_wlock(shmfd, off, off + len); + switch (cmd) { + case SPACECTL_DEALLOC: +--- sys/vm/vm_page.c.orig ++++ sys/vm/vm_page.c +@@ -4121,6 +4121,9 @@ + { + u_int old; + ++ KASSERT(nqueue < PQ_COUNT, ++ ("vm_page_unwire: invalid queue %u request for page %p", ++ nqueue, m)); + KASSERT((m->oflags & VPO_UNMANAGED) == 0, + ("%s: page %p is unmanaged", __func__, m)); + +@@ -4179,17 +4182,15 @@ + void + vm_page_unwire(vm_page_t m, uint8_t nqueue) + { +- +- KASSERT(nqueue < PQ_COUNT, +- ("vm_page_unwire: invalid queue %u request for page %p", +- nqueue, m)); ++ KASSERT(nqueue < PQ_COUNT || nqueue == PQ_NONE, ++ ("%s: invalid queue %u request for page %p", __func__, nqueue, m)); + + if ((m->oflags & VPO_UNMANAGED) != 0) { + if (vm_page_unwire_noq(m) && m->ref_count == 0) + vm_page_free(m); +- return; ++ } else { ++ vm_page_unwire_managed(m, nqueue, false); + } +- vm_page_unwire_managed(m, nqueue, false); + } + + /* +@@ -4363,13 +4364,15 @@ + void + vm_page_release(vm_page_t m, int flags) + { +- vm_object_t object; +- +- KASSERT((m->oflags & VPO_UNMANAGED) == 0, +- ("vm_page_release: page %p is unmanaged", m)); ++ if ((m->oflags & VPO_UNMANAGED) != 0) { ++ vm_page_unwire(m, PQ_NONE); ++ return; ++ } + + if ((flags & VPR_TRYFREE) != 0) { + for (;;) { ++ vm_object_t object; ++ + object = atomic_load_ptr(&m->object); + if (object == NULL) + break; +--- tests/sys/posixshm/posixshm_test.c.orig ++++ tests/sys/posixshm/posixshm_test.c +@@ -34,6 +34,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -1380,6 +1381,27 @@ + ATF_REQUIRE(close(fd) == 0); + } + ++ATF_TC_WITHOUT_HEAD(largepage_fspacectl); ++ATF_TC_BODY(largepage_fspacectl, tc) ++{ ++ struct spacectl_range range; ++ size_t ps[MAXPAGESIZES]; ++ int fd, pscnt; ++ ++ pscnt = pagesizes(ps); ++ ++ for (int i = 1; i < pscnt; i++) { ++ fd = shm_open_large(i, SHM_LARGEPAGE_ALLOC_DEFAULT, ps[i]); ++ ++ range.r_offset = 0; ++ range.r_len = ps[i]; ++ ATF_REQUIRE_ERRNO(ENOTSUP, ++ fspacectl(fd, SPACECTL_DEALLOC, &range, 0, &range) == -1); ++ ++ ATF_REQUIRE(close(fd) == 0); ++ } ++} ++ + ATF_TC_WITHOUT_HEAD(largepage_mmap); + ATF_TC_BODY(largepage_mmap, tc) + { +@@ -2130,6 +2152,130 @@ + "close failed; errno=%d", errno); + } + ++static unsigned char ++largepage_sendfile_expected(size_t off) ++{ ++ ++ return ((unsigned char)(off * 131 + (off >> 8))); ++} ++ ++ATF_TC_WITHOUT_HEAD(largepage_sendfile); ++ATF_TC_BODY(largepage_sendfile, tc) ++{ ++ static const int flags[] = { 0, SF_NOCACHE }; ++ char *addr; ++ off_t sbytes; ++ size_t ps[MAXPAGESIZES]; ++ int error, fd, pscnt, sd[2], status; ++ pid_t child; ++ ++ pscnt = pagesizes(ps); ++ ++ for (int i = 1; i < pscnt; i++) { ++ for (int fi = 0; fi < (int)nitems(flags); fi++) { ++ fd = shm_open_large(i, SHM_LARGEPAGE_ALLOC_DEFAULT, ++ ps[i]); ++ addr = mmap(NULL, ps[i], PROT_READ | PROT_WRITE, ++ MAP_SHARED, fd, 0); ++ ATF_REQUIRE_MSG(addr != MAP_FAILED, ++ "mmap(%zu bytes) failed; error=%d", ps[i], errno); ++ ++ /* Fill with a verifiable pattern. */ ++ for (size_t j = 0; j < ps[i]; j++) ++ addr[j] = largepage_sendfile_expected(j); ++ ++ ATF_REQUIRE(socketpair(PF_LOCAL, SOCK_STREAM, 0, ++ sd) == 0); ++ ++ child = fork(); ++ ATF_REQUIRE_MSG(child != -1, ++ "fork() failed; error=%d", errno); ++ if (child == 0) { ++ char buf[BUFSIZ]; ++ ssize_t len; ++ size_t off, resid; ++ ++ (void)close(sd[0]); ++ off = 0; ++ for (resid = ps[i]; resid > 0; resid -= len) { ++ len = read(sd[1], buf, sizeof(buf)); ++ if (len <= 0) ++ _exit(1); ++ for (ssize_t k = 0; k < len; k++) { ++ if ((unsigned char)buf[k] != ++ largepage_sendfile_expected( ++ off + k)) ++ _exit(2); ++ } ++ off += len; ++ } ++ _exit(0); ++ } ++ ATF_REQUIRE(close(sd[1]) == 0); ++ ++ sbytes = 0; ++ error = sendfile(fd, sd[0], 0, ps[i], NULL, &sbytes, ++ flags[fi]); ++ ATF_REQUIRE_MSG(error == 0, ++ "sendfile() failed; error=%d flags=%#x", ++ errno, flags[fi]); ++ ATF_REQUIRE_MSG(sbytes == (off_t)ps[i], ++ "sendfile() short; sbytes=%jd expected=%zu flags=%#x", ++ (intmax_t)sbytes, ps[i], flags[fi]); ++ ++ ATF_REQUIRE(close(sd[0]) == 0); ++ ++ ATF_REQUIRE_MSG(waitpid(child, &status, 0) == child, ++ "waitpid() failed; error=%d", errno); ++ ATF_REQUIRE_MSG(WIFEXITED(status), ++ "child killed by signal %d", WTERMSIG(status)); ++ ATF_REQUIRE_MSG(WEXITSTATUS(status) == 0, ++ "child exited with status %d (flags=%#x)", ++ WEXITSTATUS(status), flags[fi]); ++ ++ ATF_REQUIRE(munmap(addr, ps[i]) == 0); ++ ATF_REQUIRE(close(fd) == 0); ++ } ++ } ++} ++ ++ATF_TC_WITHOUT_HEAD(largepage_truncate); ++ATF_TC_BODY(largepage_truncate, tc) ++{ ++ size_t ps[MAXPAGESIZES]; ++ int fd, psind; ++ ++ (void)pagesizes(ps); ++ psind = 1; ++ ++ gen_test_path(); ++ fd = shm_create_largepage(test_path, O_CREAT | O_RDWR, psind, ++ SHM_LARGEPAGE_ALLOC_DEFAULT, 0600); ++ if (fd < 0 && errno == ENOTTY) ++ atf_tc_skip("no large page support"); ++ ATF_REQUIRE_MSG(fd >= 0, "shm_create_largepage failed; error=%d", errno); ++ ++ ATF_REQUIRE_MSG(ftruncate(fd, ps[psind]) == 0, ++ "ftruncate failed; error=%d", errno); ++ ++ ATF_REQUIRE_MSG(close(fd) == 0, "close failed; error=%d", errno); ++ ++ fd = shm_open(test_path, O_RDWR | O_TRUNC, 0); ++ ATF_REQUIRE_MSG(fd == -1, "shm_open(O_TRUNC) should have failed"); ++ ATF_REQUIRE_ERRNO(ENOTSUP, fd == -1); ++ ++ fd = shm_open(test_path, O_RDWR, 0); ++ ATF_REQUIRE_MSG(fd >= 0, "shm_open failed; error=%d", errno); ++ ++ ATF_REQUIRE_MSG(ftruncate(fd, ps[psind]) == 0, ++ "ftruncate to same size failed; error=%d", errno); ++ ++ ATF_REQUIRE_MSG(shm_unlink(test_path) == 0, ++ "shm_unlink failed; errno=%d", errno); ++ ATF_REQUIRE_MSG(close(fd) == 0, ++ "close failed; errno=%d", errno); ++} ++ + ATF_TP_ADD_TCS(tp) + { + ATF_TP_ADD_TC(tp, remap_object); +@@ -2168,6 +2314,7 @@ + ATF_TP_ADD_TC(tp, mmap_prot); + ATF_TP_ADD_TC(tp, largepage_basic); + ATF_TP_ADD_TC(tp, largepage_config); ++ ATF_TP_ADD_TC(tp, largepage_fspacectl); + ATF_TP_ADD_TC(tp, largepage_mmap); + ATF_TP_ADD_TC(tp, largepage_munmap); + ATF_TP_ADD_TC(tp, largepage_madvise); +@@ -2180,6 +2327,8 @@ + ATF_TP_ADD_TC(tp, largepage_pkru); + #endif + ATF_TP_ADD_TC(tp, largepage_reopen); ++ ATF_TP_ADD_TC(tp, largepage_sendfile); ++ ATF_TP_ADD_TC(tp, largepage_truncate); + + return (atf_no_error()); + } diff --git a/website/static/security/patches/SA-26:44/posixshm-14.patch.asc b/website/static/security/patches/SA-26:44/posixshm-14.patch.asc new file mode 100644 index 0000000000..7518bc34ec --- /dev/null +++ b/website/static/security/patches/SA-26:44/posixshm-14.patch.asc @@ -0,0 +1,17 @@ +-----BEGIN PGP SIGNATURE----- + +iQJPBAABCgA5FiEEthUnfoEIffdcgYM7bljekB8AGu8FAmpEEksbFIAAAAAABAAO +bWFudTIsMi41KzEuMTIsMCwzAAoJEG5Y3pAfABrvvqQQAI4e4bz9S+IDdgpKr8Mb +xMwzIB4SQXU/8ilJwrFQjTDGBk8qZMOHQ31ZMT02ptGmoA/yftkDuzKQiDMLjxxU +1pPpIAb86fvC1xeyPC7sxI1EF+UPQJDvDDYVghuMd5ywlx3pW6tls3+Hu2TxBiW7 +SkpHpvY9SaYr/0LdrWf4N8YgSnt7WMWEfAWjRSsmzQ8lNYu5qEbMtbhhnWpNQWVl +CHbu9NJPBQygmbclQ3KzSybokw4cZIkwRLiqgmtO6UPgCa7gQfXKE0QkOP387bfX +nxdJJi6c209GtG5//6Zu7mCT+MXtof4PGEzUd8QmjGKhucvF9y3AYQbrjo41Hk3n +4hdSv/8YqwiQ8+xtvB6MrEfabJMQ6MBnvSSL23CoPkOYfsJ0URgEifscTB5su7Pq +MW/VTCgFXeJs0TgLS1Kw0L4iaDdCMP88U/OHnQ6ZBbSzxQZ1qH+kmjI7W1iI9Fob +IXWzIx/OQU5piMe3FaCk9zVpEPKQCofpIWGiU/XDc7iuzn+WSuro0KiDrDT68IK0 +Q4mUHYbIOomcfL2IlF/JXZrlnSec87gNmKzVBZOaP6Y1vVdlOwZduHb72dJnfA0f +pbjFAPZ6tflwZ1WRLaXwumXmVlr+7hlS09C3SFWeSthupsNx+GQ8DaN4+zYPpDip +4Wc/7XxJyhIlv7VQA9PxsIQQ +=sTD+ +-----END PGP SIGNATURE----- diff --git a/website/static/security/patches/SA-26:44/posixshm-15.0.patch b/website/static/security/patches/SA-26:44/posixshm-15.0.patch new file mode 100644 index 0000000000..04dd377b55 --- /dev/null +++ b/website/static/security/patches/SA-26:44/posixshm-15.0.patch @@ -0,0 +1,339 @@ +--- sys/kern/uipc_shm.c.orig ++++ sys/kern/uipc_shm.c +@@ -326,6 +326,7 @@ + shm_largepage_phys_ctor(vm_object_t object, vm_prot_t prot, + vm_ooffset_t foff, struct ucred *cred) + { ++ object->flags |= OBJ_PG_DTOR; + } + + static void +@@ -333,11 +334,27 @@ + { + int psind; + ++ VM_OBJECT_ASSERT_WLOCKED(object); ++ + psind = object->un_pager.phys.data_val; + if (psind != 0) { ++ struct pctrie_iter pages; ++ vm_page_t m; ++ bool removed __diagused; ++ ++ vm_page_iter_init(&pages, object); ++restart: ++ VM_RADIX_FOREACH(m, &pages) { ++ if (!vm_page_busy_acquire(m, VM_ALLOC_WAITFAIL)) { ++ pctrie_iter_reset(&pages); ++ goto restart; ++ } ++ removed = vm_page_iter_remove(&pages, m); ++ KASSERT(!removed, ("%s: page %p not wired", __func__, m)); ++ vm_page_unwire(m, PQ_NONE); ++ } + atomic_subtract_long(&count_largepages[psind], + object->size / (pagesizes[psind] / PAGE_SIZE)); +- vm_wire_sub(object->size); + } else { + KASSERT(object->size == 0, + ("largepage phys obj %p not initialized bit size %#jx > 0", +@@ -788,7 +805,7 @@ + vm_pindex_t oldobjsz __unused; + int aflags, error, i, psind, try; + +- KASSERT(length >= 0, ("shm_dotruncate: length < 0")); ++ KASSERT(length >= 0, ("shm_dotruncate_largepage: length < 0")); + object = shmfd->shm_object; + VM_OBJECT_ASSERT_WLOCKED(object); + rangelock_cookie_assert(rl_cookie, RA_WLOCKED); +@@ -820,7 +837,7 @@ + if ((shmfd->shm_seals & F_SEAL_GROW) != 0) + return (EPERM); + +- aflags = VM_ALLOC_NORMAL | VM_ALLOC_ZERO; ++ aflags = VM_ALLOC_NORMAL | VM_ALLOC_ZERO | VM_ALLOC_WIRED; + if (shmfd->shm_lp_alloc_policy == SHM_LARGEPAGE_ALLOC_NOWAIT) + aflags |= VM_ALLOC_WAITFAIL; + try = 0; +@@ -868,7 +885,6 @@ + object->size += OFF_TO_IDX(pagesizes[psind]); + shmfd->shm_size += pagesizes[psind]; + atomic_add_long(&count_largepages[psind], 1); +- vm_wire_add(atop(pagesizes[psind])); + } + return (0); + } +@@ -1328,15 +1344,13 @@ + if (error == 0 && + (flags & (O_ACCMODE | O_TRUNC)) == + (O_RDWR | O_TRUNC)) { +- VM_OBJECT_WLOCK(shmfd->shm_object); + #ifdef MAC + error = mac_posixshm_check_truncate( +- td->td_ucred, fp->f_cred, shmfd); ++ td->td_ucred, fp->f_cred, shmfd); + if (error == 0) + #endif +- error = shm_dotruncate_locked(shmfd, 0, ++ error = shm_dotruncate_cookie(shmfd, 0, + rl_cookie); +- VM_OBJECT_WUNLOCK(shmfd->shm_object); + } + if (error == 0) { + /* +@@ -2090,11 +2104,14 @@ + ("shm_fspacectl: non-zero flags")); + KASSERT(*offset >= 0 && *length > 0 && *length <= OFF_MAX - *offset, + ("shm_fspacectl: offset/length overflow or underflow")); +- error = EINVAL; ++ + shmfd = fp->f_data; + off = *offset; + len = *length; + ++ if (shm_largepage(shmfd)) ++ return (ENOTSUP); ++ + rl_cookie = shm_rangelock_wlock(shmfd, off, off + len); + switch (cmd) { + case SPACECTL_DEALLOC: +--- sys/vm/vm_page.c.orig ++++ sys/vm/vm_page.c +@@ -4254,6 +4254,9 @@ + { + u_int old; + ++ KASSERT(nqueue < PQ_COUNT, ++ ("vm_page_unwire: invalid queue %u request for page %p", ++ nqueue, m)); + KASSERT((m->oflags & VPO_UNMANAGED) == 0, + ("%s: page %p is unmanaged", __func__, m)); + +@@ -4312,17 +4315,15 @@ + void + vm_page_unwire(vm_page_t m, uint8_t nqueue) + { +- +- KASSERT(nqueue < PQ_COUNT, +- ("vm_page_unwire: invalid queue %u request for page %p", +- nqueue, m)); ++ KASSERT(nqueue < PQ_COUNT || nqueue == PQ_NONE, ++ ("%s: invalid queue %u request for page %p", __func__, nqueue, m)); + + if ((m->oflags & VPO_UNMANAGED) != 0) { + if (vm_page_unwire_noq(m) && m->ref_count == 0) + vm_page_free(m); +- return; ++ } else { ++ vm_page_unwire_managed(m, nqueue, false); + } +- vm_page_unwire_managed(m, nqueue, false); + } + + /* +@@ -4496,13 +4497,15 @@ + void + vm_page_release(vm_page_t m, int flags) + { +- vm_object_t object; +- +- KASSERT((m->oflags & VPO_UNMANAGED) == 0, +- ("vm_page_release: page %p is unmanaged", m)); ++ if ((m->oflags & VPO_UNMANAGED) != 0) { ++ vm_page_unwire(m, PQ_NONE); ++ return; ++ } + + if ((flags & VPR_TRYFREE) != 0) { + for (;;) { ++ vm_object_t object; ++ + object = atomic_load_ptr(&m->object); + if (object == NULL) + break; +--- tests/sys/posixshm/posixshm_test.c.orig ++++ tests/sys/posixshm/posixshm_test.c +@@ -33,6 +33,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -1379,6 +1380,27 @@ + ATF_REQUIRE(close(fd) == 0); + } + ++ATF_TC_WITHOUT_HEAD(largepage_fspacectl); ++ATF_TC_BODY(largepage_fspacectl, tc) ++{ ++ struct spacectl_range range; ++ size_t ps[MAXPAGESIZES]; ++ int fd, pscnt; ++ ++ pscnt = pagesizes(ps); ++ ++ for (int i = 1; i < pscnt; i++) { ++ fd = shm_open_large(i, SHM_LARGEPAGE_ALLOC_DEFAULT, ps[i]); ++ ++ range.r_offset = 0; ++ range.r_len = ps[i]; ++ ATF_REQUIRE_ERRNO(ENOTSUP, ++ fspacectl(fd, SPACECTL_DEALLOC, &range, 0, &range) == -1); ++ ++ ATF_REQUIRE(close(fd) == 0); ++ } ++} ++ + ATF_TC_WITHOUT_HEAD(largepage_mmap); + ATF_TC_BODY(largepage_mmap, tc) + { +@@ -2129,6 +2151,130 @@ + "close failed; errno=%d", errno); + } + ++static unsigned char ++largepage_sendfile_expected(size_t off) ++{ ++ ++ return ((unsigned char)(off * 131 + (off >> 8))); ++} ++ ++ATF_TC_WITHOUT_HEAD(largepage_sendfile); ++ATF_TC_BODY(largepage_sendfile, tc) ++{ ++ static const int flags[] = { 0, SF_NOCACHE }; ++ char *addr; ++ off_t sbytes; ++ size_t ps[MAXPAGESIZES]; ++ int error, fd, pscnt, sd[2], status; ++ pid_t child; ++ ++ pscnt = pagesizes(ps); ++ ++ for (int i = 1; i < pscnt; i++) { ++ for (int fi = 0; fi < (int)nitems(flags); fi++) { ++ fd = shm_open_large(i, SHM_LARGEPAGE_ALLOC_DEFAULT, ++ ps[i]); ++ addr = mmap(NULL, ps[i], PROT_READ | PROT_WRITE, ++ MAP_SHARED, fd, 0); ++ ATF_REQUIRE_MSG(addr != MAP_FAILED, ++ "mmap(%zu bytes) failed; error=%d", ps[i], errno); ++ ++ /* Fill with a verifiable pattern. */ ++ for (size_t j = 0; j < ps[i]; j++) ++ addr[j] = largepage_sendfile_expected(j); ++ ++ ATF_REQUIRE(socketpair(PF_LOCAL, SOCK_STREAM, 0, ++ sd) == 0); ++ ++ child = fork(); ++ ATF_REQUIRE_MSG(child != -1, ++ "fork() failed; error=%d", errno); ++ if (child == 0) { ++ char buf[BUFSIZ]; ++ ssize_t len; ++ size_t off, resid; ++ ++ (void)close(sd[0]); ++ off = 0; ++ for (resid = ps[i]; resid > 0; resid -= len) { ++ len = read(sd[1], buf, sizeof(buf)); ++ if (len <= 0) ++ _exit(1); ++ for (ssize_t k = 0; k < len; k++) { ++ if ((unsigned char)buf[k] != ++ largepage_sendfile_expected( ++ off + k)) ++ _exit(2); ++ } ++ off += len; ++ } ++ _exit(0); ++ } ++ ATF_REQUIRE(close(sd[1]) == 0); ++ ++ sbytes = 0; ++ error = sendfile(fd, sd[0], 0, ps[i], NULL, &sbytes, ++ flags[fi]); ++ ATF_REQUIRE_MSG(error == 0, ++ "sendfile() failed; error=%d flags=%#x", ++ errno, flags[fi]); ++ ATF_REQUIRE_MSG(sbytes == (off_t)ps[i], ++ "sendfile() short; sbytes=%jd expected=%zu flags=%#x", ++ (intmax_t)sbytes, ps[i], flags[fi]); ++ ++ ATF_REQUIRE(close(sd[0]) == 0); ++ ++ ATF_REQUIRE_MSG(waitpid(child, &status, 0) == child, ++ "waitpid() failed; error=%d", errno); ++ ATF_REQUIRE_MSG(WIFEXITED(status), ++ "child killed by signal %d", WTERMSIG(status)); ++ ATF_REQUIRE_MSG(WEXITSTATUS(status) == 0, ++ "child exited with status %d (flags=%#x)", ++ WEXITSTATUS(status), flags[fi]); ++ ++ ATF_REQUIRE(munmap(addr, ps[i]) == 0); ++ ATF_REQUIRE(close(fd) == 0); ++ } ++ } ++} ++ ++ATF_TC_WITHOUT_HEAD(largepage_truncate); ++ATF_TC_BODY(largepage_truncate, tc) ++{ ++ size_t ps[MAXPAGESIZES]; ++ int fd, psind; ++ ++ (void)pagesizes(ps); ++ psind = 1; ++ ++ gen_test_path(); ++ fd = shm_create_largepage(test_path, O_CREAT | O_RDWR, psind, ++ SHM_LARGEPAGE_ALLOC_DEFAULT, 0600); ++ if (fd < 0 && errno == ENOTTY) ++ atf_tc_skip("no large page support"); ++ ATF_REQUIRE_MSG(fd >= 0, "shm_create_largepage failed; error=%d", errno); ++ ++ ATF_REQUIRE_MSG(ftruncate(fd, ps[psind]) == 0, ++ "ftruncate failed; error=%d", errno); ++ ++ ATF_REQUIRE_MSG(close(fd) == 0, "close failed; error=%d", errno); ++ ++ fd = shm_open(test_path, O_RDWR | O_TRUNC, 0); ++ ATF_REQUIRE_MSG(fd == -1, "shm_open(O_TRUNC) should have failed"); ++ ATF_REQUIRE_ERRNO(ENOTSUP, fd == -1); ++ ++ fd = shm_open(test_path, O_RDWR, 0); ++ ATF_REQUIRE_MSG(fd >= 0, "shm_open failed; error=%d", errno); ++ ++ ATF_REQUIRE_MSG(ftruncate(fd, ps[psind]) == 0, ++ "ftruncate to same size failed; error=%d", errno); ++ ++ ATF_REQUIRE_MSG(shm_unlink(test_path) == 0, ++ "shm_unlink failed; errno=%d", errno); ++ ATF_REQUIRE_MSG(close(fd) == 0, ++ "close failed; errno=%d", errno); ++} ++ + ATF_TP_ADD_TCS(tp) + { + ATF_TP_ADD_TC(tp, remap_object); +@@ -2167,6 +2313,7 @@ + ATF_TP_ADD_TC(tp, mmap_prot); + ATF_TP_ADD_TC(tp, largepage_basic); + ATF_TP_ADD_TC(tp, largepage_config); ++ ATF_TP_ADD_TC(tp, largepage_fspacectl); + ATF_TP_ADD_TC(tp, largepage_mmap); + ATF_TP_ADD_TC(tp, largepage_munmap); + ATF_TP_ADD_TC(tp, largepage_madvise); +@@ -2179,6 +2326,8 @@ + ATF_TP_ADD_TC(tp, largepage_pkru); + #endif + ATF_TP_ADD_TC(tp, largepage_reopen); ++ ATF_TP_ADD_TC(tp, largepage_sendfile); ++ ATF_TP_ADD_TC(tp, largepage_truncate); + + return (atf_no_error()); + } diff --git a/website/static/security/patches/SA-26:44/posixshm-15.0.patch.asc b/website/static/security/patches/SA-26:44/posixshm-15.0.patch.asc new file mode 100644 index 0000000000..75f530b4ed --- /dev/null +++ b/website/static/security/patches/SA-26:44/posixshm-15.0.patch.asc @@ -0,0 +1,17 @@ +-----BEGIN PGP SIGNATURE----- + +iQJPBAABCgA5FiEEthUnfoEIffdcgYM7bljekB8AGu8FAmpEEkwbFIAAAAAABAAO +bWFudTIsMi41KzEuMTIsMCwzAAoJEG5Y3pAfABrv7EsQAMEFnW3OAUeK399vGTuY +33xaO5bvvXoy+0qY8PyIi34rI4xPEOgTAQOlOeCvOqPC6fllFVaXncxRJIH6VSHH +qy7poxI4bemY20ZmSQd6f2kT7UWx1sTyAhy1MtF7mvDiioOZdCdixf0wiU3Z/Km8 +i5oBqjcHk5SOsVyvMkIC5okangxEwlmK7Cuv61dGWJLGmq+x9hrgfD+NIkCRqQDq +1AqFa5SUPgL7tQw9sbdjogzOi6XLfjA11u9FvC655nwhmXwuPt5MW3/wTWwskyUs +dMgLxQieMlQ4R6SgCwgdOxvwqbi7ZishsVxnVnCIgtdLrwUK/yiDPCX/oiEUgIfP +vH9VsZoCg70HO397Zn1Rk/zV+OoO11diD+pZw6e5HZxQpNad2GHL0jbB1mfPgJwd +V+48AfcOl1dzNCLL9xNT9kom/Qe3WAjDGgMu7Tep/HtBmle5VzwdixSCEo6Uipmu +ErWStsM1ZNv1wancegujoQzDMNMsfeb9kku2z/UZ3qRVtpgrZnzFAUSoqMtsUIxE +ati+xiVguLwbl06fnH+R3pzaGcMiWL6uFn8j3sCwtV15MCZNhwU4ZT91cKF+6IP2 +7Ilhjt53Q8T41VNt83Fw948JnwdpjAeZTQKWpi2T/iOT/iF1tPzUUNzkPNQp6Jgm +skTWOK9FFDbIrkpdMvvy/m20 +=Hqwr +-----END PGP SIGNATURE----- diff --git a/website/static/security/patches/SA-26:44/posixshm-15.1.patch b/website/static/security/patches/SA-26:44/posixshm-15.1.patch new file mode 100644 index 0000000000..cbec5fab98 --- /dev/null +++ b/website/static/security/patches/SA-26:44/posixshm-15.1.patch @@ -0,0 +1,339 @@ +--- sys/kern/uipc_shm.c.orig ++++ sys/kern/uipc_shm.c +@@ -326,6 +326,7 @@ + shm_largepage_phys_ctor(vm_object_t object, vm_prot_t prot, + vm_ooffset_t foff, struct ucred *cred) + { ++ object->flags |= OBJ_PG_DTOR; + } + + static void +@@ -333,11 +334,27 @@ + { + int psind; + ++ VM_OBJECT_ASSERT_WLOCKED(object); ++ + psind = object->un_pager.phys.data_val; + if (psind != 0) { ++ struct pctrie_iter pages; ++ vm_page_t m; ++ bool removed __diagused; ++ ++ vm_page_iter_init(&pages, object); ++restart: ++ VM_RADIX_FOREACH(m, &pages) { ++ if (!vm_page_busy_acquire(m, VM_ALLOC_WAITFAIL)) { ++ pctrie_iter_reset(&pages); ++ goto restart; ++ } ++ removed = vm_page_iter_remove(&pages, m); ++ KASSERT(!removed, ("%s: page %p not wired", __func__, m)); ++ vm_page_unwire(m, PQ_NONE); ++ } + atomic_subtract_long(&count_largepages[psind], + object->size / (pagesizes[psind] / PAGE_SIZE)); +- vm_wire_sub(object->size); + } else { + KASSERT(object->size == 0, + ("largepage phys obj %p not initialized bit size %#jx > 0", +@@ -786,7 +803,7 @@ + vm_pindex_t oldobjsz __unused; + int aflags, error, i, psind, try; + +- KASSERT(length >= 0, ("shm_dotruncate: length < 0")); ++ KASSERT(length >= 0, ("shm_dotruncate_largepage: length < 0")); + object = shmfd->shm_object; + VM_OBJECT_ASSERT_WLOCKED(object); + rangelock_cookie_assert(rl_cookie, RA_WLOCKED); +@@ -818,7 +835,7 @@ + if ((shmfd->shm_seals & F_SEAL_GROW) != 0) + return (EPERM); + +- aflags = VM_ALLOC_NORMAL | VM_ALLOC_ZERO; ++ aflags = VM_ALLOC_NORMAL | VM_ALLOC_ZERO | VM_ALLOC_WIRED; + if (shmfd->shm_lp_alloc_policy == SHM_LARGEPAGE_ALLOC_NOWAIT) + aflags |= VM_ALLOC_WAITFAIL; + try = 0; +@@ -874,7 +891,6 @@ + object->size += OFF_TO_IDX(pagesizes[psind]); + shmfd->shm_size += pagesizes[psind]; + atomic_add_long(&count_largepages[psind], 1); +- vm_wire_add(atop(pagesizes[psind])); + } + return (0); + } +@@ -1334,15 +1350,13 @@ + if (error == 0 && + (flags & (O_ACCMODE | O_TRUNC)) == + (O_RDWR | O_TRUNC)) { +- VM_OBJECT_WLOCK(shmfd->shm_object); + #ifdef MAC + error = mac_posixshm_check_truncate( +- td->td_ucred, fp->f_cred, shmfd); ++ td->td_ucred, fp->f_cred, shmfd); + if (error == 0) + #endif +- error = shm_dotruncate_locked(shmfd, 0, ++ error = shm_dotruncate_cookie(shmfd, 0, + rl_cookie); +- VM_OBJECT_WUNLOCK(shmfd->shm_object); + } + if (error == 0) { + /* +@@ -2096,11 +2110,14 @@ + ("shm_fspacectl: non-zero flags")); + KASSERT(*offset >= 0 && *length > 0 && *length <= OFF_MAX - *offset, + ("shm_fspacectl: offset/length overflow or underflow")); +- error = EINVAL; ++ + shmfd = fp->f_data; + off = *offset; + len = *length; + ++ if (shm_largepage(shmfd)) ++ return (ENOTSUP); ++ + rl_cookie = shm_rangelock_wlock(shmfd, off, off + len); + switch (cmd) { + case SPACECTL_DEALLOC: +--- sys/vm/vm_page.c.orig ++++ sys/vm/vm_page.c +@@ -4272,6 +4272,9 @@ + { + u_int old; + ++ KASSERT(nqueue < PQ_COUNT, ++ ("vm_page_unwire: invalid queue %u request for page %p", ++ nqueue, m)); + KASSERT((m->oflags & VPO_UNMANAGED) == 0, + ("%s: page %p is unmanaged", __func__, m)); + +@@ -4330,17 +4333,15 @@ + void + vm_page_unwire(vm_page_t m, uint8_t nqueue) + { +- +- KASSERT(nqueue < PQ_COUNT, +- ("vm_page_unwire: invalid queue %u request for page %p", +- nqueue, m)); ++ KASSERT(nqueue < PQ_COUNT || nqueue == PQ_NONE, ++ ("%s: invalid queue %u request for page %p", __func__, nqueue, m)); + + if ((m->oflags & VPO_UNMANAGED) != 0) { + if (vm_page_unwire_noq(m) && m->ref_count == 0) + vm_page_free(m); +- return; ++ } else { ++ vm_page_unwire_managed(m, nqueue, false); + } +- vm_page_unwire_managed(m, nqueue, false); + } + + /* +@@ -4514,13 +4515,15 @@ + void + vm_page_release(vm_page_t m, int flags) + { +- vm_object_t object; +- +- KASSERT((m->oflags & VPO_UNMANAGED) == 0, +- ("vm_page_release: page %p is unmanaged", m)); ++ if ((m->oflags & VPO_UNMANAGED) != 0) { ++ vm_page_unwire(m, PQ_NONE); ++ return; ++ } + + if ((flags & VPR_TRYFREE) != 0) { + for (;;) { ++ vm_object_t object; ++ + object = atomic_load_ptr(&m->object); + if (object == NULL) + break; +--- tests/sys/posixshm/posixshm_test.c.orig ++++ tests/sys/posixshm/posixshm_test.c +@@ -33,6 +33,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -1369,6 +1370,27 @@ + ATF_REQUIRE(close(fd) == 0); + } + ++ATF_TC_WITHOUT_HEAD(largepage_fspacectl); ++ATF_TC_BODY(largepage_fspacectl, tc) ++{ ++ struct spacectl_range range; ++ size_t ps[MAXPAGESIZES]; ++ int fd, pscnt; ++ ++ pscnt = pagesizes(ps, true); ++ ++ for (int i = 1; i < pscnt; i++) { ++ fd = shm_open_large(i, SHM_LARGEPAGE_ALLOC_DEFAULT, ps[i]); ++ ++ range.r_offset = 0; ++ range.r_len = ps[i]; ++ ATF_REQUIRE_ERRNO(ENOTSUP, ++ fspacectl(fd, SPACECTL_DEALLOC, &range, 0, &range) == -1); ++ ++ ATF_REQUIRE(close(fd) == 0); ++ } ++} ++ + ATF_TC_WITHOUT_HEAD(largepage_mmap); + ATF_TC_BODY(largepage_mmap, tc) + { +@@ -2127,6 +2149,130 @@ + "close failed; errno=%d", errno); + } + ++static unsigned char ++largepage_sendfile_expected(size_t off) ++{ ++ ++ return ((unsigned char)(off * 131 + (off >> 8))); ++} ++ ++ATF_TC_WITHOUT_HEAD(largepage_sendfile); ++ATF_TC_BODY(largepage_sendfile, tc) ++{ ++ static const int flags[] = { 0, SF_NOCACHE }; ++ char *addr; ++ off_t sbytes; ++ size_t ps[MAXPAGESIZES]; ++ int error, fd, pscnt, sd[2], status; ++ pid_t child; ++ ++ pscnt = pagesizes(ps, true); ++ ++ for (int i = 1; i < pscnt; i++) { ++ for (int fi = 0; fi < (int)nitems(flags); fi++) { ++ fd = shm_open_large(i, SHM_LARGEPAGE_ALLOC_DEFAULT, ++ ps[i]); ++ addr = mmap(NULL, ps[i], PROT_READ | PROT_WRITE, ++ MAP_SHARED, fd, 0); ++ ATF_REQUIRE_MSG(addr != MAP_FAILED, ++ "mmap(%zu bytes) failed; error=%d", ps[i], errno); ++ ++ /* Fill with a verifiable pattern. */ ++ for (size_t j = 0; j < ps[i]; j++) ++ addr[j] = largepage_sendfile_expected(j); ++ ++ ATF_REQUIRE(socketpair(PF_LOCAL, SOCK_STREAM, 0, ++ sd) == 0); ++ ++ child = fork(); ++ ATF_REQUIRE_MSG(child != -1, ++ "fork() failed; error=%d", errno); ++ if (child == 0) { ++ char buf[BUFSIZ]; ++ ssize_t len; ++ size_t off, resid; ++ ++ (void)close(sd[0]); ++ off = 0; ++ for (resid = ps[i]; resid > 0; resid -= len) { ++ len = read(sd[1], buf, sizeof(buf)); ++ if (len <= 0) ++ _exit(1); ++ for (ssize_t k = 0; k < len; k++) { ++ if ((unsigned char)buf[k] != ++ largepage_sendfile_expected( ++ off + k)) ++ _exit(2); ++ } ++ off += len; ++ } ++ _exit(0); ++ } ++ ATF_REQUIRE(close(sd[1]) == 0); ++ ++ sbytes = 0; ++ error = sendfile(fd, sd[0], 0, ps[i], NULL, &sbytes, ++ flags[fi]); ++ ATF_REQUIRE_MSG(error == 0, ++ "sendfile() failed; error=%d flags=%#x", ++ errno, flags[fi]); ++ ATF_REQUIRE_MSG(sbytes == (off_t)ps[i], ++ "sendfile() short; sbytes=%jd expected=%zu flags=%#x", ++ (intmax_t)sbytes, ps[i], flags[fi]); ++ ++ ATF_REQUIRE(close(sd[0]) == 0); ++ ++ ATF_REQUIRE_MSG(waitpid(child, &status, 0) == child, ++ "waitpid() failed; error=%d", errno); ++ ATF_REQUIRE_MSG(WIFEXITED(status), ++ "child killed by signal %d", WTERMSIG(status)); ++ ATF_REQUIRE_MSG(WEXITSTATUS(status) == 0, ++ "child exited with status %d (flags=%#x)", ++ WEXITSTATUS(status), flags[fi]); ++ ++ ATF_REQUIRE(munmap(addr, ps[i]) == 0); ++ ATF_REQUIRE(close(fd) == 0); ++ } ++ } ++} ++ ++ATF_TC_WITHOUT_HEAD(largepage_truncate); ++ATF_TC_BODY(largepage_truncate, tc) ++{ ++ size_t ps[MAXPAGESIZES]; ++ int fd, psind; ++ ++ (void)pagesizes(ps, true); ++ psind = 1; ++ ++ gen_test_path(); ++ fd = shm_create_largepage(test_path, O_CREAT | O_RDWR, psind, ++ SHM_LARGEPAGE_ALLOC_DEFAULT, 0600); ++ if (fd < 0 && errno == ENOTTY) ++ atf_tc_skip("no large page support"); ++ ATF_REQUIRE_MSG(fd >= 0, "shm_create_largepage failed; error=%d", errno); ++ ++ ATF_REQUIRE_MSG(ftruncate(fd, ps[psind]) == 0, ++ "ftruncate failed; error=%d", errno); ++ ++ ATF_REQUIRE_MSG(close(fd) == 0, "close failed; error=%d", errno); ++ ++ fd = shm_open(test_path, O_RDWR | O_TRUNC, 0); ++ ATF_REQUIRE_MSG(fd == -1, "shm_open(O_TRUNC) should have failed"); ++ ATF_REQUIRE_ERRNO(ENOTSUP, fd == -1); ++ ++ fd = shm_open(test_path, O_RDWR, 0); ++ ATF_REQUIRE_MSG(fd >= 0, "shm_open failed; error=%d", errno); ++ ++ ATF_REQUIRE_MSG(ftruncate(fd, ps[psind]) == 0, ++ "ftruncate to same size failed; error=%d", errno); ++ ++ ATF_REQUIRE_MSG(shm_unlink(test_path) == 0, ++ "shm_unlink failed; errno=%d", errno); ++ ATF_REQUIRE_MSG(close(fd) == 0, ++ "close failed; errno=%d", errno); ++} ++ + ATF_TP_ADD_TCS(tp) + { + ATF_TP_ADD_TC(tp, remap_object); +@@ -2165,6 +2311,7 @@ + ATF_TP_ADD_TC(tp, mmap_prot); + ATF_TP_ADD_TC(tp, largepage_basic); + ATF_TP_ADD_TC(tp, largepage_config); ++ ATF_TP_ADD_TC(tp, largepage_fspacectl); + ATF_TP_ADD_TC(tp, largepage_mmap); + ATF_TP_ADD_TC(tp, largepage_munmap); + ATF_TP_ADD_TC(tp, largepage_madvise); +@@ -2177,6 +2324,8 @@ + ATF_TP_ADD_TC(tp, largepage_pkru); + #endif + ATF_TP_ADD_TC(tp, largepage_reopen); ++ ATF_TP_ADD_TC(tp, largepage_sendfile); ++ ATF_TP_ADD_TC(tp, largepage_truncate); + + return (atf_no_error()); + } diff --git a/website/static/security/patches/SA-26:44/posixshm-15.1.patch.asc b/website/static/security/patches/SA-26:44/posixshm-15.1.patch.asc new file mode 100644 index 0000000000..6654b18970 --- /dev/null +++ b/website/static/security/patches/SA-26:44/posixshm-15.1.patch.asc @@ -0,0 +1,17 @@ +-----BEGIN PGP SIGNATURE----- + +iQJPBAABCgA5FiEEthUnfoEIffdcgYM7bljekB8AGu8FAmpEEk4bFIAAAAAABAAO +bWFudTIsMi41KzEuMTIsMCwzAAoJEG5Y3pAfABrvIkkQAM+9Wpm3tTHAlc2LWMoK +9T/C8ALUjYlRI3+xW1o8J1rjXPL2rj2z4PM5fTYX5anQdmm2DdYwVvzTbRa8epzO +KrrQeGjyG6ELHE9VZhm++XtpR0Yz6ag4qduLqqrTCmo8Qi5/OXfVsCo1WbV9nFjh +ZeQ+x9gzzOrnV/F3OXtpMHdyNbf1Z60EdGQ6hyLgQFLAGQe5agVjIT+FtVmhDIeH +ys9flKPZxqE+46KVJbexgazJaMVfibOG/CKnb1YidGW+h2nfY086faSS7bjUf59d +5QpquUoPuGg/nfRpioe3Ox2gja0ALAdad6gvtn6QXWlG+8pId2Wylc1RzqLGIBTw +KmUDrc9XuxA2SVrKk/HCU5pingj8/nlyQnbk0UtQT7ZyKDndjtgGeKh1kR6Q1njv +NjGmnYFdJTh3mymHEO0NTBxct81teCsKE81mWkPETrP8HM6j1w7UWLyGdtM1j7uL +f5m+bnWoxSXqKyCbJRwTzaHF34GEqjgItgdBTCW5L6FSa3VzDvDXpJtAaJnXaqBO +sWe5tl0gMxBCx8DU5RnpangpApwD2LL4LPtmy0b5Vx5vkQdaemybt2W+Nt+MA6d6 +VPVEcU2X1rcZar+NLVtOLXzlmN7vewhVfPs1e14oBuOiz1URxnuWe+4eD+Sj4ozq +eyaERcENULGVub35wEJuEZUE +=aWUn +-----END PGP SIGNATURE----- diff --git a/website/static/security/patches/SA-26:45/audit.patch b/website/static/security/patches/SA-26:45/audit.patch new file mode 100644 index 0000000000..2e64cf813a --- /dev/null +++ b/website/static/security/patches/SA-26:45/audit.patch @@ -0,0 +1,11 @@ +--- sys/kern/kern_sig.c.orig ++++ sys/kern/kern_sig.c +@@ -2766,7 +2766,7 @@ + td->td_errno = nerror; + + if (audited) +- AUDIT_SYSCALL_EXIT(error, td); ++ AUDIT_SYSCALL_EXIT(tsr->ts_ret.sr_error, td); + if (!sy_thr_static) + syscall_thread_exit(td, se); + } diff --git a/website/static/security/patches/SA-26:45/audit.patch.asc b/website/static/security/patches/SA-26:45/audit.patch.asc new file mode 100644 index 0000000000..20641a48ce --- /dev/null +++ b/website/static/security/patches/SA-26:45/audit.patch.asc @@ -0,0 +1,17 @@ +-----BEGIN PGP SIGNATURE----- + +iQJPBAABCgA5FiEEthUnfoEIffdcgYM7bljekB8AGu8FAmpEElAbFIAAAAAABAAO +bWFudTIsMi41KzEuMTIsMCwzAAoJEG5Y3pAfABrvMJgQAIblpRS0aez8sc2zSmn7 +KiUoC1pzbIYgUj3EGVgTgXRfWONfc2TPL8n08RVgUYPW+42wbKNba5P+dQz/CGjH +cHQ4gmZY3FQC7z9NUTcCFS77yjluXEfZVO5+HUTTM8Yz6hoZoWhZuwwG+srcD4kA +Uz1QY00vULv6D7IN3P5UY8jwAR7Y75q5TrDbpNAcMl0QTvx2577YzDsVVGA1tX1P +ntwfPhwVnSwRzRNxUAD8gDSYNvO6mD7AtP0bUYbyJ09lUlF46rcjp/24KGMhcso1 +n/37F4oRERk2pPAa3w0Dtra2cKNo4EYezLm5JDKDetPIj7R09QcPSMlVA186+c95 +IL+2ck36Yb5afLTNs7vipo5v08gmm1XwDlxvFY+yV3JyTvnIKe2dOcd9H6T+/rZr +HKSXQjbXWJ75c7LxasphXJlmg52J6k8NyCMRYRZ/pQNnQZyRWF3BP7Y8IZfVkEfC +fzyc4gs/ymxQk9JAGe8jm6reGPTn7tyhhebkCqzFnOatsxICywu5HWi8FvFfuy/J +UVaCkPoZN3MNHpNqvvh/733d7m5qx25VTCf15hZlpcJNSP4Boja1PCeB4zYckBe8 +cxKB8qNy/CJ6IsUGsolKgT02aaBzXLUgFO320SIcLnYGbc9yuYlIUruYQM9n/uVU +RcdKQhQuEfHP6CF9VlTNqGyg +=mxVy +-----END PGP SIGNATURE----- diff --git a/website/static/security/patches/SA-26:46/ktls.patch b/website/static/security/patches/SA-26:46/ktls.patch new file mode 100644 index 0000000000..46a04c34a4 --- /dev/null +++ b/website/static/security/patches/SA-26:46/ktls.patch @@ -0,0 +1,172 @@ +--- sys/opencrypto/ktls_ocf.c.orig ++++ sys/opencrypto/ktls_ocf.c +@@ -500,13 +500,14 @@ + iov[0].iov_base = &ad; + iov[0].iov_len = sizeof(ad); + skip = sizeof(*hdr) + AES_BLOCK_LEN; +- for (i = 1, n = m; n != NULL; i++, n = n->m_next) { ++ for (i = 1, n = m; n != NULL; n = n->m_next) { + if (n->m_len < skip) { + skip -= n->m_len; + continue; + } + iov[i].iov_base = mtod(n, char *) + skip; + iov[i].iov_len = n->m_len - skip; ++ i++; + skip = 0; + } + uio.uio_iov = iov; +--- tests/sys/kern/ktls_test.c.orig ++++ tests/sys/kern/ktls_test.c +@@ -303,6 +303,15 @@ + ATF_REQUIRE(fcntl(fd, F_SETFL, flags) != -1); + } + ++static void ++tcp_nodelay(int fd) ++{ ++ int nodelay = 1; ++ ++ ATF_REQUIRE(setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &nodelay, ++ sizeof(nodelay)) == 0); ++} ++ + static bool + cbc_crypt(const EVP_CIPHER *cipher, const char *key, const char *iv, + const char *input, char *output, size_t size, int enc) +@@ -1920,6 +1929,55 @@ + close_sockets_ignore_errors(sockets); + } + ++static void ++test_ktls_receive_split_record(const atf_tc_t *tc, struct tls_enable *en, ++ uint64_t seqno, size_t len, size_t first_len) ++{ ++ char *plaintext, *received, *outbuf; ++ size_t outbuf_cap, outbuf_len; ++ ssize_t rv; ++ int sockets[2]; ++ ++ ATF_REQUIRE(len <= TLS_MAX_MSG_SIZE_V10_2); ++ ++ plaintext = alloc_buffer(len); ++ received = malloc(len); ++ outbuf_cap = tls_header_len(en) + len + tls_trailer_len(en); ++ outbuf = malloc(outbuf_cap); ++ ++ ATF_REQUIRE_MSG(open_sockets(tc, sockets), "failed to create sockets"); ++ ++ ATF_REQUIRE(setsockopt(sockets[0], IPPROTO_TCP, TCP_RXTLS_ENABLE, en, ++ sizeof(*en)) == 0); ++ check_tls_mode(tc, sockets[0], TCP_RXTLS_MODE); ++ ++ fd_set_blocking(sockets[0]); ++ fd_set_blocking(sockets[1]); ++ ++ outbuf_len = encrypt_tls_record(tc, en, TLS_RLTYPE_APP, seqno, ++ plaintext, len, outbuf, outbuf_cap, 0); ++ ATF_REQUIRE(first_len < outbuf_len); ++ ++ tcp_nodelay(sockets[1]); ++ rv = write(sockets[1], outbuf, first_len); ++ ATF_REQUIRE_INTEQ((ssize_t)(first_len), rv); ++ ++ rv = write(sockets[1], outbuf + first_len, outbuf_len - first_len); ++ ATF_REQUIRE_INTEQ((ssize_t)(outbuf_len - first_len), rv); ++ ++ rv = ktls_receive_tls_record(en, sockets[0], TLS_RLTYPE_APP, received, ++ len); ++ ATF_REQUIRE_INTEQ((ssize_t)len, rv); ++ ++ ATF_REQUIRE(memcmp(plaintext, received, len) == 0); ++ ++ free(outbuf); ++ free(received); ++ free(plaintext); ++ ++ close_sockets(sockets); ++} ++ + #define TLS_10_TESTS(M) \ + M(aes128_cbc_1_0_sha1, CRYPTO_AES_CBC, 128 / 8, \ + CRYPTO_SHA1_HMAC, TLS_MINOR_VER_ZERO) \ +@@ -2360,6 +2418,26 @@ + auth_alg, minor, name) \ + ATF_TP_ADD_TC(tp, ktls_receive_##cipher_name##_##name); + ++#define GEN_RECEIVE_SPLIT_RECORD_TEST(cipher_name, cipher_alg, \ ++ key_size, auth_alg, minor, name, len, first_len) \ ++ATF_TC_WITHOUT_HEAD(ktls_receive_##cipher_name##_split_##name); \ ++ATF_TC_BODY(ktls_receive_##cipher_name##_split_##name, tc) \ ++{ \ ++ struct tls_enable en; \ ++ uint64_t seqno; \ ++ \ ++ ATF_REQUIRE_KTLS(); \ ++ seqno = random(); \ ++ build_tls_enable(tc, cipher_alg, key_size, auth_alg, minor, \ ++ seqno, &en); \ ++ test_ktls_receive_split_record(tc, &en, seqno, len, first_len); \ ++ free_tls_enable(&en); \ ++} ++ ++#define ADD_RECEIVE_SPLIT_RECORD_TEST(cipher_name, cipher_alg, \ ++ key_size, auth_alg, minor, name) \ ++ ATF_TP_ADD_TC(tp, ktls_receive_##cipher_name##_split_##name); ++ + #define GEN_RECEIVE_TESTS(cipher_name, cipher_alg, key_size, auth_alg, \ + minor) \ + GEN_RECEIVE_APP_DATA_TEST(cipher_name, cipher_alg, key_size, \ +@@ -2381,7 +2459,22 @@ + tls_minimum_record_payload(&en) - 1) \ + GEN_RECEIVE_BAD_SIZE_TEST(cipher_name, cipher_alg, key_size, \ + auth_alg, minor, oversized_record, \ +- TLS_MAX_MSG_SIZE_V10_2 * 2) ++ TLS_MAX_MSG_SIZE_V10_2 * 2) \ ++ GEN_RECEIVE_SPLIT_RECORD_TEST(cipher_name, cipher_alg, \ ++ key_size, auth_alg, minor, header, 64, \ ++ sizeof(struct tls_record_layer)); \ ++ GEN_RECEIVE_SPLIT_RECORD_TEST(cipher_name, cipher_alg, \ ++ key_size, auth_alg, minor, full_header, 64, \ ++ tls_header_len(&en)); \ ++ GEN_RECEIVE_SPLIT_RECORD_TEST(cipher_name, cipher_alg, \ ++ key_size, auth_alg, minor, half, 64, \ ++ tls_header_len(&en) + 32); \ ++ GEN_RECEIVE_SPLIT_RECORD_TEST(cipher_name, cipher_alg, \ ++ key_size, auth_alg, minor, trailer_start, 64, \ ++ tls_header_len(&en) + 64); \ ++ GEN_RECEIVE_SPLIT_RECORD_TEST(cipher_name, cipher_alg, \ ++ key_size, auth_alg, minor, trailer_middle, 64, \ ++ tls_header_len(&en) + 64 + tls_trailer_len(&en) / 2); + + #define ADD_RECEIVE_TESTS(cipher_name, cipher_alg, key_size, auth_alg, \ + minor) \ +@@ -2402,7 +2495,17 @@ + ADD_RECEIVE_BAD_SIZE_TEST(cipher_name, cipher_alg, key_size, \ + auth_alg, minor, small_record) \ + ADD_RECEIVE_BAD_SIZE_TEST(cipher_name, cipher_alg, key_size, \ +- auth_alg, minor, oversized_record) ++ auth_alg, minor, oversized_record) \ ++ ADD_RECEIVE_SPLIT_RECORD_TEST(cipher_name, cipher_alg, \ ++ key_size, auth_alg, minor, header) \ ++ ADD_RECEIVE_SPLIT_RECORD_TEST(cipher_name, cipher_alg, \ ++ key_size, auth_alg, minor, full_header) \ ++ ADD_RECEIVE_SPLIT_RECORD_TEST(cipher_name, cipher_alg, \ ++ key_size, auth_alg, minor, half) \ ++ ADD_RECEIVE_SPLIT_RECORD_TEST(cipher_name, cipher_alg, \ ++ key_size, auth_alg, minor, trailer_start) \ ++ ADD_RECEIVE_SPLIT_RECORD_TEST(cipher_name, cipher_alg, \ ++ key_size, auth_alg, minor, trailer_middle) \ + + /* + * For each supported cipher suite, run several receive tests: +@@ -2425,6 +2528,9 @@ + * size + * + * - a test with an oversized TLS record ++ * ++ * - tests of a single record whose data is split across two writes, ++ * with each test using a different split point + */ + AES_CBC_NONZERO_TESTS(GEN_RECEIVE_TESTS); + AES_GCM_TESTS(GEN_RECEIVE_TESTS); diff --git a/website/static/security/patches/SA-26:46/ktls.patch.asc b/website/static/security/patches/SA-26:46/ktls.patch.asc new file mode 100644 index 0000000000..105797f59e --- /dev/null +++ b/website/static/security/patches/SA-26:46/ktls.patch.asc @@ -0,0 +1,17 @@ +-----BEGIN PGP SIGNATURE----- + +iQJPBAABCgA5FiEEthUnfoEIffdcgYM7bljekB8AGu8FAmpEElMbFIAAAAAABAAO +bWFudTIsMi41KzEuMTIsMCwzAAoJEG5Y3pAfABrv6ZYP/R2mshdfh05xev1pYH02 +ubTOPNOzcIDZw5TsOxspYMzevritin6DvUPCSv2uOWXM2ktxWvjgJr2iUQEcqp8V +nAfkf/OGq5bV3QAg7cFI3n0lIYP7bx15V8t43IFKdZPi02qSP+yr1jlXjVLuUDzU +LpFpiBDBiLo2H8XCOb9yPNoZIamCwoLPAcVrW6s7DVUj5rDx1zEnWmD2YcZXg2TO +NYMUh+bqU6gZcE8vj6JwVHxQTNsqrQvRhcywicpxInvqXJBgXFdOnQNElq6b9g+w +ySYiFhP4Aa9ngOId972IsuACQUnmujNBkvwi0S900lQWqGqN4OJC+x5AJLwmtR0Y +reRUyyW6/kXWTOJfR6JEskHqw1EcgeHUfZuL/Fgjr4HGd/1trdkbPOtTV3oLiUlO +f/TElD1ir6LeJOPZDxdDcMkamRUpwyJhCjbm7TozNP9JwFO1bXmOa9IAEWh2vxQP +u0U8tqk/daNK7TSslfce4e/3fYDFD77lqiZq3y5iy4I05bdIkA0EfbaF1V5X70QG +PFJVbJNvj3gMCir3lluQ9WXIlGIE1eLaH0/cUU+Elr5keDHSM5jwkdkr411Z4viw +7x8bo4B75MiUd9mRXSD2cdK8a0PtmLKhLhlLV38uiYAep1JpkyJYXwtLLwhG+WOk +ApQnEdi7/uWJSgsZBtYvu+0o +=LJin +-----END PGP SIGNATURE----- diff --git a/website/static/security/patches/SA-26:47/linux.patch b/website/static/security/patches/SA-26:47/linux.patch new file mode 100644 index 0000000000..2f99cc0884 --- /dev/null +++ b/website/static/security/patches/SA-26:47/linux.patch @@ -0,0 +1,10 @@ +--- sys/compat/linux/linux_misc.c.orig ++++ sys/compat/linux/linux_misc.c +@@ -749,6 +749,7 @@ + error = linux_copyout_rusage(&wru.wru_self, rup); + if (error == 0 && infop != NULL && td->td_retval[0] != 0) { + sig = bsd_to_linux_signal(siginfo.si_signo); ++ memset(&lsi, 0, sizeof(lsi)); + siginfo_to_lsiginfo(&siginfo, &lsi, sig); + error = copyout(&lsi, infop, sizeof(lsi)); + } diff --git a/website/static/security/patches/SA-26:47/linux.patch.asc b/website/static/security/patches/SA-26:47/linux.patch.asc new file mode 100644 index 0000000000..d26b4c5a7d --- /dev/null +++ b/website/static/security/patches/SA-26:47/linux.patch.asc @@ -0,0 +1,17 @@ +-----BEGIN PGP SIGNATURE----- + +iQJPBAABCgA5FiEEthUnfoEIffdcgYM7bljekB8AGu8FAmpEElUbFIAAAAAABAAO +bWFudTIsMi41KzEuMTIsMCwzAAoJEG5Y3pAfABrvOskP/3FyeVcGuaNn0PRITQ9e +D9iu8Xuy2+ZLtTkOvnrNgO/NAs6/DlX/yTrEsGH2OUY1n5z/WSxgZxl7Qsy7Wacc +Bx6+U6lb1kGV4nM2FNutbxztO3wrr80QPGgm6NOcJHkJvlWQGER9I6bkx3rm3Rwr +arKbsY0QDro3Dr3OS3vLusS8PJk5NCsxGUn3Pu+1p2wl6LCVn6cJ/K37EhsYkbaz +gziTJ81/SHoolFAVn0xaGJh3+ax4jQCN2hmwDoSZPClXL8LvoPJuj0IymWec87rn +enfVQP++OrEq0rq1yGXkZYJQdE96NOEacuCtHzE0jF8AD9bvmYUWqgmh8MHys4BW +FTdkOGXfoXlZ1Y5In+DmTQwmGtgZdQcEygUMwVz4MVMIzYXhKFsBMtxXYKETmKM4 +L6w/uYuKz8+fUWP6+zM0CM2sxTRHcnN8dRmXcIvEUsC+w6RkINjijPj8PKHTCn5K +cU6GCsnjETDIrFsDSH6w6sSA5DlmjSzV9ss9Ljy8WTTJQRp+kOncjLqZgPFG6fsb +07yvotlqSLoswypuwjhfuqY0ycLlQ+5qMOoxQPfGEYkKp008hvVsjZwikc9xLiXw +dyExTKuZmfuSeH4XX90ppOaveWzHm6riGohVR6oPqDexqUxQN+W7AGONiqxxMI98 +zm3KR9Jfc6qRbNgxLvyRGeNx +=FLrk +-----END PGP SIGNATURE----- diff --git a/website/static/security/patches/SA-26:48/compat32.patch b/website/static/security/patches/SA-26:48/compat32.patch new file mode 100644 index 0000000000..990c7da498 --- /dev/null +++ b/website/static/security/patches/SA-26:48/compat32.patch @@ -0,0 +1,11 @@ +--- sys/compat/freebsd32/freebsd32_misc.c.orig ++++ sys/compat/freebsd32/freebsd32_misc.c +@@ -765,7 +765,7 @@ + freebsd32_kevent_copyout(void *arg, struct kevent *kevp, int count) + { + struct freebsd32_kevent_args *uap; +- struct kevent32 ks32[KQ_NEVENTS]; ++ struct kevent32 ks32[KQ_NEVENTS] = {}; + int i, error; + + KASSERT(count <= KQ_NEVENTS, ("count (%d) > KQ_NEVENTS", count)); diff --git a/website/static/security/patches/SA-26:48/compat32.patch.asc b/website/static/security/patches/SA-26:48/compat32.patch.asc new file mode 100644 index 0000000000..9d3680e9e0 --- /dev/null +++ b/website/static/security/patches/SA-26:48/compat32.patch.asc @@ -0,0 +1,17 @@ +-----BEGIN PGP SIGNATURE----- + +iQJPBAABCgA5FiEEthUnfoEIffdcgYM7bljekB8AGu8FAmpEElgbFIAAAAAABAAO +bWFudTIsMi41KzEuMTIsMCwzAAoJEG5Y3pAfABrvyKMP+wR619wEaxpAFPveKjqZ +WSZRo+x0jOi1lP3HTRGlIwBO7oDAavkcWjTeRglkLqeTp9qtUj2KpZxWRxtgbMK3 +/YqynjCJuKmBhwNmK7wOU0EVdy7ZiijH6Op7+XLPu4GDRlUheJb92q2BzxHBU543 +p5YUPIGepDHf4ZPQv7jUQhHLBb7ZTzGMWigIIpoWiK9AI/lDit+Fi/mmn8/OhXgD +h2jFcxp54kRBOnw3yQyE3Ixi6viW0h0UCAeUaDlC/afhPrv2fF3al0OUZZKfDBOs +pJowbY0C3qmfvWPkevrqpLkk5DPD/GQ0gvqPPbDVen2fdxnU2pJgx8AE9YWvOsD9 +dbXygfIRBd+zLr76oLWGuGU9hjXTjC6iXC++fXtKvDHLuHLr+9d0zmO9zkDi6Y6E +apwL7L2ZZgdMe4acZd173h0O4mRZ2Q7k1LXew2nvEOoPe9WaiF7ERCl34SZdWg9Z +ZDoKOvh45S0Kyd8ehJWmABrpgo5kGOMWSDNe9a+sWo/hD5/S5Ot+O7+qj/MyJdfu +VgQInG20817QoOoZZqbOOmOJ6ia6tTzJq1THLRio0zrdVlE5+r2wa+pXE9B8OlWT ++TRT+JTBbgCLhsfLm/jUmwwL3n26EKCwst3+dhF3JnkcviequzWHn9n+h3AXimz2 +W2mjccqS3/By80cfxDtiPzHq +=4tgE +-----END PGP SIGNATURE----- diff --git a/website/static/security/patches/SA-26:49/iconv.patch b/website/static/security/patches/SA-26:49/iconv.patch new file mode 100644 index 0000000000..540cabc306 --- /dev/null +++ b/website/static/security/patches/SA-26:49/iconv.patch @@ -0,0 +1,532 @@ +--- /dev/null ++++ contrib/netbsd-tests/lib/libc/locale/t_iconv.c +@@ -0,0 +1,375 @@ ++/* $NetBSD$ */ ++ ++/*- ++ * Copyright (c) 2025 The NetBSD Foundation, Inc. ++ * All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * 1. Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * 2. Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in the ++ * documentation and/or other materials provided with the distribution. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS ++ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ++ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR ++ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS ++ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR ++ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF ++ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS ++ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN ++ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ++ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ++ * POSSIBILITY OF SUCH DAMAGE. ++ */ ++ ++/* ++ * iconv(3) ++ */ ++ ++#include ++__RCSID("$NetBSD: t_mbrtoc8.c,v 1.3 2024/08/20 17:43:09 riastradh Exp $"); ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "h_macros.h" ++ ++static const struct sample { ++ const char *src_codeset; ++ size_t nsrc; ++ const char *src; ++ const char *dst_codeset; ++ size_t ndst; ++ const char *dst; ++ size_t ninval; ++ size_t ninval_rev; ++ const char *xfail; ++#define IRREVERSIBLE ((size_t)-1) ++} samples[] = { ++ [0] = { "us-ascii", 6, "hello", ++ "us-ascii", 6, "hello", ++ 0, 0, NULL }, ++ /* LATIN SMALL LETTER E WITH ACUTE ACCENT */ ++ [1] = { "iso-8859-1", 1, (const char[1]){0xe9}, ++ "UTF-8", 2, (const char[2]){0xc3,0xa9}, ++ 0, 0, NULL }, ++ /* LEFT CURLY BRACKET */ ++ [2] = { "UTF-8", 2, (const char[2]){0x00,0x7b}, ++ "ZW", 6, (const char[6]){0x00,0x7a,0x57,0x20,0x7b,0x0a}, ++ 0, 0, NULL }, ++ /* LATIN SMALL LETTER O, TILDE */ ++ [3] = { "UTF-8", 2, (const char[2]){0x4f,0x7e}, ++ "VIQR", 3, (const char[3]){0x4f,0x5c,0x7e}, ++ 0, 0, NULL }, ++ /* LEFT CURLY BRACKET (optionally encoded in UTF-7) */ ++ [4] = { "UTF-7", 1, (const char[1]){0x7b}, ++ "UTF-8", 1, (const char[1]){0x7b}, ++ 0, IRREVERSIBLE, NULL }, ++ [5] = { "UTF-7", 4, "+AHs-", ++ "UTF-8", 1, (const char[1]){0x7b}, ++ 0, 0, NULL }, ++ /* éclair */ ++ [6] = { "UTF-7", 10, "+AOk-clair", ++ "UTF-8", 7, (const char[7]){ ++ 0xc3,0xa9,0x63,0x6c,0x61,0x69,0x72, ++ }, ++ 0, 0, NULL }, ++ [7] = { "HZ", 55, /* RFC 1843, Sec. 4, Example 1 */ ++ "The next sentence is in GB.~{<:Ky2;S{#,NpJ)l6HK!#~}Bye.", ++ "UTF-8", 61, (const char[61]) { ++ 0x54,0x68,0x65,0x20, 0x6e,0x65,0x78,0x74, ++ 0x20,0x73,0x65,0x6e, 0x74,0x65,0x6e,0x63, ++ 0x65,0x20,0x69,0x73, 0x20,0x69,0x6e,0x20, ++ 0x47,0x42,0x2e,0xe5, 0xb7,0xb1,0xe6,0x89, ++ 0x80,0xe4,0xb8,0x8d, 0xe6,0xac,0xb2,0xef, ++ 0xbc,0x8c,0xe5,0x8b, 0xbf,0xe6,0x96,0xbd, ++ 0xe6,0x96,0xbc,0xe4, 0xba,0xba,0xe3,0x80, ++ 0x82,0x42,0x79,0x65, 0x2e ++ }, ++ 0, 0, NULL }, ++ /* Same as above but with HZ8 instead of HZ. */ ++ [8] = { "HZ8", 55, (const char[55]) { ++ 0x54,0x68,0x65,0x20,0x6e,0x65,0x78,0x74, ++ 0x20,0x73,0x65,0x6e,0x74,0x65,0x6e,0x63, ++ 0x65,0x20,0x69,0x73,0x20,0x69,0x6e,0x20, ++ 0x47,0x42,0x2e,0x7e,0x7b,0xbc,0xba,0xcb, ++ 0xf9,0xb2,0xbb,0xd3,0xfb,0xa3,0xac,0xce, ++ 0xf0,0xca,0xa9,0xec,0xb6,0xc8,0xcb,0xa1, ++ 0xa3,0x7e,0x7d,0x42,0x79,0x65,0x2e ++ }, ++ "UTF-8", 61, (const char[61]) { ++ 0x54,0x68,0x65,0x20, 0x6e,0x65,0x78,0x74, ++ 0x20,0x73,0x65,0x6e, 0x74,0x65,0x6e,0x63, ++ 0x65,0x20,0x69,0x73, 0x20,0x69,0x6e,0x20, ++ 0x47,0x42,0x2e,0xe5, 0xb7,0xb1,0xe6,0x89, ++ 0x80,0xe4,0xb8,0x8d, 0xe6,0xac,0xb2,0xef, ++ 0xbc,0x8c,0xe5,0x8b, 0xbf,0xe6,0x96,0xbd, ++ 0xe6,0x96,0xbc,0xe4, 0xba,0xba,0xe3,0x80, ++ 0x82,0x42,0x79,0x65, 0x2e ++ }, ++ 0, 0, NULL }, ++ /* 馬 from CNS 11643-1 */ ++ [9] = { "UTF-8", 3, (const char[3]){0xe9,0xa6,0xac}, ++ "ISO-2022-CN", 8, ++ (const char[8]){0x1b,0x24,0x29,0x47,0x0e,0x58,0x6b,0x0f}, ++ 0, 0, NULL }, ++ /* 馬毦 shifting from CNS 11643-1 to CNS 11643-2 */ ++ [10] = { "UTF-8", 6, (const char[6]){0xe9,0xa6,0xac,0xe6,0xaf,0xa6}, ++ "ISO-2022-CN", 16, ++ (const char[16]){ ++ /* ESC $ ) G (shift G1 to CNS 11643 plane 1) */ ++ 0x1b,0x24,0x29,0x47, ++ 0x0e, /* GL is G1 from now on */ ++ 0x58,0x6b, /* 馬 */ ++ /* ESC $ * H (shift G2 to CNS 11643 plane 2) */ ++ 0x1b,0x24,0x2a,0x48, ++ 0x1b,0x4e, /* GL is G2 for next char */ ++ 0x30,0x21, /* 毦 */ ++ 0x0f, /* GL is G0 from now on */ ++ }, ++ 0, 0, "PR lib/59019: various iconv issues ([case 10: ISO-2022-CN to UTF-8 14/6] iconv: Illegal byte sequence (85))" }, ++}; ++ ++#ifdef MIN ++#undef MIN ++#endif ++#define MIN(x, y) ((x) < (y) ? (x) : (y)) ++ ++static void ++test_sample_bounded(const char *title, const struct sample *S, ++ size_t nsrc, size_t ndst) ++{ ++ char inbuf[4096], inguard = arc4random(); ++ char outbuf[4096], outguard = arc4random(); ++ iconv_t C; ++ char *src0, *src, *dst0, *dst; ++ size_t srcleft0, srcleft, dstleft0, dstleft; ++ size_t ninval; ++ int error; ++ ++ ATF_REQUIRE_MSG(S->nsrc < sizeof(inbuf) - 2, "[%s]", title); ++ ATF_REQUIRE_MSG(S->ndst < sizeof(outbuf) - 2, "[%s]", title); ++ ++ memset(inbuf, inguard, sizeof(inbuf)); ++ memset(outbuf, outguard, sizeof(outbuf)); ++ src = src0 = inbuf + 1; ++ memcpy(src, S->src, nsrc); ++ dst = dst0 = outbuf + 1; ++ srcleft = srcleft0 = nsrc; ++ dstleft = dstleft0 = ndst; ++ ++ C = iconv_open(S->dst_codeset, S->src_codeset); ++ if (C == (iconv_t)-1) { ++ error = errno; ++ atf_tc_fail_nonfatal("[%s] iconv_open: %s (%d)", title, ++ strerror(error), error); ++ return; ++ } ++ ++ ninval = iconv(C, &src, &srcleft, &dst, &dstleft); ++ if (ninval == (size_t)-1) { ++ error = errno; ++ /* ++ * Incomplete input manifests as EINVAL -- ignore that, ++ * unless we're trying the full-size input. ++ * ++ * Truncated output manifests as E2BIG -- ignore that, ++ * unless we're trying the full-size output. ++ */ ++ if ((error != EINVAL || nsrc == S->nsrc) && ++ (error != E2BIG || ndst == S->ndst)) { ++ atf_tc_fail_nonfatal("[%s] iconv: %s (%d)", ++ title, strerror(error), error); ++ goto next; ++ } ++ } else if (ninval != S->ninval) { ++ error = errno; ++ atf_tc_fail_nonfatal("[%s] iconv:" ++ " %zu invalid, expected %zu", ++ title, ninval, S->ninval); ++ } ++ ++ ATF_CHECK_MSG(src0 <= src && src <= src0 + srcleft0, "[%s] iconv:" ++ " src went from %p to %p, expected [%p,%p]", ++ title, src0, src, src0, src0 + srcleft0); ++ ATF_CHECK_MSG(srcleft <= srcleft0, "[%s] iconv:" ++ " srcleft went from %zu to %zu", ++ title, srcleft0, srcleft); ++ ATF_CHECK_MSG(dst0 <= dst && dst <= dst0 + dstleft0, "[%s] iconv:" ++ " dst went from %p to %p, expected [%p,%p]", ++ title, dst0, dst, dst0, dst0 + dstleft0); ++ ATF_CHECK_MSG(dstleft <= dstleft0, "[%s] iconv:" ++ " dstleft went from %zu to %zu", ++ title, dstleft0, dstleft); ++ if (memcmp(dst0, S->dst, MIN(ndst, dstleft0 - dstleft)) != 0) { ++ size_t k; ++ ++ atf_tc_fail_nonfatal("[%s] iconv: bad conv", title); ++ fprintf(stderr, "[%s] input: ", title); ++ for (k = 0; k < nsrc; k++) ++ fprintf(stderr, " %02x", (unsigned char)S->src[k]); ++ fprintf(stderr, "\n"); ++ fprintf(stderr, "[%s] expected: ", title); ++ for (k = 0; k < ndst; k++) ++ fprintf(stderr, " %02x", (unsigned char)S->dst[k]); ++ fprintf(stderr, "\n"); ++ fprintf(stderr, "[%s] got: ", title); ++ for (k = 0; k < ndst; k++) ++ fprintf(stderr, " %02x", (unsigned char)dst0[k]); ++ fprintf(stderr, "\n"); ++ } ++ ++next: if (dst0[-1] != outguard) { ++ atf_tc_fail_nonfatal("[%s] iconv overran before buffer:" ++ " dst0[-1] = 0x%02x, expected 0x%02x", ++ title, dst0[-1], outguard); ++ } ++ if (dst0[ndst] != outguard) { ++ atf_tc_fail_nonfatal("[%s] iconv overran after buffer:" ++ " dst0[ndst=%zu] = 0x%02x, expected 0x%02x", ++ title, ndst, dst0[ndst], outguard); ++ } ++ if (dst[0] != outguard) { ++ atf_tc_fail_nonfatal("[%s] iconv overran past updated dst:" ++ " dst[0] = 0x%02x, expected 0x%02x", ++ title, dst[0], outguard); ++ } ++ ++ if (iconv_close(C) == -1) { ++ error = errno; ++ atf_tc_fail_nonfatal("[%s] iconv_close: %s (%d)", ++ title, strerror(error), error); ++ } ++} ++ ++static void ++test_sample(const char *title, const struct sample *S) ++{ ++ char buf[128]; ++ size_t nsrc, ndst; ++ ++ fprintf(stderr, "test %s from %s to %s\n", ++ title, S->src_codeset, S->dst_codeset); ++ ++ for (nsrc = 0; nsrc <= S->nsrc; nsrc++) { ++ snprintf(buf, sizeof(buf), "%s %zu/%zu", title, nsrc, S->ndst); ++ test_sample_bounded(buf, S, nsrc, S->ndst); ++ } ++ ++ for (ndst = 0; ndst <= S->ndst; ndst++) { ++ snprintf(buf, sizeof(buf), "%s %zu/%zu", title, S->nsrc, ndst); ++ test_sample_bounded(buf, S, S->nsrc, ndst); ++ } ++} ++ ++ATF_TC(iconv_samples); ++ATF_TC_HEAD(iconv_samples, tc) ++{ ++ ++ atf_tc_set_md_var(tc, "descr", "Test iconv on various fixed samples"); ++} ++ATF_TC_BODY(iconv_samples, tc) ++{ ++ unsigned i; ++ ++ for (i = 0; i < __arraycount(samples); i++) { ++ const struct sample *S = &samples[i]; ++ struct sample reverse = { ++ .src_codeset = S->dst_codeset, ++ .dst_codeset = S->src_codeset, ++ .nsrc = S->ndst, ++ .src = S->dst, ++ .ndst = S->nsrc, ++ .dst = S->src, ++ .ninval = S->ninval_rev, ++ }; ++ char buf[128]; ++ ++ if (S->xfail) ++ atf_tc_expect_fail("%s", S->xfail); ++ ++ snprintf(buf, sizeof(buf), "case %u: %s to %s", i, ++ S->src_codeset, S->dst_codeset); ++ test_sample(buf, S); ++ if (S->ninval_rev != IRREVERSIBLE) { ++ snprintf(buf, sizeof(buf), "case %u: %s to %s", i, ++ S->dst_codeset, S->src_codeset); ++ test_sample(buf, &reverse); ++ } ++ ++ if (S->xfail) ++ atf_tc_expect_pass(); ++ } ++} ++ ++ATF_TC(iconv_pr59019_hz8); ++ATF_TC_HEAD(iconv_pr59019_hz8, tc) ++{ ++ ++ atf_tc_set_md_var(tc, "descr", "Truncated HZ8 input from PR 59019"); ++} ++ATF_TC_BODY(iconv_pr59019_hz8, tc) ++{ ++ const char title[] = "iconv_pr59019_hz8"; ++ char in[4] = "\x7e\x7b\x7e\x7e"; /* ~{~~ */ ++ char out[4096], guard = arc4random(); ++ char *src0, *src, *dst0, *dst; ++ size_t srcleft0, srcleft, dstleft0, dstleft; ++ iconv_t C; ++ size_t ninval; ++ ++ memset(out, guard, sizeof(out)); ++ ++ REQUIRE_LIBC((C = iconv_open(/*to*/"UTF-8", /*from*/"HZ8")), ++ (iconv_t)-1); ++ ++ src = src0 = in; ++ srcleft = srcleft0 = sizeof(in); ++ dst = dst0 = out + 1; ++ dstleft = dstleft0 = sizeof(out) - 2; ++ ++ ninval = iconv(C, &src, &srcleft, &dst, &dstleft); ++ ++ /* ++ * XXX Not actually 100% sure this is the correct result -- I ++ * can't find a reference for the HZ8 encoding. ++ */ ++ ATF_CHECK_EQ_MSG(ninval, (size_t)-1, "[%s] iconv: ninval=%zu", title, ++ ninval); ++ ++ ATF_CHECK_MSG(src0 <= src && src <= src0 + srcleft0, "[%s] iconv:" ++ " src went from %p to %p, expected [%p,%p)", ++ title, src0, src, src0, src0 + srcleft0); ++ ATF_CHECK_MSG(srcleft <= srcleft0, "[%s] iconv:" ++ " srcleft went from %zu to %zu", ++ title, srcleft0, srcleft); ++ ATF_CHECK_MSG(dst0 <= dst && dst <= dst0 + dstleft0, "[%s] iconv:" ++ " dst went from %p to %p, expected [%p,%p)", ++ title, dst0, dst, dst0, dst0 + dstleft0); ++ ATF_CHECK_MSG(dstleft <= dstleft0, "[%s] iconv:" ++ " dstleft went from %zu to %zu", ++ title, dstleft0, dstleft); ++ ++ ATF_CHECK_EQ(dst0[-1], guard); ++ ATF_CHECK_EQ(dst0[dstleft0], guard); ++ ++ RL(iconv_close(C)); ++} ++ ++ATF_TP_ADD_TCS(tp) ++{ ++ ++ ATF_TP_ADD_TC(tp, iconv_pr59019_hz8); ++ ATF_TP_ADD_TC(tp, iconv_samples); ++ ++ return atf_no_error(); ++} +--- lib/libc/tests/locale/Makefile.orig ++++ lib/libc/tests/locale/Makefile +@@ -21,6 +21,7 @@ + + # Note: io_test requires zh_TW.Big5 locale (see ^/head@r315568) + #NETBSD_ATF_TESTS_C= io_test ++NETBSD_ATF_TESTS_C+= iconv_test + NETBSD_ATF_TESTS_C+= mbrtowc_test + NETBSD_ATF_TESTS_C+= mbstowcs_test + NETBSD_ATF_TESTS_C+= mbsnrtowcs_test +--- lib/libiconv_modules/HZ/citrus_hz.c.orig ++++ lib/libiconv_modules/HZ/citrus_hz.c +@@ -132,7 +132,7 @@ + typedef struct { + escape_t *inuse; + int chlen; +- char ch[ROWCOL_MAX]; ++ char ch[4 + ROWCOL_MAX]; + } _HZState; + + #define _CEI_TO_EI(_cei_) (&(_cei_)->ei) +@@ -262,6 +262,8 @@ + tail = psenc->chlen = 0; + continue; + } ++ if (graphic == NULL) ++ break; + } else if (ch & 0x80) { + if (graphic != GR(psenc->inuse)) + break; +--- lib/libiconv_modules/ISO2022/citrus_iso2022.c.orig ++++ lib/libiconv_modules/ISO2022/citrus_iso2022.c +@@ -129,7 +129,7 @@ + #define _FUNCNAME(m) _citrus_ISO2022_##m + #define _ENCODING_INFO _ISO2022EncodingInfo + #define _ENCODING_STATE _ISO2022State +-#define _ENCODING_MB_CUR_MAX(_ei_) MB_LEN_MAX ++#define _ENCODING_MB_CUR_MAX(_ei_) 10 + #define _ENCODING_IS_STATE_DEPENDENT 1 + #define _STATE_NEEDS_EXPLICIT_INIT(_ps_) \ + (!((_ps_)->flags & _ISO2022STATE_FLAG_INITIALIZED)) +@@ -1012,7 +1012,7 @@ + { + _ISO2022Charset cs; + char *p; +- char tmp[MB_LEN_MAX]; ++ char tmp[10]; + size_t len; + int bit8, i = 0, target; + unsigned char mask; +@@ -1177,7 +1177,7 @@ + size_t * __restrict nresult) + { + char *result; +- char buf[MB_LEN_MAX]; ++ char buf[10]; + size_t len; + int ret; + +@@ -1206,7 +1206,7 @@ + _ISO2022State * __restrict psenc, size_t * __restrict nresult) + { + char *result; +- char buf[MB_LEN_MAX]; ++ char buf[10]; + size_t len; + int ret; + +--- lib/libiconv_modules/UTF7/citrus_utf7.c.orig ++++ lib/libiconv_modules/UTF7/citrus_utf7.c +@@ -296,7 +296,7 @@ + + static int + _citrus_UTF7_utf16tomb(_UTF7EncodingInfo * __restrict ei, +- char * __restrict s, size_t n __unused, uint16_t u16, ++ char * __restrict s, size_t n, uint16_t u16, + _UTF7State * __restrict psenc, size_t * __restrict nresult) + { + int bits, i; +@@ -336,6 +336,8 @@ + psenc->ch[psenc->chlen++] = base64[i]; + } + } ++ if (n < (size_t)psenc->chlen) ++ return (E2BIG); + memcpy(s, psenc->ch, psenc->chlen); + *nresult = psenc->chlen; + psenc->chlen = 0; +@@ -352,6 +354,8 @@ + uint16_t u16[2]; + int err, i, len; + size_t nr, siz; ++ char buf[8], *bufp = buf; ++ _UTF7State psenc_save = *psenc; + + u32 = (uint32_t)wchar; + if (u32 <= UTF16_MAX) { +@@ -367,14 +371,20 @@ + return (EILSEQ); + } + siz = 0; ++ if (n > sizeof(buf)) ++ n = sizeof(buf); + for (i = 0; i < len; ++i) { +- err = _citrus_UTF7_utf16tomb(ei, s, n, u16[i], psenc, &nr); +- if (err != 0) +- return (err); /* XXX: state has been modified */ +- s += nr; ++ err = _citrus_UTF7_utf16tomb(ei, bufp, n, u16[i], psenc, &nr); ++ if (err != 0) { ++ *nresult = (size_t)-1; ++ *psenc = psenc_save; /* restore state */ ++ return (err); ++ } ++ bufp += nr; + n -= nr; + siz += nr; + } ++ memcpy(s, buf, siz); + *nresult = siz; + + return (0); +--- lib/libiconv_modules/VIQR/citrus_viqr.c.orig ++++ lib/libiconv_modules/VIQR/citrus_viqr.c +@@ -323,7 +323,11 @@ + int ch = 0; + + switch (psenc->chlen) { +- case 0: case 1: ++ case 0: ++ break; ++ case 1: ++ if (n-- < 1) ++ goto e2big; + break; + default: + return (EINVAL); +--- lib/libiconv_modules/ZW/citrus_zw.c.orig ++++ lib/libiconv_modules/ZW/citrus_zw.c +@@ -263,9 +263,12 @@ + ch = (unsigned char)wc; + switch (psenc->charset) { + case NONE: +- if (ch == '\0' || ch == '\n') ++ if (ch == '\0' || ch == '\n') { ++ if (n < 1) ++ return (E2BIG); ++ n -= 1; + psenc->ch[psenc->chlen++] = ch; +- else { ++ } else { + if (n < 4) + return (E2BIG); + n -= 4; diff --git a/website/static/security/patches/SA-26:49/iconv.patch.asc b/website/static/security/patches/SA-26:49/iconv.patch.asc new file mode 100644 index 0000000000..7109c118d8 --- /dev/null +++ b/website/static/security/patches/SA-26:49/iconv.patch.asc @@ -0,0 +1,17 @@ +-----BEGIN PGP SIGNATURE----- + +iQJPBAABCgA5FiEEthUnfoEIffdcgYM7bljekB8AGu8FAmpEElobFIAAAAAABAAO +bWFudTIsMi41KzEuMTIsMCwzAAoJEG5Y3pAfABrvF84P/1Xc7khiZZquDwUpOb7G +nLSjX7guNeTpw7LgOVQpLfpqfkAU83n7u+u627I8yjxCRz7flzfaUk+B+mslj6xF +qrwW8Oip8oDFN2kK48ODMM9iPNhUWdqZWP9bl/4j6pl1ftX9qOlLzlZ80eqIr5lm +gOdKj8VOyvXz+T2z/Pta74P76qAfpFek5XfAkYdPVGYVs8FPanOsabD8vLviAIl7 +W8eX8VJWYQ6qhxg+uV86kkONSkIMPN6FakcXTY2p3a4qYKMyqDb8geV6PYVMDula +Gfc7i4C0+IpQiSf+kda+jliw5H69igNnwMEQf0xREHioHzJj3BMfOGu2X4EQmxfR +yoG3Zor1xKwuQRJMPpOI2FkjWI1Ctp2ueOYsNWji+weCd8BJB2q1l3gxUCQ1ZPlF +fJci1FAAx7v8AhMQDXOaJax413dbXyqMtdY19Ufoyxzp5ctfChH60paUjmInN7Xj +8ULeWY/fuy425S5TVyZ6dU9GCMttNMy0skHD10dPPQH/KqJ3ZW2KUej8ZlWMwdEo +4W0WkzQYrsDqEbh7zAWTtVf5LzXR/HI1yPMmHBAycczuSPu9G2L34EP3FJGVSDpN +hKDQn5ycREFFjg74syrkGEVwx9qTPaz+fAFew1XNf1Gi0t3K97k1FFNiZBUC9XL8 +W7XK27PkZySz+Q9GyYEGqwF5 +=Zbm1 +-----END PGP SIGNATURE-----