93 lines
2.1 KiB
C
93 lines
2.1 KiB
C
/* $OpenBSD: subr_poison.c,v 1.15 2022/08/14 01:58:28 jsg Exp $ */
|
|
/*
|
|
* Copyright (c) 2013 Ted Unangst <tedu@openbsd.org>
|
|
*
|
|
* Permission to use, copy, modify, and distribute this software for any
|
|
* purpose with or without fee is hereby granted, provided that the above
|
|
* copyright notice and this permission notice appear in all copies.
|
|
*
|
|
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
*/
|
|
|
|
#include <sys/param.h>
|
|
|
|
/*
|
|
* The POISON is used as known text to copy into free objects so
|
|
* that modifications after frees can be detected.
|
|
*/
|
|
#ifdef DEADBEEF0
|
|
#define POISON0 ((unsigned) DEADBEEF0)
|
|
#else
|
|
#define POISON0 ((unsigned) 0xdeadbeef)
|
|
#endif
|
|
#ifdef DEADBEEF1
|
|
#define POISON1 ((unsigned) DEADBEEF1)
|
|
#else
|
|
#define POISON1 ((unsigned) 0xdeafbead)
|
|
#endif
|
|
#define POISON_SIZE 64
|
|
|
|
uint32_t
|
|
poison_value(void *v)
|
|
{
|
|
ulong l = (u_long)v;
|
|
|
|
l = l >> PAGE_SHIFT;
|
|
|
|
switch (l & 3) {
|
|
case 0:
|
|
return POISON0;
|
|
case 1:
|
|
return POISON1;
|
|
case 2:
|
|
return (POISON0 & 0xffff0000) | (~POISON0 & 0x0000ffff);
|
|
case 3:
|
|
return (POISON1 & 0xffff0000) | (~POISON1 & 0x0000ffff);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
void
|
|
poison_mem(void *v, size_t len)
|
|
{
|
|
uint32_t *ip = v;
|
|
size_t i;
|
|
uint32_t poison;
|
|
|
|
poison = poison_value(v);
|
|
|
|
if (len > POISON_SIZE)
|
|
len = POISON_SIZE;
|
|
len = len / sizeof(*ip);
|
|
for (i = 0; i < len; i++)
|
|
ip[i] = poison;
|
|
}
|
|
|
|
int
|
|
poison_check(void *v, size_t len, size_t *pidx, uint32_t *pval)
|
|
{
|
|
uint32_t *ip = v;
|
|
size_t i;
|
|
uint32_t poison;
|
|
|
|
poison = poison_value(v);
|
|
|
|
if (len > POISON_SIZE)
|
|
len = POISON_SIZE;
|
|
len = len / sizeof(*ip);
|
|
for (i = 0; i < len; i++) {
|
|
if (ip[i] != poison) {
|
|
*pidx = i;
|
|
*pval = poison;
|
|
return 1;
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|