History

Merge tag 'kmalloc_obj-v7.0-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux

Pull kmalloc_obj updates from Kees Cook: "Introduce the kmalloc_obj* family of APIs for switching to type-based kmalloc allocations, away from purely size-based allocations. Discussed on lkml, with you, and at Linux Plumbers. It's been in -next for the entire dev cycle. Before the merge window closes, I'd like to send the treewide change (generated from the Coccinelle script included here), which mechanically converts almost 20k callsites from kmalloc* to kmalloc_obj*: 8007 files changed, 19980 insertions(+), 20838 deletions(-) This change needed fixes for mismatched types (since now the return type from allocations is a pointer to the requested type, not "void *"), and I've been fixing these over the last 4 releases. These fixes have mostly been trivial mismatches with const qualifiers or accidentally identical sizes (e.g. same object size: "struct kvec" vs "struct iovec", or differing pointers to pointers), but I did catch one case of too-small allocation. Summary: - Introduce kmalloc_obj*() family of type-based allocator APIs - checkpatch: Suggest kmalloc_obj family for sizeof allocations - coccinelle: Add kmalloc_objs conversion script" * tag 'kmalloc_obj-v7.0-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux: coccinelle: Add kmalloc_objs conversion script slab: Introduce kmalloc_flex() and family compiler_types: Introduce __flex_counter() and family checkpatch: Suggest kmalloc_obj family for sizeof allocations slab: Introduce kmalloc_obj() and family

Linus Torvalds committed 9 months ago

Commit 958f7fb2 parents 85f24b0 bdc50716 files · +367 −6Browse files

Unified · Split

6 files
  1. Documentation/process/deprecated.rst +31 −0
  2. include/linux/compiler_types.h +31 −0
  3. include/linux/overflow.h +42 −0
  4. include/linux/slab.h +106 −0
  5. scripts/checkpatch.pl +33 −6
  6. scripts/coccinelle/api/kmalloc_objs.cocci +124 −0
Documentation/process/deprecated.rst+31−0
@@ -372,3 +372,34 @@ The helper must be used:: · 371 unmodified lines
372372 DECLARE_FLEX_ARRAY(struct type2, two);
373373 };
374374 };
375+
376+Open-coded kmalloc assignments for struct objects
377+-------------------------------------------------
378+Performing open-coded kmalloc()-family allocation assignments prevents
379+the kernel (and compiler) from being able to examine the type of the
380+variable being assigned, which limits any related introspection that
381+may help with alignment, wrap-around, or additional hardening. The
382+kmalloc_obj()-family of macros provide this introspection, which can be
383+used for the common code patterns for single, array, and flexible object
384+allocations. For example, these open coded assignments::
385+
386+ ptr = kmalloc(sizeof(*ptr), gfp);
387+ ptr = kzalloc(sizeof(*ptr), gfp);
388+ ptr = kmalloc_array(count, sizeof(*ptr), gfp);
389+ ptr = kcalloc(count, sizeof(*ptr), gfp);
390+ ptr = kmalloc(struct_size(ptr, flex_member, count), gfp);
391+ ptr = kmalloc(sizeof(struct foo, gfp);
392+
393+become, respectively::
394+
395+ ptr = kmalloc_obj(*ptr, gfp);
396+ ptr = kzalloc_obj(*ptr, gfp);
397+ ptr = kmalloc_objs(*ptr, count, gfp);
398+ ptr = kzalloc_objs(*ptr, count, gfp);
399+ ptr = kmalloc_flex(*ptr, flex_member, count, gfp);
400+ __auto_type ptr = kmalloc_obj(struct foo, gfp);
401+
402+If `ptr->flex_member` is annotated with __counted_by(), the allocation
403+will automatically fail if `count` is larger than the maximum
404+representable value that can be stored in the counter member associated
405+with `flex_member`.
include/linux/compiler_types.h+31−0
@@ -551,6 +551,37 @@ struct ftrace_likely_data { · 550 unmodified lines
551551 #define __annotated(var, attr) __builtin_has_attribute(var, attr)
552552 #endif
553553
554+/*
555+ * Optional: only supported since gcc >= 15, clang >= 19
556+ *
557+ * gcc: https://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html#index-_005f_005fbuiltin_005fcounted_005fby_005fref
558+ * clang: https://clang.llvm.org/docs/LanguageExtensions.html#builtin-counted-by-ref
559+ */
560+#if __has_builtin(__builtin_counted_by_ref)
561+/**
562+ * __flex_counter() - Get pointer to counter member for the given
563+ * flexible array, if it was annotated with __counted_by()
564+ * @FAM: Pointer to flexible array member of an addressable struct instance
565+ *
566+ * For example, with:
567+ *
568+ * struct foo {
569+ * int counter;
570+ * short array[] __counted_by(counter);
571+ * } *p;
572+ *
573+ * __flex_counter(p->array) will resolve to &p->counter.
574+ *
575+ * Note that Clang may not allow this to be assigned to a separate
576+ * variable; it must be used directly.
577+ *
578+ * If p->array is unannotated, this returns (void *)NULL.
579+ */
580+#define __flex_counter(FAM) __builtin_counted_by_ref(FAM)
581+#else
582+#define __flex_counter(FAM) ((void *)NULL)
583+#endif
584+
554585 /*
555586 * Some versions of gcc do not mark 'asm goto' volatile:
556587 *
include/linux/overflow.h+42−0
@@ -552,4 +552,46 @@ static inline size_t __must_check size_sub(size_t minuend, size_t subtrahend) · 551 unmodified lines
552552 (__member_size((name)->array) / sizeof(*(name)->array) + \
553553 __must_be_array((name)->array))
554554
555+/**
556+ * typeof_flex_counter() - Return the type of the counter variable of a given
557+ * flexible array member annotated by __counted_by().
558+ * @FAM: Instance of flexible array member within a given struct.
559+ *
560+ * Returns: "size_t" if no annotation exists.
561+ */
562+#define typeof_flex_counter(FAM) \
563+ typeof(_Generic(__flex_counter(FAM), \
564+ void *: (size_t)0, \
565+ default: *__flex_counter(FAM)))
566+
567+/**
568+ * overflows_flex_counter_type() - Check if the counter associated with the
569+ * given flexible array member can represent
570+ * a value.
571+ * @TYPE: Type of the struct that contains the @FAM.
572+ * @FAM: Member name of the FAM within @TYPE.
573+ * @COUNT: Value to check against the __counted_by annotated @FAM's counter.
574+ *
575+ * Returns: true if @COUNT can be represented in the @FAM's counter. When
576+ * @FAM is not annotated with __counted_by(), always returns true.
577+ */
578+#define overflows_flex_counter_type(TYPE, FAM, COUNT) \
579+ (!overflows_type(COUNT, typeof_flex_counter(((TYPE *)NULL)->FAM)))
580+
581+/**
582+ * __set_flex_counter() - Set the counter associated with the given flexible
583+ * array member that has been annoated by __counted_by().
584+ * @FAM: Instance of flexible array member within a given struct.
585+ * @COUNT: Value to store to the __counted_by annotated @FAM_PTR's counter.
586+ *
587+ * This is a no-op if no annotation exists. Count needs to be checked with
588+ * overflows_flex_counter_type() before using this function.
589+ */
590+#define __set_flex_counter(FAM, COUNT) \
591+({ \
592+ *_Generic(__flex_counter(FAM), \
593+ void *: &(size_t){ 0 }, \
594+ default: __flex_counter(FAM)) = (COUNT); \
595+})
596+
555597 #endif /* __LINUX_OVERFLOW_H */
include/linux/slab.h+106−0
@@ -12,6 +12,7 @@ · 11 unmodified lines
1212 #ifndef _LINUX_SLAB_H
1313 #define _LINUX_SLAB_H
1414
15+#include <linux/bug.h>
1516 #include <linux/cache.h>
1617 #include <linux/gfp.h>
1718 #include <linux/overflow.h>
@@ -965,6 +966,111 @@ static __always_inline __alloc_size(1) void *kmalloc_noprof(size_t size, gfp_t f · 947 unmodified lines
965966 void *kmalloc_nolock_noprof(size_t size, gfp_t gfp_flags, int node);
966967 #define kmalloc_nolock(...) alloc_hooks(kmalloc_nolock_noprof(__VA_ARGS__))
967968
969+/**
970+ * __alloc_objs - Allocate objects of a given type using
971+ * @KMALLOC: which size-based kmalloc wrapper to allocate with.
972+ * @GFP: GFP flags for the allocation.
973+ * @TYPE: type to allocate space for.
974+ * @COUNT: how many @TYPE objects to allocate.
975+ *
976+ * Returns: Newly allocated pointer to (first) @TYPE of @COUNT-many
977+ * allocated @TYPE objects, or NULL on failure.
978+ */
979+#define __alloc_objs(KMALLOC, GFP, TYPE, COUNT) \
980+({ \
981+ const size_t __obj_size = size_mul(sizeof(TYPE), COUNT); \
982+ (TYPE *)KMALLOC(__obj_size, GFP); \
983+})
984+
985+/**
986+ * __alloc_flex - Allocate an object that has a trailing flexible array
987+ * @KMALLOC: kmalloc wrapper function to use for allocation.
988+ * @GFP: GFP flags for the allocation.
989+ * @TYPE: type of structure to allocate space for.
990+ * @FAM: The name of the flexible array member of @TYPE structure.
991+ * @COUNT: how many @FAM elements to allocate space for.
992+ *
993+ * Returns: Newly allocated pointer to @TYPE with @COUNT-many trailing
994+ * @FAM elements, or NULL on failure or if @COUNT cannot be represented
995+ * by the member of @TYPE that counts the @FAM elements (annotated via
996+ * __counted_by()).
997+ */
998+#define __alloc_flex(KMALLOC, GFP, TYPE, FAM, COUNT) \
999+({ \
1000+ const size_t __count = (COUNT); \
1001+ const size_t __obj_size = struct_size_t(TYPE, FAM, __count); \
1002+ TYPE *__obj_ptr; \
1003+ if (WARN_ON_ONCE(overflows_flex_counter_type(TYPE, FAM, __count))) \
1004+ __obj_ptr = NULL; \
1005+ else \
1006+ __obj_ptr = KMALLOC(__obj_size, GFP); \
1007+ if (__obj_ptr) \
1008+ __set_flex_counter(__obj_ptr->FAM, __count); \
1009+ __obj_ptr; \
1010+})
1011+
1012+/**
1013+ * kmalloc_obj - Allocate a single instance of the given type
1014+ * @VAR_OR_TYPE: Variable or type to allocate.
1015+ * @GFP: GFP flags for the allocation.
1016+ *
1017+ * Returns: newly allocated pointer to a @VAR_OR_TYPE on success, or NULL
1018+ * on failure.
1019+ */
1020+#define kmalloc_obj(VAR_OR_TYPE, GFP) \
1021+ __alloc_objs(kmalloc, GFP, typeof(VAR_OR_TYPE), 1)
1022+
1023+/**
1024+ * kmalloc_objs - Allocate an array of the given type
1025+ * @VAR_OR_TYPE: Variable or type to allocate an array of.
1026+ * @COUNT: How many elements in the array.
1027+ * @GFP: GFP flags for the allocation.
1028+ *
1029+ * Returns: newly allocated pointer to array of @VAR_OR_TYPE on success,
1030+ * or NULL on failure.
1031+ */
1032+#define kmalloc_objs(VAR_OR_TYPE, COUNT, GFP) \
1033+ __alloc_objs(kmalloc, GFP, typeof(VAR_OR_TYPE), COUNT)
1034+
1035+/**
1036+ * kmalloc_flex - Allocate a single instance of the given flexible structure
1037+ * @VAR_OR_TYPE: Variable or type to allocate (with its flex array).
1038+ * @FAM: The name of the flexible array member of the structure.
1039+ * @COUNT: How many flexible array member elements are desired.
1040+ * @GFP: GFP flags for the allocation.
1041+ *
1042+ * Returns: newly allocated pointer to @VAR_OR_TYPE on success, NULL on
1043+ * failure. If @FAM has been annotated with __counted_by(), the allocation
1044+ * will immediately fail if @COUNT is larger than what the type of the
1045+ * struct's counter variable can represent.
1046+ */
1047+#define kmalloc_flex(VAR_OR_TYPE, FAM, COUNT, GFP) \
1048+ __alloc_flex(kmalloc, GFP, typeof(VAR_OR_TYPE), FAM, COUNT)
1049+
1050+/* All kzalloc aliases for kmalloc_(obj|objs|flex). */
1051+#define kzalloc_obj(P, GFP) \
1052+ __alloc_objs(kzalloc, GFP, typeof(P), 1)
1053+#define kzalloc_objs(P, COUNT, GFP) \
1054+ __alloc_objs(kzalloc, GFP, typeof(P), COUNT)
1055+#define kzalloc_flex(P, FAM, COUNT, GFP) \
1056+ __alloc_flex(kzalloc, GFP, typeof(P), FAM, COUNT)
1057+
1058+/* All kvmalloc aliases for kmalloc_(obj|objs|flex). */
1059+#define kvmalloc_obj(P, GFP) \
1060+ __alloc_objs(kvmalloc, GFP, typeof(P), 1)
1061+#define kvmalloc_objs(P, COUNT, GFP) \
1062+ __alloc_objs(kvmalloc, GFP, typeof(P), COUNT)
1063+#define kvmalloc_flex(P, FAM, COUNT, GFP) \
1064+ __alloc_flex(kvmalloc, GFP, typeof(P), FAM, COUNT)
1065+
1066+/* All kvzalloc aliases for kmalloc_(obj|objs|flex). */
1067+#define kvzalloc_obj(P, GFP) \
1068+ __alloc_objs(kvzalloc, GFP, typeof(P), 1)
1069+#define kvzalloc_objs(P, COUNT, GFP) \
1070+ __alloc_objs(kvzalloc, GFP, typeof(P), COUNT)
1071+#define kvzalloc_flex(P, FAM, COUNT, GFP) \
1072+ __alloc_flex(kvzalloc, GFP, typeof(P), FAM, COUNT)
1073+
9681074 #define kmem_buckets_alloc(_b, _size, _flags) \
9691075 alloc_hooks(__kmalloc_node_noprof(PASS_BUCKET_PARAMS(_size, _b), _flags, NUMA_NO_NODE))
9701076
scripts/checkpatch.pl+33−6
@@ -7260,17 +7260,42 @@ sub process { · 7259 unmodified lines
72607260 "Prefer $3(sizeof(*$1)...) over $3($4...)\n" . $herecurr);
72617261 }
72627262
7263−# check for (kv|k)[mz]alloc with multiplies that could be kmalloc_array/kvmalloc_array/kvcalloc/kcalloc
7263+# check for (kv|k)[mz]alloc that could be kmalloc_obj/kvmalloc_obj/kzalloc_obj/kvzalloc_obj
7264+ if ($perl_version_ok &&
7265+ defined $stat &&
7266+ $stat =~ /^\+\s*($Lval)\s*\=\s*(?:$balanced_parens)?\s*((?:kv|k)[mz]alloc)\s*\(\s*($FuncArg)\s*,/) {
7267+ my $oldfunc = $3;
7268+ my $a1 = $4;
7269+ my $newfunc = "kmalloc_obj";
7270+ $newfunc = "kvmalloc_obj" if ($oldfunc eq "kvmalloc");
7271+ $newfunc = "kvzalloc_obj" if ($oldfunc eq "kvzalloc");
7272+ $newfunc = "kzalloc_obj" if ($oldfunc eq "kzalloc");
7273+
7274+ if ($a1 =~ s/^sizeof\s*\S\(?([^\)]*)\)?$/$1/) {
7275+ my $cnt = statement_rawlines($stat);
7276+ my $herectx = get_stat_here($linenr, $cnt, $here);
7277+
7278+ if (WARN("ALLOC_WITH_SIZEOF",
7279+ "Prefer $newfunc over $oldfunc with sizeof\n" . $herectx) &&
7280+ $cnt == 1 &&
7281+ $fix) {
7282+ $fixed[$fixlinenr] =~ s/\b($Lval)\s*\=\s*(?:$balanced_parens)?\s*((?:kv|k)[mz]alloc)\s*\(\s*($FuncArg)\s*,/$1 = $newfunc($a1,/;
7283+ }
7284+ }
7285+ }
7286+
7287+
7288+# check for (kv|k)[mz]alloc with multiplies that could be kmalloc_objs/kvmalloc_objs/kzalloc_objs/kvzalloc_objs
72647289 if ($perl_version_ok &&
72657290 defined $stat &&
72667291 $stat =~ /^\+\s*($Lval)\s*\=\s*(?:$balanced_parens)?\s*((?:kv|k)[mz]alloc)\s*\(\s*($FuncArg)\s*\*\s*($FuncArg)\s*,/) {
72677292 my $oldfunc = $3;
72687293 my $a1 = $4;
72697294 my $a2 = $10;
7270− my $newfunc = "kmalloc_array";
7271− $newfunc = "kvmalloc_array" if ($oldfunc eq "kvmalloc");
7272− $newfunc = "kvcalloc" if ($oldfunc eq "kvzalloc");
7273− $newfunc = "kcalloc" if ($oldfunc eq "kzalloc");
7295+ my $newfunc = "kmalloc_objs";
7296+ $newfunc = "kvmalloc_objs" if ($oldfunc eq "kvmalloc");
7297+ $newfunc = "kvzalloc_objs" if ($oldfunc eq "kvzalloc");
7298+ $newfunc = "kzalloc_objs" if ($oldfunc eq "kzalloc");
72747299 my $r1 = $a1;
72757300 my $r2 = $a2;
72767301 if ($a1 =~ /^sizeof\s*\S/) {
@@ -7286,7 +7311,9 @@ sub process { · 9 unmodified lines
72867311 "Prefer $newfunc over $oldfunc with multiply\n" . $herectx) &&
72877312 $cnt == 1 &&
72887313 $fix) {
7289− $fixed[$fixlinenr] =~ s/\b($Lval)\s*\=\s*(?:$balanced_parens)?\s*((?:kv|k)[mz]alloc)\s*\(\s*($FuncArg)\s*\*\s*($FuncArg)/$1 . ' = ' . "$newfunc(" . trim($r1) . ', ' . trim($r2)/e;
7314+ my $sized = trim($r2);
7315+ $sized =~ s/^sizeof\s*\S\(?([^\)]*)\)?$/$1/;
7316+ $fixed[$fixlinenr] =~ s/\b($Lval)\s*\=\s*(?:$balanced_parens)?\s*((?:kv|k)[mz]alloc)\s*\(\s*($FuncArg)\s*\*\s*($FuncArg)/$1 . ' = ' . "$newfunc(" . $sized . ', ' . trim($r1)/e;
72907317 }
72917318 }
72927319 }
scripts/coccinelle/api/kmalloc_objs.cocci+124−0
@@ -0,0 +1,124 @@
1+// SPDX-License-Identifier: GPL-2.0-only
2+/// Use kmalloc_obj family of macros for allocations
3+///
4+// Confidence: High
5+// Options: --include-headers-for-types --all-includes --include-headers --keep-comments
6+
7+virtual patch
8+
9+@initialize:python@
10+@@
11+import sys
12+
13+def alloc_array(name):
14+ func = "FAILED_RENAME"
15+ if name == "kmalloc_array":
16+ func = "kmalloc_objs"
17+ elif name == "kvmalloc_array":
18+ func = "kvmalloc_objs"
19+ elif name == "kcalloc":
20+ func = "kzalloc_objs"
21+ elif name == "kvcalloc":
22+ func = "kvzalloc_objs"
23+ else:
24+ print(f"Unknown transform for {name}", file=sys.stderr)
25+ return func
26+
27+// This excludes anything that is assigning to or from integral types or
28+// string literals. Everything else gets the sizeof() extracted for the
29+// kmalloc_obj() type/var argument. sizeof(void *) is also excluded because
30+// it will need case-by-case double-checking to make sure the right type is
31+// being assigned.
32+@direct depends on patch && !(file in "tools") && !(file in "samples")@
33+typedef u8, u16, u32, u64;
34+typedef __u8, __u16, __u32, __u64;
35+typedef uint8_t, uint16_t, uint32_t, uint64_t;
36+typedef uchar, ushort, uint, ulong;
37+typedef __le16, __le32, __le64;
38+typedef __be16, __be32, __be64;
39+typedef wchar_t;
40+type INTEGRAL = {u8,__u8,uint8_t,char,unsigned char,uchar,wchar_t,
41+ u16,__u16,uint16_t,unsigned short,ushort,
42+ u32,__u32,uint32_t,unsigned int,uint,
43+ u64,__u64,uint64_t,unsigned long,ulong,
44+ __le16,__le32,__le64,__be16,__be32,__be64};
45+char [] STRING;
46+INTEGRAL *BYTES;
47+INTEGRAL **BYTES_PTRS;
48+type TYPE;
49+expression VAR;
50+expression GFP;
51+expression COUNT;
52+expression FLEX;
53+expression E;
54+identifier ALLOC =~ "^kv?[mz]alloc$";
55+fresh identifier ALLOC_OBJ = ALLOC ## "_obj";
56+fresh identifier ALLOC_FLEX = ALLOC ## "_flex";
57+identifier ALLOC_ARRAY = {kmalloc_array,kvmalloc_array,kcalloc,kvcalloc};
58+fresh identifier ALLOC_OBJS = script:python(ALLOC_ARRAY) { alloc_array(ALLOC_ARRAY) };
59+@@
60+
61+(
62+- VAR = ALLOC((sizeof(*VAR)), GFP)
63++ VAR = ALLOC_OBJ(*VAR, GFP)
64+|
65+ ALLOC((\(sizeof(STRING)\|sizeof(INTEGRAL)\|sizeof(INTEGRAL *)\)), GFP)
66+|
67+ BYTES = ALLOC((sizeof(E)), GFP)
68+|
69+ BYTES = ALLOC((sizeof(TYPE)), GFP)
70+|
71+ BYTES_PTRS = ALLOC((sizeof(E)), GFP)
72+|
73+ BYTES_PTRS = ALLOC((sizeof(TYPE)), GFP)
74+|
75+ ALLOC((sizeof(void *)), GFP)
76+|
77+- ALLOC((sizeof(E)), GFP)
78++ ALLOC_OBJ(E, GFP)
79+|
80+- ALLOC((sizeof(TYPE)), GFP)
81++ ALLOC_OBJ(TYPE, GFP)
82+|
83+ ALLOC_ARRAY(COUNT, (\(sizeof(STRING)\|sizeof(INTEGRAL)\|sizeof(INTEGRAL *)\)), GFP)
84+|
85+ BYTES = ALLOC_ARRAY(COUNT, (sizeof(E)), GFP)
86+|
87+ BYTES = ALLOC_ARRAY(COUNT, (sizeof(TYPE)), GFP)
88+|
89+ BYTES_PTRS = ALLOC_ARRAY(COUNT, (sizeof(E)), GFP)
90+|
91+ BYTES_PTRS = ALLOC_ARRAY(COUNT, (sizeof(TYPE)), GFP)
92+|
93+ ALLOC_ARRAY((\(sizeof(STRING)\|sizeof(INTEGRAL)\|sizeof(INTEGRAL *)\)), COUNT, GFP)
94+|
95+ BYTES = ALLOC_ARRAY((sizeof(E)), COUNT, GFP)
96+|
97+ BYTES = ALLOC_ARRAY((sizeof(TYPE)), COUNT, GFP)
98+|
99+ BYTES_PTRS = ALLOC_ARRAY((sizeof(E)), COUNT, GFP)
100+|
101+ BYTES_PTRS = ALLOC_ARRAY((sizeof(TYPE)), COUNT, GFP)
102+|
103+ ALLOC_ARRAY(COUNT, (sizeof(void *)), GFP)
104+|
105+ ALLOC_ARRAY((sizeof(void *)), COUNT, GFP)
106+|
107+- ALLOC_ARRAY(COUNT, (sizeof(E)), GFP)
108++ ALLOC_OBJS(E, COUNT, GFP)
109+|
110+- ALLOC_ARRAY(COUNT, (sizeof(TYPE)), GFP)
111++ ALLOC_OBJS(TYPE, COUNT, GFP)
112+|
113+- ALLOC_ARRAY((sizeof(E)), COUNT, GFP)
114++ ALLOC_OBJS(E, COUNT, GFP)
115+|
116+- ALLOC_ARRAY((sizeof(TYPE)), COUNT, GFP)
117++ ALLOC_OBJS(TYPE, COUNT, GFP)
118+|
119+- ALLOC(struct_size(VAR, FLEX, COUNT), GFP)
120++ ALLOC_FLEX(*VAR, FLEX, COUNT, GFP)
121+|
122+- ALLOC(struct_size_t(TYPE, FLEX, COUNT), GFP)
123++ ALLOC_FLEX(TYPE, FLEX, COUNT, GFP)
124+)