1 #ifndef _BOUNDS_H
2 #define _BOUNDS_H
3 /*
4 ** Copyright (C) 2003-2009 Sourcefire, Inc.
5 **               Chris Green <cmg@sourcefire.com>
6 **
7 ** This program is free software; you can redistribute it and/or modify
8 ** it under the terms of the GNU General Public License Version 2 as
9 ** published by the Free Software Foundation.  You may not use, modify or
10 ** distribute this program under any other version of the GNU General
11 ** Public License.
12 **
13 ** This program is distributed in the hope that it will be useful,
14 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
15 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 ** GNU General Public License for more details.
17 **
18 ** You should have received a copy of the GNU General Public License
19 ** along with this program; if not, write to the Free Software
20 ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21 **
22 */
23 
24 
25 #ifdef HAVE_CONFIG_H
26 #include "config.h"
27 #endif
28 
29 #ifdef OSF1
30 #include <sys/bitypes.h>
31 #endif
32 
33 #include <string.h>
34 #include <stdio.h>
35 #include <stdlib.h>
36 #include <sys/types.h>
37 #include <assert.h>
38 #include <unistd.h>
39 
40 #define SAFEMEM_ERROR 0
41 #define SAFEMEM_SUCCESS 1
42 
43 #include "debug.h"
44 #ifndef DEBUG
45     #define ERRORRET return SAFEMEM_ERROR;
46 #else
47     #define ERRORRET assert(0==1)
48 #endif /* DEBUG */
49 
50 #include "sf_types.h"
51 
52 
53 /*
54  * Check to make sure that p is less than or equal to the ptr range
55  * pointers
56  *
57  * 1 means it's in bounds, 0 means it's not
58  */
inBounds(const uint8_t * start,const uint8_t * end,const uint8_t * p)59 static INLINE int inBounds(const uint8_t *start, const uint8_t *end, const uint8_t *p)
60 {
61     if(p >= start && p < end)
62     {
63         return 1;
64     }
65 
66     return 0;
67 }
68 
69 /**
70  * A Safer Memcpy
71  *
72  * @param dst where to copy to
73  * @param src where to copy from
74  * @param n number of bytes to copy
75  * @param start start of the dest buffer
76  * @param end end of the dst buffer
77  *
78  * @return 0 on failure, 1 on success
79  */
SafeMemcpy(void * dst,const void * src,size_t n,const void * start,const void * end)80 static INLINE int SafeMemcpy(void *dst, const void *src, size_t n, const void *start, const void *end)
81 {
82     void *tmp;
83 
84     if(n < 1)
85     {
86         ERRORRET;
87     }
88 
89     if (!dst || !src || !start || !end)
90     {
91         ERRORRET;
92     }
93 
94     tmp = ((uint8_t*)dst) + (n-1);
95     if (tmp < dst)
96     {
97         ERRORRET;
98     }
99 
100     if(!inBounds(start,end, dst) || !inBounds(start,end,tmp))
101     {
102         ERRORRET;
103     }
104 
105     memcpy(dst, src, n);
106 
107     return SAFEMEM_SUCCESS;
108 }
109 
110 /**
111  * A Safer Memmove
112  * dst and src can be in the same buffer
113  *
114  * @param dst where to copy to
115  * @param src where to copy from
116  * @param n number of bytes to copy
117  * @param start start of the dest buffer
118  * @param end end of the dst buffer
119  *
120  * @return 0 on failure, 1 on success
121  */
SafeMemmove(void * dst,const void * src,size_t n,const void * start,const void * end)122 static INLINE int SafeMemmove(void *dst, const void *src, size_t n, const void *start, const void *end)
123 {
124     void *tmp;
125 
126     if(n < 1)
127     {
128         ERRORRET;
129     }
130 
131     if (!dst || !src || !start || !end)
132     {
133         ERRORRET;
134     }
135 
136     tmp = ((uint8_t*)dst) + (n-1);
137     if (tmp < dst)
138     {
139         ERRORRET;
140     }
141 
142     if(!inBounds(start,end, dst) || !inBounds(start,end,tmp))
143     {
144         ERRORRET;
145     }
146 
147     memmove(dst, src, n);
148 
149     return SAFEMEM_SUCCESS;
150 }
151 
152 /**
153  * A Safer *a = *b
154  *
155  * @param start start of the dst buffer
156  * @param end end of the dst buffer
157  * @param dst the location to write to
158  * @param src the source to read from
159  *
160  * @return 0 on failure, 1 on success
161  */
SafeWrite(uint8_t * start,uint8_t * end,uint8_t * dst,uint8_t * src)162 static INLINE int SafeWrite(uint8_t *start, uint8_t *end, uint8_t *dst, uint8_t *src)
163 {
164     if(!inBounds(start, end, dst))
165     {
166         ERRORRET;
167     }
168 
169     *dst = *src;
170     return 1;
171 }
172 
SafeRead(uint8_t * start,uint8_t * end,uint8_t * src,uint8_t * read)173 static INLINE int SafeRead(uint8_t *start, uint8_t *end, uint8_t *src, uint8_t *read)
174 {
175     if(!inBounds(start,end, src))
176     {
177         ERRORRET;
178     }
179 
180     *read = *start;
181     return 1;
182 }
183 
184 #endif /* _BOUNDS_H */
185