On 22/05/2024 11:05 am, Jan Beulich wrote:
> On 22.05.2024 11:56, scan-ad...@coverity.com wrote:
>> ** CID 1598431:  Memory - corruptions  (OVERRUN)
>>
>>
>> ________________________________________________________________________________________________________
>> *** CID 1598431:  Memory - corruptions  (OVERRUN)
>> /xen/common/trace.c: 798 in trace()
>> 792         }
>> 793     
>> 794         if ( rec_size > bytes_to_wrap )
>> 795             insert_wrap_record(buf, rec_size);
>> 796     
>> 797         /* Write the original record */
>>>>>     CID 1598431:  Memory - corruptions  (OVERRUN)
>>>>>     Overrunning callee's array of size 28 by passing argument "extra" 
>>>>> (which evaluates to 31) in call to "__insert_record".
>> 798         __insert_record(buf, event, extra, cycles, rec_size, extra_data);
>> 799     
>> 800     unlock:
>> 801         spin_unlock_irqrestore(&this_cpu(t_lock), flags);
>> 802     
>> 803         /* Notify trace buffer consumer that we've crossed the high 
>> water mark. */
> How does the tool conclude "extra" evaluating to 31, when at the top of
> the function it is clearly checked to be less than 28?

Which "top" ?

The reasoning is:

 2. Condition extra % 4UL /* sizeof (uint32_t) */, taking false branch.
 3. Condition extra / 4UL /* sizeof (uint32_t) */ > 7, taking false branch.
 4. cond_at_most: Checking extra / 4UL > 7UL implies that extra may be
up to 31 on the false branch.

which is where 31 comes from.

What Coverity hasn't done is equated "<31 && multiple of 4" to mean
"<28".  I don't think this is unreasonable; analysis has to prune the
reasoning somewhere...

This is (fundamentally) a dumb-ABI problem where we're passing a byte
count but only ever wanting to use it as a unit-of-uint32_t's count.

But it's also problem that we're passing both extra and rec_size into
__insert_record() when one is calculated from the other.

I had decided to leave this alone for now, but maybe it could do with
some improvements (simplifications) to the code.

~Andrew

Reply via email to