Am Dienstag, dem 01.08.2023 um 15:45 -0700 schrieb Kees Cook:
> On Mon, Jul 31, 2023 at 08:14:42PM +0000, Qing Zhao wrote:
> > /* In general, Due to type casting, the type for the pointee of a pointer
> >    does not say anything about the object it points to,
> >    So, __builtin_object_size can not directly use the type of the pointee
> >    to decide the size of the object the pointer points to.
> > 
> >    there are only two reliable ways:
> >    A. observed allocations  (call to the allocation functions in the 
> > routine)
> >    B. observed accesses     (read or write access to the location of the 
> >                              pointer points to)
> > 
> >    that provide information about the type/existence of an object at
> >    the corresponding address.
> > 
> >    for A, we use the "alloc_size" attribute for the corresponding allocation
> >    functions to determine the object size;
> > 
> >    For B, we use the SIZE info of the TYPE attached to the corresponding 
> > access.
> >    (We treat counted_by attribute as a complement to the SIZE info of the 
> > TYPE
> >     for FMA) 
> > 
> >    The only other way in C which ensures that a pointer actually points
> >    to an object of the correct type is 'static':
> > 
> >    void foo(struct P *p[static 1]);   
> > 
> >    See https://gcc.gnu.org/pipermail/gcc-patches/2023-July/624814.html
> >    for more details.  */
> 
> This is a great explanation; thank you!
> 
> In the future I might want to have a new builtin that will allow
> a program to query a pointer when neither A nor B have happened. But
> for the first version of the __counted_by infrastructure, the above
> limitations seen fine.
> 
> For example, maybe __builtin_counted_size(p) (which returns sizeof(*p) +
> sizeof(*p->flex_array_member) * p->counted_by_member). Though since
> there might be multiple flex array members, maybe this can't work. :)

We had a _Lengthof proposal for arrays (instead of sizeof/sizeof)
and thought about how to extend this to structs with FAM. The
problem is that it can not rely on an attribute.

With GCC's VLA in structs you could do 

struct foo { int n; char buf[n_init]; } *p = malloc(sizeof *p);
p->n_init = n;

and get sizeof and bounds checking with UBSan
https://godbolt.org/z/d4nneqs3P

(but also compiler bugs and other issues)


Also see my experimental container library, where you can do:

vec_decl(int);
vec(int)* v = vec_alloc(int);

vec_push(&v, 1);
vec_push(&v, 3);

auto p = &vec_array(v);
(*p)[1] = 1; // bounds check

Here, "vec_array()" would give you a regular C array view
of the vector contant and with correct dynamic size, so you
can apply "sizeof" and  have bounds checking with UBSan and
it just works (with clang / GCC without changes). 
https://github.com/uecker/noplate



Martin







Reply via email to