> On Jul 15, 2024, at 17:41, Martin Uecker <uec...@tugraz.at> wrote: > > Am Montag, dem 15.07.2024 um 21:26 +0000 schrieb Qing Zhao: >> Hi, Martin, >> I didn’t see your v3 patches attached to the email, did you miss them? >> (I really want to see them -:). > > Sorry, I should have CCed you. It was sent as a series of patches: > > https://gcc.gnu.org/pipermail/gcc-patches/2024-July/657254.html
Thanks. Will take a look at them. > >> >>> On Jul 15, 2024, at 16:58, Martin Uecker <uec...@tugraz.at> wrote: >>> >>> Am Montag, dem 15.07.2024 um 13:05 -0700 schrieb Kees Cook: >>>> 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/ >>> >>> Indeed, I already complained a lot to them about that design ;-) >>>> >>>> Those attributes end up being similar to what you have >>> >>> Well, the syntax is from C99, we just have to make it work. >>> >>>> 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.) >>> >>> And isn't this a lot nicer? It also follows the exact same >>> scoping rules of the language as everything else. >>> >>> In GCC the example above works also with this: >>> >>> int h(int n; char buf[n], int n) >>> { >>> return __builtin_dynamic_object_size(buf, 1); >>> } >>> https://godbolt.org/z/vfqoKaq7e >>> >>> and one can hide it with a macro if necessary >>> I hope we will get the syntax with C2Y and also: >>> >>> struct { int n; char buf[.n]; }; >> >> Yes, this is definitely great if we can get this into the C standard. >> Do you have any idea on when that might be possible? > > Hard to tell, but it is being worked on. Implementation > experience in GCC would help. Do you mean that GCC will implement this as an extension first? Qing > > Martin > >>> >>> In any case, I hope we get proper language integration and >>> not a soup of attributes (although the attributes are a step >>> up from not having bounds checking at all.). >> >> agreed. >>> >>> >>> The problem in GCC is that the code for the access attributes >>> that are internally used also for parameters with variably >>> modified types is rather complicated and fragile, which makes >>> it harder than necessary to add the missing pieces. I will >>> probably try to simply add the .ACCESS_WITH_SIZE builtin >>> in the FE to function parameters just like for 'counted_by'. >>> Maybe this is already sufficient to make it work. >> >> As we discussed previously for .ACCESS_WITH_SIZE, IIRC, >> for those current available attributes, “access”, and “alloc_size”, >> if we implement them with .ACCESS_WITH_SIZE, we can make >> them more robust. >> >> I remembered that there were some PRs filed to those issues, >> Will find those PRs. >> >> Maybe it’s time to resolve this PRs as well. I will take a look here. > >>> >>> In general I have the vague idea that at any point where an >>> array decays or is adjusted into a pointer and size is then >>> lost from the type, we could insert this builtin to make >>> the size discoverable by BDOS later. A seamless handover >>> from types to BDOS magic... >> >> Yeah, sounds reasonable to me.