Viktor Dukhovni via Postfix-users <[email protected]> writes:

> On Sat, Sep 19, 2026 at 07:37:56PM -0400, Wietse Venema via Postfix-users 
> wrote:
>
>> I have added support for counted_by() annotations, and for loggging
>> array bound violations with Postfix logging routines. Note: this
>> adds only counted_by() support, not actual counted_by() annotations.
>
> On Fedora 43 with GCC 15.2.1, the test program does not compile:
>
>     ubsan_logger_test.c: In function ‘test_counted_by’:
>     ubsan_logger_test.c:31:17: error: ‘counted_by’ attribute is not allowed 
> for a non-array field
>        31 |         int    *data __counted_by(len);
>           |                 ^~~~
>     make: *** [Makefile:543: ubsan_logger_test] Error 1
>
> With "clang", the test compiles and passes:
>
>     clang [...] -o ubsan_logger_test ubsan_logger_test.c [...] -lubsan [...]
>     LD_LIBRARY_PATH=...  ./ubsan_logger_test
>     RUN  test __counted_by__ support
>     LOG  (expected) warning: ubsan_logger_test.c:39:5: out-of-bounds-index: 
> Index 2 out of bounds for type 'int * __counted_by(len)' (aka 'int *')
>     ubsan_logger_test.c:39:5: runtime error: index 2 out of bounds for type 
> 'int * __counted_by(len)' (aka 'int *')
>     SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior 
> ubsan_logger_test.c:39:5
>     PASS test __counted_by__ support
>
>     ubsan_logger_test: PASS: 1, SKIP: 0, FAIL: 0
>
> The GCC failure is despite the documentation
> https://gcc.gnu.org/onlinedocs/gcc/Common-Attributes.html#index-counted_005fby
> promising otherwise (the "[[gnu::counted_by (...)]]" syntax behaves
> identically to "__counted_by(...)"):

I think you're looking at docs for GCC trunk. It may work there.

>
>   counted_by (count)
>
>         The counted_by attribute may be attached to a C99 flexible array
>         member or a pointer field of a structure.
>
>         It indicates that the number of the elements of the array that
>         is held by the flexible array member field, or is pointed to by
>         the pointer field, is given by the field named by the identifier
>         count in the same structure as the flexible array member or the
>         pointer field. 
>
>     For instance, the following code:
>
>         struct P {
>           size_t count;
>           char other;
>           [[gnu::counted_by (count)]] char array[];
>         } *p;
>
>     specifies that the array is a flexible array member whose number of
>     elements is given by the field count in the same structure.
>
>         struct PP {
>           size_t count2;
>           char other1;
>           [[gnu::counted_by (count2)]] char *array2;
>           int other2;
>         } *pp;
>
>     specifies that the array2 is an array that is pointed by the pointer
>     field, and its number of elements is given by the field count2 in
>     the same structure. 
>     [...]
>     An explicit counted_by annotation defines a relationship between two
>     objects, p->array and p->count, and there are the following
>     requirements on the relationship between this pair:
>
>         * p->count must be initialized before the first reference to p->array;
>         * p->array has at least p->count number of elements available all
>           the time. This relationship must hold even after any of these
>           related objects are updated during the program. 
>
> The documentation appears to be ahead of the implementation[1].  Using a 
> "flexible
> array member field" makes the compiler happy:
>
>     --- a/ubsan_logger_test.c
>     +++ b/ubsan_logger_test.c
>     @@ -30,10 +30,11 @@ static void test_counted_by(PTEST_CTX *t, const 
> PTEST_CASE *tp)
>             size_t  len;
>     -       int    *data __counted_by(len);
>     +       int     data[] __counted_by(len);
>          };
>     -    struct foo *pfoo = mymalloc(sizeof(*pfoo));
>     +    struct foo *pfoo = mymalloc(sizeof(*pfoo) + 2*sizeof(int));
>          int     len = 2;
>      
>     -    pfoo->data = (int *) mymalloc(len * sizeof(pfoo->data[0]));
>     +    // pfoo->data = (int *) mymalloc(len * sizeof(pfoo->data[0]));
>          pfoo->len = len;
>          expect_ptest_log_event(t, "warning: ubsan_logger_test.c:");
>     +    pfoo->data[1] = 0;
>          pfoo->data[2] = 0;
>
> but this significantly limits the usability of the feature.
>
>> This is uploaded to Postfix source mirrors as postfix-3.12-20260919.
>> It will show up in Viktor's github as time permits.
>
> Done.

Attachment: signature.asc
Description: PGP signature

_______________________________________________
Postfix-users mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to