> On Jun 18, 2025, at 20:51, Siddhesh Poyarekar <siddh...@gotplt.org> wrote:
> 
> On 2025-06-18 18:40, Qing Zhao wrote:
>>>> Okay, I guess that I didn’t put enough attention on the above example 
>>>> previously, sorry about that...
>>>> Read it multiple times this time, my question is for the following code 
>>>> portion:
>>>>  objsz = __builtin_dynamic_object_size (ptr, 0);
>>>>  __memcpy_chk (ptr, src, sz, objsz);
>>>> When program get  to the this point, “ptr” is freed and invalid already,  
>>>> is the program still considered as a valid program when the first argument 
>>>> to the call to __memcpy_chk is an invalid pointer but the 3rd parameter is 
>>>> 0?
>>> 
>>> AFAICT, strictly according to the standards it should not be considered 
>>> valid since any use of an invalid pointer (not just dereferencing it) is 
>>> considered undefined behaviour.  However in practice it doesn't result in 
>>> an invalid access because of SZ=0.
>> Then should we follow the standards here? i.e, even though the program does 
>> not result in an invalid access because of SZ=0, the program has undefined 
>> behavior due to the use of invalid pointer?
> 
> It won't be "following", it would be "taking advantage of", which is 
> technically fair, but I don't think it's a good idea to do by default because 
> it has the potential to create vulnerabilities where there wasn't one before. 
>  It would have been fine if the builtin reliably crashed the program, but 
> here we're simply creating an invalid read, which could potentially be 
> silently exploited.
> 
> However like I said to Kees elsewhere in this thread, maybe we could hide 
> this one behind a new --param:
> 
> ```
> --param objsz-allow-dereference-input
> 
> Allow object size expressions generated by the __builtin_dynamic_object_size 
> builtin function to dereference the input pointer.  This may allow the 
> builtin function to get the size of an object when size information is 
> embedded in the object itself, e.g. with structures that have flexible array 
> members at their end, annotated with the __counted_by__ attribute.  Use this 
> parameter with caution because in cases where a non-NULL input pointer is not 
> known to be valid, e.g. when it points to memory that is either protected or 
> freed, enabling this parameter may result in dereferencing that invalid 
> pointer, potentially introducing additional undefined behaviour.

Okay, this is a reasonable solution to this problem. 

I will add a new —param option as suggested, and then guard the generation of 
the size expression for:

__builtin_dynamic_object_size (p, 1)

With this opinion before the NULL pointer checking.  Then update the testing 
cases as well. 

Is that reasonable?

Thanks.

Qing

> ```
> 
> Sid

Reply via email to