Commit b2d8eb02 authored by unknown's avatar unknown
Browse files

InnoDB: Fix potential buffer underflow.


innobase/include/ut0mem.h:
  Add ut_strlcpy_rev.
innobase/mem/mem0mem.c:
  Use ut_strlcpy_rev instead of buggy own implementation.
innobase/ut/ut0mem.c:
  Add ut_strlcpy_rev.
parent a5dd3d5d
Loading
Loading
Loading
Loading
+13 −0
Original line number Diff line number Diff line
@@ -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
+1 −3
Original line number Diff line number Diff line
@@ -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	
+24 −1
Original line number Diff line number Diff line
@@ -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);
}

/**************************************************************************