git: 0beb17289849 - main - ucode: Fix validation on Intel platforms
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Wed, 27 May 2026 21:12:53 UTC
The branch main has been updated by markj:
URL: https://cgit.FreeBSD.org/src/commit/?id=0beb172898499fff51eed4df3d9284cd1094afbb
commit 0beb172898499fff51eed4df3d9284cd1094afbb
Author: Mark Johnston <markj@FreeBSD.org>
AuthorDate: 2026-05-27 20:18:05 +0000
Commit: Mark Johnston <markj@FreeBSD.org>
CommitDate: 2026-05-27 21:12:35 +0000
ucode: Fix validation on Intel platforms
The check for the extended signature table was backwards, so we always
ignored it.
We should verify that the extended signature table fits within the total
image size.
Reviewed by: jrm, kib
MFC after: 1 week
Differential Revision: https://reviews.freebsd.org/D57209
---
sys/x86/x86/ucode.c | 32 ++++++++++++++++++++++++--------
1 file changed, 24 insertions(+), 8 deletions(-)
diff --git a/sys/x86/x86/ucode.c b/sys/x86/x86/ucode.c
index 72133de211f8..2e996331dd2e 100644
--- a/sys/x86/x86/ucode.c
+++ b/sys/x86/x86/ucode.c
@@ -204,7 +204,6 @@ ucode_intel_match(const uint8_t *data, size_t *len)
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];
@@ -226,19 +225,35 @@ ucode_intel_match(const uint8_t *data, size_t *len)
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))
+
+ 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) {
@@ -248,6 +263,7 @@ ucode_intel_match(const uint8_t *data, size_t *len)
}
}
}
+out:
return (NULL);
}