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