> On Aug 26, 2024, at 17:01, Martin Uecker <uec...@tugraz.at> wrote: > > Am Montag, dem 26.08.2024 um 13:30 -0700 schrieb Kees Cook: >> On Mon, Aug 26, 2024 at 07:30:15PM +0000, Qing Zhao wrote: >>> Hi, Martin, >>> >>> Looks like that there is some issue when I tried to use the _Generic for >>> the testing cases, and then I narrowed down to a >>> small testing case that shows the problem without any change to GCC. >>> >>> [opc@qinzhao-ol8u3-x86 gcc]$ cat t1.c >>> struct annotated { >>> char b; >>> int c[]; >>> } *array_annotated; >>> extern void * counted_by_ref (int *); >>> >>> int main(int argc, char *argv[]) >>> { >>> typeof(counted_by_ref (array_annotated->c)) ret >>> = counted_by_ref (array_annotated->c); >>> _Generic (ret, void* : (void)0, default: *ret = 10); >>> >>> return 0; >>> } >>> [opc@qinzhao-ol8u3-x86 gcc]$ /home/opc/Install/latest/bin/gcc t1.c >>> t1.c: In function ‘main’: >>> t1.c:12:44: warning: dereferencing ‘void *’ pointer >>> 12 | _Generic (ret, void* : (void)0, default: *ret = 10); >>> | ^~~~ >>> t1.c:12:49: error: invalid use of void expression >>> 12 | _Generic (ret, void* : (void)0, default: *ret = 10); >>> | ^ >> >> I implemented it like this[1] in the Linux kernel. So yours could be: >> >> struct annotated { >> char b; >> int c[] __attribute__((counted_by(b)); >> }; >> extern struct annotated *array_annotated; >> >> int main(int argc, char *argv[]) >> { >> typeof(_Generic(__builtin_get_counted_by(array_annotated->c), >> void *: (size_t *)NULL, >> default: __builtin_get_counted_by(array_annotated->c))) >> ret = __builtin_get_counted_by(array_annotated->c); >> if (ret) >> *ret = 10; >> >> return 0; >> } >> >> It's a bit cumbersome, but it does what's needed. >> >> This is, however, just doing exactly what Bill has suggested: it is >> converting the (void *)NULL into (size_t *)NULL when there is no >> counted_by annotation... >> >> -Kees >> >> [1] >> https://lore.kernel.org/linux-hardening/20240822231324.make.666-k...@kernel.org/ > > Interesting. Will __builtin_get_counted_by(array_annotated->c) give > a null pointer (or an invalid pointer) of the correct type if > array_annotated is a null pointer of an annotated struct type?
A little confused here: 1. can array_annotated->c be passed to __builtin_get_counted_by as __builtin_get_counted_by(array_annotated->c) when array_annotated is NULL? 2. If YES, then this should cause a run time error? Qing > > I also wonder a bit about the multiple macro evaluations of the arguments > for P and SIZE. > > Martin