1 /* $OpenBSD: subr_poison.c,v 1.13 2015/03/14 03:38:50 jsg 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 21 #include <uvm/uvm_extern.h> 22 23 /* 24 * The POISON is used as known text to copy into free objects so 25 * that modifications after frees can be detected. 26 */ 27 #ifdef DEADBEEF0 28 #define POISON0 ((unsigned) DEADBEEF0) 29 #else 30 #define POISON0 ((unsigned) 0xdeadbeef) 31 #endif 32 #ifdef DEADBEEF1 33 #define POISON1 ((unsigned) DEADBEEF1) 34 #else 35 #define POISON1 ((unsigned) 0xdeafbead) 36 #endif 37 #define POISON_SIZE 64 38 39 uint32_t 40 poison_value(void *v) 41 { 42 ulong l = (u_long)v; 43 44 l = l >> PAGE_SHIFT; 45 46 switch (l & 3) { 47 case 0: 48 return POISON0; 49 case 1: 50 return POISON1; 51 case 2: 52 return (POISON0 & 0xffff0000) | (~POISON0 & 0x0000ffff); 53 case 3: 54 return (POISON1 & 0xffff0000) | (~POISON1 & 0x0000ffff); 55 } 56 return 0; 57 } 58 59 void 60 poison_mem(void *v, size_t len) 61 { 62 uint32_t *ip = v; 63 size_t i; 64 uint32_t poison; 65 66 poison = poison_value(v); 67 68 if (len > POISON_SIZE) 69 len = POISON_SIZE; 70 len = len / sizeof(*ip); 71 for (i = 0; i < len; i++) 72 ip[i] = poison; 73 } 74 75 int 76 poison_check(void *v, size_t len, size_t *pidx, uint32_t *pval) 77 { 78 uint32_t *ip = v; 79 size_t i; 80 uint32_t poison; 81 82 poison = poison_value(v); 83 84 if (len > POISON_SIZE) 85 len = POISON_SIZE; 86 len = len / sizeof(*ip); 87 for (i = 0; i < len; i++) { 88 if (ip[i] != poison) { 89 *pidx = i; 90 *pval = poison; 91 return 1; 92 } 93 } 94 return 0; 95 } 96 97