Merge branch 'for-5.10' of git://git.kernel.org/pub/scm/linux/kernel/git/jlawall/linux

Pull coccinelle updates from Julia Lawall.

* 'for-5.10' of git://git.kernel.org/pub/scm/linux/kernel/git/jlawall/linux:
coccinelle: api: add kfree_mismatch script
coccinelle: iterators: Add for_each_child.cocci script
scripts: coccicheck: Change default condition for parallelism
scripts: coccicheck: Add quotes to improve portability
coccinelle: api: kfree_sensitive: print memset position
coccinelle: misc: add flexible_array.cocci script
coccinelle: api: add kvmalloc script
scripts: coccicheck: Change default value for parallelism
coccinelle: misc: add excluded_middle.cocci script
scripts: coccicheck: Improve error feedback when coccicheck fails
coccinelle: api: update kzfree script to kfree_sensitive
coccinelle: misc: add uninitialized_var.cocci script
coccinelle: ifnullfree: add vfree(), kvfree*() functions
coccinelle: api: add kobj_to_dev.cocci script
coccinelle: add patch rule for dma_alloc_coherent
scripts: coccicheck: Add chain mode to list of modes

+1118 -26
+14 -3
scripts/coccicheck
··· 75 75 OPTIONS="--dir $KBUILD_EXTMOD $COCCIINCLUDE" 76 76 fi 77 77 78 + # Use only one thread per core by default if hyperthreading is enabled 79 + THREADS_PER_CORE=$(lscpu | grep "Thread(s) per core: " | tr -cd "[:digit:]") 78 80 if [ -z "$J" ]; then 79 81 NPROC=$(getconf _NPROCESSORS_ONLN) 82 + if [ $THREADS_PER_CORE -gt 1 -a $NPROC -gt 4 ] ; then 83 + NPROC=$((NPROC/2)) 84 + fi 80 85 else 81 86 NPROC="$J" 82 87 fi ··· 104 99 if [ "$MODE" = "" ] ; then 105 100 if [ "$ONLINE" = "0" ] ; then 106 101 echo 'You have not explicitly specified the mode to use. Using default "report" mode.' 107 - echo 'Available modes are the following: patch, report, context, org' 102 + echo 'Available modes are the following: patch, report, context, org, chain' 108 103 echo 'You can specify the mode with "make coccicheck MODE=<mode>"' 109 104 echo 'Note however that some modes are not implemented by some semantic patches.' 110 105 fi ··· 131 126 if [ $VERBOSE -ne 0 ] ; then 132 127 echo "Running ($NPROC in parallel): $@" 133 128 fi 134 - echo $@ >>$DEBUG_FILE 135 - $@ 2>>$DEBUG_FILE 129 + if [ "$DEBUG_FILE" != "/dev/null" -a "$DEBUG_FILE" != "" ]; then 130 + echo $@>>$DEBUG_FILE 131 + $@ 2>>$DEBUG_FILE 132 + else 133 + echo $@ 134 + $@ 2>&1 135 + fi 136 + 136 137 err=$? 137 138 if [[ $err -ne 0 ]]; then 138 139 echo "coccicheck failed"
+13 -3
scripts/coccinelle/api/alloc/zalloc-simple.cocci
··· 127 127 if ((x==NULL) || ...) S 128 128 - memset((T2)x,0,E1); 129 129 130 + @depends on patch@ 131 + type T, T2; 132 + expression x; 133 + expression E1,E2,E3,E4; 134 + statement S; 135 + @@ 136 + x = (T)dma_alloc_coherent(E1, E2, E3, E4); 137 + if ((x==NULL) || ...) S 138 + - memset((T2)x, 0, E2); 139 + 130 140 //---------------------------------------------------------- 131 141 // For org mode 132 142 //---------------------------------------------------------- ··· 209 199 position p; 210 200 @@ 211 201 212 - x = (T)dma_alloc_coherent@p(E2,E1,E3,E4); 202 + x = (T)dma_alloc_coherent@p(E1,E2,E3,E4); 213 203 if ((x==NULL) || ...) S 214 - memset((T2)x,0,E1); 204 + memset((T2)x,0,E2); 215 205 216 206 @script:python depends on org@ 217 207 p << r2.p; ··· 227 217 x << r2.x; 228 218 @@ 229 219 230 - msg="WARNING: dma_alloc_coherent use in %s already zeroes out memory, so memset is not needed" % (x) 220 + msg="WARNING: dma_alloc_coherent used in %s already zeroes out memory, so memset is not needed" % (x) 231 221 coccilib.report.print_report(p[0], msg) 232 222 233 223 //-----------------------------------------------------------------
+228
scripts/coccinelle/api/kfree_mismatch.cocci
··· 1 + // SPDX-License-Identifier: GPL-2.0-only 2 + /// 3 + /// Check that kvmalloc'ed memory is freed by kfree functions, 4 + /// vmalloc'ed by vfree functions and kvmalloc'ed by kvfree 5 + /// functions. 6 + /// 7 + // Confidence: High 8 + // Copyright: (C) 2020 Denis Efremov ISPRAS 9 + // Options: --no-includes --include-headers 10 + // 11 + 12 + virtual patch 13 + virtual report 14 + virtual org 15 + virtual context 16 + 17 + @alloc@ 18 + expression E, E1; 19 + position kok, vok; 20 + @@ 21 + 22 + ( 23 + if (...) { 24 + ... 25 + E = \(kmalloc\|kzalloc\|krealloc\|kcalloc\| 26 + kmalloc_node\|kzalloc_node\|kmalloc_array\| 27 + kmalloc_array_node\|kcalloc_node\)(...)@kok 28 + ... 29 + } else { 30 + ... 31 + E = \(vmalloc\|vzalloc\|vmalloc_user\|vmalloc_node\| 32 + vzalloc_node\|vmalloc_exec\|vmalloc_32\| 33 + vmalloc_32_user\|__vmalloc\|__vmalloc_node_range\| 34 + __vmalloc_node\)(...)@vok 35 + ... 36 + } 37 + | 38 + E = \(kmalloc\|kzalloc\|krealloc\|kcalloc\|kmalloc_node\|kzalloc_node\| 39 + kmalloc_array\|kmalloc_array_node\|kcalloc_node\)(...)@kok 40 + ... when != E = E1 41 + when any 42 + if (E == NULL) { 43 + ... 44 + E = \(vmalloc\|vzalloc\|vmalloc_user\|vmalloc_node\| 45 + vzalloc_node\|vmalloc_exec\|vmalloc_32\| 46 + vmalloc_32_user\|__vmalloc\|__vmalloc_node_range\| 47 + __vmalloc_node\)(...)@vok 48 + ... 49 + } 50 + ) 51 + 52 + @free@ 53 + expression E; 54 + position fok; 55 + @@ 56 + 57 + E = \(kvmalloc\|kvzalloc\|kvcalloc\|kvzalloc_node\|kvmalloc_node\| 58 + kvmalloc_array\)(...) 59 + ... 60 + kvfree(E)@fok 61 + 62 + @vfree depends on !patch@ 63 + expression E; 64 + position a != alloc.kok; 65 + position f != free.fok; 66 + @@ 67 + 68 + * E = \(kmalloc\|kzalloc\|krealloc\|kcalloc\|kmalloc_node\| 69 + * kzalloc_node\|kmalloc_array\|kmalloc_array_node\| 70 + * kcalloc_node\)(...)@a 71 + ... when != if (...) { ... E = \(vmalloc\|vzalloc\|vmalloc_user\|vmalloc_node\|vzalloc_node\|vmalloc_exec\|vmalloc_32\|vmalloc_32_user\|__vmalloc\|__vmalloc_node_range\|__vmalloc_node\)(...); ... } 72 + when != is_vmalloc_addr(E) 73 + when any 74 + * \(vfree\|vfree_atomic\|kvfree\)(E)@f 75 + 76 + @depends on patch exists@ 77 + expression E; 78 + position a != alloc.kok; 79 + position f != free.fok; 80 + @@ 81 + 82 + E = \(kmalloc\|kzalloc\|krealloc\|kcalloc\|kmalloc_node\| 83 + kzalloc_node\|kmalloc_array\|kmalloc_array_node\| 84 + kcalloc_node\)(...)@a 85 + ... when != if (...) { ... E = \(vmalloc\|vzalloc\|vmalloc_user\|vmalloc_node\|vzalloc_node\|vmalloc_exec\|vmalloc_32\|vmalloc_32_user\|__vmalloc\|__vmalloc_node_range\|__vmalloc_node\)(...); ... } 86 + when != is_vmalloc_addr(E) 87 + when any 88 + - \(vfree\|vfree_atomic\|kvfree\)(E)@f 89 + + kfree(E) 90 + 91 + @kfree depends on !patch@ 92 + expression E; 93 + position a != alloc.vok; 94 + position f != free.fok; 95 + @@ 96 + 97 + * E = \(vmalloc\|vzalloc\|vmalloc_user\|vmalloc_node\|vzalloc_node\| 98 + * vmalloc_exec\|vmalloc_32\|vmalloc_32_user\|__vmalloc\| 99 + * __vmalloc_node_range\|__vmalloc_node\)(...)@a 100 + ... when != is_vmalloc_addr(E) 101 + when any 102 + * \(kfree\|kfree_sensitive\|kvfree\)(E)@f 103 + 104 + @depends on patch exists@ 105 + expression E; 106 + position a != alloc.vok; 107 + position f != free.fok; 108 + @@ 109 + 110 + E = \(vmalloc\|vzalloc\|vmalloc_user\|vmalloc_node\|vzalloc_node\| 111 + vmalloc_exec\|vmalloc_32\|vmalloc_32_user\|__vmalloc\| 112 + __vmalloc_node_range\|__vmalloc_node\)(...)@a 113 + ... when != is_vmalloc_addr(E) 114 + when any 115 + - \(kfree\|kvfree\)(E)@f 116 + + vfree(E) 117 + 118 + @kvfree depends on !patch@ 119 + expression E; 120 + position a, f; 121 + @@ 122 + 123 + * E = \(kvmalloc\|kvzalloc\|kvcalloc\|kvzalloc_node\|kvmalloc_node\| 124 + * kvmalloc_array\)(...)@a 125 + ... when != is_vmalloc_addr(E) 126 + when any 127 + * \(kfree\|kfree_sensitive\|vfree\|vfree_atomic\)(E)@f 128 + 129 + @depends on patch exists@ 130 + expression E; 131 + @@ 132 + 133 + E = \(kvmalloc\|kvzalloc\|kvcalloc\|kvzalloc_node\|kvmalloc_node\| 134 + kvmalloc_array\)(...) 135 + ... when != is_vmalloc_addr(E) 136 + when any 137 + - \(kfree\|vfree\)(E) 138 + + kvfree(E) 139 + 140 + @kvfree_switch depends on !patch@ 141 + expression alloc.E; 142 + position f; 143 + @@ 144 + 145 + ... when != is_vmalloc_addr(E) 146 + when any 147 + * \(kfree\|kfree_sensitive\|vfree\|vfree_atomic\)(E)@f 148 + 149 + @depends on patch exists@ 150 + expression alloc.E; 151 + position f; 152 + @@ 153 + 154 + ... when != is_vmalloc_addr(E) 155 + when any 156 + ( 157 + - \(kfree\|vfree\)(E)@f 158 + + kvfree(E) 159 + | 160 + - kfree_sensitive(E)@f 161 + + kvfree_sensitive(E) 162 + ) 163 + 164 + @script: python depends on report@ 165 + a << vfree.a; 166 + f << vfree.f; 167 + @@ 168 + 169 + msg = "WARNING kmalloc is used to allocate this memory at line %s" % (a[0].line) 170 + coccilib.report.print_report(f[0], msg) 171 + 172 + @script: python depends on org@ 173 + a << vfree.a; 174 + f << vfree.f; 175 + @@ 176 + 177 + msg = "WARNING kmalloc is used to allocate this memory at line %s" % (a[0].line) 178 + coccilib.org.print_todo(f[0], msg) 179 + 180 + @script: python depends on report@ 181 + a << kfree.a; 182 + f << kfree.f; 183 + @@ 184 + 185 + msg = "WARNING vmalloc is used to allocate this memory at line %s" % (a[0].line) 186 + coccilib.report.print_report(f[0], msg) 187 + 188 + @script: python depends on org@ 189 + a << kfree.a; 190 + f << kfree.f; 191 + @@ 192 + 193 + msg = "WARNING vmalloc is used to allocate this memory at line %s" % (a[0].line) 194 + coccilib.org.print_todo(f[0], msg) 195 + 196 + @script: python depends on report@ 197 + a << kvfree.a; 198 + f << kvfree.f; 199 + @@ 200 + 201 + msg = "WARNING kvmalloc is used to allocate this memory at line %s" % (a[0].line) 202 + coccilib.report.print_report(f[0], msg) 203 + 204 + @script: python depends on org@ 205 + a << kvfree.a; 206 + f << kvfree.f; 207 + @@ 208 + 209 + msg = "WARNING kvmalloc is used to allocate this memory at line %s" % (a[0].line) 210 + coccilib.org.print_todo(f[0], msg) 211 + 212 + @script: python depends on report@ 213 + ka << alloc.kok; 214 + va << alloc.vok; 215 + f << kvfree_switch.f; 216 + @@ 217 + 218 + msg = "WARNING kmalloc (line %s) && vmalloc (line %s) are used to allocate this memory" % (ka[0].line, va[0].line) 219 + coccilib.report.print_report(f[0], msg) 220 + 221 + @script: python depends on org@ 222 + ka << alloc.kok; 223 + va << alloc.vok; 224 + f << kvfree_switch.f; 225 + @@ 226 + 227 + msg = "WARNING kmalloc (line %s) && vmalloc (line %s) are used to allocate this memory" % (ka[0].line, va[0].line) 228 + coccilib.org.print_todo(f[0], msg)
+45
scripts/coccinelle/api/kobj_to_dev.cocci
··· 1 + // SPDX-License-Identifier: GPL-2.0-only 2 + /// 3 + /// Use kobj_to_dev() instead of container_of() 4 + /// 5 + // Confidence: High 6 + // Copyright: (C) 2020 Denis Efremov ISPRAS 7 + // Options: --no-includes --include-headers 8 + // 9 + // Keywords: kobj_to_dev, container_of 10 + // 11 + 12 + virtual context 13 + virtual report 14 + virtual org 15 + virtual patch 16 + 17 + 18 + @r depends on !patch@ 19 + expression ptr; 20 + symbol kobj; 21 + position p; 22 + @@ 23 + 24 + * container_of(ptr, struct device, kobj)@p 25 + 26 + 27 + @depends on patch@ 28 + expression ptr; 29 + @@ 30 + 31 + - container_of(ptr, struct device, kobj) 32 + + kobj_to_dev(ptr) 33 + 34 + 35 + @script:python depends on report@ 36 + p << r.p; 37 + @@ 38 + 39 + coccilib.report.print_report(p[0], "WARNING opportunity for kobj_to_dev()") 40 + 41 + @script:python depends on org@ 42 + p << r.p; 43 + @@ 44 + 45 + coccilib.org.print_todo(p[0], "WARNING opportunity for kobj_to_dev()")
+256
scripts/coccinelle/api/kvmalloc.cocci
··· 1 + // SPDX-License-Identifier: GPL-2.0-only 2 + /// 3 + /// Find if/else condition with kmalloc/vmalloc calls. 4 + /// Suggest to use kvmalloc instead. Same for kvfree. 5 + /// 6 + // Confidence: High 7 + // Copyright: (C) 2020 Denis Efremov ISPRAS 8 + // Options: --no-includes --include-headers 9 + // 10 + 11 + virtual patch 12 + virtual report 13 + virtual org 14 + virtual context 15 + 16 + @initialize:python@ 17 + @@ 18 + filter = frozenset(['kvfree']) 19 + 20 + def relevant(p): 21 + return not (filter & {el.current_element for el in p}) 22 + 23 + @kvmalloc depends on !patch@ 24 + expression E, E1, size; 25 + identifier flags; 26 + binary operator cmp = {<=, <, ==, >, >=}; 27 + identifier x; 28 + type T; 29 + position p; 30 + @@ 31 + 32 + ( 33 + * if (size cmp E1 || ...)@p { 34 + ... 35 + * E = \(kmalloc\|kzalloc\|kcalloc\|kmalloc_node\|kzalloc_node\| 36 + * kmalloc_array\|kmalloc_array_node\|kcalloc_node\) 37 + * (..., size, \(flags\|GFP_KERNEL\|\(GFP_KERNEL\|flags\)|__GFP_NOWARN\), ...) 38 + ... 39 + } else { 40 + ... 41 + * E = \(vmalloc\|vzalloc\|vmalloc_node\|vzalloc_node\)(..., size, ...) 42 + ... 43 + } 44 + | 45 + * E = \(kmalloc\|kzalloc\|kcalloc\|kmalloc_node\|kzalloc_node\| 46 + * kmalloc_array\|kmalloc_array_node\|kcalloc_node\) 47 + * (..., size, \(flags\|GFP_KERNEL\|\(GFP_KERNEL\|flags\)|__GFP_NOWARN\), ...) 48 + ... when != E = E1 49 + when != size = E1 50 + when any 51 + * if (E == NULL)@p { 52 + ... 53 + * E = \(vmalloc\|vzalloc\|vmalloc_node\|vzalloc_node\)(..., size, ...) 54 + ... 55 + } 56 + | 57 + * T x = \(kmalloc\|kzalloc\|kcalloc\|kmalloc_node\|kzalloc_node\| 58 + * kmalloc_array\|kmalloc_array_node\|kcalloc_node\) 59 + * (..., size, \(flags\|GFP_KERNEL\|\(GFP_KERNEL\|flags\)|__GFP_NOWARN\), ...); 60 + ... when != x = E1 61 + when != size = E1 62 + when any 63 + * if (x == NULL)@p { 64 + ... 65 + * x = \(vmalloc\|vzalloc\|vmalloc_node\|vzalloc_node\)(..., size, ...) 66 + ... 67 + } 68 + ) 69 + 70 + @kvfree depends on !patch@ 71 + expression E; 72 + position p : script:python() { relevant(p) }; 73 + @@ 74 + 75 + * if (is_vmalloc_addr(E))@p { 76 + ... 77 + * vfree(E) 78 + ... 79 + } else { 80 + ... when != krealloc(E, ...) 81 + when any 82 + * \(kfree\|kzfree\)(E) 83 + ... 84 + } 85 + 86 + @depends on patch@ 87 + expression E, E1, size, node; 88 + binary operator cmp = {<=, <, ==, >, >=}; 89 + identifier flags, x; 90 + type T; 91 + @@ 92 + 93 + ( 94 + - if (size cmp E1) 95 + - E = kmalloc(size, flags); 96 + - else 97 + - E = vmalloc(size); 98 + + E = kvmalloc(size, flags); 99 + | 100 + - if (size cmp E1) 101 + - E = kmalloc(size, \(GFP_KERNEL\|GFP_KERNEL|__GFP_NOWARN\)); 102 + - else 103 + - E = vmalloc(size); 104 + + E = kvmalloc(size, GFP_KERNEL); 105 + | 106 + - E = kmalloc(size, flags | __GFP_NOWARN); 107 + - if (E == NULL) 108 + - E = vmalloc(size); 109 + + E = kvmalloc(size, flags); 110 + | 111 + - E = kmalloc(size, \(GFP_KERNEL\|GFP_KERNEL|__GFP_NOWARN\)); 112 + - if (E == NULL) 113 + - E = vmalloc(size); 114 + + E = kvmalloc(size, GFP_KERNEL); 115 + | 116 + - T x = kmalloc(size, flags | __GFP_NOWARN); 117 + - if (x == NULL) 118 + - x = vmalloc(size); 119 + + T x = kvmalloc(size, flags); 120 + | 121 + - T x = kmalloc(size, \(GFP_KERNEL\|GFP_KERNEL|__GFP_NOWARN\)); 122 + - if (x == NULL) 123 + - x = vmalloc(size); 124 + + T x = kvmalloc(size, GFP_KERNEL); 125 + | 126 + - if (size cmp E1) 127 + - E = kzalloc(size, flags); 128 + - else 129 + - E = vzalloc(size); 130 + + E = kvzalloc(size, flags); 131 + | 132 + - if (size cmp E1) 133 + - E = kzalloc(size, \(GFP_KERNEL\|GFP_KERNEL|__GFP_NOWARN\)); 134 + - else 135 + - E = vzalloc(size); 136 + + E = kvzalloc(size, GFP_KERNEL); 137 + | 138 + - E = kzalloc(size, flags | __GFP_NOWARN); 139 + - if (E == NULL) 140 + - E = vzalloc(size); 141 + + E = kvzalloc(size, flags); 142 + | 143 + - E = kzalloc(size, \(GFP_KERNEL\|GFP_KERNEL|__GFP_NOWARN\)); 144 + - if (E == NULL) 145 + - E = vzalloc(size); 146 + + E = kvzalloc(size, GFP_KERNEL); 147 + | 148 + - T x = kzalloc(size, flags | __GFP_NOWARN); 149 + - if (x == NULL) 150 + - x = vzalloc(size); 151 + + T x = kvzalloc(size, flags); 152 + | 153 + - T x = kzalloc(size, \(GFP_KERNEL\|GFP_KERNEL|__GFP_NOWARN\)); 154 + - if (x == NULL) 155 + - x = vzalloc(size); 156 + + T x = kvzalloc(size, GFP_KERNEL); 157 + | 158 + - if (size cmp E1) 159 + - E = kmalloc_node(size, flags, node); 160 + - else 161 + - E = vmalloc_node(size, node); 162 + + E = kvmalloc_node(size, flags, node); 163 + | 164 + - if (size cmp E1) 165 + - E = kmalloc_node(size, \(GFP_KERNEL\|GFP_KERNEL|__GFP_NOWARN\), node); 166 + - else 167 + - E = vmalloc_node(size, node); 168 + + E = kvmalloc_node(size, GFP_KERNEL, node); 169 + | 170 + - E = kmalloc_node(size, flags | __GFP_NOWARN, node); 171 + - if (E == NULL) 172 + - E = vmalloc_node(size, node); 173 + + E = kvmalloc_node(size, flags, node); 174 + | 175 + - E = kmalloc_node(size, \(GFP_KERNEL\|GFP_KERNEL|__GFP_NOWARN\), node); 176 + - if (E == NULL) 177 + - E = vmalloc_node(size, node); 178 + + E = kvmalloc_node(size, GFP_KERNEL, node); 179 + | 180 + - T x = kmalloc_node(size, flags | __GFP_NOWARN, node); 181 + - if (x == NULL) 182 + - x = vmalloc_node(size, node); 183 + + T x = kvmalloc_node(size, flags, node); 184 + | 185 + - T x = kmalloc_node(size, \(GFP_KERNEL\|GFP_KERNEL|__GFP_NOWARN\), node); 186 + - if (x == NULL) 187 + - x = vmalloc_node(size, node); 188 + + T x = kvmalloc_node(size, GFP_KERNEL, node); 189 + | 190 + - if (size cmp E1) 191 + - E = kvzalloc_node(size, flags, node); 192 + - else 193 + - E = vzalloc_node(size, node); 194 + + E = kvzalloc_node(size, flags, node); 195 + | 196 + - if (size cmp E1) 197 + - E = kvzalloc_node(size, \(GFP_KERNEL\|GFP_KERNEL|__GFP_NOWARN\), node); 198 + - else 199 + - E = vzalloc_node(size, node); 200 + + E = kvzalloc_node(size, GFP_KERNEL, node); 201 + | 202 + - E = kvzalloc_node(size, flags | __GFP_NOWARN, node); 203 + - if (E == NULL) 204 + - E = vzalloc_node(size, node); 205 + + E = kvzalloc_node(size, flags, node); 206 + | 207 + - E = kvzalloc_node(size, \(GFP_KERNEL\|GFP_KERNEL|__GFP_NOWARN\), node); 208 + - if (E == NULL) 209 + - E = vzalloc_node(size, node); 210 + + E = kvzalloc_node(size, GFP_KERNEL, node); 211 + | 212 + - T x = kvzalloc_node(size, flags | __GFP_NOWARN, node); 213 + - if (x == NULL) 214 + - x = vzalloc_node(size, node); 215 + + T x = kvzalloc_node(size, flags, node); 216 + | 217 + - T x = kvzalloc_node(size, \(GFP_KERNEL\|GFP_KERNEL|__GFP_NOWARN\), node); 218 + - if (x == NULL) 219 + - x = vzalloc_node(size, node); 220 + + T x = kvzalloc_node(size, GFP_KERNEL, node); 221 + ) 222 + 223 + @depends on patch@ 224 + expression E; 225 + position p : script:python() { relevant(p) }; 226 + @@ 227 + 228 + - if (is_vmalloc_addr(E))@p 229 + - vfree(E); 230 + - else 231 + - kfree(E); 232 + + kvfree(E); 233 + 234 + @script: python depends on report@ 235 + p << kvmalloc.p; 236 + @@ 237 + 238 + coccilib.report.print_report(p[0], "WARNING opportunity for kvmalloc") 239 + 240 + @script: python depends on org@ 241 + p << kvmalloc.p; 242 + @@ 243 + 244 + coccilib.org.print_todo(p[0], "WARNING opportunity for kvmalloc") 245 + 246 + @script: python depends on report@ 247 + p << kvfree.p; 248 + @@ 249 + 250 + coccilib.report.print_report(p[0], "WARNING opportunity for kvfree") 251 + 252 + @script: python depends on org@ 253 + p << kvfree.p; 254 + @@ 255 + 256 + coccilib.org.print_todo(p[0], "WARNING opportunity for kvfree")
+17 -18
scripts/coccinelle/api/kzfree.cocci scripts/coccinelle/api/kfree_sensitive.cocci
··· 1 1 // SPDX-License-Identifier: GPL-2.0-only 2 2 /// 3 - /// Use kzfree, kvfree_sensitive rather than memset or 4 - /// memzero_explicit followed by kfree 3 + /// Use kfree_sensitive, kvfree_sensitive rather than memset or 4 + /// memzero_explicit followed by kfree. 5 5 /// 6 6 // Confidence: High 7 7 // Copyright: (C) 2020 Denis Efremov ISPRAS 8 8 // Options: --no-includes --include-headers 9 9 // 10 - // Keywords: kzfree, kvfree_sensitive 10 + // Keywords: kfree_sensitive, kvfree_sensitive 11 11 // 12 12 13 13 virtual context ··· 18 18 @initialize:python@ 19 19 @@ 20 20 # kmalloc_oob_in_memset uses memset to explicitly trigger out-of-bounds access 21 - filter = frozenset(['kmalloc_oob_in_memset', 'kzfree', 'kvfree_sensitive']) 21 + filter = frozenset(['kmalloc_oob_in_memset', 22 + 'kfree_sensitive', 'kvfree_sensitive']) 22 23 23 24 def relevant(p): 24 25 return not (filter & {el.current_element for el in p}) ··· 57 56 - memzero_explicit@m((T)E, size); 58 57 ... when != E 59 58 when strict 60 - // TODO: uncomment when kfree_sensitive will be merged. 61 - // Only this case is commented out because developers 62 - // may not like patches like this since kzfree uses memset 63 - // internally (not memzero_explicit). 64 - //( 65 - //- kfree(E)@p; 66 - //+ kfree_sensitive(E); 67 - //| 59 + ( 60 + - kfree(E)@p; 61 + + kfree_sensitive(E); 62 + | 68 63 - \(vfree\|kvfree\)(E)@p; 69 64 + kvfree_sensitive(E, size); 70 - //) 65 + ) 71 66 72 67 @rp_memset depends on patch@ 73 68 expression E, size; ··· 77 80 when strict 78 81 ( 79 82 - kfree(E)@p; 80 - + kzfree(E); 83 + + kfree_sensitive(E); 81 84 | 82 85 - \(vfree\|kvfree\)(E)@p; 83 86 + kvfree_sensitive(E, size); ··· 85 88 86 89 @script:python depends on report@ 87 90 p << r.p; 91 + m << r.m; 88 92 @@ 89 93 90 - coccilib.report.print_report(p[0], 91 - "WARNING: opportunity for kzfree/kvfree_sensitive") 94 + msg = "WARNING opportunity for kfree_sensitive/kvfree_sensitive (memset at line %s)" 95 + coccilib.report.print_report(p[0], msg % (m[0].line)) 92 96 93 97 @script:python depends on org@ 94 98 p << r.p; 99 + m << r.m; 95 100 @@ 96 101 97 - coccilib.org.print_todo(p[0], 98 - "WARNING: opportunity for kzfree/kvfree_sensitive") 102 + msg = "WARNING opportunity for kfree_sensitive/kvfree_sensitive (memset at line %s)" 103 + coccilib.org.print_todo(p[0], msg % (m[0].line))
+9 -2
scripts/coccinelle/free/ifnullfree.cocci
··· 21 21 ( 22 22 kfree(E); 23 23 | 24 + kvfree(E); 25 + | 24 26 kfree_sensitive(E); 27 + | 28 + kvfree_sensitive(E, ...); 29 + | 30 + vfree(E); 25 31 | 26 32 debugfs_remove(E); 27 33 | ··· 48 42 @@ 49 43 50 44 * if (E != NULL) 51 - * \(kfree@p\|kfree_sensitive@p\|debugfs_remove@p\|debugfs_remove_recursive@p\| 45 + * \(kfree@p\|kvfree@p\|kfree_sensitive@p\|kvfree_sensitive@p\|vfree@p\| 46 + * debugfs_remove@p\|debugfs_remove_recursive@p\| 52 47 * usb_free_urb@p\|kmem_cache_destroy@p\|mempool_destroy@p\| 53 - * dma_pool_destroy@p\)(E); 48 + * dma_pool_destroy@p\)(E, ...); 54 49 55 50 @script:python depends on org@ 56 51 p << r.p;
+358
scripts/coccinelle/iterators/for_each_child.cocci
··· 1 + // SPDX-License-Identifier: GPL-2.0-only 2 + // Adds missing of_node_put() before return/break/goto statement within a for_each iterator for child nodes. 3 + //# False positives can be due to function calls within the for_each 4 + //# loop that may encapsulate an of_node_put. 5 + /// 6 + // Confidence: High 7 + // Copyright: (C) 2020 Sumera Priyadarsini 8 + // URL: http://coccinelle.lip6.fr 9 + // Options: --no-includes --include-headers 10 + 11 + virtual patch 12 + virtual context 13 + virtual org 14 + virtual report 15 + 16 + @r@ 17 + local idexpression n; 18 + expression e1,e2; 19 + iterator name for_each_node_by_name, for_each_node_by_type, 20 + for_each_compatible_node, for_each_matching_node, 21 + for_each_matching_node_and_match, for_each_child_of_node, 22 + for_each_available_child_of_node, for_each_node_with_property; 23 + iterator i; 24 + statement S; 25 + expression list [n1] es; 26 + @@ 27 + 28 + ( 29 + ( 30 + for_each_node_by_name(n,e1) S 31 + | 32 + for_each_node_by_type(n,e1) S 33 + | 34 + for_each_compatible_node(n,e1,e2) S 35 + | 36 + for_each_matching_node(n,e1) S 37 + | 38 + for_each_matching_node_and_match(n,e1,e2) S 39 + | 40 + for_each_child_of_node(e1,n) S 41 + | 42 + for_each_available_child_of_node(e1,n) S 43 + | 44 + for_each_node_with_property(n,e1) S 45 + ) 46 + & 47 + i(es,n,...) S 48 + ) 49 + 50 + @ruleone depends on patch && !context && !org && !report@ 51 + 52 + local idexpression r.n; 53 + iterator r.i,i1; 54 + expression e; 55 + expression list [r.n1] es; 56 + statement S; 57 + @@ 58 + 59 + i(es,n,...) { 60 + ... 61 + ( 62 + of_node_put(n); 63 + | 64 + e = n 65 + | 66 + return n; 67 + | 68 + i1(...,n,...) S 69 + | 70 + - return of_node_get(n); 71 + + return n; 72 + | 73 + + of_node_put(n); 74 + ? return ...; 75 + ) 76 + ... when any 77 + } 78 + 79 + @ruletwo depends on patch && !context && !org && !report@ 80 + 81 + local idexpression r.n; 82 + iterator r.i,i1,i2; 83 + expression e,e1; 84 + expression list [r.n1] es; 85 + statement S,S2; 86 + @@ 87 + 88 + i(es,n,...) { 89 + ... 90 + ( 91 + of_node_put(n); 92 + | 93 + e = n 94 + | 95 + i1(...,n,...) S 96 + | 97 + + of_node_put(n); 98 + ? break; 99 + ) 100 + ... when any 101 + } 102 + ... when != n 103 + when strict 104 + when forall 105 + ( 106 + n = e1; 107 + | 108 + ?i2(...,n,...) S2 109 + ) 110 + 111 + @rulethree depends on patch && !context && !org && !report exists@ 112 + 113 + local idexpression r.n; 114 + iterator r.i,i1,i2; 115 + expression e,e1; 116 + identifier l; 117 + expression list [r.n1] es; 118 + statement S,S2; 119 + @@ 120 + 121 + i(es,n,...) { 122 + ... 123 + ( 124 + of_node_put(n); 125 + | 126 + e = n 127 + | 128 + i1(...,n,...) S 129 + | 130 + + of_node_put(n); 131 + ? goto l; 132 + ) 133 + ... when any 134 + } 135 + ... when exists 136 + l: ... when != n 137 + when strict 138 + when forall 139 + ( 140 + n = e1; 141 + | 142 + ?i2(...,n,...) S2 143 + ) 144 + 145 + // ---------------------------------------------------------------------------- 146 + 147 + @ruleone_context depends on !patch && (context || org || report) exists@ 148 + statement S; 149 + expression e; 150 + expression list[r.n1] es; 151 + iterator r.i, i1; 152 + local idexpression r.n; 153 + position j0, j1; 154 + @@ 155 + 156 + i@j0(es,n,...) { 157 + ... 158 + ( 159 + of_node_put(n); 160 + | 161 + e = n 162 + | 163 + return n; 164 + | 165 + i1(...,n,...) S 166 + | 167 + return @j1 ...; 168 + ) 169 + ... when any 170 + } 171 + 172 + @ruleone_disj depends on !patch && (context || org || report)@ 173 + expression list[r.n1] es; 174 + iterator r.i; 175 + local idexpression r.n; 176 + position ruleone_context.j0, ruleone_context.j1; 177 + @@ 178 + 179 + * i@j0(es,n,...) { 180 + ... 181 + *return @j1...; 182 + ... when any 183 + } 184 + 185 + @ruletwo_context depends on !patch && (context || org || report) exists@ 186 + statement S, S2; 187 + expression e, e1; 188 + expression list[r.n1] es; 189 + iterator r.i, i1, i2; 190 + local idexpression r.n; 191 + position j0, j2; 192 + @@ 193 + 194 + i@j0(es,n,...) { 195 + ... 196 + ( 197 + of_node_put(n); 198 + | 199 + e = n 200 + | 201 + i1(...,n,...) S 202 + | 203 + break@j2; 204 + ) 205 + ... when any 206 + } 207 + ... when != n 208 + when strict 209 + when forall 210 + ( 211 + n = e1; 212 + | 213 + ?i2(...,n,...) S2 214 + ) 215 + 216 + @ruletwo_disj depends on !patch && (context || org || report)@ 217 + statement S2; 218 + expression e1; 219 + expression list[r.n1] es; 220 + iterator r.i, i2; 221 + local idexpression r.n; 222 + position ruletwo_context.j0, ruletwo_context.j2; 223 + @@ 224 + 225 + * i@j0(es,n,...) { 226 + ... 227 + *break @j2; 228 + ... when any 229 + } 230 + ... when != n 231 + when strict 232 + when forall 233 + ( 234 + n = e1; 235 + | 236 + ?i2(...,n,...) S2 237 + ) 238 + 239 + @rulethree_context depends on !patch && (context || org || report) exists@ 240 + identifier l; 241 + statement S,S2; 242 + expression e, e1; 243 + expression list[r.n1] es; 244 + iterator r.i, i1, i2; 245 + local idexpression r.n; 246 + position j0, j3; 247 + @@ 248 + 249 + i@j0(es,n,...) { 250 + ... 251 + ( 252 + of_node_put(n); 253 + | 254 + e = n 255 + | 256 + i1(...,n,...) S 257 + | 258 + goto l@j3; 259 + ) 260 + ... when any 261 + } 262 + ... when exists 263 + l: 264 + ... when != n 265 + when strict 266 + when forall 267 + ( 268 + n = e1; 269 + | 270 + ?i2(...,n,...) S2 271 + ) 272 + 273 + @rulethree_disj depends on !patch && (context || org || report) exists@ 274 + identifier l; 275 + statement S2; 276 + expression e1; 277 + expression list[r.n1] es; 278 + iterator r.i, i2; 279 + local idexpression r.n; 280 + position rulethree_context.j0, rulethree_context.j3; 281 + @@ 282 + 283 + * i@j0(es,n,...) { 284 + ... 285 + *goto l@j3; 286 + ... when any 287 + } 288 + ... when exists 289 + l: 290 + ... when != n 291 + when strict 292 + when forall 293 + ( 294 + n = e1; 295 + | 296 + ?i2(...,n,...) S2 297 + ) 298 + 299 + // ---------------------------------------------------------------------------- 300 + 301 + @script:python ruleone_org depends on org@ 302 + i << r.i; 303 + j0 << ruleone_context.j0; 304 + j1 << ruleone_context. j1; 305 + @@ 306 + 307 + msg = "WARNING: Function \"%s\" should have of_node_put() before return " % (i) 308 + coccilib.org.print_safe_todo(j0[0], msg) 309 + coccilib.org.print_link(j1[0], "") 310 + 311 + @script:python ruletwo_org depends on org@ 312 + i << r.i; 313 + j0 << ruletwo_context.j0; 314 + j2 << ruletwo_context.j2; 315 + @@ 316 + 317 + msg = "WARNING: Function \"%s\" should have of_node_put() before break " % (i) 318 + coccilib.org.print_safe_todo(j0[0], msg) 319 + coccilib.org.print_link(j2[0], "") 320 + 321 + @script:python rulethree_org depends on org@ 322 + i << r.i; 323 + j0 << rulethree_context.j0; 324 + j3 << rulethree_context.j3; 325 + @@ 326 + 327 + msg = "WARNING: Function \"%s\" should have of_node_put() before goto " % (i) 328 + coccilib.org.print_safe_todo(j0[0], msg) 329 + coccilib.org.print_link(j3[0], "") 330 + 331 + // ---------------------------------------------------------------------------- 332 + 333 + @script:python ruleone_report depends on report@ 334 + i << r.i; 335 + j0 << ruleone_context.j0; 336 + j1 << ruleone_context.j1; 337 + @@ 338 + 339 + msg = "WARNING: Function \"%s\" should have of_node_put() before return around line %s." % (i, j1[0].line) 340 + coccilib.report.print_report(j0[0], msg) 341 + 342 + @script:python ruletwo_report depends on report@ 343 + i << r.i; 344 + j0 << ruletwo_context.j0; 345 + j2 << ruletwo_context.j2; 346 + @@ 347 + 348 + msg = "WARNING: Function \"%s\" should have of_node_put() before break around line %s." % (i,j2[0].line) 349 + coccilib.report.print_report(j0[0], msg) 350 + 351 + @script:python rulethree_report depends on report@ 352 + i << r.i; 353 + j0 << rulethree_context.j0; 354 + j3 << rulethree_context.j3; 355 + @@ 356 + 357 + msg = "WARNING: Function \"%s\" should have of_node_put() before goto around lines %s." % (i,j3[0].line) 358 + coccilib.report.print_report(j0[0], msg)
+39
scripts/coccinelle/misc/excluded_middle.cocci
··· 1 + // SPDX-License-Identifier: GPL-2.0-only 2 + /// 3 + /// Condition !A || A && B is equivalent to !A || B. 4 + /// 5 + // Confidence: High 6 + // Copyright: (C) 2020 Denis Efremov ISPRAS 7 + // Options: --no-includes --include-headers 8 + 9 + virtual patch 10 + virtual context 11 + virtual org 12 + virtual report 13 + 14 + @r depends on !patch@ 15 + expression A, B; 16 + position p; 17 + @@ 18 + 19 + * !A || (A &&@p B) 20 + 21 + @depends on patch@ 22 + expression A, B; 23 + @@ 24 + 25 + !A || 26 + - (A && B) 27 + + B 28 + 29 + @script:python depends on report@ 30 + p << r.p; 31 + @@ 32 + 33 + coccilib.report.print_report(p[0], "WARNING !A || A && B is equivalent to !A || B") 34 + 35 + @script:python depends on org@ 36 + p << r.p; 37 + @@ 38 + 39 + coccilib.org.print_todo(p[0], "WARNING !A || A && B is equivalent to !A || B")
+88
scripts/coccinelle/misc/flexible_array.cocci
··· 1 + // SPDX-License-Identifier: GPL-2.0-only 2 + /// 3 + /// Zero-length and one-element arrays are deprecated, see 4 + /// Documentation/process/deprecated.rst 5 + /// Flexible-array members should be used instead. 6 + /// 7 + // 8 + // Confidence: High 9 + // Copyright: (C) 2020 Denis Efremov ISPRAS. 10 + // Comments: 11 + // Options: --no-includes --include-headers 12 + 13 + virtual context 14 + virtual report 15 + virtual org 16 + virtual patch 17 + 18 + @initialize:python@ 19 + @@ 20 + def relevant(positions): 21 + for p in positions: 22 + if "uapi" in p.file: 23 + return False 24 + return True 25 + 26 + @r depends on !patch@ 27 + identifier name, array; 28 + type T; 29 + position p : script:python() { relevant(p) }; 30 + @@ 31 + 32 + ( 33 + struct name { 34 + ... 35 + * T array@p[\(0\|1\)]; 36 + }; 37 + | 38 + struct { 39 + ... 40 + * T array@p[\(0\|1\)]; 41 + }; 42 + | 43 + union name { 44 + ... 45 + * T array@p[\(0\|1\)]; 46 + }; 47 + | 48 + union { 49 + ... 50 + * T array@p[\(0\|1\)]; 51 + }; 52 + ) 53 + 54 + @depends on patch@ 55 + identifier name, array; 56 + type T; 57 + position p : script:python() { relevant(p) }; 58 + @@ 59 + 60 + ( 61 + struct name { 62 + ... 63 + T array@p[ 64 + - 0 65 + ]; 66 + }; 67 + | 68 + struct { 69 + ... 70 + T array@p[ 71 + - 0 72 + ]; 73 + }; 74 + ) 75 + 76 + @script: python depends on report@ 77 + p << r.p; 78 + @@ 79 + 80 + msg = "WARNING use flexible-array member instead (https://www.kernel.org/doc/html/latest/process/deprecated.html#zero-length-and-one-element-arrays)" 81 + coccilib.report.print_report(p[0], msg) 82 + 83 + @script: python depends on org@ 84 + p << r.p; 85 + @@ 86 + 87 + msg = "WARNING use flexible-array member instead (https://www.kernel.org/doc/html/latest/process/deprecated.html#zero-length-and-one-element-arrays)" 88 + coccilib.org.print_todo(p[0], msg)
+51
scripts/coccinelle/misc/uninitialized_var.cocci
··· 1 + // SPDX-License-Identifier: GPL-2.0-only 2 + /// 3 + /// Please, don't reintroduce uninitialized_var(). 4 + /// From Documentation/process/deprecated.rst: 5 + /// For any compiler warnings about uninitialized variables, just add 6 + /// an initializer. Using warning-silencing tricks is dangerous as it 7 + /// papers over real bugs (or can in the future), and suppresses unrelated 8 + /// compiler warnings (e.g. "unused variable"). If the compiler thinks it 9 + /// is uninitialized, either simply initialize the variable or make compiler 10 + /// changes. Keep in mind that in most cases, if an initialization is 11 + /// obviously redundant, the compiler's dead-store elimination pass will make 12 + /// sure there are no needless variable writes. 13 + /// 14 + // Confidence: High 15 + // Copyright: (C) 2020 Denis Efremov ISPRAS 16 + // Options: --no-includes --include-headers 17 + // 18 + 19 + virtual context 20 + virtual report 21 + virtual org 22 + 23 + @r@ 24 + identifier var; 25 + type T; 26 + position p; 27 + @@ 28 + 29 + ( 30 + * T var =@p var; 31 + | 32 + * T var =@p *(&(var)); 33 + | 34 + * var =@p var 35 + | 36 + * var =@p *(&(var)) 37 + ) 38 + 39 + @script:python depends on report@ 40 + p << r.p; 41 + @@ 42 + 43 + coccilib.report.print_report(p[0], 44 + "WARNING this kind of initialization is deprecated (https://www.kernel.org/doc/html/latest/process/deprecated.html#uninitialized-var)") 45 + 46 + @script:python depends on org@ 47 + p << r.p; 48 + @@ 49 + 50 + coccilib.org.print_todo(p[0], 51 + "WARNING this kind of initialization is deprecated (https://www.kernel.org/doc/html/latest/process/deprecated.html#uninitialized-var)")