Deleted Added
sdiff udiff text old ( 216425 ) new ( 226313 )
full compact
1/*-
2 * Copyright (c) 2005, Bosko Milekic <bmilekic@FreeBSD.org>.
3 * Copyright (c) 2010 Isilon Systems, Inc. (http://www.isilon.com/)
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:

--- 12 unchanged lines hidden (view full) ---

21 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28#include <sys/cdefs.h>
29__FBSDID("$FreeBSD: head/sys/vm/memguard.c 216425 2010-12-14 05:47:35Z alc $");
30
31/*
32 * MemGuard is a simple replacement allocator for debugging only
33 * which provides ElectricFence-style memory barrier protection on
34 * objects being allocated, and is used to detect tampering-after-free
35 * scenarios.
36 *
37 * See the memguard(9) man page for more information on using MemGuard.

--- 13 unchanged lines hidden (view full) ---

51
52#include <vm/vm.h>
53#include <vm/uma.h>
54#include <vm/vm_param.h>
55#include <vm/vm_page.h>
56#include <vm/vm_map.h>
57#include <vm/vm_object.h>
58#include <vm/vm_extern.h>
59#include <vm/memguard.h>
60
61SYSCTL_NODE(_vm, OID_AUTO, memguard, CTLFLAG_RW, NULL, "MemGuard data");
62/*
63 * The vm_memguard_divisor variable controls how much of kmem_map should be
64 * reserved for MemGuard.
65 */
66static u_int vm_memguard_divisor;

--- 53 unchanged lines hidden (view full) ---

120 &memguard_wrap, 0, "MemGuard cursor wrap count");
121SYSCTL_ULONG(_vm_memguard, OID_AUTO, numalloc, CTLFLAG_RD,
122 &memguard_succ, 0, "Count of successful MemGuard allocations");
123SYSCTL_ULONG(_vm_memguard, OID_AUTO, fail_kva, CTLFLAG_RD,
124 &memguard_fail_kva, 0, "MemGuard failures due to lack of KVA");
125SYSCTL_ULONG(_vm_memguard, OID_AUTO, fail_pgs, CTLFLAG_RD,
126 &memguard_fail_pgs, 0, "MemGuard failures due to lack of pages");
127
128#define MG_GUARD 0x001
129#define MG_ALLLARGE 0x002
130static int memguard_options = MG_GUARD;
131TUNABLE_INT("vm.memguard.options", &memguard_options);
132SYSCTL_INT(_vm_memguard, OID_AUTO, options, CTLFLAG_RW,
133 &memguard_options, 0,
134 "MemGuard options:\n"
135 "\t0x001 - add guard pages around each allocation\n"
136 "\t0x002 - always use MemGuard for allocations over a page");
137
138static u_int memguard_minsize;
139static u_long memguard_minsize_reject;
140SYSCTL_UINT(_vm_memguard, OID_AUTO, minsize, CTLFLAG_RW,
141 &memguard_minsize, 0, "Minimum size for page promotion");
142SYSCTL_ULONG(_vm_memguard, OID_AUTO, minsize_reject, CTLFLAG_RD,
143 &memguard_minsize_reject, 0, "# times rejected for size");
144

--- 132 unchanged lines hidden (view full) ---

277 /*
278 * To ensure there are holes on both sides of the allocation,
279 * request 2 extra pages of KVA. We will only actually add a
280 * vm_map_entry and get pages for the original request. Save
281 * the value of memguard_options so we have a consistent
282 * value.
283 */
284 size_v = size_p;
285 do_guard = (memguard_options & MG_GUARD) != 0;
286 if (do_guard)
287 size_v += 2 * PAGE_SIZE;
288
289 vm_map_lock(memguard_map);
290 /*
291 * When we pass our memory limit, reject sub-page allocations.
292 * Page-size and larger allocations will use the same amount
293 * of physical memory whether we allocate or hand off to

--- 130 unchanged lines hidden (view full) ---

424
425 /* Copy over original contents. */
426 old_size = *v2sizep(trunc_page((uintptr_t)addr));
427 bcopy(addr, newaddr, min(size, old_size));
428 memguard_free(addr);
429 return (newaddr);
430}
431
432int
433memguard_cmp(struct malloc_type *mtp, unsigned long size)
434{
435
436 if (size < memguard_minsize) {
437 memguard_minsize_reject++;
438 return (0);
439 }
440 if ((memguard_options & MG_ALLLARGE) != 0 && size >= PAGE_SIZE)
441 return (1);
442 if (memguard_frequency > 0 &&
443 (random() % 100000) < memguard_frequency) {
444 memguard_frequency_hits++;
445 return (1);
446 }
447#if 1
448 /*
449 * The safest way of comparsion is to always compare short description
450 * string of memory type, but it is also the slowest way.
451 */
452 return (strcmp(mtp->ks_shortdesc, vm_memguard_desc) == 0);
453#else
454 /*

--- 7 unchanged lines hidden (view full) ---

462 return (mtp == vm_memguard_mtype);
463 if (strcmp(mtp->ks_shortdesc, vm_memguard_desc) == 0) {
464 vm_memguard_mtype = mtp;
465 return (1);
466 }
467 return (0);
468#endif
469}