diff --git a/website/static/security/advisories/FreeBSD-EN-26:20.microcode.asc b/website/static/security/advisories/FreeBSD-EN-26:20.microcode.asc
index 1720320815..c5ad40f0bf 100644
--- a/website/static/security/advisories/FreeBSD-EN-26:20.microcode.asc
+++ b/website/static/security/advisories/FreeBSD-EN-26:20.microcode.asc
@@ -1,202 +1,213 @@
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA512
=============================================================================
FreeBSD-EN-26:20.microcode Errata Notice
The FreeBSD Project
Topic: Early loading of Intel CPU microcode fails for some CPUs
Category: core
Module: ucode
Announced: 2026-08-25
Affects: All supported versions of FreeBSD.
Corrected: 2026-06-15 18:01:43 UTC (stable/15, 15.1-STABLE)
2026-08-25 16:01:16 UTC (releng/15.1, 15.1-RELEASE-p3)
2026-08-25 16:00:56 UTC (releng/15.0, 15.0-RELEASE-p13)
2026-07-14 14:56:07 UTC (stable/14, 14.4-STABLE)
2026-08-25 16:00:22 UTC (releng/14.4, 14.4-RELEASE-p9)
For general information regarding FreeBSD Errata Notices and Security
Advisories, including descriptions of the fields above, security
branches, and the following sections, please visit
.
+0. Revision History
+
+v1.0 - 2026-08-25 -- Initial revision
+v1.1 - 2026-08-27 -- Split patches for 15.x and 14.x due to missed commit
+
I. Background
Modern x86 CPUs support updates to their microcode. FreeBSD can apply these
updates in two ways: "early loading," performed by the kernel during boot
before CPU feature detection, and "late loading," performed after boot by
cpucontrol(8) or the microcode_update rc(8) service.
An Intel microcode distribution file may describe the CPUs an update applies
to using a primary signature in the image header and, optionally, an extended
signature table listing additional matching signatures.
II. Problem Description
The kernel's early-loading matcher, ucode_intel_match() in
sys/x86/x86/ucode.c, contained an inverted bounds check that caused the
extended signature table to always be treated as absent. Consequently, a CPU
whose matching signature+platform pair appears only in an image's extended
signature table was never matched during early loading, and its microcode
update was not applied. The kernel reports "CPU microcode: no matching
update found" in this case.
Late loading via cpucontrol(8) is not affected. There, the userland matcher
parses extended signature tables correctly.
III. Impact
On affected Intel CPUs, early loading applies no microcode update even when a
suitable update is present in the loaded file. Such systems run with only
the microcode installed by the system firmware (BIOS/UEFI), which may be
older than the packaged update and may lack functional or security-related
errata fixes. At the time of writing, 19 CPU signatures / 58
signature+platform combinations in the packaged Intel microcode are affected,
spanning various Alder Lake, Raptor Lake, Sapphire Rapids, and Emerald Rapids
steppings, as well as some newer Intel Core Ultra client processors.
To determine whether your system is affected, run the following commands as
root:
# kldload -n cpuctl
# cpucontrol -i 0x01 /dev/cpuctl0
If the first hexadecimal value (the CPUID signature) appears in the
following list, the system is affected by the bug.
0x000806f4
0x000806f5
0x000806f6
0x000806f7
0x00090675
0x000906a4
0x000b0674
0x000b06a3
0x000b06a8
0x000b06f2
0x000b06f5
0x000b06f6
0x000b06f7
0x000c0652
0x000c0664
0x000c06a2
0x000c06c2
0x000c06c3
0x000c06f1
Note, for signature 0x000906a4, only systems with platform ID 7 are
affected. These report 0x001c0000 as the first value in the output of
"cpucontrol -m 0x17 /dev/cpuctl0".
Systems whose CPU signature matches an image's primary header, and all
AMD systems, are unaffected.
IV. Workaround
Use late loading instead of, or in addition to, early loading. Install both
sysutils/cpu-microcode-intel and sysutils/cpu-microcode-rc and enable the
service:
# sysrc microcode_update_enable="YES"
# service microcode_update start
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:20/microcode.patch
-# fetch https://security.FreeBSD.org/patches/EN-26:20/microcode.patch.asc
-# gpg --verify microcode.patch.asc
+[FreeBSD 15.x]
+# fetch https://security.FreeBSD.org/patches/EN-26:20/microcode-15.patch
+# fetch https://security.FreeBSD.org/patches/EN-26:20/microcode-15.patch.asc
+# gpg --verify microcode-15.patch.asc
+
+[FreeBSD 14.x]
+# fetch https://security.FreeBSD.org/patches/EN-26:20/microcode-14.patch
+# fetch https://security.FreeBSD.org/patches/EN-26:20/microcode-14.patch.asc
+# gpg --verify microcode-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/ 2a1eaaf331f7 stable/15-n283974
releng/15.1/ a0e96483e2ce releng/15.1-n283597
releng/15.0/ 4a66af1ce037 releng/15.0-n281100
stable/14/ 38cbd2588f0b stable/14-n274496
releng/14.4/ c905b341204e releng/14.4-n273756
- -------------------------------------------------------------------------
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-----
-iQJPBAEBCgA5FiEEthUnfoEIffdcgYM7bljekB8AGu8FAmqN3XAbFIAAAAAABAAO
-bWFudTIsMi41KzEuMTIsMCwzAAoJEG5Y3pAfABrvse4P/isqmBRUFLLUnVFS/AD7
-Wlg20e54L4CRORCqhL1p33WdcKs6bHg7Tgvutwy23HmX9ISrOanm5WkFq2qN16qc
-olNJDvlXHLeIseDH6WQrxWiBooYqqJpLOJyolqB+R0TIGRvRMidbdM24gHyOCWST
-MvraPYkqkQH9DSO1CYUHoLTcVLek/l9ux1p2WApHSqOw7GPcltiYUnyvKrOqBxYs
-DD4n0GIw0JfsXK1L9MLXJILjROUpItDHnv1CsG8VVaWQI0c+5826dTVoFsDQ1RUc
-mcIiBiWP/gmKxl48wzjq9qZccGN2vHMLrFYA0Zu/syqpB2g5b0zQbm9iKIak+YIJ
-mKHTUGAZ0YJpQAXf8f1q+pED91Veh9k0fIvnSwsDa2dfgk2XMfZeWIyHbddxS0p6
-fvnCroT4sMvequ2wpC64jpebASmwjiZYYY9gPk2TdgOlu83PnYUkMbT4gv5RHgIo
-qwK7WQ2bDO3GaRHGQ3Zfo/Dl97bGg6KDDZZEbFOBv9hWu2bKgmLMvo2HtgKGGLDa
-UBGypDYWC0abbtbaqTBFtJsvUbcpf6llG/lJT6YaipVrqBjLyNFJhETS1zNIQQSr
-Y8pvUc+tsqlLmrI4AaqcvIwC0OY6ATppQ49ZMpujaDf3nj9wG9vw6d1l12kIWjEE
-0XE3NnDLvAne7G2cC+ktwGzB
-=KmJ4
+iQJPBAEBCgA5FiEEthUnfoEIffdcgYM7bljekB8AGu8FAmqQiB0bFIAAAAAABAAO
+bWFudTIsMi41KzEuMTIsMCwzAAoJEG5Y3pAfABrvqg8P+wSA96Z9Lx3voJpcGcWf
+DQG8AB/17xx8vU6Vvc4yEGUnVlglEIPKbpMQxVBirF+HDOYvkjTcmRF4NDQUz04T
+5zcZiRVbc06k1+U+guEYmlOB7LqBfBaU+j/67bxK1ZVtCOg3N5zJjQsRlTzJ5Ip6
+xFZuwdbD1VMy+RVwXgllb9XKqdNdqBF1/ULyqhI3HhqWYJC7mdWAw9616SaeLYl7
+qydBkdXF8DIiEriwB96g609W8Xu3+9gghnce3tYKEPKietGidsqdl0PAEoHTW2JE
+LI83M+9p1URJEauoVMvbVARrDv0KTASuBgRFehNipqoHruFusTrmQqekKp7IqDXI
+SYBaJC1j7QIRStAcR9mTQ/8YFxRD7p22ydlGrhDt4SqtIUGZ1L1geEIQBI36/nZs
+fX96aZq5AW1Fr30723W9dLarsRkEaNvARPF91CXmn19oPqpmKVEfi6Lf6rqNskak
+o3oij3YZYNat8meB598BGvjPun99f6oVFABkipHIMzsnt4d+k1sA3t7LCjImABLW
+Sqhtf2l3EHAatVDgCz7iAGV0ydr3ljnsNLRQdPjmZ6JStYQUCI5D1+cBzx/yS9vD
++EhKNbuPXkTxaQy9kVlpQuAtN7gLnV2vf3YkjfgsuK2pvpSTRWC1/JSB+XNJWL8T
+24unZWhJ+n2bp5t8rdUnw527
+=AAwg
-----END PGP SIGNATURE-----
diff --git a/website/static/security/patches/EN-26:20/microcode-14.patch b/website/static/security/patches/EN-26:20/microcode-14.patch
new file mode 100644
index 0000000000..1eb51a5325
--- /dev/null
+++ b/website/static/security/patches/EN-26:20/microcode-14.patch
@@ -0,0 +1,168 @@
+--- sys/x86/include/ucode.h.orig
++++ sys/x86/include/ucode.h
+@@ -56,7 +56,7 @@
+ } entries[0];
+ };
+
+-int ucode_intel_load(void *data, bool unsafe,
++int ucode_intel_load(const void *data, bool unsafe,
+ uint64_t *nrevp, uint64_t *orevp);
+ size_t ucode_load_bsp(uintptr_t free);
+ void ucode_load_ap(int cpu);
+--- sys/x86/x86/ucode.c.orig
++++ sys/x86/x86/ucode.c
+@@ -51,14 +51,14 @@
+ #include
+ #include
+
+-static void *ucode_intel_match(uint8_t *data, size_t *len);
+-static int ucode_intel_verify(struct ucode_intel_header *hdr,
++static const void *ucode_intel_match(const uint8_t *data, size_t *len);
++static int ucode_intel_verify(const struct ucode_intel_header *hdr,
+ size_t resid);
+
+ static struct ucode_ops {
+ const char *vendor;
+- int (*load)(void *, bool, uint64_t *, uint64_t *);
+- void *(*match)(uint8_t *, size_t *);
++ int (*load)(const void *, bool, uint64_t *, uint64_t *);
++ const void *(*match)(const uint8_t *, size_t *);
+ } loaders[] = {
+ {
+ .vendor = INTEL_VENDOR_ID,
+@@ -68,8 +68,8 @@
+ };
+
+ /* Selected microcode update data. */
+-static void *early_ucode_data;
+-static void *ucode_data;
++static const void *early_ucode_data;
++static const void *ucode_data;
+ static struct ucode_ops *ucode_loader;
+
+ /* Variables used for reporting success or failure. */
+@@ -104,7 +104,7 @@
+ SYSINIT(ucode_log, SI_SUB_CPU, SI_ORDER_FIRST, log_msg, NULL);
+
+ int
+-ucode_intel_load(void *data, bool unsafe, uint64_t *nrevp, uint64_t *orevp)
++ucode_intel_load(const void *data, bool unsafe, uint64_t *nrevp, uint64_t *orevp)
+ {
+ uint64_t nrev, orev;
+ uint32_t cpuid[4];
+@@ -141,9 +141,10 @@
+ }
+
+ static int
+-ucode_intel_verify(struct ucode_intel_header *hdr, size_t resid)
++ucode_intel_verify(const struct ucode_intel_header *hdr, size_t resid)
+ {
+- uint32_t cksum, *data, size;
++ const uint32_t *data;
++ uint32_t cksum, size;
+ int i;
+
+ if (resid < sizeof(struct ucode_intel_header))
+@@ -161,7 +162,7 @@
+ return (1);
+
+ cksum = 0;
+- data = (uint32_t *)hdr;
++ data = (const uint32_t *)hdr;
+ for (i = 0; i < size / sizeof(uint32_t); i++)
+ cksum += data[i];
+ if (cksum != 0)
+@@ -169,16 +170,15 @@
+ return (0);
+ }
+
+-static void *
+-ucode_intel_match(uint8_t *data, size_t *len)
++static const void *
++ucode_intel_match(const uint8_t *data, size_t *len)
+ {
+- struct ucode_intel_header *hdr;
+- struct ucode_intel_extsig_table *table;
+- struct ucode_intel_extsig *entry;
++ const struct ucode_intel_header *hdr;
++ const struct ucode_intel_extsig_table *table;
++ const struct ucode_intel_extsig *entry;
+ uint64_t platformid;
+ size_t resid;
+ uint32_t data_size, flags, regs[4], sig, total_size;
+- int i;
+
+ do_cpuid(1, regs);
+ sig = regs[0];
+@@ -187,7 +187,7 @@
+ flags = 1 << ((platformid >> 50) & 0x7);
+
+ for (resid = *len; resid > 0; data += total_size, resid -= total_size) {
+- hdr = (struct ucode_intel_header *)data;
++ hdr = (const struct ucode_intel_header *)data;
+ if (ucode_intel_verify(hdr, resid) != 0) {
+ ucode_error = VERIFICATION_FAILED;
+ break;
+@@ -200,19 +200,35 @@
+ if (total_size == 0)
+ total_size = UCODE_INTEL_DEFAULT_DATA_SIZE +
+ sizeof(struct ucode_intel_header);
+- if (data_size > total_size + sizeof(struct ucode_intel_header))
+- table = (struct ucode_intel_extsig_table *)
+- ((uint8_t *)(hdr + 1) + data_size);
++
++ if (total_size > data_size + sizeof(struct ucode_intel_header))
++ table = (const struct ucode_intel_extsig_table *)
++ ((const uint8_t *)(hdr + 1) + data_size);
+ else
+ table = NULL;
+
+- if (hdr->processor_signature == sig) {
+- if ((hdr->processor_flags & flags) != 0) {
+- *len = data_size;
+- return (hdr + 1);
++ if (hdr->processor_signature == sig &&
++ (hdr->processor_flags & flags) != 0) {
++ *len = data_size;
++ return (hdr + 1);
++ }
++ if (table != NULL) {
++ size_t extsize;
++
++ extsize = total_size -
++ (data_size + sizeof(struct ucode_intel_header));
++ if (extsize < sizeof(struct ucode_intel_extsig_table)) {
++ ucode_error = VERIFICATION_FAILED;
++ break;
+ }
+- } else if (table != NULL) {
+- for (i = 0; i < table->signature_count; i++) {
++ extsize -= sizeof(struct ucode_intel_extsig_table);
++ for (uint32_t i = 0; i < table->signature_count; i++) {
++ if (extsize < sizeof(struct ucode_intel_extsig)) {
++ ucode_error = VERIFICATION_FAILED;
++ goto out;
++ }
++ extsize -= sizeof(struct ucode_intel_extsig);
++
+ entry = &table->entries[i];
+ if (entry->processor_signature == sig &&
+ (entry->processor_flags & flags) != 0) {
+@@ -222,6 +238,7 @@
+ }
+ }
+ }
++out:
+ return (NULL);
+ }
+
+@@ -318,7 +335,8 @@
+ uint32_t regs[4];
+ char vendor[13];
+ } cpuid;
+- uint8_t *addr, *fileaddr, *match;
++ const uint8_t *fileaddr, *match;
++ uint8_t *addr;
+ char *type;
+ uint64_t nrev, orev;
+ caddr_t file;
diff --git a/website/static/security/patches/EN-26:20/microcode-14.patch.asc b/website/static/security/patches/EN-26:20/microcode-14.patch.asc
new file mode 100644
index 0000000000..33912c2d7e
--- /dev/null
+++ b/website/static/security/patches/EN-26:20/microcode-14.patch.asc
@@ -0,0 +1,17 @@
+-----BEGIN PGP SIGNATURE-----
+
+iQJPBAABCgA5FiEEthUnfoEIffdcgYM7bljekB8AGu8FAmqQhvIbFIAAAAAABAAO
+bWFudTIsMi41KzEuMTIsMCwzAAoJEG5Y3pAfABrvrNUQALl25DoTG6AIm6V4fyzT
+M1ZjDhPk6QeafcmOs8o1Go3M+jqmIeuy7/PU9TblTkoM+8QD+PoDiLeGCer6aKZD
+vIvcSnxAkUluRFnZn9CvV5yT3XRTHz/O7VOkZGsEUl+f5RRnToTLMe8k0jaJCWnm
+Lq+gRZBA68N4hwrdNw4LwdbUVpsPo6GmNjTo2Wf7vEGVyOXuyEtusVZH4PzgXrdL
+qhuDyREjI0ZkO/tTs0OlYeZyQ6IXNExR6JTOs7TIXAbhIDbT7LRTt7xWNpfK1LEx
+QRkijbExsMrY4K5DgpDSWBMgsEH343jaHwZ0yR4GVE60O+I7HI/w5ACtr16kJO/p
+CY6lhnq+CPZAfF36BlMiftrT+7m6MH7lvtpw78gLt+Gmff9V8HWWMyc5FV7EuUtk
+66LbolhQ+HMzC3jAkfBHQE+uBF+Y6RZOL0ckxo+Pki9eqLufGw7kUP7ej9VUNgoE
+doy+5hAuhj0FWHYQkKu0FFdHg8GbE2/7nv3uAZVmTFUHnsvZBLRHxCIVZT7eHhuM
+tUKm2IS6xb6pP/tuT6SV1b0ZkU7bbB5QTsheHxEKB948pyZOybJOWXbhRwztnWdW
+hUVACdt+Iotjm/aug6g7X9UUWw82PXyg6EhLRoP8eLYM/kt5SBmSlSmBocCSaEtc
+XdmIyzmjJii8Fr1gGhhjGTG6
+=zZo4
+-----END PGP SIGNATURE-----
diff --git a/website/static/security/patches/EN-26:20/microcode.patch b/website/static/security/patches/EN-26:20/microcode-15.patch
similarity index 100%
rename from website/static/security/patches/EN-26:20/microcode.patch
rename to website/static/security/patches/EN-26:20/microcode-15.patch
diff --git a/website/static/security/patches/EN-26:20/microcode.patch.asc b/website/static/security/patches/EN-26:20/microcode-15.patch.asc
similarity index 100%
rename from website/static/security/patches/EN-26:20/microcode.patch.asc
rename to website/static/security/patches/EN-26:20/microcode-15.patch.asc