diff options
Diffstat (limited to 'source3')
-rw-r--r-- | source3/include/safe_string.h | 164 | ||||
-rw-r--r-- | source3/lib/charcnv.c | 115 | ||||
-rw-r--r-- | source3/lib/util.c | 16 | ||||
-rw-r--r-- | source3/lib/util_str.c | 98 | ||||
-rw-r--r-- | source3/libsmb/clistr.c | 28 |
5 files changed, 240 insertions, 181 deletions
diff --git a/source3/include/safe_string.h b/source3/include/safe_string.h index 95cf23df83..ad7b4139a3 100644 --- a/source3/include/safe_string.h +++ b/source3/include/safe_string.h @@ -48,29 +48,48 @@ #endif /* !_SPLINT_ */ +/* We need a number of different prototypes for our + non-existant fuctions */ char * __unsafe_string_function_usage_here__(void); -#if 0 && defined __GNUC__ && __GNUC__ >= 2 && defined __OPTIMIZE__ +size_t __unsafe_string_function_usage_here_size_t__(void); -#define pstrcpy(d,s) ((sizeof(d) != sizeof(pstring) && sizeof(d) != sizeof(char *)) ? __unsafe_string_function_usage_here__() : safe_strcpy((d), (s),sizeof(pstring)-1)) -#define pstrcat(d,s) ((sizeof(d) != sizeof(pstring) && sizeof(d) != sizeof(char *)) ? __unsafe_string_function_usage_here__() : safe_strcat((d), (s),sizeof(pstring)-1)) -#define fstrcpy(d,s) ((sizeof(d) != sizeof(fstring) && sizeof(d) != sizeof(char *)) ? __unsafe_string_function_usage_here__() : safe_strcpy((d),(s),sizeof(fstring)-1)) -#define fstrcat(d,s) ((sizeof(d) != sizeof(fstring) && sizeof(d) != sizeof(char *)) ? __unsafe_string_function_usage_here__() : safe_strcat((d),(s),sizeof(fstring)-1)) +size_t __unsafe_string_function_usage_here_char__(void); -#define fstrterminate(d) ((sizeof(d) != sizeof(fstring) && sizeof(d) != sizeof(char *)) ? __unsafe_string_function_usage_here__() : (((d)[sizeof(fstring)-1]) = '\0')) -#define pstrterminate(d) ((sizeof(d) != sizeof(pstring) && sizeof(d) != sizeof(char *)) ? __unsafe_string_function_usage_here__() : (((d)[sizeof(pstring)-1]) = '\0')) +#ifdef HAVE_COMPILER_WILL_OPTIMIZE_OUT_FNS -#define wpstrcpy(d,s) ((sizeof(d) != sizeof(wpstring) && sizeof(d) != sizeof(smb_ucs2_t *)) ? __unsafe_string_function_usage_here__() : safe_strcpy_w((d),(s),sizeof(wpstring))) -#define wpstrcat(d,s) ((sizeof(d) != sizeof(wpstring) && sizeof(d) != sizeof(smb_ucs2_t *)) ? __unsafe_string_function_usage_here__() : safe_strcat_w((d),(s),sizeof(wpstring))) -#define wfstrcpy(d,s) ((sizeof(d) != sizeof(wfstring) && sizeof(d) != sizeof(smb_ucs2_t *)) ? __unsafe_string_function_usage_here__() : safe_strcpy_w((d),(s),sizeof(wfstring))) -#define wfstrcat(d,s) ((sizeof(d) != sizeof(wfstring) && sizeof(d) != sizeof(smb_ucs2_t *)) ? __unsafe_string_function_usage_here__() : safe_strcat_w((d),(s),sizeof(wfstring))) +/* if the compiler will optimize out function calls, then use this to tell if we are + have the correct types (this works only where sizeof() returns the size of the buffer, not + the size of the pointer). */ -#else +#define CHECK_STRING_SIZE(d, len) (sizeof(d) != (len) && sizeof(d) != sizeof(char *)) -#define pstrcpy(d,s) safe_strcpy((d), (s),sizeof(pstring)-1) -#define pstrcat(d,s) safe_strcat((d), (s),sizeof(pstring)-1) -#define fstrcpy(d,s) safe_strcpy((d),(s),sizeof(fstring)-1) -#define fstrcat(d,s) safe_strcat((d),(s),sizeof(fstring)-1) +#define fstrterminate(d) (CHECK_STRING_SIZE(d, sizeof(fstring)) \ + ? __unsafe_string_function_usage_here_char__() \ + : (((d)[sizeof(fstring)-1]) = '\0')) +#define pstrterminate(d) (CHECK_STRING_SIZE(d, sizeof(pstring)) \ + ? __unsafe_string_function_usage_here_char__() \ + : (((d)[sizeof(pstring)-1]) = '\0')) + +#define wpstrcpy(d,s) ((sizeof(d) != sizeof(wpstring) && sizeof(d) != sizeof(smb_ucs2_t *)) \ + ? __unsafe_string_function_usage_here__() \ + : safe_strcpy_w((d),(s),sizeof(wpstring))) +#define wpstrcat(d,s) ((sizeof(d) != sizeof(wpstring) && sizeof(d) != sizeof(smb_ucs2_t *)) \ + ? __unsafe_string_function_usage_here__() \ + : safe_strcat_w((d),(s),sizeof(wpstring))) +#define wfstrcpy(d,s) ((sizeof(d) != sizeof(wfstring) && sizeof(d) != sizeof(smb_ucs2_t *)) \ + ? __unsafe_string_function_usage_here__() \ + : safe_strcpy_w((d),(s),sizeof(wfstring))) +#define wfstrcat(d,s) ((sizeof(d) != sizeof(wfstring) && sizeof(d) != sizeof(smb_ucs2_t *)) \ + ? __unsafe_string_function_usage_here__() \ + : safe_strcat_w((d),(s),sizeof(wfstring))) + +#define push_pstring_base(dest, src, pstring_base) \ + (CHECK_STRING_SIZE(pstring_base, sizeof(pstring)) \ + ? __unsafe_string_function_usage_here_size_t__() \ + : push_ascii(dest, src, sizeof(pstring)-PTR_DIFF(dest,pstring_base)-1, STR_TERMINATE)) + +#else /* HAVE_COMPILER_WILL_OPTIMIZE_OUT_FNS */ #define fstrterminate(d) (((d)[sizeof(fstring)-1]) = '\0') #define pstrterminate(d) (((d)[sizeof(pstring)-1]) = '\0') @@ -80,12 +99,10 @@ char * __unsafe_string_function_usage_here__(void); #define wfstrcpy(d,s) safe_strcpy_w((d),(s),sizeof(wfstring)) #define wfstrcat(d,s) safe_strcat_w((d),(s),sizeof(wfstring)) -#endif +#define push_pstring_base(dest, src, pstring_base) \ + push_ascii(dest, src, sizeof(pstring)-PTR_DIFF(dest,pstring_base)-1, STR_TERMINATE) -/* replace some string functions with multi-byte - versions */ -#define strlower(s) strlower_m(s) -#define strupper(s) strupper_m(s) +#endif /* HAVE_COMPILER_WILL_OPTIMIZE_OUT_FNS */ /* the addition of the DEVELOPER checks in safe_strcpy means we must * update a lot of code. To make this a little easier here are some @@ -93,8 +110,109 @@ char * __unsafe_string_function_usage_here__(void); #define pstrcpy_base(dest, src, pstring_base) \ safe_strcpy(dest, src, sizeof(pstring)-PTR_DIFF(dest,pstring_base)-1) -#define push_pstring_base(dest, src, pstring_base) \ - push_ascii(dest, src, sizeof(pstring)-PTR_DIFF(dest,pstring_base)-1, STR_TERMINATE) +#define safe_strcpy_base(dest, src, base, size) \ + safe_strcpy(dest, src, size-PTR_DIFF(dest,base)-1) + +/* String copy functions - macro hell below adds 'type checking' (limited, but the best we can + do in C) and may tag with function name/number to record the last 'clobber region' on + that string */ + +#define pstrcpy(d,s) safe_strcpy((d), (s),sizeof(pstring)-1) +#define pstrcat(d,s) safe_strcat((d), (s),sizeof(pstring)-1) +#define fstrcpy(d,s) safe_strcpy((d),(s),sizeof(fstring)-1) +#define fstrcat(d,s) safe_strcat((d),(s),sizeof(fstring)-1) + +/* the addition of the DEVELOPER checks in safe_strcpy means we must + * update a lot of code. To make this a little easier here are some + * functions that provide the lengths with less pain */ +#define pstrcpy_base(dest, src, pstring_base) \ + safe_strcpy(dest, src, sizeof(pstring)-PTR_DIFF(dest,pstring_base)-1) + + +/* inside the _fn varients of these is a call to 'clobber_region' - which might + destory the stack on a buggy function. Help the debugging process by putting + the function and line it was last called from into a static buffer + + But only for developers */ + +#ifdef DEVELOPER +#define overmalloc_safe_strcpy(dest,src,maxlength) safe_strcpy_fn(__FUNCTION__,__LINE__,dest,src,maxlength) +#define safe_strcpy(dest,src,maxlength) safe_strcpy_fn2(__FUNCTION__,__LINE__,dest,src,maxlength) +#define safe_strcat(dest,src,maxlength) safe_strcat_fn2(__FUNCTION__,__LINE__,dest,src,maxlength) +#define push_string(base_ptr, dest, src, dest_len, flags) push_string_fn2(__FUNCTION__, __LINE__, base_ptr, dest, src, dest_len, flags) +#define pull_string(base_ptr, dest, src, dest_len, src_len, flags) pull_string_fn2(__FUNCTION__, __LINE__, base_ptr, dest, src, dest_len, src_len, flags) +#define clistr_push(cli, dest, src, dest_len, flags) clistr_push_fn2(__FUNCTION__, __LINE__, cli, dest, src, dest_len, flags) +#define clistr_pull(cli, dest, src, dest_len, src_len, flags) clistr_pull_fn2(__FUNCTION__, __LINE__, cli, dest, src, dest_len, src_len, flags) + +#define alpha_strcpy(dest,src,other_safe_chars,maxlength) alpha_strcpy_fn(__FUNCTION__,__LINE__,dest,src,other_safe_chars,maxlength) +#define StrnCpy(dest,src,n) StrnCpy_fn(__FUNCTION__,__LINE__,dest,src,n) + +#else + +#define overmalloc_safe_strcpy(dest,src,maxlength) safe_strcpy_fn(NULL,0,dest,src,maxlength) +#define safe_strcpy(dest,src,maxlength) safe_strcpy_fn2(NULL,0,dest,src,maxlength) +#define safe_strcat(dest,src,maxlength) safe_strcat_fn2(NULL,0,dest,src,maxlength) +#define push_string(base_ptr, dest, src, dest_len, flags) push_string_fn2(NULL, 0, base_ptr, dest, src, dest_len, flags) +#define pull_string(base_ptr, dest, src, dest_len, src_len, flags) pull_string_fn2(NULL, 0, base_ptr, dest, src, dest_len, src_len, flags) +#define clistr_push(cli, dest, src, dest_len, flags) clistr_push_fn2(NULL, 0, cli, dest, src, dest_len, flags) +#define clistr_pull(cli, dest, src, dest_len, src_len, flags) clistr_pull_fn2(NULL, 0, cli, dest, src, dest_len, src_len, flags) + +#define alpha_strcpy(dest,src,other_safe_chars,maxlength) alpha_strcpy_fn(NULL,0,dest,src,other_safe_chars,maxlength) +#define StrnCpy(dest,src,n) StrnCpy_fn(NULL,0,dest,src,n) +#endif /* DEVELOPER */ + + +#ifdef HAVE_COMPILER_WILL_OPTIMIZE_OUT_FNS + +/* if the compiler will optimize out function calls, then use this to tell if we are + have the correct types (this works only where sizeof() returns the size of the buffer, not + the size of the pointer). */ + +#define safe_strcpy_fn2(fn_name, fn_line, d, s, max_len) \ + (CHECK_STRING_SIZE(d, max_len+1) \ + ? __unsafe_string_function_usage_here__() \ + : safe_strcpy_fn(fn_name, fn_line, (d), (s), (max_len))) + +#define safe_strcat_fn2(fn_name, fn_line, d, s, max_len) \ + (CHECK_STRING_SIZE(d, max_len+1) \ + ? __unsafe_string_function_usage_here__() \ + : safe_strcat_fn(fn_name, fn_line, (d), (s), (max_len))) + +#define push_string_fn2(fn_name, fn_line, base_ptr, dest, src, dest_len, flags) \ + (CHECK_STRING_SIZE(dest, dest_len) \ + ? __unsafe_string_function_usage_here_size_t__() \ + : push_string_fn(fn_name, fn_line, base_ptr, dest, src, dest_len, flags)) + +#define pull_string_fn2(fn_name, fn_line, base_ptr, dest, src, dest_len, src_len, flags) \ + (CHECK_STRING_SIZE(dest, dest_len) \ + ? __unsafe_string_function_usage_here_size_t__() \ + : pull_string_fn(fn_name, fn_line, base_ptr, dest, src, dest_len, src_len, flags)) + +#define clistr_push_fn2(fn_name, fn_line, cli, dest, src, dest_len, flags) \ + (CHECK_STRING_SIZE(dest, dest_len) \ + ? __unsafe_string_function_usage_here_size_t__() \ + : clistr_push_fn(fn_name, fn_line, cli, dest, src, dest_len, flags)) + +#define clistr_pull_fn2(fn_name, fn_line, cli, dest, src, dest_len, srclen, flags) \ + (CHECK_STRING_SIZE(dest, dest_len) \ + ? __unsafe_string_function_usage_here_size_t__() \ + : clistr_pull_fn(fn_name, fn_line, cli, dest, src, dest_len, srclen, flags)) + +#else + +#define safe_strcpy_fn2 safe_strcpy_fn +#define safe_strcat_fn2 safe_strcat_fn +#define push_string_fn2 push_string_fn +#define pull_string_fn2 pull_string_fn +#define clistr_push_fn2 clistr_push_fn +#define clistr_pull_fn2 clistr_pull_fn + +#endif + +/* replace some string functions with multi-byte + versions */ +#define strlower(s) strlower_m(s) +#define strupper(s) strupper_m(s) #define safe_strcpy_base(dest, src, base, size) \ safe_strcpy(dest, src, size-PTR_DIFF(dest,base)-1) diff --git a/source3/lib/charcnv.c b/source3/lib/charcnv.c index a8df003f8b..fa646573d8 100644 --- a/source3/lib/charcnv.c +++ b/source3/lib/charcnv.c @@ -186,7 +186,7 @@ size_t convert_string(charset_t from, charset_t to, * @returns Size in bytes of the converted string; or -1 in case of error. **/ -size_t convert_string_allocate(charset_t from, charset_t to, +static size_t convert_string_allocate(charset_t from, charset_t to, void const *src, size_t srclen, void **dest) { size_t i_len, o_len, destlen; @@ -265,7 +265,7 @@ convert: * * @returns Size in bytes of the converted string; or -1 in case of error. **/ -size_t convert_string_talloc(TALLOC_CTX *ctx, charset_t from, charset_t to, +static size_t convert_string_talloc(TALLOC_CTX *ctx, charset_t from, charset_t to, void const *src, size_t srclen, void **dest) { void *alloced_string; @@ -303,7 +303,7 @@ size_t unix_strlower(const char *src, size_t srclen, char *dest, size_t destlen) } -size_t ucs2_align(const void *base_ptr, const void *p, int flags) +static size_t ucs2_align(const void *base_ptr, const void *p, int flags) { if (flags & (STR_NOALIGN|STR_ASCII)) return 0; @@ -356,11 +356,6 @@ size_t push_ascii_pstring(void *dest, const char *src) return push_ascii(dest, src, sizeof(pstring), STR_TERMINATE); } -size_t push_pstring(void *dest, const char *src) -{ - return push_ascii(dest, src, sizeof(pstring), STR_TERMINATE); -} - /** * Copy a string from a dos codepage source to a unix char* destination. * @@ -507,7 +502,7 @@ size_t push_ucs2_allocate(smb_ucs2_t **dest, const char *src) is -1 then no maxiumum is used. **/ -size_t push_utf8(void *dest, const char *src, size_t dest_len, int flags) +static size_t push_utf8(void *dest, const char *src, size_t dest_len, int flags) { size_t src_len = strlen(src); pstring tmpbuf; @@ -533,11 +528,6 @@ size_t push_utf8_fstring(void *dest, const char *src) return push_utf8(dest, src, sizeof(fstring), STR_TERMINATE); } -size_t push_utf8_pstring(void *dest, const char *src) -{ - return push_utf8(dest, src, sizeof(pstring), STR_TERMINATE); -} - /** * Copy a string from a unix char* src to a UTF-8 destination, allocating a buffer using talloc * @@ -657,51 +647,6 @@ size_t pull_ucs2_allocate(void **dest, const smb_ucs2_t *src) } /** - Copy a string from a utf-8 source to a unix char* destination. - Flags can have: - STR_TERMINATE means the string in src is null terminated. - if STR_TERMINATE is set then src_len is ignored. - src_len is the length of the source area in bytes - Return the number of bytes occupied by the string in src. - The resulting string in "dest" is always null terminated. -**/ - -size_t pull_utf8(char *dest, const void *src, size_t dest_len, size_t src_len, int flags) -{ - size_t ret; - - if (dest_len == (size_t)-1) - dest_len = sizeof(pstring); - - if (flags & STR_TERMINATE) { - if (src_len == (size_t)-1) { - src_len = strlen(src) + 1; - } else { - size_t len = strnlen(src, src_len); - if (len < src_len) - len++; - src_len = len; - } - } - - ret = convert_string(CH_UTF8, CH_UNIX, src, src_len, dest, dest_len); - if (dest_len) - dest[MIN(ret, dest_len-1)] = 0; - - return src_len; -} - -size_t pull_utf8_pstring(char *dest, const void *src) -{ - return pull_utf8(dest, src, sizeof(pstring), -1, STR_TERMINATE); -} - -size_t pull_utf8_fstring(char *dest, const void *src) -{ - return pull_utf8(dest, src, sizeof(fstring), -1, STR_TERMINATE); -} - -/** * Copy a string from a UTF-8 src to a unix char * destination, allocating a buffer using talloc * * @param dest always set at least to NULL @@ -745,8 +690,11 @@ size_t pull_utf8_allocate(void **dest, const char *src) is -1 then no maxiumum is used. **/ -size_t push_string(const void *base_ptr, void *dest, const char *src, size_t dest_len, int flags) +size_t push_string_fn(const char *function, unsigned int line, const void *base_ptr, void *dest, const char *src, size_t dest_len, int flags) { + if (dest_len != (size_t)-1) + clobber_region(function, line, dest, dest_len); + if (!(flags & STR_ASCII) && \ ((flags & STR_UNICODE || \ (SVAL(base_ptr, smb_flg2) & FLAGS2_UNICODE_STRINGS)))) { @@ -770,8 +718,11 @@ size_t push_string(const void *base_ptr, void *dest, const char *src, size_t des The resulting string in "dest" is always null terminated. **/ -size_t pull_string(const void *base_ptr, char *dest, const void *src, size_t dest_len, size_t src_len, int flags) +size_t pull_string_fn(const char *function, unsigned int line, const void *base_ptr, char *dest, const void *src, size_t dest_len, size_t src_len, int flags) { + if (dest_len != (size_t)-1) + clobber_region(function, line, dest, dest_len); + if (!(flags & STR_ASCII) && \ ((flags & STR_UNICODE || \ (SVAL(base_ptr, smb_flg2) & FLAGS2_UNICODE_STRINGS)))) { @@ -791,27 +742,6 @@ size_t align_string(const void *base_ptr, const char *p, int flags) } /** - Convert from ucs2 to unix charset and return the - allocated and converted string or NULL if an error occurred. - You must provide a zero terminated string. - The returning string will be zero terminated. -**/ - -char *acnv_u2ux(const smb_ucs2_t *src) -{ - size_t slen; - size_t dlen; - void *dest; - - slen = (strlen_w(src) + 1) * sizeof(smb_ucs2_t); - dlen = convert_string_allocate(CH_UCS2, CH_UNIX, src, slen, &dest); - if (dlen == (size_t)-1) - return NULL; - else - return dest; -} - -/** Convert from unix to ucs2 charset and return the allocated and converted string or NULL if an error occurred. You must provide a zero terminated string. @@ -833,27 +763,6 @@ smb_ucs2_t *acnv_uxu2(const char *src) } /** - Convert from ucs2 to dos charset and return the - allocated and converted string or NULL if an error occurred. - You must provide a zero terminated string. - The returning string will be zero terminated. -**/ - -char *acnv_u2dos(const smb_ucs2_t *src) -{ - size_t slen; - size_t dlen; - void *dest; - - slen = (strlen_w(src) + 1) * sizeof(smb_ucs2_t); - dlen = convert_string_allocate(CH_UCS2, CH_DOS, src, slen, &dest); - if (dlen == (size_t)-1) - return NULL; - else - return dest; -} - -/** Convert from dos to ucs2 charset and return the allocated and converted string or NULL if an error occurred. You must provide a zero terminated string. diff --git a/source3/lib/util.c b/source3/lib/util.c index bdf67a515a..4216310335 100644 --- a/source3/lib/util.c +++ b/source3/lib/util.c @@ -1398,9 +1398,23 @@ gid_t nametogid(const char *name) void smb_panic(const char *why) { - char *cmd = lp_panic_action(); + char *cmd; int result; +#ifdef DEVELOPER + { + extern char *global_clobber_region_function; + extern unsigned int global_clobber_region_line; + + if (global_clobber_region_function) { + DEBUG(0,("smb_panic: clobber_region() last called from [%s(%u)]\n", + global_clobber_region_function, + global_clobber_region_line)); + } + } +#endif + + cmd = lp_panic_action(); if (cmd && *cmd) { DEBUG(0, ("smb_panic(): calling panic action [%s]\n", cmd)); result = system(cmd); diff --git a/source3/lib/util_str.c b/source3/lib/util_str.c index 070c59c1b2..7643c2807e 100644 --- a/source3/lib/util_str.c +++ b/source3/lib/util_str.c @@ -21,6 +21,11 @@ #include "includes.h" +#ifdef DEVELOPER +const char *global_clobber_region_function; +unsigned int global_clobber_region_line; +#endif + /** * Get the next token from a string, return False if none found. * Handles double-quotes. @@ -73,7 +78,7 @@ parameter so you can pass NULL. This is useful for user interface code but beware the fact that it is not re-entrant! **/ -static char *last_ptr=NULL; +static const char *last_ptr=NULL; BOOL next_token_nr(const char **ptr,char *buff, const char *sep, size_t bufsize) { @@ -410,32 +415,33 @@ size_t count_chars(const char *s,char c) } /** -Return True if a string consists only of one particular character. -**/ - -BOOL str_is_all(const char *s,char c) + * In developer builds, clobber a region of memory. + * + * If we think a string buffer is longer than it really is, this ought + * to make the failure obvious, by segfaulting (if in the heap) or by + * killing the return address (on the stack), or by trapping under a + * memory debugger. + * + * This is meant to catch possible string overflows, even if the + * actual string copied is not big enough to cause an overflow. + **/ +void clobber_region(const char *fn, unsigned int line, char *dest, size_t len) { - smb_ucs2_t *ptr; - - if(s == NULL) - return False; - if(!*s) - return False; - - push_ucs2(NULL, tmpbuf,s, sizeof(tmpbuf), STR_TERMINATE); - for(ptr=tmpbuf;*ptr;ptr++) - if(*ptr!=UCS2_CHAR(c)) - return False; - - return True; +#ifdef DEVELOPER + /* F1 is odd and 0xf1f1f1f1 shouldn't be a valid pointer */ + memset(dest, 0xF1, len); + global_clobber_region_function = fn; + global_clobber_region_line = line; +#endif } + /** Safe string copy into a known length string. maxlength does not include the terminating zero. **/ -char *safe_strcpy(char *dest,const char *src, size_t maxlength) +char *safe_strcpy_fn(const char *fn, int line, char *dest,const char *src, size_t maxlength) { size_t len; @@ -444,13 +450,7 @@ char *safe_strcpy(char *dest,const char *src, size_t maxlength) return NULL; } -#ifdef DEVELOPER - /* We intentionally write out at the extremity of the destination - * string. If the destination is too short (e.g. pstrcpy into mallocd - * or fstring) then this should cause an error under a memory - * checker. */ - dest[maxlength] = '\0'; -#endif + clobber_region(fn,line,dest, maxlength+1); if (!src) { *dest = 0; @@ -474,8 +474,7 @@ char *safe_strcpy(char *dest,const char *src, size_t maxlength) Safe string cat into a string. maxlength does not include the terminating zero. **/ - -char *safe_strcat(char *dest, const char *src, size_t maxlength) +char *safe_strcat_fn(const char *fn, int line, char *dest, const char *src, size_t maxlength) { size_t src_len, dest_len; @@ -490,6 +489,8 @@ char *safe_strcat(char *dest, const char *src, size_t maxlength) src_len = strlen(src); dest_len = strlen(dest); + clobber_region(fn, line, dest + dest_len, maxlength + 1 - dest_len); + if (src_len + dest_len > maxlength) { DEBUG(0,("ERROR: string overflow by %d in safe_strcat [%.50s]\n", (int)(src_len + dest_len - maxlength), src)); @@ -499,7 +500,7 @@ char *safe_strcat(char *dest, const char *src, size_t maxlength) dest[maxlength] = 0; return NULL; } - + memcpy(&dest[dest_len], src, src_len); dest[dest_len + src_len] = 0; return dest; @@ -511,11 +512,12 @@ char *safe_strcat(char *dest, const char *src, size_t maxlength) and replaces with '_'. Deliberately does *NOT* check for multibyte characters. Don't change it ! **/ - -char *alpha_strcpy(char *dest, const char *src, const char *other_safe_chars, size_t maxlength) +char *alpha_strcpy_fn(const char *fn, int line, char *dest, const char *src, const char *other_safe_chars, size_t maxlength) { size_t len, i; + clobber_region(fn, line, dest, maxlength); + if (!dest) { DEBUG(0,("ERROR: NULL dest in alpha_strcpy\n")); return NULL; @@ -550,12 +552,15 @@ char *alpha_strcpy(char *dest, const char *src, const char *other_safe_chars, si Like strncpy but always null terminates. Make sure there is room! The variable n should always be one less than the available size. **/ - -char *StrnCpy(char *dest,const char *src,size_t n) +char *StrnCpy_fn(const char *fn, int line,char *dest,const char *src,size_t n) { char *d = dest; + + clobber_region(fn, line, dest, n+1); + if (!dest) return(NULL); + if (!src) { *dest = 0; return(dest); @@ -566,16 +571,19 @@ char *StrnCpy(char *dest,const char *src,size_t n) return(dest); } +#if 0 /** Like strncpy but copies up to the character marker. always null terminates. returns a pointer to the character marker in the source string (src). **/ -char *strncpyn(char *dest, const char *src, size_t n, char c) +static char *strncpyn(char *dest, const char *src, size_t n, char c) { char *p; size_t str_len; + clobber_region(dest, n+1); + p = strchr_m(src, c); if (p == NULL) { DEBUG(5, ("strncpyn: separator character (%c) not found\n", c)); @@ -588,6 +596,7 @@ char *strncpyn(char *dest, const char *src, size_t n, char c) return p; } +#endif /** Routine to get hex characters and turn them into a 16 byte array. @@ -898,7 +907,7 @@ void all_string_sub(char *s,const char *pattern,const char *insert, size_t len) Use with caution! **/ -smb_ucs2_t *all_string_sub_w(const smb_ucs2_t *s, const smb_ucs2_t *pattern, +static smb_ucs2_t *all_string_sub_w(const smb_ucs2_t *s, const smb_ucs2_t *pattern, const smb_ucs2_t *insert) { smb_ucs2_t *r, *rp; @@ -956,11 +965,12 @@ smb_ucs2_t *all_string_sub_wa(smb_ucs2_t *s, const char *pattern, return all_string_sub_w(s, p, i); } +#if 0 /** Splits out the front and back at a separator. **/ -void split_at_last_component(char *path, char *front, char sep, char *back) +static void split_at_last_component(char *path, char *front, char sep, char *back) { char *p = strrchr_m(path, sep); @@ -979,6 +989,7 @@ void split_at_last_component(char *path, char *front, char sep, char *back) back[0] = 0; } } +#endif /** Write an octal as a string. @@ -998,7 +1009,7 @@ const char *octal_string(int i) Truncate a string at a specified length. **/ -char *string_truncate(char *s, int length) +char *string_truncate(char *s, unsigned int length) { if (s && strlen(s) > length) s[length] = 0; @@ -1157,11 +1168,12 @@ char *binary_string(char *buf, int len) return ret; } +#if 0 /** Just a typesafety wrapper for snprintf into a fstring. **/ - int fstr_sprintf(fstring s, const char *fmt, ...) +static int fstr_sprintf(fstring s, const char *fmt, ...) { va_list ap; int ret; @@ -1171,6 +1183,7 @@ char *binary_string(char *buf, int len) va_end(ap); return ret; } +#endif #ifndef HAVE_STRNDUP /** @@ -1642,12 +1655,3 @@ char * base64_encode_data_blob(DATA_BLOB data) return result; } -#ifdef VALGRIND -size_t valgrind_strlen(const char *s) -{ - size_t count; - for(count = 0; *s++; count++) - ; - return count; -} -#endif diff --git a/source3/libsmb/clistr.c b/source3/libsmb/clistr.c index 3c9964368e..97a3fa6cc9 100644 --- a/source3/libsmb/clistr.c +++ b/source3/libsmb/clistr.c @@ -20,24 +20,38 @@ #include "includes.h" -int clistr_push(struct cli_state *cli, void *dest, const char *src, int dest_len, int flags) +size_t clistr_push_fn(const char *function, unsigned int line, + struct cli_state *cli, void *dest, + const char *src, int dest_len, int flags) { - return push_string(cli->outbuf, dest, src, dest_len, flags); + size_t buf_used = PTR_DIFF(dest, cli->outbuf); + if (dest_len == -1) { + if (((ptrdiff_t)dest < (ptrdiff_t)cli->outbuf) || (buf_used > cli->bufsize)) { + DEBUG(0, ("Pushing string of 'unlimited' length into non-SMB buffer!\n")); + return push_string_fn(function, line, cli->outbuf, dest, src, -1, flags); + } + return push_string_fn(function, line, cli->outbuf, dest, src, cli->bufsize - buf_used, flags); + } + + /* 'normal' push into size-specified buffer */ + return push_string_fn(function, line, cli->outbuf, dest, src, dest_len, flags); } -int clistr_pull(struct cli_state *cli, char *dest, const void *src, int dest_len, int src_len, - int flags) +size_t clistr_pull_fn(const char *function, unsigned int line, + struct cli_state *cli, char *dest, const void *src, + int dest_len, int src_len, + int flags) { - return pull_string(cli->inbuf, dest, src, dest_len, src_len, flags); + return pull_string_fn(function, line, cli->inbuf, dest, src, dest_len, src_len, flags); } -int clistr_align_out(struct cli_state *cli, const void *p, int flags) +size_t clistr_align_out(struct cli_state *cli, const void *p, int flags) { return align_string(cli->outbuf, p, flags); } -int clistr_align_in(struct cli_state *cli, const void *p, int flags) +size_t clistr_align_in(struct cli_state *cli, const void *p, int flags) { return align_string(cli->inbuf, p, flags); } |