1155087Spjd/*-
2155087Spjd * Copyright (c) 2006 Pawel Jakub Dawidek <pjd@FreeBSD.org>
3155087Spjd * All rights reserved.
4155087Spjd *
5155087Spjd * Redistribution and use in source and binary forms, with or without
6155087Spjd * modification, are permitted provided that the following conditions
7155087Spjd * are met:
8155087Spjd * 1. Redistributions of source code must retain the above copyright
9155087Spjd *    notice, this list of conditions and the following disclaimer.
10155087Spjd * 2. Redistributions in binary form must reproduce the above copyright
11155087Spjd *    notice, this list of conditions and the following disclaimer in the
12155087Spjd *    documentation and/or other materials provided with the distribution.
13155087Spjd *
14155087Spjd * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
15155087Spjd * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16155087Spjd * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17155087Spjd * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
18155087Spjd * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19155087Spjd * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20155087Spjd * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21155087Spjd * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22155087Spjd * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23155087Spjd * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24155087Spjd * SUCH DAMAGE.
25155087Spjd */
26155087Spjd
27155087Spjd#include <sys/cdefs.h>
28155087Spjd__FBSDID("$FreeBSD: releng/10.2/tools/regression/redzone9/redzone.c 155087 2006-01-31 11:20:13Z pjd $");
29155087Spjd
30155087Spjd#include <sys/param.h>
31155087Spjd#include <sys/systm.h>
32155087Spjd#include <sys/kernel.h>
33155087Spjd#include <sys/linker.h>
34155087Spjd#include <sys/module.h>
35155087Spjd#include <sys/malloc.h>
36155087Spjd#include <sys/sysctl.h>
37155087Spjd
38155087Spjd
39155087SpjdSYSCTL_NODE(_debug, OID_AUTO, redzone, CTLFLAG_RW, 0, "");
40155087Spjd
41155087Spjd#define	REDZONE_MALLOC_UNDERFLOW		0
42155087Spjd#define	REDZONE_MALLOC_OVERFLOW			1
43155087Spjd#define	REDZONE_REALLOC_SMALLER_UNDERFLOW	2
44155087Spjd#define	REDZONE_REALLOC_SMALLER_OVERFLOW	3
45155087Spjd#define	REDZONE_REALLOC_BIGGER_UNDERFLOW	4
46155087Spjd#define	REDZONE_REALLOC_BIGGER_OVERFLOW		5
47155087Spjd
48155087Spjdstatic int
49155087Spjdredzone_sysctl(SYSCTL_HANDLER_ARGS)
50155087Spjd{
51155087Spjd	u_char *p = NULL;
52155087Spjd	int error, val = 0;
53155087Spjd
54155087Spjd	error = sysctl_handle_int(oidp, &val, sizeof(val), req);
55155087Spjd	if (error != 0 || req->newptr == NULL)
56155087Spjd		return (0);
57155087Spjd	switch (arg2) {
58155087Spjd	case REDZONE_MALLOC_UNDERFLOW:
59155087Spjd		p = malloc(10, M_TEMP, M_NOWAIT);
60155087Spjd		if (p == NULL)
61155087Spjd			return (ENOMEM);
62155087Spjd		p[-1] = '\0';
63155087Spjd		break;
64155087Spjd	case REDZONE_MALLOC_OVERFLOW:
65155087Spjd		p = malloc(10, M_TEMP, M_NOWAIT);
66155087Spjd		if (p == NULL)
67155087Spjd			return (ENOMEM);
68155087Spjd		p[10] = '\0';
69155087Spjd		break;
70155087Spjd	case REDZONE_REALLOC_SMALLER_UNDERFLOW:
71155087Spjd		p = malloc(8192, M_TEMP, M_NOWAIT);
72155087Spjd		if (p == NULL)
73155087Spjd			return (ENOMEM);
74155087Spjd		p[-1] = '\0';
75155087Spjd		p = realloc(p, 10, M_TEMP, M_NOWAIT);
76155087Spjd		if (p == NULL)
77155087Spjd			return (ENOMEM);
78155087Spjd		break;
79155087Spjd	case REDZONE_REALLOC_SMALLER_OVERFLOW:
80155087Spjd		p = malloc(8192, M_TEMP, M_NOWAIT);
81155087Spjd		if (p == NULL)
82155087Spjd			return (ENOMEM);
83155087Spjd		p[8192] = '\0';
84155087Spjd		p = realloc(p, 10, M_TEMP, M_NOWAIT);
85155087Spjd		if (p == NULL)
86155087Spjd			return (ENOMEM);
87155087Spjd		break;
88155087Spjd	case REDZONE_REALLOC_BIGGER_UNDERFLOW:
89155087Spjd		p = malloc(10, M_TEMP, M_NOWAIT);
90155087Spjd		if (p == NULL)
91155087Spjd			return (ENOMEM);
92155087Spjd		p[-1] = '\0';
93155087Spjd		p = realloc(p, 8192, M_TEMP, M_NOWAIT);
94155087Spjd		if (p == NULL)
95155087Spjd			return (ENOMEM);
96155087Spjd		break;
97155087Spjd	case REDZONE_REALLOC_BIGGER_OVERFLOW:
98155087Spjd		p = malloc(10, M_TEMP, M_NOWAIT);
99155087Spjd		if (p == NULL)
100155087Spjd			return (ENOMEM);
101155087Spjd		p[10] = '\0';
102155087Spjd		p = realloc(p, 8192, M_TEMP, M_NOWAIT);
103155087Spjd		if (p == NULL)
104155087Spjd			return (ENOMEM);
105155087Spjd		break;
106155087Spjd	}
107155087Spjd	free(p, M_TEMP);
108155087Spjd        return (0);
109155087Spjd}
110155087SpjdSYSCTL_PROC(_debug_redzone, OID_AUTO, malloc_underflow, CTLTYPE_INT | CTLFLAG_RW,
111155087Spjd    NULL, REDZONE_MALLOC_UNDERFLOW, redzone_sysctl, "I", "");
112155087SpjdSYSCTL_PROC(_debug_redzone, OID_AUTO, malloc_overflow, CTLTYPE_INT | CTLFLAG_RW,
113155087Spjd    NULL, REDZONE_MALLOC_OVERFLOW, redzone_sysctl, "I", "");
114155087SpjdSYSCTL_PROC(_debug_redzone, OID_AUTO, realloc_smaller_underflow, CTLTYPE_INT | CTLFLAG_RW,
115155087Spjd    NULL, REDZONE_REALLOC_SMALLER_UNDERFLOW, redzone_sysctl, "I", "");
116155087SpjdSYSCTL_PROC(_debug_redzone, OID_AUTO, realloc_smaller_overflow, CTLTYPE_INT | CTLFLAG_RW,
117155087Spjd    NULL, REDZONE_REALLOC_SMALLER_OVERFLOW, redzone_sysctl, "I", "");
118155087SpjdSYSCTL_PROC(_debug_redzone, OID_AUTO, realloc_bigger_underflow, CTLTYPE_INT | CTLFLAG_RW,
119155087Spjd    NULL, REDZONE_REALLOC_BIGGER_UNDERFLOW, redzone_sysctl, "I", "");
120155087SpjdSYSCTL_PROC(_debug_redzone, OID_AUTO, realloc_bigger_overflow, CTLTYPE_INT | CTLFLAG_RW,
121155087Spjd    NULL, REDZONE_REALLOC_BIGGER_OVERFLOW, redzone_sysctl, "I", "");
122155087Spjd
123155087Spjdstatic int
124155087Spjdredzone_modevent(module_t mod, int type, void *data)
125155087Spjd{
126155087Spjd
127155087Spjd	switch (type) {
128155087Spjd	case MOD_LOAD:
129155087Spjd	case MOD_UNLOAD:
130155087Spjd		break;
131155087Spjd	default:
132155087Spjd		return (EOPNOTSUPP);
133155087Spjd	}
134155087Spjd	return (0);
135155087Spjd}
136155087Spjdstatic moduledata_t redzone_module = {
137155087Spjd	"redzone",
138155087Spjd	redzone_modevent,
139155087Spjd	NULL
140155087Spjd};
141155087SpjdDECLARE_MODULE(redzone, redzone_module, SI_SUB_DRIVERS, SI_ORDER_MIDDLE);
142