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