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