1 /*
2  * (c) Copyright 1990 Conor P. Cahill (uunet!virtech!cpcahil).
3  * You may copy, distribute, and use this software as long as this
4  * copyright statement is not removed.
5  */
6 
7 #include <stdio.h>
8 #include "malloc.h"
9 #include "debug.h"
10 
11 #ifndef lint
12 static
13 char rcs_hdr[] = "$Id: mlc_chk.c,v 1.2 2006-07-25 10:09:34 rt Exp $";
14 #endif
15 
16 extern struct mlist	  malloc_start;
17 extern struct mlist	* malloc_end;
18 extern char		* malloc_data_start;
19 extern char		* malloc_data_end;
20 
21 /*
22  * Function:	malloc_in_arena()
23  *
24  * Purpose:	to verify address is within malloc arena.
25  *
26  * Arguments:	ptr	- pointer to verify
27  *
28  * Returns:	TRUE	- if pointer is within malloc area
29  *		FALSE	- otherwise
30  *
31  * Narrative:
32  *   IF pointer is >= malloc area start AND <= malloc area end
33  *      return TRUE
34  *   ELSE
35  *      return FALSE
36  *
37  * Mod History:
38  *   90/01/24	cpcahil		Initial revision.
39  */
40 int
malloc_in_arena(ptr)41 malloc_in_arena(ptr)
42 	char	* ptr;
43 {
44 	extern char	* malloc_data_start;
45 	extern char	* malloc_data_end;
46 	int		  rtn = 0;
47 
48 	if( ptr >= malloc_data_start && ptr <= malloc_data_end )
49 	{
50 		rtn = 1;
51 	}
52 
53 	return(rtn);
54 }
55 
56 /*
57  * Function:	malloc_check_str()
58  *
59  * Arguments:	func	- name of function calling this routine
60  *		str	- pointer to area to check
61  *
62  * Purpose:	to verify that if str is within the malloc arena, the data
63  *		it points to does not extend beyond the applicable region.
64  *
65  * Returns:	Nothing of any use (function is void).
66  *
67  * Narrative:
68  *   IF pointer is within malloc arena
69  *      determin length of string
70  *      call malloc_verify() to verify data is withing applicable region
71  *   return
72  *
73  * Mod History:
74  *   90/01/24	cpcahil		Initial revision.
75  *   90/01/29	cpcahil		Added code to ignore recursive calls.
76  */
77 void
malloc_check_str(func,str)78 malloc_check_str(func,str)
79 	char		* func;
80 	char		* str;
81 {
82 	static int	  layers;
83 	register char	* s;
84 
85 	if( (layers++ == 0) &&  malloc_in_arena(str) )
86 	{
87 		for( s=str; *s; s++)
88 		{
89 		}
90 
91 		malloc_verify(func,str,s-str+1);
92 	}
93 
94 	layers--;
95 }
96 
97 /*
98  * Function:	malloc_check_strn()
99  *
100  * Arguments:	func	- name of function calling this routine
101  *		str	- pointer to area to check
102  * 		len     - max length of string
103  *
104  * Purpose:	to verify that if str is within the malloc arena, the data
105  *		it points to does not extend beyond the applicable region.
106  *
107  * Returns:	Nothing of any use (function is void).
108  *
109  * Narrative:
110  *   IF pointer is within malloc arena
111  *      determin length of string
112  *      call malloc_verify() to verify data is withing applicable region
113  *   return
114  *
115  * Mod History:
116  *   90/01/24	cpcahil		Initial revision.
117  *   90/01/29	cpcahil		Added code to ignore recursive calls.
118  *   90/08/29	cpcahil		added length (for strn* functions)
119  */
120 void
malloc_check_strn(func,str,len)121 malloc_check_strn(func,str,len)
122 	char		* func;
123 	char		* str;
124 	int		  len;
125 {
126 	register int	  i;
127 	static int	  layers;
128 	register char	* s;
129 
130 	if( (layers++ == 0) &&  malloc_in_arena(str) )
131 	{
132 		for( s=str,i=0; (i < len) && *s; s++)
133 		{
134 		}
135 
136 		malloc_verify(func,str,s-str+1);
137 	}
138 
139 	layers--;
140 }
141 
142 /*
143  * Function:	malloc_check_data()
144  *
145  * Arguments:	func	- name of function calling this routine
146  *		ptr	- pointer to area to check
147  *		len 	- length to verify
148  *
149  * Purpose:	to verify that if ptr is within the malloc arena, the data
150  *		it points to does not extend beyond the applicable region.
151  *
152  * Returns:	Nothing of any use (function is void).
153  *
154  * Narrative:
155  *   IF pointer is within malloc arena
156  *      call malloc_verify() to verify data is withing applicable region
157  *   return
158  *
159  * Mod History:
160  *   90/01/24	cpcahil		Initial revision.
161  *   90/01/29	cpcahil		Added code to ignore recursive calls.
162  */
163 void
malloc_check_data(func,ptr,len)164 malloc_check_data(func,ptr,len)
165 	char		* func;
166 	char		* ptr;
167 	int		  len;
168 {
169 	static int	  layers;
170 
171 	if( layers++ == 0 )
172 	{
173 		DEBUG3(40,"malloc_check_data(%s,0x%x,%d) called...",
174 			func,ptr,len);
175 		if( malloc_in_arena(ptr) )
176 		{
177 			DEBUG0(10,"pointer in malloc arena, verifying...");
178 			malloc_verify(func,ptr,len);
179 		}
180 	}
181 
182 	layers--;
183 }
184 
185 /*
186  * Function:	malloc_verify()
187  *
188  * Arguments:	func	- name of function calling the malloc check routines
189  *		ptr	- pointer to area to check
190  *		len 	- length to verify
191  *
192  * Purpose:	to verify that the data ptr points to does not extend beyond
193  *		the applicable malloc region.  This function is only called
194  *		if it has been determined that ptr points into the malloc arena.
195  *
196  * Returns:	Nothing of any use (function is void).
197  *
198  * Narrative:
199  *
200  * Mod History:
201  *   90/01/24	cpcahil		Initial revision.
202  */
203 void
malloc_verify(func,ptr,len)204 malloc_verify(func,ptr,len)
205 	char		* func;
206 	char		* ptr;
207 	int		  len;
208 {
209 	extern struct mlist	* malloc_end;
210 	extern int		  malloc_errno;
211 	extern struct mlist 	  malloc_start;
212 	struct mlist		* mptr;
213 
214 	DEBUG3(40,"malloc_verify(%s,0x%x,%d) called...", func,ptr,len);
215 	/*
216 	 * Find the malloc block that includes this pointer
217 	 */
218 	mptr = &malloc_start;
219 	while( mptr &&
220 		! (((char *)mptr < ptr) && ((mptr->data+mptr->s.size) > ptr) ) )
221 	{
222 		mptr = mptr->next;
223 	}
224 
225 	/*
226 	 * if ptr was not in a malloc block, it must be part of
227 	 *    some direct sbrk() stuff, so just return.
228 	 */
229 	if( ! mptr )
230 	{
231 		DEBUG1(10,"ptr (0x%x) not found in malloc search", ptr);
232 		return;
233 	}
234 
235 	/*
236  	 * Now we have a valid malloc block that contains the indicated
237 	 * pointer.  We must verify that it is withing the requested block
238 	 * size (as opposed to the real block size which is rounded up to
239 	 * allow for correct alignment).
240 	 */
241 
242 	DEBUG4(60,"Checking  0x%x-0x%x, 0x%x-0x%x",
243 			ptr, ptr+len, mptr->data, mptr->data+mptr->r_size);
244 
245 	if( (ptr < mptr->data) || ((ptr+len) > (mptr->data+mptr->r_size)) )
246 	{
247 		DEBUG4(0,"pointer not within region 0x%x-0x%x, 0x%x-0x%x",
248 			ptr, ptr+len, mptr->data, mptr->data+mptr->r_size);
249 
250 		malloc_errno = M_CODE_OUTOF_BOUNDS;
251 		malloc_warning(func);
252 	}
253 
254 	return;
255 }
256 
257