include/safe_string.h

説明を見る。
00001 /* 
00002    Unix SMB/CIFS implementation.
00003    Safe string handling routines.
00004    Copyright (C) Andrew Tridgell 1994-1998
00005    Copyright (C) Andrew Bartlett <abartlet@samba.org> 2003
00006    
00007    This program is free software; you can redistribute it and/or modify
00008    it under the terms of the GNU General Public License as published by
00009    the Free Software Foundation; either version 2 of the License, or
00010    (at your option) any later version.
00011    
00012    This program is distributed in the hope that it will be useful,
00013    but WITHOUT ANY WARRANTY; without even the implied warranty of
00014    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015    GNU General Public License for more details.
00016    
00017    You should have received a copy of the GNU General Public License
00018    along with this program; if not, write to the Free Software
00019    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00020 */
00021 
00022 #ifndef _SAFE_STRING_H
00023 #define _SAFE_STRING_H
00024 
00025 #ifndef _SPLINT_ /* http://www.splint.org */
00026 
00027 /* Some macros to ensure people don't use buffer overflow vulnerable string
00028    functions. */
00029 
00030 #ifdef bcopy
00031 #undef bcopy
00032 #endif /* bcopy */
00033 #define bcopy(src,dest,size) __ERROR__XX__NEVER_USE_BCOPY___;
00034 
00035 #ifdef strcpy
00036 #undef strcpy
00037 #endif /* strcpy */
00038 #define strcpy(dest,src) __ERROR__XX__NEVER_USE_STRCPY___;
00039 
00040 #ifdef strcat
00041 #undef strcat
00042 #endif /* strcat */
00043 #define strcat(dest,src) __ERROR__XX__NEVER_USE_STRCAT___;
00044 
00045 #ifdef sprintf
00046 #undef sprintf
00047 #endif /* sprintf */
00048 #define sprintf __ERROR__XX__NEVER_USE_SPRINTF__;
00049 
00050 /*
00051  * strcasecmp/strncasecmp aren't an error, but it means you're not thinking about
00052  * multibyte. Don't use them. JRA.
00053  */
00054 #ifdef strcasecmp
00055 #undef strcasecmp
00056 #endif
00057 #define strcasecmp __ERROR__XX__NEVER_USE_STRCASECMP__;
00058 
00059 #ifdef strncasecmp
00060 #undef strncasecmp
00061 #endif
00062 #define strncasecmp __ERROR__XX__NEVER_USE_STRNCASECMP__;
00063 
00064 #endif /* !_SPLINT_ */
00065 
00066 #ifdef DEVELOPER
00067 #define SAFE_STRING_FUNCTION_NAME FUNCTION_MACRO
00068 #define SAFE_STRING_LINE __LINE__
00069 #else
00070 #define SAFE_STRING_FUNCTION_NAME ("")
00071 #define SAFE_STRING_LINE (0)
00072 #endif
00073 
00074 /* We need a number of different prototypes for our 
00075    non-existant fuctions */
00076 char * __unsafe_string_function_usage_here__(void);
00077 
00078 size_t __unsafe_string_function_usage_here_size_t__(void);
00079 
00080 size_t __unsafe_string_function_usage_here_char__(void);
00081 
00082 #ifdef HAVE_COMPILER_WILL_OPTIMIZE_OUT_FNS
00083 
00084 /* if the compiler will optimize out function calls, then use this to tell if we are 
00085    have the correct types (this works only where sizeof() returns the size of the buffer, not
00086    the size of the pointer). */
00087 
00088 #define CHECK_STRING_SIZE(d, len) (sizeof(d) != (len) && sizeof(d) != sizeof(char *))
00089 
00090 #define fstrterminate(d) (CHECK_STRING_SIZE(d, sizeof(fstring)) \
00091     ? __unsafe_string_function_usage_here_char__() \
00092     : (((d)[sizeof(fstring)-1]) = '\0'))
00093 #define pstrterminate(d) (CHECK_STRING_SIZE(d, sizeof(pstring)) \
00094     ? __unsafe_string_function_usage_here_char__() \
00095     : (((d)[sizeof(pstring)-1]) = '\0'))
00096 
00097 #define wpstrcpy(d,s) ((sizeof(d) != sizeof(wpstring) && sizeof(d) != sizeof(smb_ucs2_t *)) \
00098     ? __unsafe_string_function_usage_here__() \
00099     : safe_strcpy_w((d),(s),sizeof(wpstring)))
00100 #define wpstrcat(d,s) ((sizeof(d) != sizeof(wpstring) && sizeof(d) != sizeof(smb_ucs2_t *)) \
00101     ? __unsafe_string_function_usage_here__() \
00102     : safe_strcat_w((d),(s),sizeof(wpstring)))
00103 #define wfstrcpy(d,s) ((sizeof(d) != sizeof(wfstring) && sizeof(d) != sizeof(smb_ucs2_t *)) \
00104     ? __unsafe_string_function_usage_here__() \
00105     : safe_strcpy_w((d),(s),sizeof(wfstring)))
00106 #define wfstrcat(d,s) ((sizeof(d) != sizeof(wfstring) && sizeof(d) != sizeof(smb_ucs2_t *)) \
00107     ? __unsafe_string_function_usage_here__() \
00108     : safe_strcat_w((d),(s),sizeof(wfstring)))
00109 
00110 #define push_pstring_base(dest, src, pstring_base) \
00111     (CHECK_STRING_SIZE(pstring_base, sizeof(pstring)) \
00112     ? __unsafe_string_function_usage_here_size_t__() \
00113     : push_ascii(dest, src, sizeof(pstring)-PTR_DIFF(dest,pstring_base)-1, STR_TERMINATE))
00114 
00115 #else /* HAVE_COMPILER_WILL_OPTIMIZE_OUT_FNS */
00116 
00117 #define fstrterminate(d) (((d)[sizeof(fstring)-1]) = '\0')
00118 #define pstrterminate(d) (((d)[sizeof(pstring)-1]) = '\0')
00119 
00120 #define wpstrcpy(d,s) safe_strcpy_w((d),(s),sizeof(wpstring))
00121 #define wpstrcat(d,s) safe_strcat_w((d),(s),sizeof(wpstring))
00122 #define wfstrcpy(d,s) safe_strcpy_w((d),(s),sizeof(wfstring))
00123 #define wfstrcat(d,s) safe_strcat_w((d),(s),sizeof(wfstring))
00124 
00125 #define push_pstring_base(dest, src, pstring_base) \
00126     push_ascii(dest, src, sizeof(pstring)-PTR_DIFF(dest,pstring_base)-1, STR_TERMINATE)
00127 
00128 #endif /* HAVE_COMPILER_WILL_OPTIMIZE_OUT_FNS */
00129 
00130 #define safe_strcpy_base(dest, src, base, size) \
00131     safe_strcpy(dest, src, size-PTR_DIFF(dest,base)-1)
00132 
00133 /* String copy functions - macro hell below adds 'type checking' (limited,
00134    but the best we can do in C) and may tag with function name/number to
00135    record the last 'clobber region' on that string */
00136 
00137 #define pstrcpy(d,s) safe_strcpy((d), (s),sizeof(pstring)-1)
00138 #define pstrcat(d,s) safe_strcat((d), (s),sizeof(pstring)-1)
00139 #define fstrcpy(d,s) safe_strcpy((d),(s),sizeof(fstring)-1)
00140 #define fstrcat(d,s) safe_strcat((d),(s),sizeof(fstring)-1)
00141 #define nstrcpy(d,s) safe_strcpy((d), (s),sizeof(nstring)-1)
00142 #define unstrcpy(d,s) safe_strcpy((d), (s),sizeof(unstring)-1)
00143 
00144 /* the addition of the DEVELOPER checks in safe_strcpy means we must
00145  * update a lot of code. To make this a little easier here are some
00146  * functions that provide the lengths with less pain */
00147 #define pstrcpy_base(dest, src, pstring_base) \
00148     safe_strcpy(dest, src, sizeof(pstring)-PTR_DIFF(dest,pstring_base)-1)
00149 
00150 
00151 /* Inside the _fn variants of these is a call to clobber_region(), -
00152  * which might destroy the stack on a buggy function.  We help the
00153  * debugging process by putting the function and line who last caused
00154  * a clobbering into a static buffer.  If the program crashes at
00155  * address 0xf1f1f1f1 then this function is probably, but not
00156  * necessarily, to blame. */
00157 
00158 /* overmalloc_safe_strcpy: DEPRECATED!  Used when you know the
00159  * destination buffer is longer than maxlength, but you don't know how
00160  * long.  This is not a good situation, because we can't do the normal
00161  * sanity checks. Don't use in new code! */
00162 
00163 #define overmalloc_safe_strcpy(dest,src,maxlength)      safe_strcpy_fn(SAFE_STRING_FUNCTION_NAME, SAFE_STRING_LINE,dest,src,maxlength)
00164 #define safe_strcpy(dest,src,maxlength) safe_strcpy_fn2(SAFE_STRING_FUNCTION_NAME, SAFE_STRING_LINE,dest,src,maxlength)
00165 #define safe_strcat(dest,src,maxlength) safe_strcat_fn2(SAFE_STRING_FUNCTION_NAME, SAFE_STRING_LINE,dest,src,maxlength)
00166 #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)
00167 #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)
00168 #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)
00169 #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)
00170 #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)
00171 
00172 #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)
00173 #define StrnCpy(dest,src,n)             StrnCpy_fn(SAFE_STRING_FUNCTION_NAME,SAFE_STRING_LINE,dest,src,n)
00174 
00175 #ifdef HAVE_COMPILER_WILL_OPTIMIZE_OUT_FNS
00176 
00177 /* if the compiler will optimize out function calls, then use this to tell if we are 
00178    have the correct types (this works only where sizeof() returns the size of the buffer, not
00179    the size of the pointer). */
00180 
00181 #define safe_strcpy_fn2(fn_name, fn_line, d, s, max_len) \
00182     (CHECK_STRING_SIZE(d, max_len+1) \
00183     ? __unsafe_string_function_usage_here__() \
00184     : safe_strcpy_fn(fn_name, fn_line, (d), (s), (max_len)))
00185 
00186 #define safe_strcat_fn2(fn_name, fn_line, d, s, max_len) \
00187     (CHECK_STRING_SIZE(d, max_len+1) \
00188     ? __unsafe_string_function_usage_here__() \
00189     : safe_strcat_fn(fn_name, fn_line, (d), (s), (max_len)))
00190 
00191 #define push_string_fn2(fn_name, fn_line, base_ptr, dest, src, dest_len, flags) \
00192     (CHECK_STRING_SIZE(dest, dest_len) \
00193     ? __unsafe_string_function_usage_here_size_t__() \
00194     : push_string_fn(fn_name, fn_line, base_ptr, dest, src, dest_len, flags))
00195 
00196 #define pull_string_fn2(fn_name, fn_line, base_ptr, dest, src, dest_len, src_len, flags) \
00197     (CHECK_STRING_SIZE(dest, dest_len) \
00198     ? __unsafe_string_function_usage_here_size_t__() \
00199     : pull_string_fn(fn_name, fn_line, base_ptr, dest, src, dest_len, src_len, flags))
00200 
00201 #define clistr_push_fn2(fn_name, fn_line, cli, dest, src, dest_len, flags) \
00202     (CHECK_STRING_SIZE(dest, dest_len) \
00203     ? __unsafe_string_function_usage_here_size_t__() \
00204     : clistr_push_fn(fn_name, fn_line, cli, dest, src, dest_len, flags))
00205 
00206 #define clistr_pull_fn2(fn_name, fn_line, cli, dest, src, dest_len, srclen, flags) \
00207     (CHECK_STRING_SIZE(dest, dest_len) \
00208     ? __unsafe_string_function_usage_here_size_t__() \
00209     : clistr_pull_fn(fn_name, fn_line, cli, dest, src, dest_len, srclen, flags))
00210 
00211 #define srvstr_push_fn2(fn_name, fn_line, base_ptr, dest, src, dest_len, flags) \
00212     (CHECK_STRING_SIZE(dest, dest_len) \
00213     ? __unsafe_string_function_usage_here_size_t__() \
00214     : srvstr_push_fn(fn_name, fn_line, base_ptr, dest, src, dest_len, flags))
00215 
00216 #else
00217 
00218 #define safe_strcpy_fn2 safe_strcpy_fn
00219 #define safe_strcat_fn2 safe_strcat_fn
00220 #define push_string_fn2 push_string_fn
00221 #define pull_string_fn2 pull_string_fn
00222 #define clistr_push_fn2 clistr_push_fn
00223 #define clistr_pull_fn2 clistr_pull_fn
00224 #define srvstr_push_fn2 srvstr_push_fn
00225 
00226 #endif
00227 
00228 #endif

Sambaに対してSat Aug 29 21:22:57 2009に生成されました。  doxygen 1.4.7