| // SPDX-License-Identifier: GPL-2.0-only | |
| /// Find uses of standard freeing functons on values allocated using devm_ | |
| /// functions. Values allocated using the devm_functions are freed when | |
| /// the device is detached, and thus the use of the standard freeing | |
| /// function would cause a double free. | |
| /// See Documentation/driver-api/driver-model/devres.rst for more information. | |
| /// | |
| /// A difficulty of detecting this problem is that the standard freeing | |
| /// function might be called from a different function than the one | |
| /// containing the allocation function. It is thus necessary to make the | |
| /// connection between the allocation function and the freeing function. | |
| /// Here this is done using the specific argument text, which is prone to | |
| /// false positives. There is no rule for the request_region and | |
| /// request_mem_region variants because this heuristic seems to be a bit | |
| /// less reliable in these cases. | |
| /// | |
| // Confidence: Moderate | |
| // Copyright: (C) 2011 Julia Lawall, INRIA/LIP6. | |
| // Copyright: (C) 2011 Gilles Muller, INRIA/LiP6. | |
| // URL: https://coccinelle.gitlabpages.inria.fr/website | |
| // Comments: | |
| // Options: --no-includes --include-headers | |
| virtual org | |
| virtual report | |
| virtual context | |
| @r depends on context || org || report@ | |
| expression x; | |
| @@ | |
| ( | |
| x = devm_kmalloc(...) | |
| | | |
| x = devm_kvasprintf(...) | |
| | | |
| x = devm_kasprintf(...) | |
| | | |
| x = devm_kzalloc(...) | |
| | | |
| x = devm_kmalloc_array(...) | |
| | | |
| x = devm_kcalloc(...) | |
| | | |
| x = devm_kstrdup(...) | |
| | | |
| x = devm_kmemdup(...) | |
| | | |
| x = devm_get_free_pages(...) | |
| | | |
| x = devm_request_irq(...) | |
| | | |
| x = devm_ioremap(...) | |
| | | |
| x = devm_ioport_map(...) | |
| ) | |
| @safe depends on context || org || report exists@ | |
| expression x; | |
| position p; | |
| @@ | |
| ( | |
| x = kmalloc(...) | |
| | | |
| x = kvasprintf(...) | |
| | | |
| x = kasprintf(...) | |
| | | |
| x = kzalloc(...) | |
| | | |
| x = kmalloc_array(...) | |
| | | |
| x = kcalloc(...) | |
| | | |
| x = kstrdup(...) | |
| | | |
| x = kmemdup(...) | |
| | | |
| x = get_free_pages(...) | |
| | | |
| x = request_irq(...) | |
| | | |
| x = ioremap(...) | |
| | | |
| x = ioport_map(...) | |
| ) | |
| ... | |
| ( | |
| kfree@p(x) | |
| | | |
| kfree_sensitive@p(x) | |
| | | |
| krealloc@p(x, ...) | |
| | | |
| free_pages@p(x, ...) | |
| | | |
| free_page@p(x) | |
| | | |
| free_irq@p(x) | |
| | | |
| iounmap@p(x) | |
| | | |
| ioport_unmap@p(x) | |
| ) | |
| @pb@ | |
| expression r.x; | |
| position p != safe.p; | |
| @@ | |
| ( | |
| * kfree@p(x) | |
| | | |
| * kfree_sensitive@p(x) | |
| | | |
| * krealloc@p(x, ...) | |
| | | |
| * free_pages@p(x, ...) | |
| | | |
| * free_page@p(x) | |
| | | |
| * free_irq@p(x) | |
| | | |
| * iounmap@p(x) | |
| | | |
| * ioport_unmap@p(x) | |
| ) | |
| @script:python depends on org@ | |
| p << pb.p; | |
| @@ | |
| msg="WARNING: invalid free of devm_ allocated data" | |
| coccilib.org.print_todo(p[0], msg) | |
| @script:python depends on report@ | |
| p << pb.p; | |
| @@ | |
| msg="WARNING: invalid free of devm_ allocated data" | |
| coccilib.report.print_report(p[0], msg) | |