1/*-
2 * Copyright (c) 2006 Pawel Jakub Dawidek <pjd@FreeBSD.org>
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 *    notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 *    notice, this list of conditions and the following disclaimer in the
12 *    documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 */
26
27#include <sys/cdefs.h>
28__FBSDID("$FreeBSD: releng/10.3/tools/regression/redzone9/redzone.c 155087 2006-01-31 11:20:13Z pjd $");
29
30#include <sys/param.h>
31#include <sys/systm.h>
32#include <sys/kernel.h>
33#include <sys/linker.h>
34#include <sys/module.h>
35#include <sys/malloc.h>
36#include <sys/sysctl.h>
37
38
39SYSCTL_NODE(_debug, OID_AUTO, redzone, CTLFLAG_RW, 0, "");
40
41#define	REDZONE_MALLOC_UNDERFLOW		0
42#define	REDZONE_MALLOC_OVERFLOW			1
43#define	REDZONE_REALLOC_SMALLER_UNDERFLOW	2
44#define	REDZONE_REALLOC_SMALLER_OVERFLOW	3
45#define	REDZONE_REALLOC_BIGGER_UNDERFLOW	4
46#define	REDZONE_REALLOC_BIGGER_OVERFLOW		5
47
48static int
49redzone_sysctl(SYSCTL_HANDLER_ARGS)
50{
51	u_char *p = NULL;
52	int error, val = 0;
53
54	error = sysctl_handle_int(oidp, &val, sizeof(val), req);
55	if (error != 0 || req->newptr == NULL)
56		return (0);
57	switch (arg2) {
58	case REDZONE_MALLOC_UNDERFLOW:
59		p = malloc(10, M_TEMP, M_NOWAIT);
60		if (p == NULL)
61			return (ENOMEM);
62		p[-1] = '\0';
63		break;
64	case REDZONE_MALLOC_OVERFLOW:
65		p = malloc(10, M_TEMP, M_NOWAIT);
66		if (p == NULL)
67			return (ENOMEM);
68		p[10] = '\0';
69		break;
70	case REDZONE_REALLOC_SMALLER_UNDERFLOW:
71		p = malloc(8192, M_TEMP, M_NOWAIT);
72		if (p == NULL)
73			return (ENOMEM);
74		p[-1] = '\0';
75		p = realloc(p, 10, M_TEMP, M_NOWAIT);
76		if (p == NULL)
77			return (ENOMEM);
78		break;
79	case REDZONE_REALLOC_SMALLER_OVERFLOW:
80		p = malloc(8192, M_TEMP, M_NOWAIT);
81		if (p == NULL)
82			return (ENOMEM);
83		p[8192] = '\0';
84		p = realloc(p, 10, M_TEMP, M_NOWAIT);
85		if (p == NULL)
86			return (ENOMEM);
87		break;
88	case REDZONE_REALLOC_BIGGER_UNDERFLOW:
89		p = malloc(10, M_TEMP, M_NOWAIT);
90		if (p == NULL)
91			return (ENOMEM);
92		p[-1] = '\0';
93		p = realloc(p, 8192, M_TEMP, M_NOWAIT);
94		if (p == NULL)
95			return (ENOMEM);
96		break;
97	case REDZONE_REALLOC_BIGGER_OVERFLOW:
98		p = malloc(10, M_TEMP, M_NOWAIT);
99		if (p == NULL)
100			return (ENOMEM);
101		p[10] = '\0';
102		p = realloc(p, 8192, M_TEMP, M_NOWAIT);
103		if (p == NULL)
104			return (ENOMEM);
105		break;
106	}
107	free(p, M_TEMP);
108        return (0);
109}
110SYSCTL_PROC(_debug_redzone, OID_AUTO, malloc_underflow, CTLTYPE_INT | CTLFLAG_RW,
111    NULL, REDZONE_MALLOC_UNDERFLOW, redzone_sysctl, "I", "");
112SYSCTL_PROC(_debug_redzone, OID_AUTO, malloc_overflow, CTLTYPE_INT | CTLFLAG_RW,
113    NULL, REDZONE_MALLOC_OVERFLOW, redzone_sysctl, "I", "");
114SYSCTL_PROC(_debug_redzone, OID_AUTO, realloc_smaller_underflow, CTLTYPE_INT | CTLFLAG_RW,
115    NULL, REDZONE_REALLOC_SMALLER_UNDERFLOW, redzone_sysctl, "I", "");
116SYSCTL_PROC(_debug_redzone, OID_AUTO, realloc_smaller_overflow, CTLTYPE_INT | CTLFLAG_RW,
117    NULL, REDZONE_REALLOC_SMALLER_OVERFLOW, redzone_sysctl, "I", "");
118SYSCTL_PROC(_debug_redzone, OID_AUTO, realloc_bigger_underflow, CTLTYPE_INT | CTLFLAG_RW,
119    NULL, REDZONE_REALLOC_BIGGER_UNDERFLOW, redzone_sysctl, "I", "");
120SYSCTL_PROC(_debug_redzone, OID_AUTO, realloc_bigger_overflow, CTLTYPE_INT | CTLFLAG_RW,
121    NULL, REDZONE_REALLOC_BIGGER_OVERFLOW, redzone_sysctl, "I", "");
122
123static int
124redzone_modevent(module_t mod, int type, void *data)
125{
126
127	switch (type) {
128	case MOD_LOAD:
129	case MOD_UNLOAD:
130		break;
131	default:
132		return (EOPNOTSUPP);
133	}
134	return (0);
135}
136static moduledata_t redzone_module = {
137	"redzone",
138	redzone_modevent,
139	NULL
140};
141DECLARE_MODULE(redzone, redzone_module, SI_SUB_DRIVERS, SI_ORDER_MIDDLE);
142