On Mon, Jul 15, 2024 at 07:20:31PM +0200, Martin Uecker wrote: > No, there are still two many missing pieces. The following > works already > > int h(int n, int buf[n]) > { > return __builtin_dynamic_object_size(buf, 1); > }
Yeah, this is nice. There are some interesting things happening around this general idea. Clang has the rather limited attributes "pass_object_size" and "pass_dynamic_object_size" that will work on function prototypes that will inform a _bos or _bdos internally, but you can only choose _one_ type to apply to a given function parameter: size_t h(char * const __attribute__((pass_dynamic_object_size(1))) buf) { return __builtin_dynamic_object_size(buf, 1); } https://clang.llvm.org/docs/AttributeReference.html#pass-object-size-pass-dynamic-object-size I have found it easier to just make wrapper macros, as that can allow both size types: size_t h(char *buf, const size_t p_max, const size_t p_min); #define h(p) \ ({ \ const size_t __p_max = __builtin_dynamic_object_size(p, 0); \ const size_t __p_min = __builtin_dynamic_object_size(p, 1); \ __h(p, __p_max, __p_min); \ }) But best is that it just gets handled automatically, which will be the goals of the more generalized "counted_by" (and "sized_by") attributes that will provide similar coverage as your example: size_t h(int * __attribute__((sized_by(bytes))) buf, int bytes) { return __builtin_dynamic_object_size(buf, 1); } https://discourse.llvm.org/t/rfc-enforcing-bounds-safety-in-c-fbounds-safety/ Those attributes end up being similar to what you have only the explicit predeclaration isn't needed. i.e. to put "int n" in your example after "buf", it needs predeclaration: int h(int n; int buf[n], int n) { ... } (But Clang doesn't appear to support predeclarations.) -- Kees Cook