> On Aug 26, 2024, at 16:30, Kees Cook <k...@kernel.org> wrote: > > 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...
That’s the reason why I returned a (size_t *) instead of a (void *) for the NULL pointer when there is no counted_by annotation in the 1st version of the patch, then the conversion from (void *) NULL to (size_t *) NULL in the source code level will not be needed. Then the above can be simplified as: typeof (__builtin_get_counted_by(array_annotated->c)) ret = __builtin_get_counted_by(array_annotated->c); If (ret) *ret = 10; I am wondering shall I still keep the (size_t *) for the returned NULL pointer instead of the (void *)? Qing > > -Kees > > [1] > https://lore.kernel.org/linux-hardening/20240822231324.make.666-k...@kernel.org/ > > -- > Kees Cook