Subject: Re: [PATCH v5 16/16] reftable: be more paranoid about 0-length memcpy calls

From: Junio C Hamano <[email-masked]>
Date: Thu, 23 Dec 2021 20:16:29 -0800

Han-Wen Nienhuys <[email-masked]> writes:

> On Wed, Dec 22, 2021 at 11:50 PM Junio C Hamano <[email-masked]> wrote:
>
>> > -     memcpy(r->hash_prefix, key.buf, key.len);
>> > +     if (key.len)
>> > +             memcpy(r->hash_prefix, key.buf, key.len);
>> >       r->hash_prefix_len = key.len;
>> >
>> >       if (val_type == 0) {
>>
>> I am not sure why any of these are needed.
>
> I'm not sure they are needed, but IMO it's not worth spending brain
> cycles on deciding either way. Checking the length is always a safe
> alternative.
>
> I would support having a safe_memcpy() that does this check centrally
> (note how our array_copy() array function also does this check, even
> if it's not always needed.)

But your safe_memcpy() should not be

    safe_memcpy(dst, src, n)
    {
	if (n)
		memcpy(dst, src, n);
	return dst;
    }

Using memcpy() with size==0 is not a crime wrt the language.
Passing an invalid pointer while doing so is.

It should rather be

    safe_memcpy(dst, src, n)
    {
	if (dst)
		memcpy(dst, src, n);
	else if (n)
               	BUG(...);
	return dst;
    }

to support a common pattern of <ptr, len> that lazily allocates the
ptr only when len goes more than zero from triggering an error from
picky runtime, compiler and tools.  We want to allow "dst==NULL &&
n==0", while still catching "dst==NULL && n!=0" as an error.

And these places, I do not think use of safe_memcpy() is relevant.