162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only 262306a36Sopenharmony_ci/// Find uses of standard freeing functons on values allocated using devm_ 362306a36Sopenharmony_ci/// functions. Values allocated using the devm_functions are freed when 462306a36Sopenharmony_ci/// the device is detached, and thus the use of the standard freeing 562306a36Sopenharmony_ci/// function would cause a double free. 662306a36Sopenharmony_ci/// See Documentation/driver-api/driver-model/devres.rst for more information. 762306a36Sopenharmony_ci/// 862306a36Sopenharmony_ci/// A difficulty of detecting this problem is that the standard freeing 962306a36Sopenharmony_ci/// function might be called from a different function than the one 1062306a36Sopenharmony_ci/// containing the allocation function. It is thus necessary to make the 1162306a36Sopenharmony_ci/// connection between the allocation function and the freeing function. 1262306a36Sopenharmony_ci/// Here this is done using the specific argument text, which is prone to 1362306a36Sopenharmony_ci/// false positives. There is no rule for the request_region and 1462306a36Sopenharmony_ci/// request_mem_region variants because this heuristic seems to be a bit 1562306a36Sopenharmony_ci/// less reliable in these cases. 1662306a36Sopenharmony_ci/// 1762306a36Sopenharmony_ci// Confidence: Moderate 1862306a36Sopenharmony_ci// Copyright: (C) 2011 Julia Lawall, INRIA/LIP6. 1962306a36Sopenharmony_ci// Copyright: (C) 2011 Gilles Muller, INRIA/LiP6. 2062306a36Sopenharmony_ci// URL: https://coccinelle.gitlabpages.inria.fr/website 2162306a36Sopenharmony_ci// Comments: 2262306a36Sopenharmony_ci// Options: --no-includes --include-headers 2362306a36Sopenharmony_ci 2462306a36Sopenharmony_civirtual org 2562306a36Sopenharmony_civirtual report 2662306a36Sopenharmony_civirtual context 2762306a36Sopenharmony_ci 2862306a36Sopenharmony_ci@r depends on context || org || report@ 2962306a36Sopenharmony_ciexpression x; 3062306a36Sopenharmony_ci@@ 3162306a36Sopenharmony_ci 3262306a36Sopenharmony_ci( 3362306a36Sopenharmony_ci x = devm_kmalloc(...) 3462306a36Sopenharmony_ci| 3562306a36Sopenharmony_ci x = devm_kvasprintf(...) 3662306a36Sopenharmony_ci| 3762306a36Sopenharmony_ci x = devm_kasprintf(...) 3862306a36Sopenharmony_ci| 3962306a36Sopenharmony_ci x = devm_kzalloc(...) 4062306a36Sopenharmony_ci| 4162306a36Sopenharmony_ci x = devm_kmalloc_array(...) 4262306a36Sopenharmony_ci| 4362306a36Sopenharmony_ci x = devm_kcalloc(...) 4462306a36Sopenharmony_ci| 4562306a36Sopenharmony_ci x = devm_kstrdup(...) 4662306a36Sopenharmony_ci| 4762306a36Sopenharmony_ci x = devm_kmemdup(...) 4862306a36Sopenharmony_ci| 4962306a36Sopenharmony_ci x = devm_get_free_pages(...) 5062306a36Sopenharmony_ci| 5162306a36Sopenharmony_ci x = devm_request_irq(...) 5262306a36Sopenharmony_ci| 5362306a36Sopenharmony_ci x = devm_ioremap(...) 5462306a36Sopenharmony_ci| 5562306a36Sopenharmony_ci x = devm_ioport_map(...) 5662306a36Sopenharmony_ci) 5762306a36Sopenharmony_ci 5862306a36Sopenharmony_ci@safe depends on context || org || report exists@ 5962306a36Sopenharmony_ciexpression x; 6062306a36Sopenharmony_ciposition p; 6162306a36Sopenharmony_ci@@ 6262306a36Sopenharmony_ci 6362306a36Sopenharmony_ci( 6462306a36Sopenharmony_ci x = kmalloc(...) 6562306a36Sopenharmony_ci| 6662306a36Sopenharmony_ci x = kvasprintf(...) 6762306a36Sopenharmony_ci| 6862306a36Sopenharmony_ci x = kasprintf(...) 6962306a36Sopenharmony_ci| 7062306a36Sopenharmony_ci x = kzalloc(...) 7162306a36Sopenharmony_ci| 7262306a36Sopenharmony_ci x = kmalloc_array(...) 7362306a36Sopenharmony_ci| 7462306a36Sopenharmony_ci x = kcalloc(...) 7562306a36Sopenharmony_ci| 7662306a36Sopenharmony_ci x = kstrdup(...) 7762306a36Sopenharmony_ci| 7862306a36Sopenharmony_ci x = kmemdup(...) 7962306a36Sopenharmony_ci| 8062306a36Sopenharmony_ci x = get_free_pages(...) 8162306a36Sopenharmony_ci| 8262306a36Sopenharmony_ci x = request_irq(...) 8362306a36Sopenharmony_ci| 8462306a36Sopenharmony_ci x = ioremap(...) 8562306a36Sopenharmony_ci| 8662306a36Sopenharmony_ci x = ioport_map(...) 8762306a36Sopenharmony_ci) 8862306a36Sopenharmony_ci... 8962306a36Sopenharmony_ci( 9062306a36Sopenharmony_ci kfree@p(x) 9162306a36Sopenharmony_ci| 9262306a36Sopenharmony_ci kfree_sensitive@p(x) 9362306a36Sopenharmony_ci| 9462306a36Sopenharmony_ci krealloc@p(x, ...) 9562306a36Sopenharmony_ci| 9662306a36Sopenharmony_ci free_pages@p(x, ...) 9762306a36Sopenharmony_ci| 9862306a36Sopenharmony_ci free_page@p(x) 9962306a36Sopenharmony_ci| 10062306a36Sopenharmony_ci free_irq@p(x) 10162306a36Sopenharmony_ci| 10262306a36Sopenharmony_ci iounmap@p(x) 10362306a36Sopenharmony_ci| 10462306a36Sopenharmony_ci ioport_unmap@p(x) 10562306a36Sopenharmony_ci) 10662306a36Sopenharmony_ci 10762306a36Sopenharmony_ci@pb@ 10862306a36Sopenharmony_ciexpression r.x; 10962306a36Sopenharmony_ciposition p != safe.p; 11062306a36Sopenharmony_ci@@ 11162306a36Sopenharmony_ci 11262306a36Sopenharmony_ci( 11362306a36Sopenharmony_ci* kfree@p(x) 11462306a36Sopenharmony_ci| 11562306a36Sopenharmony_ci* kfree_sensitive@p(x) 11662306a36Sopenharmony_ci| 11762306a36Sopenharmony_ci* krealloc@p(x, ...) 11862306a36Sopenharmony_ci| 11962306a36Sopenharmony_ci* free_pages@p(x, ...) 12062306a36Sopenharmony_ci| 12162306a36Sopenharmony_ci* free_page@p(x) 12262306a36Sopenharmony_ci| 12362306a36Sopenharmony_ci* free_irq@p(x) 12462306a36Sopenharmony_ci| 12562306a36Sopenharmony_ci* iounmap@p(x) 12662306a36Sopenharmony_ci| 12762306a36Sopenharmony_ci* ioport_unmap@p(x) 12862306a36Sopenharmony_ci) 12962306a36Sopenharmony_ci 13062306a36Sopenharmony_ci@script:python depends on org@ 13162306a36Sopenharmony_cip << pb.p; 13262306a36Sopenharmony_ci@@ 13362306a36Sopenharmony_ci 13462306a36Sopenharmony_cimsg="WARNING: invalid free of devm_ allocated data" 13562306a36Sopenharmony_cicoccilib.org.print_todo(p[0], msg) 13662306a36Sopenharmony_ci 13762306a36Sopenharmony_ci@script:python depends on report@ 13862306a36Sopenharmony_cip << pb.p; 13962306a36Sopenharmony_ci@@ 14062306a36Sopenharmony_ci 14162306a36Sopenharmony_cimsg="WARNING: invalid free of devm_ allocated data" 14262306a36Sopenharmony_cicoccilib.report.print_report(p[0], msg) 14362306a36Sopenharmony_ci 144