summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Bartlett <abartlet@samba.org>2003-03-15 07:14:55 +0000
committerAndrew Bartlett <abartlet@samba.org>2003-03-15 07:14:55 +0000
commit3b5bc93e9db4df6ded2eef7b32bda74328b04811 (patch)
treea1eda3d3fa69f62a05414b4f0fff2f4520c81055
parent9a00acc472b3a9530ca71705faef3166aa9c4d47 (diff)
downloadsamba-3b5bc93e9db4df6ded2eef7b32bda74328b04811.tar.gz
samba-3b5bc93e9db4df6ded2eef7b32bda74328b04811.tar.bz2
samba-3b5bc93e9db4df6ded2eef7b32bda74328b04811.zip
String handling parinoia fixes.
This patch enables the compile-time checking of strings assable by means of sizeof(). (Original code had the configure check reversed). This is extended to all safe_strcpy() users, push_string and pull_string, as well as the cli and srv derivitives. There is an attempt to cap strings at the end of the cli buffer, and clobber_region() of the speified length (when not -1 :-). Becouse of the way they are declared, the 'overmalloc a string' users of safe_strcpy() have been changed to use overmalloc_safe_strcpy() (which skips some of the checks). This whole ball of mud worked fine, until I pulled out my 'fix' for our statcache. When jeremy fixes that, we should be able to get back to testing this stuff. This patch also includes a 'marker' of the last caller to clobber_region (ie, the function that called pstrcpy() that called clobber_region) to assist in debugging problems that may have smashed the stack. This is printed at smb_panic() time. (Original idea and patch by metze). It also removes some unsused functions, and #if 0's some others that are unused but probably should be used in the near future. For now, this patch gives us some confidence on one class of trivial parsing error in our code. Andrew Bartlett (This used to be commit 31f4827acc2a2f00399a5528fc83a0dae5cebaf4)
-rw-r--r--source3/Makefile.in2
-rw-r--r--source3/configure.in2
-rw-r--r--source3/include/includes.h1
-rw-r--r--source3/include/safe_string.h161
-rw-r--r--source3/include/srvstr.h (renamed from source3/smbd/srvstr.c)21
-rw-r--r--source3/lib/charcnv.c83
-rw-r--r--source3/lib/util.c16
-rw-r--r--source3/lib/util_str.c72
-rw-r--r--source3/libsmb/clistr.c28
-rw-r--r--source3/nmbd/nmbd_become_lmb.c2
-rw-r--r--source3/nmbd/nmbd_browsesync.c2
-rw-r--r--source3/smbd/statcache.c12
12 files changed, 236 insertions, 166 deletions
diff --git a/source3/Makefile.in b/source3/Makefile.in
index 2334e278f2..1a4d97e083 100644
--- a/source3/Makefile.in
+++ b/source3/Makefile.in
@@ -336,7 +336,7 @@ SMBD_OBJ_SRV = smbd/files.o smbd/chgpasswd.o smbd/connection.o \
smbd/vfs.o smbd/vfs-wrap.o smbd/statcache.o \
smbd/posix_acls.o lib/sysacls.o lib/server_mutex.o \
smbd/process.o smbd/service.o smbd/error.o \
- printing/printfsp.o lib/util_seaccess.o smbd/srvstr.o \
+ printing/printfsp.o lib/util_seaccess.o \
smbd/build_options.o \
smbd/change_trust_pw.o \
$(MANGLE_OBJ)
diff --git a/source3/configure.in b/source3/configure.in
index aa95cf19fe..e038654f7e 100644
--- a/source3/configure.in
+++ b/source3/configure.in
@@ -662,7 +662,7 @@ AC_CACHE_CHECK([if the compiler will optimize out function calls],samba_cv_optim
AC_TRY_LINK([
#include <stdio.h>],
[
- if (1) {
+ if (0) {
this_function_does_not_exist();
} else {
return 1;
diff --git a/source3/include/includes.h b/source3/include/includes.h
index 25245e9c0c..2bba9d5084 100644
--- a/source3/include/includes.h
+++ b/source3/include/includes.h
@@ -855,6 +855,7 @@ struct printjob;
/* String routines */
+#include "srvstr.h"
#include "safe_string.h"
#ifdef __COMPAR_FN_T
diff --git a/source3/include/safe_string.h b/source3/include/safe_string.h
index 6c2bd82bb9..c7386d3ac4 100644
--- a/source3/include/safe_string.h
+++ b/source3/include/safe_string.h
@@ -48,29 +48,45 @@
#endif /* !_SPLINT_ */
+
char * __unsafe_string_function_usage_here__(void);
-#ifdef HAVE_COMPILER_WILL_OPTIMIZE_OUT_FNS
+size_t __unsafe_string_function_usage_here2__(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))
+#ifdef HAVE_COMPILER_WILL_OPTIMIZE_OUT_FNS
-#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'))
+/* 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 CHECK_STRING_SIZE(d, len) (sizeof(d) != (len) && sizeof(d) != sizeof(char *))
+
+#define fstrterminate(d) (CHECK_STRING_SIZE(d, sizeof(fstring)) \
+ ? __unsafe_string_function_usage_here__() \
+ : (((d)[sizeof(fstring)-1]) = '\0'))
+#define pstrterminate(d) (CHECK_STRING_SIZE(d, sizeof(pstring)) \
+ ? __unsafe_string_function_usage_here__() \
+ : (((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 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_here2__() \
+ : push_ascii(dest, src, sizeof(pstring)-PTR_DIFF(dest,pstring_base)-1, STR_TERMINATE))
-#else
-
-#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)
+#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 +96,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,7 +107,106 @@ 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)
+
+/* 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_push_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_here2__() \
+ : 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_here2__() \
+ : 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_here2__() \
+ : 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_here2__() \
+ : 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_fn2
+#define clistr_pull_fn2 clistr_pull_fn2
+
+#endif
+
+/* replace some string functions with multi-byte
+ versions */
+#define strlower(s) strlower_m(s)
+#define strupper(s) strupper_m(s)
#endif
diff --git a/source3/smbd/srvstr.c b/source3/include/srvstr.h
index 36fecf5bd2..a433e0e3f9 100644
--- a/source3/smbd/srvstr.c
+++ b/source3/include/srvstr.h
@@ -20,22 +20,17 @@
#include "includes.h"
-int srvstr_push(void *base_ptr, void *dest, const char *src, int dest_len, int flags)
-{
- return push_string(base_ptr, dest, src, dest_len, flags);
-}
+#define srvstr_push(base_ptr, dest, src, dest_len, flags) \
+ push_string(base_ptr, dest, src, dest_len, flags)
-int srvstr_pull(void *base_ptr, char *dest, const void *src, int dest_len, int src_len,
- int flags)
-{
- return pull_string(base_ptr, dest, src, dest_len, src_len, flags);
-}
+#define srvstr_pull(base_ptr, dest, src, dest_len, src_len, flags) \
+ pull_string(base_ptr, dest, src, dest_len, src_len, flags)
/* pull a string from the smb_buf part of a packet. In this case the
string can either be null terminated or it can be terminated by the
end of the smbbuf area
*/
-int srvstr_pull_buf(void *inbuf, char *dest, const void *src, int dest_len, int flags)
-{
- return pull_string(inbuf, dest, src, dest_len, smb_bufrem(inbuf, src), flags);
-}
+
+#define srvstr_pull_buf(inbuf, dest, src, dest_len, flags) \
+ pull_string(inbuf, dest, src, dest_len, smb_bufrem(inbuf, src), flags)
+
diff --git a/source3/lib/charcnv.c b/source3/lib/charcnv.c
index a8df003f8b..76d77ddd67 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
*
@@ -666,7 +656,7 @@ size_t pull_ucs2_allocate(void **dest, const smb_ucs2_t *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)
+static size_t pull_utf8(char *dest, const void *src, size_t dest_len, size_t src_len, int flags)
{
size_t ret;
@@ -690,16 +680,7 @@ size_t pull_utf8(char *dest, const void *src, size_t dest_len, size_t src_len, i
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);
-}
+#endif
/**
* Copy a string from a UTF-8 src to a unix char * destination, allocating a buffer using talloc
@@ -745,8 +726,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 +754,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 +778,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 +799,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 77ffa70a47..1f300a2815 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 7dd5ee4242..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,28 +415,6 @@ 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)
-{
- 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;
-}
-
-
-/**
* In developer builds, clobber a region of memory.
*
* If we think a string buffer is longer than it really is, this ought
@@ -442,11 +425,13 @@ BOOL str_is_all(const char *s,char c)
* 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(char *dest, size_t len)
+void clobber_region(const char *fn, unsigned int line, char *dest, size_t len)
{
#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
}
@@ -456,7 +441,7 @@ void clobber_region(char *dest, size_t len)
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;
@@ -465,7 +450,7 @@ char *safe_strcpy(char *dest,const char *src, size_t maxlength)
return NULL;
}
- clobber_region(dest, maxlength+1);
+ clobber_region(fn,line,dest, maxlength+1);
if (!src) {
*dest = 0;
@@ -489,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;
@@ -505,8 +489,8 @@ char *safe_strcat(char *dest, const char *src, size_t maxlength)
src_len = strlen(src);
dest_len = strlen(dest);
- clobber_region(dest + dest_len, maxlength + 1 - dest_len);
-
+ 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));
@@ -528,12 +512,11 @@ 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(dest, maxlength);
+ clobber_region(fn, line, dest, maxlength);
if (!dest) {
DEBUG(0,("ERROR: NULL dest in alpha_strcpy\n"));
@@ -569,13 +552,12 @@ 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(dest, n+1);
-
+ clobber_region(fn, line, dest, n+1);
+
if (!dest)
return(NULL);
@@ -589,12 +571,13 @@ 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;
@@ -613,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.
@@ -923,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;
@@ -981,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);
@@ -1004,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.
@@ -1023,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;
@@ -1182,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;
@@ -1196,6 +1183,7 @@ char *binary_string(char *buf, int len)
va_end(ap);
return ret;
}
+#endif
#ifndef HAVE_STRNDUP
/**
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);
}
diff --git a/source3/nmbd/nmbd_become_lmb.c b/source3/nmbd/nmbd_become_lmb.c
index 829496c195..6f8e7efb1a 100644
--- a/source3/nmbd/nmbd_become_lmb.c
+++ b/source3/nmbd/nmbd_become_lmb.c
@@ -563,7 +563,7 @@ in workgroup %s on subnet %s\n",
userdata->copy_fn = NULL;
userdata->free_fn = NULL;
userdata->userdata_len = strlen(work->work_group)+1;
- safe_strcpy(userdata->data, work->work_group, size - sizeof(*userdata) - 1);
+ overmalloc_safe_strcpy(userdata->data, work->work_group, size - sizeof(*userdata) - 1);
/* Register the special browser group name. */
register_name(subrec, MSBROWSE, 0x01, samba_nb_type|NB_GROUP,
diff --git a/source3/nmbd/nmbd_browsesync.c b/source3/nmbd/nmbd_browsesync.c
index 5914ea9637..b9082ee1c3 100644
--- a/source3/nmbd/nmbd_browsesync.c
+++ b/source3/nmbd/nmbd_browsesync.c
@@ -333,7 +333,7 @@ static void find_domain_master_name_query_success(struct subnet_record *subrec,
userdata->copy_fn = NULL;
userdata->free_fn = NULL;
userdata->userdata_len = strlen(work->work_group)+1;
- safe_strcpy(userdata->data, work->work_group, size - sizeof(*userdata) - 1);
+ overmalloc_safe_strcpy(userdata->data, work->work_group, size - sizeof(*userdata) - 1);
node_status( subrec, &nmbname, answer_ip,
domain_master_node_status_success,
diff --git a/source3/smbd/statcache.c b/source3/smbd/statcache.c
index b6e84ec9a5..ac4ffcf575 100644
--- a/source3/smbd/statcache.c
+++ b/source3/smbd/statcache.c
@@ -62,7 +62,7 @@ void stat_cache_add( char *full_orig_name, char *orig_translated_path)
return;
/*
- * If we are in case insentive mode, we need to
+ * If we are in case insentive mode, we don't need to
* store names that need no translation - else, it
* would be a waste.
*/
@@ -106,8 +106,8 @@ void stat_cache_add( char *full_orig_name, char *orig_translated_path)
DEBUG(0,("stat_cache_add: Out of memory !\n"));
return;
}
- safe_strcpy(scp->names, orig_name, namelen);
- safe_strcpy((scp->names+namelen+1), translated_path, namelen);
+ overmalloc_safe_strcpy(scp->names, orig_name, namelen);
+ overmalloc_safe_strcpy((scp->names+namelen+1), translated_path, namelen);
scp->name_len = namelen;
hash_insert(&stat_cache, (char *)scp, orig_name);
}
@@ -122,8 +122,8 @@ void stat_cache_add( char *full_orig_name, char *orig_translated_path)
DEBUG(0,("stat_cache_add: Out of memory !\n"));
return;
}
- safe_strcpy(scp->names, orig_name, namelen);
- safe_strcpy(scp->names+namelen+1, translated_path, namelen);
+ overmalloc_safe_strcpy(scp->names, orig_name, namelen);
+ overmalloc_safe_strcpy(scp->names+namelen+1, translated_path, namelen);
scp->name_len = namelen;
hash_insert(&stat_cache, (char *)scp, orig_name);
}
@@ -136,7 +136,7 @@ void stat_cache_add( char *full_orig_name, char *orig_translated_path)
Return True if we translated (and did a scuccessful stat on) the entire name.
*****************************************************************************/
-BOOL stat_cache_lookup(connection_struct *conn, char *name, char *dirpath,
+BOOL stat_cache_lookup(connection_struct *conn, pstring name, pstring dirpath,
char **start, SMB_STRUCT_STAT *pst)
{
stat_cache_entry *scp;