portable icon indicating copy to clipboard operation
portable copied to clipboard

Potential problem in recallocarray() compatibility function

Open sebhub opened this issue 3 years ago • 2 comments

The recallocarray() compatibility function performs an explicit_bzero() when memory is freed. It contains an optimization for minor size reductions:

https://github.com/libressl-portable/openbsd/blob/master/src/lib/libc/stdlib/recallocarray.c#L61

	/*
	 * Don't bother too much if we're shrinking just a bit,
	 * we do not shrink for series of small steps, oh well.
	 */
	if (newsize <= oldsize) {
		size_t d = oldsize - newsize;

		if (d < oldsize / 2 && d < (size_t)getpagesize()) {
			memset((char *)ptr + newsize, 0, d);
			return ptr;
		}
	}

Here, the memory from (char *)ptr + newsize to (char *)ptr + oldsize is not cleared by an explicit_bzero(). Is this an issue?

sebhub avatar Jan 28 '22 15:01 sebhub

On Fri, Jan 28, 2022 at 07:04:17AM -0800, Sebastian Huber wrote:

The recallocarray() compatibility function performs an explicit_bzero() when memory is freed. It contains an optimization for minor size reductions:

https://github.com/libressl-portable/openbsd/blob/master/src/lib/libc/stdlib/recallocarray.c#L61

	/*
	 * Don't bother too much if we're shrinking just a bit,
	 * we do not shrink for series of small steps, oh well.
	 */
	if (newsize <= oldsize) {
		size_t d = oldsize - newsize;

		if (d < oldsize / 2 && d < (size_t)getpagesize()) {
			memset((char *)ptr + newsize, 0, d);
			return ptr;
		}
	}

Here, the memory from (char *)ptr + newsize to (char *)ptr + oldsize is not cleared by an explicit_bzero(). Is this an issue?

Thanks. I don't think so. Since the pointer is returned, the compiler can't assume that the 0 values written by memset are not going to be looked at.

That's different from the explicit_bzero(ptr) call right before free(ptr) where the compiler may optimize away the memset to avoid writing to memory that is going to be released right after.

That said, we made a similar memset() -> explicit_bzero() conversion in OpenBSD's malloc.c, so it might also be appropriate here:

https://github.com/openbsd/src/commit/5576bc40c43cc6479ec8d4fccc16927073e664fb

-- Reply to this email directly or view it on GitHub: https://github.com/libressl-portable/portable/issues/726 You are receiving this because you are subscribed to this thread.

Message ID: @.***>

botovq avatar Jan 28 '22 15:01 botovq

Yes, it is harder for the compiler to optimize the memset() away. What about link-time optimization?

sebhub avatar Jan 28 '22 17:01 sebhub