On Wed, Jun 18, 2025 at 03:50:42PM -0400, Siddhesh Poyarekar wrote:
> On 2025-06-18 15:14, Qing Zhao wrote:
> > > struct fam_container
> > > {
> > >   int a;
> > >   int count;
> > >   char fam[] __counted_by__ (count);
> > > };
> > > 
> > > size_t
> > > baz (struct fam_container *ptr)
> > > {
> > > ...
> > >   ptr->count = 0;
> > >   __builtin_free (ptr);
> > > ...
> > >   return 0;
> > > }
> > > 
> > > void
> > > bar (size_t insz)
> > > {
> > >   struct fam_container *c =
> > >     __builtin_malloc (insz + sizeof (struct fam_container));
> > >   c->count = insz;
> > >   sz = baz (c);
> > >   foo (c, sz);
> > > }
> > > 
> > > void
> > > __attribute__ ((noinline))
> > > foo (struct fam_container *ptr, size_t sz)
> > > {
> > >   ...
> > >   objsz = __builtin_dynamic_object_size (ptr, 0);
> > >   __memcpy_chk (ptr, src, sz, objsz);
> > >   ...
> > > }
> > > 
> > > Because SZ is 0, in practice there would have been no dereference of PTR 
> > > in __memcpy_chk because the underlying memcpy would have not dereferenced 
> > > PTR.  Here, _FORTIFY_SOURCE ends up actually introducing an invalid 
> > > dereference through the OBJSZ argument.
> > > 
> > > I hope that clarifies what I'm trying to say.
> > 
> > Yes, Now I see what did you mean from the above example.
> > 
> > However, I think that the use-after-free error in the source code should be 
> > caught by a separate tool -fsanitize=address. (And I just checked the above 
> > small testing case with -fsanitize=address, Yes, the use-after-free error 
> > is detected during run-time).  It’s not the job of 
> > __builtin_dynamic_object_size to catch such errors.
> > 
> 
> I agree, validating invalid pointers is not the job of __bdos.  My concern
> is about having __bdos *generate* code that results in invalid pointer
> access.

I would like a way to indicate the desire to do the dereference. Having
an invalid pointer is a totally separate problem -- everything assumes
it has a valid pointer.

> > It should be reasonable to assume that in
> > 
> > __builtin_dynamic_object_size (ptr, 0);
> > 
> > ptr is NULL or point to a valid memory.

Right.

> > (I think that we might need clarify in the documentation of __bos and 
> > __bdos, if an invalid pointer is passed to these builtins, the behavior is 
> > undefined)
> > 
> > Forcing compiler optimization or other sanitizers always check whether 
> > every pointer reference might be use-after-free is not a reasonable 
> > requirement.

Agreed -- this is a task for hardware (i.e. memory tagging, etc).

> It's not wrong, because __bdos does not validate a pointer.  They key
> difference from the example I cited though, is that in this case the size
> expression does not *create* a dereference of a pointer.  With this patch,
> __bdos will start doing that, which is the risky proposition.

If not __bdos, I would like something that _does_.

> If we say that, it could indeed give us the ability to dereference without
> validating even for NULL, although we'll still need it to avoid a case where
> passes later assume validity of the pointer based on the dereference __bdos
> generated. 

That's reasonable, yes. Use by __bdos shouldn't change the sense of
validity.


-Kees

-- 
Kees Cook

Reply via email to