1/* 2 Unix SMB/CIFS implementation. 3 Safe string handling routines. 4 Copyright (C) Andrew Tridgell 1994-1998 5 Copyright (C) Andrew Bartlett <abartlet@samba.org> 2003 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 as published by 9 the Free Software Foundation; either version 2 of the License, or 10 (at your option) any later version. 11 12 This program is distributed in the hope that it will be useful, 13 but WITHOUT ANY WARRANTY; without even the implied warranty of 14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 GNU General Public License for more details. 16 17 You should have received a copy of the GNU General Public License 18 along with this program; if not, write to the Free Software 19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 20*/ 21 22#ifndef _SAFE_STRING_H 23#define _SAFE_STRING_H 24 25#ifndef _SPLINT_ /* http://www.splint.org */ 26 27/* Some macros to ensure people don't use buffer overflow vulnerable string 28 functions. */ 29 30#ifdef bcopy 31#undef bcopy 32#endif /* bcopy */ 33#define bcopy(src,dest,size) __ERROR__XX__NEVER_USE_BCOPY___; 34 35#ifdef strcpy 36#undef strcpy 37#endif /* strcpy */ 38#define strcpy(dest,src) __ERROR__XX__NEVER_USE_STRCPY___; 39 40#ifdef strcat 41#undef strcat 42#endif /* strcat */ 43#define strcat(dest,src) __ERROR__XX__NEVER_USE_STRCAT___; 44 45#ifdef sprintf 46#undef sprintf 47#endif /* sprintf */ 48#define sprintf __ERROR__XX__NEVER_USE_SPRINTF__; 49 50/* 51 * strcasecmp/strncasecmp aren't an error, but it means you're not thinking about 52 * multibyte. Don't use them. JRA. 53 */ 54#ifdef strcasecmp 55#undef strcasecmp 56#endif 57#define strcasecmp __ERROR__XX__NEVER_USE_STRCASECMP__; 58 59#ifdef strncasecmp 60#undef strncasecmp 61#endif 62#define strncasecmp __ERROR__XX__NEVER_USE_STRNCASECMP__; 63 64#endif /* !_SPLINT_ */ 65 66#ifdef DEVELOPER 67#define SAFE_STRING_FUNCTION_NAME FUNCTION_MACRO 68#define SAFE_STRING_LINE __LINE__ 69#else 70#define SAFE_STRING_FUNCTION_NAME ("") 71#define SAFE_STRING_LINE (0) 72#endif 73 74/* We need a number of different prototypes for our 75 non-existant fuctions */ 76char * __unsafe_string_function_usage_here__(void); 77 78size_t __unsafe_string_function_usage_here_size_t__(void); 79 80size_t __unsafe_string_function_usage_here_char__(void); 81 82#ifdef HAVE_COMPILER_WILL_OPTIMIZE_OUT_FNS 83 84/* if the compiler will optimize out function calls, then use this to tell if we are 85 have the correct types (this works only where sizeof() returns the size of the buffer, not 86 the size of the pointer). */ 87 88#define CHECK_STRING_SIZE(d, len) (sizeof(d) != (len) && sizeof(d) != sizeof(char *)) 89 90#define fstrterminate(d) (CHECK_STRING_SIZE(d, sizeof(fstring)) \ 91 ? __unsafe_string_function_usage_here_char__() \ 92 : (((d)[sizeof(fstring)-1]) = '\0')) 93#define pstrterminate(d) (CHECK_STRING_SIZE(d, sizeof(pstring)) \ 94 ? __unsafe_string_function_usage_here_char__() \ 95 : (((d)[sizeof(pstring)-1]) = '\0')) 96 97#define wpstrcpy(d,s) ((sizeof(d) != sizeof(wpstring) && sizeof(d) != sizeof(smb_ucs2_t *)) \ 98 ? __unsafe_string_function_usage_here__() \ 99 : safe_strcpy_w((d),(s),sizeof(wpstring))) 100#define wpstrcat(d,s) ((sizeof(d) != sizeof(wpstring) && sizeof(d) != sizeof(smb_ucs2_t *)) \ 101 ? __unsafe_string_function_usage_here__() \ 102 : safe_strcat_w((d),(s),sizeof(wpstring))) 103#define wfstrcpy(d,s) ((sizeof(d) != sizeof(wfstring) && sizeof(d) != sizeof(smb_ucs2_t *)) \ 104 ? __unsafe_string_function_usage_here__() \ 105 : safe_strcpy_w((d),(s),sizeof(wfstring))) 106#define wfstrcat(d,s) ((sizeof(d) != sizeof(wfstring) && sizeof(d) != sizeof(smb_ucs2_t *)) \ 107 ? __unsafe_string_function_usage_here__() \ 108 : safe_strcat_w((d),(s),sizeof(wfstring))) 109 110#define push_pstring_base(dest, src, pstring_base) \ 111 (CHECK_STRING_SIZE(pstring_base, sizeof(pstring)) \ 112 ? __unsafe_string_function_usage_here_size_t__() \ 113 : push_ascii(dest, src, sizeof(pstring)-PTR_DIFF(dest,pstring_base)-1, STR_TERMINATE)) 114 115#else /* HAVE_COMPILER_WILL_OPTIMIZE_OUT_FNS */ 116 117#define fstrterminate(d) (((d)[sizeof(fstring)-1]) = '\0') 118#define pstrterminate(d) (((d)[sizeof(pstring)-1]) = '\0') 119 120#define wpstrcpy(d,s) safe_strcpy_w((d),(s),sizeof(wpstring)) 121#define wpstrcat(d,s) safe_strcat_w((d),(s),sizeof(wpstring)) 122#define wfstrcpy(d,s) safe_strcpy_w((d),(s),sizeof(wfstring)) 123#define wfstrcat(d,s) safe_strcat_w((d),(s),sizeof(wfstring)) 124 125#define push_pstring_base(dest, src, pstring_base) \ 126 push_ascii(dest, src, sizeof(pstring)-PTR_DIFF(dest,pstring_base)-1, STR_TERMINATE) 127 128#endif /* HAVE_COMPILER_WILL_OPTIMIZE_OUT_FNS */ 129 130#define safe_strcpy_base(dest, src, base, size) \ 131 safe_strcpy(dest, src, size-PTR_DIFF(dest,base)-1) 132 133/* String copy functions - macro hell below adds 'type checking' (limited, 134 but the best we can do in C) and may tag with function name/number to 135 record the last 'clobber region' on that string */ 136 137#define pstrcpy(d,s) safe_strcpy((d), (s),sizeof(pstring)-1) 138#define pstrcat(d,s) safe_strcat((d), (s),sizeof(pstring)-1) 139#define fstrcpy(d,s) safe_strcpy((d),(s),sizeof(fstring)-1) 140#define fstrcat(d,s) safe_strcat((d),(s),sizeof(fstring)-1) 141#define nstrcpy(d,s) safe_strcpy((d), (s),sizeof(nstring)-1) 142#define unstrcpy(d,s) safe_strcpy((d), (s),sizeof(unstring)-1) 143 144/* the addition of the DEVELOPER checks in safe_strcpy means we must 145 * update a lot of code. To make this a little easier here are some 146 * functions that provide the lengths with less pain */ 147#define pstrcpy_base(dest, src, pstring_base) \ 148 safe_strcpy(dest, src, sizeof(pstring)-PTR_DIFF(dest,pstring_base)-1) 149 150 151/* Inside the _fn variants of these is a call to clobber_region(), - 152 * which might destroy the stack on a buggy function. We help the 153 * debugging process by putting the function and line who last caused 154 * a clobbering into a static buffer. If the program crashes at 155 * address 0xf1f1f1f1 then this function is probably, but not 156 * necessarily, to blame. */ 157 158/* overmalloc_safe_strcpy: DEPRECATED! Used when you know the 159 * destination buffer is longer than maxlength, but you don't know how 160 * long. This is not a good situation, because we can't do the normal 161 * sanity checks. Don't use in new code! */ 162 163#define overmalloc_safe_strcpy(dest,src,maxlength) safe_strcpy_fn(SAFE_STRING_FUNCTION_NAME, SAFE_STRING_LINE,dest,src,maxlength) 164#define safe_strcpy(dest,src,maxlength) safe_strcpy_fn2(SAFE_STRING_FUNCTION_NAME, SAFE_STRING_LINE,dest,src,maxlength) 165#define safe_strcat(dest,src,maxlength) safe_strcat_fn2(SAFE_STRING_FUNCTION_NAME, SAFE_STRING_LINE,dest,src,maxlength) 166#define push_string(base_ptr, dest, src, dest_len, flags) push_string_fn2(SAFE_STRING_FUNCTION_NAME, SAFE_STRING_LINE, base_ptr, dest, src, dest_len, flags) 167#define pull_string(base_ptr, dest, src, dest_len, src_len, flags) pull_string_fn2(SAFE_STRING_FUNCTION_NAME, SAFE_STRING_LINE, base_ptr, dest, src, dest_len, src_len, flags) 168#define clistr_push(cli, dest, src, dest_len, flags) clistr_push_fn2(SAFE_STRING_FUNCTION_NAME, SAFE_STRING_LINE, cli, dest, src, dest_len, flags) 169#define clistr_pull(cli, dest, src, dest_len, src_len, flags) clistr_pull_fn2(SAFE_STRING_FUNCTION_NAME, SAFE_STRING_LINE, cli, dest, src, dest_len, src_len, flags) 170#define srvstr_push(base_ptr, dest, src, dest_len, flags) srvstr_push_fn2(SAFE_STRING_FUNCTION_NAME, SAFE_STRING_LINE, base_ptr, dest, src, dest_len, flags) 171 172#define alpha_strcpy(dest,src,other_safe_chars,maxlength) alpha_strcpy_fn(SAFE_STRING_FUNCTION_NAME,SAFE_STRING_LINE,dest,src,other_safe_chars,maxlength) 173#define StrnCpy(dest,src,n) StrnCpy_fn(SAFE_STRING_FUNCTION_NAME,SAFE_STRING_LINE,dest,src,n) 174 175#ifdef HAVE_COMPILER_WILL_OPTIMIZE_OUT_FNS 176 177/* if the compiler will optimize out function calls, then use this to tell if we are 178 have the correct types (this works only where sizeof() returns the size of the buffer, not 179 the size of the pointer). */ 180 181#define safe_strcpy_fn2(fn_name, fn_line, d, s, max_len) \ 182 (CHECK_STRING_SIZE(d, max_len+1) \ 183 ? __unsafe_string_function_usage_here__() \ 184 : safe_strcpy_fn(fn_name, fn_line, (d), (s), (max_len))) 185 186#define safe_strcat_fn2(fn_name, fn_line, d, s, max_len) \ 187 (CHECK_STRING_SIZE(d, max_len+1) \ 188 ? __unsafe_string_function_usage_here__() \ 189 : safe_strcat_fn(fn_name, fn_line, (d), (s), (max_len))) 190 191#define push_string_fn2(fn_name, fn_line, base_ptr, dest, src, dest_len, flags) \ 192 (CHECK_STRING_SIZE(dest, dest_len) \ 193 ? __unsafe_string_function_usage_here_size_t__() \ 194 : push_string_fn(fn_name, fn_line, base_ptr, dest, src, dest_len, flags)) 195 196#define pull_string_fn2(fn_name, fn_line, base_ptr, dest, src, dest_len, src_len, flags) \ 197 (CHECK_STRING_SIZE(dest, dest_len) \ 198 ? __unsafe_string_function_usage_here_size_t__() \ 199 : pull_string_fn(fn_name, fn_line, base_ptr, dest, src, dest_len, src_len, flags)) 200 201#define clistr_push_fn2(fn_name, fn_line, cli, dest, src, dest_len, flags) \ 202 (CHECK_STRING_SIZE(dest, dest_len) \ 203 ? __unsafe_string_function_usage_here_size_t__() \ 204 : clistr_push_fn(fn_name, fn_line, cli, dest, src, dest_len, flags)) 205 206#define clistr_pull_fn2(fn_name, fn_line, cli, dest, src, dest_len, srclen, flags) \ 207 (CHECK_STRING_SIZE(dest, dest_len) \ 208 ? __unsafe_string_function_usage_here_size_t__() \ 209 : clistr_pull_fn(fn_name, fn_line, cli, dest, src, dest_len, srclen, flags)) 210 211#define srvstr_push_fn2(fn_name, fn_line, base_ptr, dest, src, dest_len, flags) \ 212 (CHECK_STRING_SIZE(dest, dest_len) \ 213 ? __unsafe_string_function_usage_here_size_t__() \ 214 : srvstr_push_fn(fn_name, fn_line, base_ptr, dest, src, dest_len, flags)) 215 216#else 217 218#define safe_strcpy_fn2 safe_strcpy_fn 219#define safe_strcat_fn2 safe_strcat_fn 220#define push_string_fn2 push_string_fn 221#define pull_string_fn2 pull_string_fn 222#define clistr_push_fn2 clistr_push_fn 223#define clistr_pull_fn2 clistr_pull_fn 224#define srvstr_push_fn2 srvstr_push_fn 225 226#endif 227 228#endif 229