> On Apr 15, 2025, at 16:35, Kees Cook <k...@kernel.org> wrote:
> 
> On Tue, Apr 15, 2025 at 09:07:44PM +0200, Martin Uecker wrote:
>> Am Dienstag, dem 15.04.2025 um 14:50 +0200 schrieb Michael Matz:
>>> Hello,
>> ...
>> 
>>>> struct A {
>>>>  int *buf __counted_by(len); // 'len' *must* be in the struct.
>>>>  int len;
>>>> };
>>> 
>>> ... means that we would have to implement general delayed parsing for 
>>> expressions in C parsers. 
>> 
>> I have to agree with Michael.  This was the main reason
>> we rejected the original approach.  
>> 
>> I also think consistency with general syntax for arrays in structs
>> is far more important for C than consistency for the special case of
>> having only one identifier in counted_by.
> 
> Okay, so I think the generally recognized way forward is with two
> attributes:
> 
> counted_by(struct_member)
> 
> and
> 
> counted_by_expr(type struct_member; ...; expression)
> 
> This leaves flexible array members with counted_by unchanged from
> current behavior.

Yes, this is one of the benefit from this compromised approach -:)
> 
> Questions I am left with:
> 
> 1) When applying counted_by to pointer members, are out-of-order member
> declarations expected to be handled? As in, is this expected to be valid?
> 
> struct foo {
> struct bar *p __attribute__((counted_by(count)));
> int count;
> };

Yes, this is valid. 
Given a lone identifier, you will use “counted_by” attribute the same as the 
counted_by for FAM, and this identifier will be looked up inside the enclosing 
structure.  (Even when the counted_by field is AFTER the pointer).

The patch I sent a while ago on the counted_by for pointer filed of a structure:
https://gcc.gnu.org/pipermail/gcc-patches/2025-January/673837.html

Have supported this without issue.


> 
> 1.A) If it is _not_ valid, is it valid to use it when the member has
> been declared earlier? Such as:
> 
> struct foo {
> int count;
> struct bar *p __attribute__((counted_by(count)));
> };
> 
> 1.B) If "1" isn't valid, but "1.A" is valid, I would expect that way to
> allow the member ordering in "1" is through counted_by_expr? For example:
> 
> struct foo {
> struct bar *p __attribute__((counted_by_expr(int count; count)));
> int count;
> };
> 
> 1.C) If "1" isn't valid, and "1.A" isn't valid, then counted_by of
> pointer members must always use counted_by_expr. Is that expected?
> (I ask because it seems like a potentially weird case there member order
> forces choosing between two differently named attributes. It'd be really
> nice if "1" could be valid.)

1 would be valid. -:)
> 
> 
> 2) For all counted_by of pointer members, I understand this to only be
> about the parsing step, not further analysis where the full sizes of
> all objects will need to be known. Which means that this is valid:
> 
> struct bar; // empty declaration
> 
> struct foo {
> struct bar *p __attribute__((counted_by_expr(int count; count)));
> int count;
> };

This could be: 
struct foo {
struct bar *p __attribute__((counted_by (count)));
int count;
};
> ...
> // defined after being referenced by counted_by_expr above
> struct bar {
> int a, b, c;
> struct foo *p;
> };
> 
> Is that correct?

I think so. 
> 
> 
> 3) It seems it will be possible to provide a "singleton" alias to
> indicate that a given pointer member is not an array of objects, but
> rather a pointer to a single object instance:
> 
> struct bar {
> int a, b, c;
> struct foo *p __attribute__((counted_by_expr(1)));
> };
> 
> Is that correct? (This will be useful once we can apply counted_by to
> function arguments...)

This is a good idea. 
> 
> 
> 4) If there are type mismatches between the counted_by_expr struct
> member declaration and the later actual struct member declaration, I
> assume that will be a hard error. For example, this would fail to compile:
> 
> struct foo {
> struct bar *p __attribute__((counted_by_expr(int count; count)));
> unsigned long count;
> };
> 
> Is that correct?

I guess that the hard error will be issued when the parser sees “unsigned long 
count” which
Is conflict with the previous seen “int count” inside counted_by_expr. 

But I am not sure on this.

Qing

> It feels like if we're already able to do this analysis,
> then "1" should be possible also. Perhaps I'm misunderstanding something
> about the parser.
> 
> 
> Thanks!
> 
> -Kees
> 
> -- 
> Kees Cook


Reply via email to