FreeBSD Bugzilla – Attachment 182122 Details for
Bug 218911
[uma] Memory corruption with certain item sizes
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
sys/vm: Set UMA_ZONE_OFFPAGE if the offset would be too large to fit into keg->uk_pgoff
sys-vm-Set-UMA_ZONE_OFFPAGE-if-the-offset-would-be.diff (text/plain), 7.32 KB, created by
Fabian Keil
on 2017-04-27 11:15:19 UTC
(
hide
)
Description:
sys/vm: Set UMA_ZONE_OFFPAGE if the offset would be too large to fit into keg->uk_pgoff
Filename:
MIME Type:
Creator:
Fabian Keil
Created:
2017-04-27 11:15:19 UTC
Size:
7.32 KB
patch
obsolete
>From 6b98d5ec0d882d99a49a7026133bc81f3336fe8c Mon Sep 17 00:00:00 2001 >From: Fabian Keil <fk@fabiankeil.de> >Date: Wed, 26 Apr 2017 11:51:16 +0200 >Subject: [PATCH] sys/vm: Set UMA_ZONE_OFFPAGE if the offset would be too large > to fit into keg->uk_pgoff > >This prevents memory corruption with certain uma zone item sizes: > > (kgdb) where > #0 __curthread () at ./machine/pcpu.h:222 > #1 doadump (textdump=1) at /usr/src/sys/kern/kern_shutdown.c:298 > #2 0xffffffff80555465 in kern_reboot (howto=260) at /usr/src/sys/kern/kern_shutdown.c:366 > #3 0xffffffff80555a40 in vpanic (fmt=<optimized out>, ap=0xfffffe0113d69980) at /usr/src/sys/kern/kern_shutdown.c:759 > #4 0xffffffff80555876 in kassert_panic (fmt=0xffffffff808c521f "Assertion %s failed at %s:%d") at /usr/src/sys/kern/kern_shutdown.c:649 > #5 0xffffffff807dd333 in keg_fetch_slab (keg=0xfffff80005b52480, zone=0xfffff80005b53700, flags=2) at /usr/src/sys/vm/uma_core.c:2343 > #6 0xffffffff807dc9ae in zone_fetch_slab (zone=0xfffff80005b53700, keg=0xfffff80005b52480, flags=2) at /usr/src/sys/vm/uma_core.c:2368 > #7 0xffffffff807dca40 in zone_import (zone=0xfffff80005b53700, bucket=0xfffff800d7eae9f8, max=1, flags=2) at /usr/src/sys/vm/uma_core.c:2494 > #8 0xffffffff807d9341 in zone_alloc_bucket (zone=0xfffff80005b53700, udata=0x0, flags=2) at /usr/src/sys/vm/uma_core.c:2524 > #9 uma_zalloc_arg (zone=0xfffff80005b53700, udata=0x0, flags=<optimized out>) at /usr/src/sys/vm/uma_core.c:2250 > #10 0xffffffff8182329f in uma_zalloc (flags=2, zone=<optimized out>) at /usr/src/sys/vm/uma.h:336 > #11 g_raid_init (mp=0xffffffff81856838 <g_raid_class>) at /usr/src/sys/modules/geom/geom_raid/../../../geom/raid/g_raid.c:2496 > #12 0xffffffff804d1125 in g_load_class (arg=<optimized out>, flag=<optimized out>) at /usr/src/sys/geom/geom_subr.c:124 > #13 0xffffffff804cd7c7 in one_event () at /usr/src/sys/geom/geom_event.c:264 > #14 g_run_events () at /usr/src/sys/geom/geom_event.c:286 > #15 0xffffffff80517e64 in fork_exit (callout=0xffffffff804cfa60 <g_event_procbody>, arg=0x0, frame=0xfffffe0113d69c00) at /usr/src/sys/kern/kern_fork.c:1040 > #16 <signal handler called> > [...] > (kgdb) f 5 > #5 0xffffffff807dd333 in keg_fetch_slab (keg=0xfffff80005b52480, zone=0xfffff80005b53700, flags=2) at /usr/src/sys/vm/uma_core.c:2343 > 2343 MPASS(slab->us_keg == keg); > (kgdb) p slab->us_keg > $1 = (uma_keg_t) 0xdeadc0dedeadc0de > (kgdb) f 9 > #9 uma_zalloc_arg (zone=0xfffff80005b53700, udata=0x0, flags=<optimized out>) at /usr/src/sys/vm/uma_core.c:2250 > 2250 bucket = zone_alloc_bucket(zone, udata, flags); > (kgdb) p zone > $2 = (uma_zone_t) 0xfffff80005b53700 > (kgdb) p *zone > $3 = {uz_lock = {lock_object = {lo_name = 0xffffffff8184f85a "uma_test", lo_flags = 21168128, lo_data = 0, lo_witness = 0xfffffe0000a0cf80}, mtx_lock = 4}, uz_lockptr = 0xfffff80005b52480, > uz_name = 0xffffffff8184f85a "uma_test", uz_link = {le_next = 0x0, le_prev = 0xfffff80005b52510}, uz_buckets = {lh_first = 0x0}, uz_kegs = {lh_first = 0xfffff80005b537b0}, uz_klink = {kl_link = {le_next = 0x0, > le_prev = 0xfffff80005b537a8}, kl_keg = 0xfffff80005b52480}, uz_slab = 0xffffffff807dc940 <zone_fetch_slab>, uz_ctor = 0xffffffff807dd730 <trash_ctor>, uz_dtor = 0xffffffff807dd780 <trash_dtor>, uz_init = 0x0, > uz_fini = 0x0, uz_import = 0xffffffff807dc9f0 <zone_import>, uz_release = 0xffffffff807dcc90 <zone_release>, uz_arg = 0xfffff80005b53700, uz_flags = 0, uz_size = 129024, uz_allocs = 0, uz_fails = 0, uz_frees = 0, > uz_sleeps = 0, uz_count = 1, uz_count_min = 1, uz_warning = 0x0, uz_ratecheck = {tv_sec = 0, tv_usec = 0}, uz_maxaction = {ta_link = {stqe_next = 0x0}, ta_pending = 0, ta_priority = 0, ta_func = 0x0, ta_context = 0x0}, > uz_cpu = {{uc_freebucket = 0x0, uc_allocbucket = 0x0, uc_allocs = 0, uc_frees = 0}}} > (kgdb) f 11 > #11 g_raid_init (mp=0xffffffff81856838 <g_raid_class>) at /usr/src/sys/modules/geom/geom_raid/../../../geom/raid/g_raid.c:2496 > 2496 p = uma_zalloc(uma_test_zone, M_WAITOK); > (kgdb) p i > $4 = 0 > (kgdb) l - > 2491 > 2492 uma_test_zone = uma_zcreate("uma_test", uma_test_zone_item_size, NULL, NULL, > 2493 NULL, NULL, 0, 0); > 2494 > 2495 for (i = 0; i <= uma_test_zone_item_size; i++) { > 2496 p = uma_zalloc(uma_test_zone, M_WAITOK); > 2497 memset(p, 0x10, i); > 2498 G_RAID_DEBUG(1, "Freeing item after filling %d bytes.", i); > 2499 uma_zfree(uma_test_zone, p); > 2500 } > (kgdb) f 9 > #9 uma_zalloc_arg (zone=0xfffff80005b53700, udata=0x0, flags=<optimized out>) at /usr/src/sys/vm/uma_core.c:2250 > 2250 bucket = zone_alloc_bucket(zone, udata, flags); > (kgdb) p zone->uz_kegs->lh_first->kl_keg > $6 = (uma_keg_t) 0xfffff80005b52480 > (kgdb) p *zone->uz_kegs->lh_first->kl_keg > $7 = {uk_lock = {lock_object = {lo_name = 0xffffffff8184f85a "uma_test", lo_flags = 21168128, lo_data = 0, lo_witness = 0xfffffe0000a0cf80}, mtx_lock = 18446735277663592448}, uk_hash = {uh_slab_hash = 0x0, uh_hashsize = 0, > uh_hashmask = 0}, uk_zones = {lh_first = 0xfffff80005b53700}, uk_part_slab = {lh_first = 0x0}, uk_free_slab = {lh_first = 0x0}, uk_full_slab = {lh_first = 0x0}, uk_align = 0, uk_pages = 32, uk_free = 1, uk_reserve = 0, > uk_size = 129024, uk_rsize = 129024, uk_maxpages = 0, uk_init = 0xffffffff807dd7b0 <trash_init>, uk_fini = 0xffffffff807dd7e0 <trash_fini>, uk_allocf = 0xffffffff807db690 <page_alloc>, > uk_freef = 0xffffffff807db770 <page_free>, uk_offset = 0, uk_kva = 0, uk_slabzone = 0x0, uk_pgoff = 65424, uk_ppera = 32, uk_ipers = 1, uk_flags = 0, uk_name = 0xffffffff8184f85a "uma_test", uk_link = { > le_next = 0xfffff80005b52300, le_prev = 0xffffffff80f45d00 <uma_kegs>}} > (kgdb) p sizeof(struct uma_slab) > $8 = 112 > (kgdb) p zone->uz_kegs->lh_first->kl_keg->uk_ppera > $9 = 32 > (kgdb) p 4096 * zone->uz_kegs->lh_first->kl_keg->uk_ppera > $10 = 131072 > (kgdb) p 4096 * zone->uz_kegs->lh_first->kl_keg->uk_ppera - sizeof(struct uma_slab) > $11 = 130960 > (kgdb) p 4096 * zone->uz_kegs->lh_first->kl_keg->uk_ppera - sizeof(struct uma_slab) - 65536 > $12 = 65424 > (kgdb) p zone->uz_kegs->lh_first->kl_keg->uk_size > $13 = 129024 > (kgdb) p 4096 * zone->uz_kegs->lh_first->kl_keg->uk_ppera - zone->uz_kegs->lh_first->kl_keg->uk_rsize > $14 = 2048 > >Obtained from: ElectroBSD >--- > sys/vm/uma_core.c | 11 +++++++++++ > 1 file changed, 11 insertions(+) > >diff --git a/sys/vm/uma_core.c b/sys/vm/uma_core.c >index 08a40ac8eb7b..b3ab82f0d1c6 100644 >--- a/sys/vm/uma_core.c >+++ b/sys/vm/uma_core.c >@@ -1339,6 +1339,17 @@ keg_large_init(uma_keg_t keg) > > if ((PAGE_SIZE * keg->uk_ppera) - keg->uk_rsize < shsize) > keg->uk_flags |= UMA_ZONE_OFFPAGE; >+ else if ((PAGE_SIZE * keg->uk_ppera) - shsize > UINT16_MAX) { >+ /* >+ * We may have enough room but keg->uk_pgoff >+ * would overflow in keg_ctor(). >+ */ >+#ifdef UMA_DEBUG >+ printf("Setting UMA_ZONE_OFFPAGE for %s " >+ "to prevent overflow\n", keg->uk_name); >+#endif >+ keg->uk_flags |= UMA_ZONE_OFFPAGE; >+ } > } > > if ((keg->uk_flags & UMA_ZONE_OFFPAGE) && >-- >2.12.1 >
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 218911
: 182122 |
182123