From ad5243671176832bff058bbb3f6dcf10211315b5 Mon Sep 17 00:00:00 2001 From: "osku@127.(none)" <> Date: Thu, 29 Sep 2005 13:02:18 +0300 Subject: [PATCH] InnoDB: Fix potential buffer underflow. --- innobase/include/ut0mem.h | 13 +++++++++++++ innobase/mem/mem0mem.c | 4 +--- innobase/ut/ut0mem.c | 25 ++++++++++++++++++++++++- 3 files changed, 38 insertions(+), 4 deletions(-) diff --git a/innobase/include/ut0mem.h b/innobase/include/ut0mem.h index 8f109a64b55..b9bbe0b5c92 100644 --- a/innobase/include/ut0mem.h +++ b/innobase/include/ut0mem.h @@ -122,6 +122,7 @@ ut_strcmp(const void* str1, const void* str2); Copies up to size - 1 characters from the NUL-terminated string src to dst, NUL-terminating the result. Returns strlen(src), so truncation occurred if the return value >= size. */ + ulint ut_strlcpy( /*=======*/ @@ -130,6 +131,18 @@ ut_strlcpy( const char* src, /* in: source buffer */ ulint size); /* in: size of destination buffer */ +/************************************************************************** +Like ut_strlcpy, but if src doesn't fit in dst completely, copies the last +(size - 1) bytes of src, not the first. */ + +ulint +ut_strlcpy_rev( +/*===========*/ + /* out: strlen(src) */ + char* dst, /* in: destination buffer */ + const char* src, /* in: source buffer */ + ulint size); /* in: size of destination buffer */ + /************************************************************************** Compute strlen(ut_strcpyq(str, q)). */ UNIV_INLINE diff --git a/innobase/mem/mem0mem.c b/innobase/mem/mem0mem.c index 85f0119d02a..daf78008d45 100644 --- a/innobase/mem/mem0mem.c +++ b/innobase/mem/mem0mem.c @@ -187,9 +187,7 @@ mem_heap_create_block( } block->magic_n = MEM_BLOCK_MAGIC_N; - ut_memcpy(&(block->file_name), file_name + ut_strlen(file_name) - 7, - 7); - block->file_name[7]='\0'; + ut_strlcpy_rev(block->file_name, file_name, sizeof(block->file_name)); block->line = line; #ifdef MEM_PERIODIC_CHECK diff --git a/innobase/ut/ut0mem.c b/innobase/ut/ut0mem.c index c1e3ebbf35c..47b1e24e5e1 100644 --- a/innobase/ut/ut0mem.c +++ b/innobase/ut/ut0mem.c @@ -364,7 +364,30 @@ ut_strlcpy( dst[n] = '\0'; } - return src_size; + return(src_size); +} + +/************************************************************************** +Like ut_strlcpy, but if src doesn't fit in dst completely, copies the last +(size - 1) bytes of src, not the first. */ + +ulint +ut_strlcpy_rev( +/*===========*/ + /* out: strlen(src) */ + char* dst, /* in: destination buffer */ + const char* src, /* in: source buffer */ + ulint size) /* in: size of destination buffer */ +{ + ulint src_size = strlen(src); + + if (size != 0) { + ulint n = ut_min(src_size, size - 1); + + memcpy(dst, src + src_size - n, n + 1); + } + + return(src_size); } /**************************************************************************