[FFmpeg-devel] [PATCH] avcodec/hevc_ps: fix the problem of memcmp losing effectiveness
Mark Thompson
sw at jkqxz.net
Fri Mar 29 18:33:30 EET 2024
On 29/03/2024 15:58, Andreas Rheinhardt wrote:
> Mark Thompson:
>> On 29/03/2024 14:00, Andreas Rheinhardt wrote:
>>> James Almer:
>>>> On 3/29/2024 10:10 AM, Mark Thompson wrote:
>>>>> On 28/03/2024 13:15, tong1.wu-at-intel.com at ffmpeg.org wrote:
>>>>>> From: Tong Wu <tong1.wu at intel.com>
>>>>>>
>>>>>> HEVCHdrParams* receives a pointer which points to a dynamically
>>>>>> allocated memory block. It causes the memcmp always returning 1.
>>>>>> Add a function to do the comparision. A condition is also added to
>>>>>> avoid malloc(0).
>>>>>>
>>>>>> Signed-off-by: Tong Wu <tong1.wu at intel.com>
>>>>>> ---
>>>>>> libavcodec/hevc_ps.c | 20 ++++++++++++++++----
>>>>>> libavcodec/hevc_ps.h | 4 +++-
>>>>>> 2 files changed, 19 insertions(+), 5 deletions(-)
>>>>>
>>>>> It doesn't seem like this method works at all, even before the recent
>>>>> change with the pointer.
>>>>>
>>>>> Structs can contain arbitrary padding, and any write to the struct
>>>>> makes the padding unspecified. memcmp() is therefore never valid as a
>>>>> method of comparing after writing some fields, as done here. (It
>>>>> could only be valid if the structs compared were made by memcpy() with
>>>>> no fields written directly.)
>>>>
>>>> The struct is zero allocated, so shouldn't the padding be exactly the
>>>> same for two equal VPSs after parsing?
>>>>
>>>
>>> In practice it is (and the current code already relied on this); yet as
>>> has already been said padding bytes take unspecified values at any store
>>> (to any member). In practice, if the compiler uses instructions that
>>> clobber the padding, the padding in both structs is clobbered in the
>>> same way.
>>
>> This seems like a strong assumption beyond that of the C specification
>> which needs to be documented.
>>
>> Are you expecting that there is no case where ABI-undefined top bits of
>> registers can leak into the padding fields, or that all functions called
>> here will necessarily set those top bits to the same values, or
>> something else?
>>
>
> Yes, I am expecting that. That is also what the code already relied on
> before the addition of the allocated field and there have been no
> reports that this caused issues.
Huh. Having just experimented a bit I find myself surprised by the lengths x86-64 gcc goes to with weird unaligned accesses to avoid this (e.g. to write to aligned uint8_t a[31] it may do aligned 16-byte write to a and unaligned 16-byte write to a+15, avoiding touching the padding for no clear reason).
Are you aware of any documentation from gcc or llvm about on what they guarantee here?
> This does not change that I consider it crazy to remove the parameter
> sets referencing a parameter set that is removed.
I agree, having now read the code more. My comment was purely driven by observing the use of memcmp() on structs (an operation well-known to be very difficult to use in standard C), not by looking carefully at the rest of the code involved.
- Mark
More information about the ffmpeg-devel
mailing list