|
| 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) |
0 commit comments