On Wed, Aug 21, 2024 at 2:54 PM Bill Wendling <isanb...@gmail.com> wrote: > > On Wed, Aug 21, 2024 at 10:44 AM Kees Cook <k...@kernel.org> wrote: > > > > On Wed, Aug 21, 2024 at 03:27:56PM +0000, Qing Zhao wrote: > > > > On Aug 21, 2024, at 10:45, Martin Uecker <uec...@tugraz.at> wrote: > > > > > > > > Am Mittwoch, dem 21.08.2024 um 16:34 +0200 schrieb Martin Uecker: > > > >> Am Mittwoch, dem 21.08.2024 um 14:12 +0000 schrieb Qing Zhao: > > > >> > > > >>> > > > >>> Yes, I do feel that the approach __builtin_get_counted_by is not very > > > >>> good. > > > >>> Maybe it’s better to provide > > > >>> A. __builtin_set_counted_by > > > >>> or > > > >>> B. The unary operator __counted_by(PTR) to return a Lvalue, in this > > > >>> case, > > > >>> we need a __builtin_has_attribute first to check whether PTR has the > > > >>> counted_by attribute first. > > > >> > > > >> You could potentially do the same __counted_by and test for type void. > > > >> > > > >> _Generic(typeof(__counted_by(PTR)), void: (void)0, __counted_by(PTR) = > > > >> COUNT); > > > > > > > > But just doing A. also seems ok. > > > > > > I am fine with A. It’s easier to be used by the end users. > > > > > > The only potential problem with A is, the functionality of READing the > > > counted-by field is missing. > > > Is that okay? Kees? > > > > After seeing the utility of __builtin_get_counted_by() I realized that > > we really do want it for the ability to examine the _type_ of the > > counter member, otherwise we run the risk of assignment truncation. For > > example: > > > > struct flex { > > unsigned char counter; > > int array[] __attribute__((counted_by(counter))); > > } *p; > > > > count = 1000; > > ... > > __builtin_set_counted_by(p->array, count); > > > > What value would p->counter end up with? (I assume it would wrap around, > > which is bad). And there would be no way to catch it at run-time without > > a way to check the type. For example with __builtin_get_counted_by, we > > can do: > > > It might be check-able. SEMA would have to look at the arguments and > determine whether there's a size difference. Not the most elegant way > of doing things for sure. Using __builtin_get_counted_by() has its > return type changed to the counter's type, so it can go through > "normal" checking. > > > if (__builtin_get_counted_by(p->array)) { > > size_t max_value = > > type_max(typeof(*__builtin_get_counted_by(p->array))); > > if (count > type_max) > > ...fail cleanly... > > *__builtin_get_counted_by(p->array) = count; > > } > > > > I don't strictly need to READ the value (but it seems nice). Currently I can > > already do a READ with something like this: > > > > size_t count = __builtin_dynamic_object_size(p->array, 1) / > > sizeof(*p->array); > > > > But I don't have a way to examine the counter _type_ without > > __builtin_get_counted_by, so I prefer it over __builtin_set_counted_by. > > > Another thing to point out, the documented type signature of > __builtin_get_counted_by() is more-or-less meaningless. It should be > adjusted during SEMA to a pointer to the count's type. It's only "void > *" if the 'counted_by' attribute. > Should read: "if the ' counted_by' attribute doesn't exist."
> -bw