https://gcc.gnu.org/bugzilla/show_bug.cgi?id=116016

--- Comment #63 from Kees Cook <kees at outflux dot net> ---
(In reply to Alejandro Colomar from comment #62)
> What's the value of returning NULL instead of just failing the compilation
> with an error?

It's so that the same allocator macros can be used for FAM structs with or
without a "counted_by" attribute. If "counted_by" is marked, the counter is
updated. If it doesn't exist, it is not.

Here's the expected usage from comment #1 (adjusted for the new API):

  #define alloc(P, FAM, COUNT, GFP) ({ \
    typeof(P) __p; \
    size_t __size = sizeof(*P) + sizeof(*P->FAM) * COUNT; \
    __p = kmalloc(__size, GFP); \
    if (__p && __builtin_get_counted_by(__p->FAM)) \
      *__builtin_get_counted_by(__p->FAM) = COUNT; \
    __p; \
  })

We can actually take this even further and sanity check "COUNT" against the
counter type in addition to setting it:

  #define alloc(P, FAM, COUNT, GFP) ({ \
    size_t __count = (COUNT); \
    typeof(P) __p; \
    if (__builtin_get_counted_by(__p->FAM) && \
        __count > type_max(typeof(*__builtin_get_counted_by(__p->FAM))) { \
      __p = NULL; \
    } else { \
      size_t __size = struct_size(*__p, FAM, __count); \
      __p = kmalloc(__size, GFP); \
      if (__p && __builtin_get_counted_by(__p->FAM)) \
        *__builtin_get_counted_by(__p->FAM) = __count; \
    }
    __p; \
  })

Reply via email to