Messages in this thread Patch in this message | | | From | Denis Efremov <> | Subject | [RFC PATCH] coccinelle: api: add flex_array_size.cocci script | Date | Fri, 28 Aug 2020 19:31:34 +0300 |
| |
Suggest flex_array_size() wrapper to compute the size of a flexible array member in a structure. The macro additionally checks for integer overflows.
The cocci script intentionally skips cases where count argument is not a member of a structure because this introduce false positives.
Cc: Gustavo A. R. Silva <gustavoars@kernel.org> Cc: Kees Cook <keescook@chromium.org> Signed-off-by: Denis Efremov <efremov@linux.com> --- Kees, Gustavo, may I have your acks if you find this script useful? Currently, it emits following warnings: ./fs/select.c:994:25-26: WARNING opportunity for flex_array_size ./include/linux/avf/virtchnl.h:711:34-35: WARNING opportunity for flex_array_size ./include/linux/avf/virtchnl.h:722:43-44: WARNING opportunity for flex_array_size ./include/linux/avf/virtchnl.h:738:40-41: WARNING opportunity for flex_array_size ./include/linux/avf/virtchnl.h:749:46-47: WARNING opportunity for flex_array_size ./drivers/dma/qcom/bam_dma.c:1055:35-36: WARNING opportunity for flex_array_size ./drivers/md/dm-crypt.c:2895:45-46: WARNING opportunity for flex_array_size ./drivers/md/dm-crypt.c:3381:47-48: WARNING opportunity for flex_array_size ./drivers/md/dm-crypt.c:2484:45-46: WARNING opportunity for flex_array_size ./drivers/md/dm-crypt.c:2484:45-46: WARNING opportunity for flex_array_size ./net/sched/em_canid.c:198:48-49: WARNING opportunity for flex_array_size ./include/linux/filter.h:741:42-43: WARNING opportunity for flex_array_size ./fs/aio.c:677:42-43: WARNING opportunity for flex_array_size ./include/rdma/rdmavt_qp.h:537:31-32: WARNING opportunity for flex_array_size ./include/rdma/rdmavt_qp.h:537:31-32: WARNING opportunity for flex_array_size ./lib/ts_fsm.c:311:49-50: WARNING opportunity for flex_array_size ./mm/slab.c:3407:59-60: WARNING opportunity for flex_array_size ./mm/slab.c:2139:55-56: WARNING opportunity for flex_array_size ./mm/slab.c:3407:59-60: WARNING opportunity for flex_array_size ./mm/slab.c:2139:55-56: WARNING opportunity for flex_array_size
scripts/coccinelle/api/flex_array_size.cocci | 180 +++++++++++++++++++ 1 file changed, 180 insertions(+) create mode 100644 scripts/coccinelle/api/flex_array_size.cocci
diff --git a/scripts/coccinelle/api/flex_array_size.cocci b/scripts/coccinelle/api/flex_array_size.cocci new file mode 100644 index 000000000000..b5264a826c29 --- /dev/null +++ b/scripts/coccinelle/api/flex_array_size.cocci @@ -0,0 +1,180 @@ +// SPDX-License-Identifier: GPL-2.0-only +/// +/// Suggest flex_array_size() wrapper to compute the size of a +/// flexible array member in a structure. The macro additionally +/// checks for integer overflows. +/// +// Confidence: High +// Copyright: (C) 2020 Denis Efremov ISPRAS +// Options: --no-includes --include-headers +// +// Keywords: flex_array_size +// + + +virtual context +virtual report +virtual org +virtual patch + +@decl_flex@ +identifier name, array, size; +type TA, TS; +@@ + + struct name { + ... + TS size; + ... +( + TA array[]; +| + TA array[\(0\|1\)]; +) + }; + +@ptr_flex@ +identifier decl_flex.name; +identifier instance; +@@ + + struct name *instance; + +@struct_flex@ +identifier decl_flex.name; +identifier instance; +@@ + + struct name instance; + +@ptr_flex_size depends on !patch@ +identifier decl_flex.array, decl_flex.size; +identifier ptr_flex.instance; +type decl_flex.TA; +position p; +@@ + +( +* instance->size * sizeof(TA)@p +| +* instance->size * sizeof(*instance->array)@p +) + +@depends on patch exists@ +identifier decl_flex.array, decl_flex.size; +identifier ptr_flex.instance; +type decl_flex.TA; +@@ + +( +- instance->size * sizeof(TA) ++ flex_array_size(instance, array, instance->size) +| +- instance->size * sizeof(*instance->array) ++ flex_array_size(instance, array, instance->size) +) + +@struct_flex_size depends on !patch@ +identifier decl_flex.array, decl_flex.size; +identifier struct_flex.instance; +type decl_flex.TA; +position p; +@@ + +( +* instance.size * sizeof(TA)@p +| +* instance.size * sizeof(*instance->array)@p +) + +@depends on patch exists@ +identifier decl_flex.array, decl_flex.size; +identifier struct_flex.instance; +type decl_flex.TA; +@@ + +( +- instance.size * sizeof(TA) ++ flex_array_size(instance, array, instance.size) +| +- instance.size * sizeof(*instance->array) ++ flex_array_size(instance, array, instance.size) +) + +@func_arg_flex_size depends on !patch@ +identifier decl_flex.name, decl_flex.array, decl_flex.size; +identifier func, instance; +type decl_flex.TA; +position p; +@@ + + func(..., struct name *instance, ...) { + ... when any +( +* instance->size * sizeof(TA)@p +| +* instance->size * sizeof(*instance->array)@p +) + ... + } + +@depends on patch exists@ +identifier decl_flex.name, decl_flex.array, decl_flex.size; +identifier func, instance; +type decl_flex.TA; +@@ + + func(..., struct name *instance, ...) { + ... when any +( +- instance->size * sizeof(TA) ++ flex_array_size(instance, array, instance->size) +| +- instance->size * sizeof(*instance->array) ++ flex_array_size(instance, array, instance->size) +) + ... + } + + +@script:python depends on report@ +p << ptr_flex_size.p; +@@ + +coccilib.report.print_report(p[0], + "WARNING opportunity for flex_array_size") + +@script:python depends on org@ +p << ptr_flex_size.p; +@@ + +coccilib.org.print_todo(p[0], + "WARNING opportunity for flex_array_size") + +@script:python depends on report@ +p << struct_flex_size.p; +@@ + +coccilib.report.print_report(p[0], + "WARNING opportunity for flex_array_size") + +@script:python depends on org@ +p << struct_flex_size.p; +@@ + +coccilib.org.print_todo(p[0], + "WARNING opportunity for flex_array_size") + +@script:python depends on report@ +p << func_arg_flex_size.p; +@@ + +coccilib.report.print_report(p[0], + "WARNING opportunity for flex_array_size") + +@script:python depends on org@ +p << func_arg_flex_size.p; +@@ + +coccilib.org.print_todo(p[0], + "WARNING opportunity for flex_array_size") -- 2.26.2
| |