Bug 266548 - malicious gpt can cause kernel page fault during tasting
Summary: malicious gpt can cause kernel page fault during tasting
Status: New
Alias: None
Product: Base System
Classification: Unclassified
Component: kern (show other bugs)
Version: CURRENT
Hardware: Any Any
: --- Affects Some People
Assignee: freebsd-bugs (Nobody)
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2022-09-22 15:11 UTC by Robert Morris
Modified: 2022-09-23 09:16 UTC (History)
3 users (show)

See Also:


Attachments
a disk image that causes a crash in the GPT taste code (8.00 KB, application/octet-stream)
2022-09-22 15:11 UTC, Robert Morris
no flags Details

Note You need to log in before you can comment on or make changes to this bug.
Description Robert Morris 2022-09-22 15:11:00 UTC
Created attachment 236747 [details]
a disk image that causes a crash in the GPT taste code

I've attached a disk image that, if it's on a USB thumb drive and
inserted (but not mounted), will cause a kernel page fault (or
assertion failure for an INVARIANTS kernel).

This code in gpt_read_tbl():

        tbl = g_malloc(hdr->hdr_entries * sizeof(struct gpt_ent),
            M_WAITOK | M_ZERO);

The disk image contains the crazy value hdr_entries=4294967295;
g_malloc()'s size argument is a 32-bit signed int, and the result is
to call g_malloc(-128).

Here's a backtrace from a CURRENT amd64 machine with INVARIANTS:

# uname -a
FreeBSD stock14 14.0-CURRENT FreeBSD 14.0-CURRENT #3 main-n258027-c9baa974717a: Thu Sep 15 20:02:51 AST 2022     root@stock14:/usr/obj/usr/src/amd64.amd64/sys/GENERIC amd64
# mdconfig -f taste18a.img
panic: Assertion size > 0 failed at /usr/src/sys/kern/subr_vmem.c:1332
cpuid = 0
time = 1663856658
KDB: stack backtrace:
db_trace_self_wrapper() at db_trace_self_wrapper+0x2b/frame 0xfffffe0063aa0c00
vpanic() at vpanic+0x151/frame 0xfffffe0063aa0c50
panic() at panic+0x43/frame 0xfffffe0063aa0cb0
vmem_alloc() at vmem_alloc+0xf1/frame 0xfffffe0063aa0ce0
kmem_malloc_domainset() at kmem_malloc_domainset+0x92/frame 0xfffffe0063aa0d50
malloc_large() at malloc_large+0x2f/frame 0xfffffe0063aa0d80
gpt_read_tbl() at gpt_read_tbl+0x25f/frame 0xfffffe0063aa0e00
g_part_gpt_read() at g_part_gpt_read+0xfb/frame 0xfffffe0063aa0e60
g_part_taste() at g_part_taste+0x172/frame 0xfffffe0063aa0ea0
g_new_provider_event() at g_new_provider_event+0x9a/frame 0xfffffe0063aa0ec0
g_run_events() at g_run_events+0x104/frame 0xfffffe0063aa0ef0
fork_exit() at fork_exit+0x80/frame 0xfffffe0063aa0f30
fork_trampoline() at fork_trampoline+0xe/frame 0xfffffe0063aa0f30

Without INVARIANTS, the kernel gets a bit farther before a page fault.
Comment 1 Zhenlei Huang 2022-09-23 08:34:28 UTC
I'm not familiar with GPT GEOM, but since hdr->hdr_entries is from untrusted source then definitely hdr->hdr_entries should be checked firstly before it being passed to g_malloc(int size, int flags) .