1 /* $OpenBSD: subr_poison.c,v 1.10 2014/07/08 22:30:26 tedu Exp $ */ 2 /* 3 * Copyright (c) 2013 Ted Unangst <tedu@openbsd.org> 4 * 5 * Permission to use, copy, modify, and distribute this software for any 6 * purpose with or without fee is hereby granted, provided that the above 7 * copyright notice and this permission notice appear in all copies. 8 * 9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16 */ 17 18 #include <sys/types.h> 19 #include <sys/param.h> 20 #include <sys/malloc.h> 21 22 #include <uvm/uvm_extern.h> 23 24 /* 25 * The POISON is used as known text to copy into free objects so 26 * that modifications after frees can be detected. 27 */ 28 #ifdef DEADBEEF0 29 #define POISON0 ((unsigned) DEADBEEF0) 30 #else 31 #define POISON0 ((unsigned) 0xdeadbeef) 32 #endif 33 #ifdef DEADBEEF1 34 #define POISON1 ((unsigned) DEADBEEF1) 35 #else 36 #define POISON1 ((unsigned) 0xdeafbead) 37 #endif 38 #define POISON_SIZE 64 39 40 uint32_t 41 poison_value(void *v) 42 { 43 ulong l = (u_long)v; 44 45 l = l >> PAGE_SHIFT; 46 47 switch (l & 3) { 48 case 0: 49 return POISON0; 50 case 1: 51 return POISON1; 52 case 2: 53 return ~POISON0; 54 case 3: 55 return ~POISON1; 56 } 57 return 0; 58 } 59 60 void 61 poison_mem(void *v, size_t len) 62 { 63 uint32_t *ip = v; 64 size_t i; 65 uint32_t poison; 66 67 poison = poison_value(v); 68 69 if (len > POISON_SIZE) 70 len = POISON_SIZE; 71 len = len / sizeof(*ip); 72 for (i = 0; i < len; i++) 73 ip[i] = poison; 74 } 75 76 int 77 poison_check(void *v, size_t len, size_t *pidx, uint32_t *pval) 78 { 79 uint32_t *ip = v; 80 size_t i; 81 uint32_t poison; 82 83 poison = poison_value(v); 84 85 if (len > POISON_SIZE) 86 len = POISON_SIZE; 87 len = len / sizeof(*ip); 88 for (i = 0; i < len; i++) { 89 if (ip[i] != poison) { 90 *pidx = i; 91 *pval = poison; 92 return 1; 93 } 94 } 95 return 0; 96 } 97 98