Fix memguard(9) in kernels with INVARIANTS enabled.
With r284861, UMA zones use the trash ctor and dtor by default. This is incompatible with memguard, which frees the backing page when the item is freed. Modify the UMA debug functions to be no-ops if the item was allocated from memguard. This also fixes constructors such as mb_ctor_pack(), which invokes the trash ctor in addition to performing some initialization. Reviewed by: glebius MFC after: 3 weeks Differential Revision: https://reviews.freebsd.org/D6562
This commit is contained in:
parent
b1a6b8dcd2
commit
bc9d08e1cf
@ -2112,16 +2112,10 @@ uma_zalloc_arg(uma_zone_t zone, void *udata, int flags)
|
||||
if (memguard_cmp_zone(zone)) {
|
||||
item = memguard_alloc(zone->uz_size, flags);
|
||||
if (item != NULL) {
|
||||
/*
|
||||
* Avoid conflict with the use-after-free
|
||||
* protecting infrastructure from INVARIANTS.
|
||||
*/
|
||||
if (zone->uz_init != NULL &&
|
||||
zone->uz_init != mtrash_init &&
|
||||
zone->uz_init(item, zone->uz_size, flags) != 0)
|
||||
return (NULL);
|
||||
if (zone->uz_ctor != NULL &&
|
||||
zone->uz_ctor != mtrash_ctor &&
|
||||
zone->uz_ctor(item, zone->uz_size, udata,
|
||||
flags) != 0) {
|
||||
zone->uz_fini(item, zone->uz_size);
|
||||
@ -2655,9 +2649,9 @@ uma_zfree_arg(uma_zone_t zone, void *item, void *udata)
|
||||
return;
|
||||
#ifdef DEBUG_MEMGUARD
|
||||
if (is_memguard_addr(item)) {
|
||||
if (zone->uz_dtor != NULL && zone->uz_dtor != mtrash_dtor)
|
||||
if (zone->uz_dtor != NULL)
|
||||
zone->uz_dtor(item, zone->uz_size, udata);
|
||||
if (zone->uz_fini != NULL && zone->uz_fini != mtrash_fini)
|
||||
if (zone->uz_fini != NULL)
|
||||
zone->uz_fini(item, zone->uz_size);
|
||||
memguard_free(item);
|
||||
return;
|
||||
|
@ -33,6 +33,8 @@
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include "opt_vm.h"
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/bitset.h>
|
||||
@ -49,6 +51,7 @@ __FBSDID("$FreeBSD$");
|
||||
#include <vm/uma.h>
|
||||
#include <vm/uma_int.h>
|
||||
#include <vm/uma_dbg.h>
|
||||
#include <vm/memguard.h>
|
||||
|
||||
static const uint32_t uma_junk = 0xdeadc0de;
|
||||
|
||||
@ -57,7 +60,6 @@ static const uint32_t uma_junk = 0xdeadc0de;
|
||||
* prior to subsequent reallocation.
|
||||
*
|
||||
* Complies with standard ctor arg/return
|
||||
*
|
||||
*/
|
||||
int
|
||||
trash_ctor(void *mem, int size, void *arg, int flags)
|
||||
@ -65,6 +67,11 @@ trash_ctor(void *mem, int size, void *arg, int flags)
|
||||
int cnt;
|
||||
uint32_t *p;
|
||||
|
||||
#ifdef DEBUG_MEMGUARD
|
||||
if (is_memguard_addr(mem))
|
||||
return (0);
|
||||
#endif
|
||||
|
||||
cnt = size / sizeof(uma_junk);
|
||||
|
||||
for (p = mem; cnt > 0; cnt--, p++)
|
||||
@ -93,6 +100,11 @@ trash_dtor(void *mem, int size, void *arg)
|
||||
int cnt;
|
||||
uint32_t *p;
|
||||
|
||||
#ifdef DEBUG_MEMGUARD
|
||||
if (is_memguard_addr(mem))
|
||||
return;
|
||||
#endif
|
||||
|
||||
cnt = size / sizeof(uma_junk);
|
||||
|
||||
for (p = mem; cnt > 0; cnt--, p++)
|
||||
@ -131,6 +143,11 @@ mtrash_ctor(void *mem, int size, void *arg, int flags)
|
||||
uint32_t *p = mem;
|
||||
int cnt;
|
||||
|
||||
#ifdef DEBUG_MEMGUARD
|
||||
if (is_memguard_addr(mem))
|
||||
return (0);
|
||||
#endif
|
||||
|
||||
size -= sizeof(struct malloc_type *);
|
||||
ksp = (struct malloc_type **)mem;
|
||||
ksp += size / sizeof(struct malloc_type *);
|
||||
@ -158,6 +175,11 @@ mtrash_dtor(void *mem, int size, void *arg)
|
||||
int cnt;
|
||||
uint32_t *p;
|
||||
|
||||
#ifdef DEBUG_MEMGUARD
|
||||
if (is_memguard_addr(mem))
|
||||
return;
|
||||
#endif
|
||||
|
||||
size -= sizeof(struct malloc_type *);
|
||||
cnt = size / sizeof(uma_junk);
|
||||
|
||||
@ -176,6 +198,11 @@ mtrash_init(void *mem, int size, int flags)
|
||||
{
|
||||
struct malloc_type **ksp;
|
||||
|
||||
#ifdef DEBUG_MEMGUARD
|
||||
if (is_memguard_addr(mem))
|
||||
return (0);
|
||||
#endif
|
||||
|
||||
mtrash_dtor(mem, size, NULL);
|
||||
|
||||
ksp = (struct malloc_type **)mem;
|
||||
|
Loading…
Reference in New Issue
Block a user