[Libguestfs] [PATCH nbdkit v2 4/4] common/allocators: Always align mlock buffer
Laszlo Ersek
lersek at redhat.com
Tue Feb 1 08:53:03 UTC 2022
On 02/01/22 09:35, Richard W.M. Jones wrote:
> On Tue, Feb 01, 2022 at 08:22:47AM +0100, Laszlo Ersek wrote:
>> On 01/31/22 17:14, Richard W.M. Jones wrote:
>>>
>>> Thanks - I pushed this as:
>>>
>>> 521e69f7..24217480 master -> master
>>>
>>> I changed patch 3 to include your recommendations. But also I noticed
>>> there was a mistake in the memcpy which I hope I fixed and it's worth
>>> reading the comment about this:
>>>
>>> https://gitlab.com/nbdkit/nbdkit/-/blob/2421748073b71ab600db50f748a53b8f36d30add/common/utils/vector.c#L147
>>
>>
>> /* How much to copy here?
>> *
>> * vector_reserve always makes the buffer larger so we don't have to
>> * deal with the case of a shrinking buffer.
>> *
>> * Like the underlying realloc we do not have to zero the newly
>> * reserved elements.
>> *
>> * However (like realloc) we have to copy the existing elements even
>> * those that are not allocated and only reserved (between 'len' and
>> * 'cap').
>>
>> That's strange; I'd say any " offset >= len" access to a vector is an out-of-bounds bug in the client code. From "common/utils/vector.h":
>>
>> * where ‘names.ptr[]’ will be an array of strings and ‘names.len’
>> * will be the number of strings. There are no get/set accessors. To
>> * iterate over the strings you can use the ‘.ptr’ field directly:
>> *
>> * for (size_t i = 0; i < names.len; ++i)
>> * printf ("%s\n", names.ptr[i]);
>>
>> Then,
>>
>> *
>> * The spec of vector is not clear on the last two points, but
>> * existing code depends on this undocumented behaviour.
>> */
>>
>> To me the spec ("common/utils/vector.h") seemed clear:
>>
>> /* Reserve n elements at the end of the vector. Note space is \
>> * allocated and capacity is increased, but the vector length \
>> * is not increased and the new elements are not initialized. \
>> */ \
>>
>> If length is not increased, then elements between "len" and "old
>> cap" remain undefined as before, and elements between "old cap" and
>> "new cap" are new, and also not initialized.
>
> That's what the spec says, but unfortunately not what the users of it
> are doing. For example, common/allocators/malloc.c uses
> vector_reserve to reserve memory and then memsets it and uses it.
> That's because there isn't an "allocate N x zero elements" operation,
> which there probably should be. plugins/data/format.c is similar
> although it does update the .len field after.
>
> TBH it's arguable both ways. Vector is only meant as a nicer wrapper
> around realloc, so you can argue that what realloc does is the spec.
> It's also intended that the implementation is completely exposed.
> This is only an internal interface after all.
>
>> I'm slightly concerned about accessing uninitialized (only
>> allocated) storage with memcpy(); maybe it can be shown to be
>> undefined behavior, maybe not, but I compilers have been exploiting
>> UB more aggressively over time.
>
> In both cases above the callers memset/initialize it before use.
OK!
Thanks!
Laszlo
More information about the Libguestfs
mailing list