summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeremy Allison <jra@samba.org>2008-02-01 14:23:54 -0800
committerJeremy Allison <jra@samba.org>2008-02-01 14:23:54 -0800
commitb9b75f37acec632333cea1737edc46071661b480 (patch)
tree10acb42e6b238c61b9c8a0fa6043d889cfa102f3
parent2fffc9a1b1fe2a1490e867bb38462e50c282d2b3 (diff)
downloadsamba-b9b75f37acec632333cea1737edc46071661b480.tar.gz
samba-b9b75f37acec632333cea1737edc46071661b480.tar.bz2
samba-b9b75f37acec632333cea1737edc46071661b480.zip
Ensure that convert_string_allocate() allocates 2 extra
bytes and null terminates them to ensure NDR wire-reads of string types are always null terminated. Bug found by Volker after great pain :-). Jeremy. (This used to be commit aab736e6079729b3f3ab653674834e3f1305d456)
-rw-r--r--source3/lib/charcnv.c20
1 files changed, 14 insertions, 6 deletions
diff --git a/source3/lib/charcnv.c b/source3/lib/charcnv.c
index eeff805459..d11620ecd7 100644
--- a/source3/lib/charcnv.c
+++ b/source3/lib/charcnv.c
@@ -524,7 +524,7 @@ size_t convert_string(charset_t from, charset_t to,
size_t convert_string_allocate(TALLOC_CTX *ctx, charset_t from, charset_t to,
void const *src, size_t srclen, void *dst, bool allow_bad_conv)
{
- size_t i_len, o_len, destlen = MAX(srclen, 512);
+ size_t i_len, o_len, destlen = (srclen * 3) / 2;
size_t retval;
const char *inbuf = (const char *)src;
char *outbuf = NULL, *ob = NULL;
@@ -550,7 +550,8 @@ size_t convert_string_allocate(TALLOC_CTX *ctx, charset_t from, charset_t to,
convert:
- if ((destlen*2) < destlen) {
+ /* +2 is for ucs2 null termination. */
+ if ((destlen*2)+2 < destlen) {
/* wrapped ! abort. */
if (!conv_silent)
DEBUG(0, ("convert_string_allocate: destlen wrapped !\n"));
@@ -561,10 +562,11 @@ size_t convert_string_allocate(TALLOC_CTX *ctx, charset_t from, charset_t to,
destlen = destlen * 2;
}
+ /* +2 is for ucs2 null termination. */
if (ctx) {
- ob = (char *)TALLOC_REALLOC(ctx, ob, destlen);
+ ob = (char *)TALLOC_REALLOC(ctx, ob, destlen + 2);
} else {
- ob = (char *)SMB_REALLOC(ob, destlen);
+ ob = (char *)SMB_REALLOC(ob, destlen + 2);
}
if (!ob) {
@@ -619,10 +621,11 @@ size_t convert_string_allocate(TALLOC_CTX *ctx, charset_t from, charset_t to,
* reallocs *cost*. JRA.
*/
if (o_len > 1024) {
+ /* We're shrinking here so we know the +2 is safe from wrap. */
if (ctx) {
- ob = (char *)TALLOC_REALLOC(ctx,ob,destlen);
+ ob = (char *)TALLOC_REALLOC(ctx,ob,destlen + 2);
} else {
- ob = (char *)SMB_REALLOC(ob,destlen);
+ ob = (char *)SMB_REALLOC(ob,destlen + 2);
}
}
@@ -632,6 +635,11 @@ size_t convert_string_allocate(TALLOC_CTX *ctx, charset_t from, charset_t to,
}
*dest = ob;
+
+ /* Must ucs2 null terminate in the extra space we allocated. */
+ ob[destlen] = '\0';
+ ob[destlen+1] = '\0';
+
return destlen;
use_as_is: