[FFmpeg-devel] [PATCH] avutil/mem: always align by at least 32 bytes

Martin Storsjö martin at martin.st
Wed Dec 6 15:29:56 EET 2023


On Wed, 6 Dec 2023, Timo Rothenpieler wrote:

>
>
> On 06/12/2023 14:25, Martin Storsjö wrote:
>> On Sun, 3 Dec 2023, Timo Rothenpieler wrote:
>> 
>>> FFmpeg has instances of DECLARE_ALIGNED(32, ...) in a lot of structs,
>>> which then end up heap-allocated.
>>> By declaring any variable in a struct, or tree of structs, to be 32 byte
>>> aligned, it allows the compiler to safely assume the entire struct
>>> itself is also 32 byte aligned.
>>>
>>> This might make the compiler emit code which straight up crashes or
>>> misbehaves in other ways, and at least in one instances is now
>>> documented to actually do (see ticket 10549 on trac).
>>> The issue there is that an unrelated variable in SingleChannelElement is
>>> declared to have an alignment of 32 bytes. So if the compiler does a copy
>>> in decode_cpe() with avx instructions, but ffmpeg is built with
>>> --disable-avx, this results in a crash, since the memory is only 16 byte
>>> aligned.
>>> Mind you, even if the compiler does not emit avx instructions, the code
>>> is still invalid and could misbehave. It just happens not to. Declaring
>>> any variable in a struct with a 32 byte alignment promises 32 byte
>>> alignment of the whole struct to the compiler.
>>>
>>> Instead of now going through all instances of variables in structs
>>> being declared as 32 byte aligned, this patch bumps the minimum alignment
>>> to 32 bytes.
>>> ---
>>> libavutil/mem.c | 2 +-
>>> 1 file changed, 1 insertion(+), 1 deletion(-)
>>>
>>> diff --git a/libavutil/mem.c b/libavutil/mem.c
>>> index 36b8940a0c..26a9b9753b 100644
>>> --- a/libavutil/mem.c
>>> +++ b/libavutil/mem.c
>>> @@ -62,7 +62,7 @@ void  free(void *ptr);
>>>
>>> #endif /* MALLOC_PREFIX */
>>>
>>> -#define ALIGN (HAVE_AVX512 ? 64 : (HAVE_AVX ? 32 : 16))
>>> +#define ALIGN (HAVE_AVX512 ? 64 : 32)
>> 
>> LGTM
>> 
>> It could be good to add a comment here, to indicate how this value 
>> relates to the alignemnts used in structs.
>> 
>> For others who commented in this thread, it all boils down to something 
>> like this:
>> 
>> struct MyData {
>>      uint8_t __attribute__((aligned(32))) aligned_data[1024];
>> };
>
> It's even a bit more complex than that.
> The case that's crashing right now is a member that has no alignment 
> declared on itself at all.
> But another member of the same struct does, and so the compiler assumes 
> the whole struct to be aligned.

Ah, tricky! Yeah, that's also a valid assumption for the compiler, but 
also a rather non-obvious one.

// Martin


More information about the ffmpeg-devel mailing list