diff options
Diffstat (limited to 'scripts/coccinelle/free')
-rw-r--r-- | scripts/coccinelle/free/clk_put.cocci | 68 | ||||
-rw-r--r-- | scripts/coccinelle/free/devm_free.cocci | 143 | ||||
-rw-r--r-- | scripts/coccinelle/free/ifnullfree.cocci | 67 | ||||
-rw-r--r-- | scripts/coccinelle/free/iounmap.cocci | 68 | ||||
-rw-r--r-- | scripts/coccinelle/free/kfree.cocci | 134 | ||||
-rw-r--r-- | scripts/coccinelle/free/kfreeaddr.cocci | 37 | ||||
-rw-r--r-- | scripts/coccinelle/free/pci_free_consistent.cocci | 53 | ||||
-rw-r--r-- | scripts/coccinelle/free/put_device.cocci | 56 |
8 files changed, 626 insertions, 0 deletions
diff --git a/scripts/coccinelle/free/clk_put.cocci b/scripts/coccinelle/free/clk_put.cocci new file mode 100644 index 000000000..7237b4949 --- /dev/null +++ b/scripts/coccinelle/free/clk_put.cocci | |||
@@ -0,0 +1,68 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0-only | ||
2 | /// Find missing clk_puts. | ||
3 | /// | ||
4 | //# This only signals a missing clk_put when there is a clk_put later | ||
5 | //# in the same function. | ||
6 | //# False positives can be due to loops. | ||
7 | // | ||
8 | // Confidence: Moderate | ||
9 | // Copyright: (C) 2012 Julia Lawall, INRIA/LIP6. | ||
10 | // Copyright: (C) 2012 Gilles Muller, INRIA/LiP6. | ||
11 | // URL: http://coccinelle.lip6.fr/ | ||
12 | // Comments: | ||
13 | // Options: | ||
14 | |||
15 | virtual context | ||
16 | virtual org | ||
17 | virtual report | ||
18 | |||
19 | @clk@ | ||
20 | expression e; | ||
21 | statement S,S1; | ||
22 | int ret; | ||
23 | position p1,p2,p3; | ||
24 | @@ | ||
25 | |||
26 | e = clk_get@p1(...) | ||
27 | ... when != clk_put(e) | ||
28 | if (<+...e...+>) S | ||
29 | ... when any | ||
30 | when != clk_put(e) | ||
31 | when != if (...) { ... clk_put(e); ... } | ||
32 | ( | ||
33 | if (ret == 0) S1 | ||
34 | | | ||
35 | if (...) | ||
36 | { ... | ||
37 | return 0; } | ||
38 | | | ||
39 | if (...) | ||
40 | { ... | ||
41 | return <+...e...+>; } | ||
42 | | | ||
43 | *if@p2 (...) | ||
44 | { ... when != clk_put(e) | ||
45 | when forall | ||
46 | return@p3 ...; } | ||
47 | ) | ||
48 | ... when any | ||
49 | clk_put(e); | ||
50 | |||
51 | @script:python depends on org@ | ||
52 | p1 << clk.p1; | ||
53 | p2 << clk.p2; | ||
54 | p3 << clk.p3; | ||
55 | @@ | ||
56 | |||
57 | cocci.print_main("clk_get",p1) | ||
58 | cocci.print_secs("if",p2) | ||
59 | cocci.print_secs("needed clk_put",p3) | ||
60 | |||
61 | @script:python depends on report@ | ||
62 | p1 << clk.p1; | ||
63 | p2 << clk.p2; | ||
64 | p3 << clk.p3; | ||
65 | @@ | ||
66 | |||
67 | msg = "ERROR: missing clk_put; clk_get on line %s and execution via conditional on line %s" % (p1[0].line,p2[0].line) | ||
68 | coccilib.report.print_report(p3[0],msg) | ||
diff --git a/scripts/coccinelle/free/devm_free.cocci b/scripts/coccinelle/free/devm_free.cocci new file mode 100644 index 000000000..da80050b9 --- /dev/null +++ b/scripts/coccinelle/free/devm_free.cocci | |||
@@ -0,0 +1,143 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0-only | ||
2 | /// Find uses of standard freeing functons on values allocated using devm_ | ||
3 | /// functions. Values allocated using the devm_functions are freed when | ||
4 | /// the device is detached, and thus the use of the standard freeing | ||
5 | /// function would cause a double free. | ||
6 | /// See Documentation/driver-api/driver-model/devres.rst for more information. | ||
7 | /// | ||
8 | /// A difficulty of detecting this problem is that the standard freeing | ||
9 | /// function might be called from a different function than the one | ||
10 | /// containing the allocation function. It is thus necessary to make the | ||
11 | /// connection between the allocation function and the freeing function. | ||
12 | /// Here this is done using the specific argument text, which is prone to | ||
13 | /// false positives. There is no rule for the request_region and | ||
14 | /// request_mem_region variants because this heuristic seems to be a bit | ||
15 | /// less reliable in these cases. | ||
16 | /// | ||
17 | // Confidence: Moderate | ||
18 | // Copyright: (C) 2011 Julia Lawall, INRIA/LIP6. | ||
19 | // Copyright: (C) 2011 Gilles Muller, INRIA/LiP6. | ||
20 | // URL: http://coccinelle.lip6.fr/ | ||
21 | // Comments: | ||
22 | // Options: --no-includes --include-headers | ||
23 | |||
24 | virtual org | ||
25 | virtual report | ||
26 | virtual context | ||
27 | |||
28 | @r depends on context || org || report@ | ||
29 | expression x; | ||
30 | @@ | ||
31 | |||
32 | ( | ||
33 | x = devm_kmalloc(...) | ||
34 | | | ||
35 | x = devm_kvasprintf(...) | ||
36 | | | ||
37 | x = devm_kasprintf(...) | ||
38 | | | ||
39 | x = devm_kzalloc(...) | ||
40 | | | ||
41 | x = devm_kmalloc_array(...) | ||
42 | | | ||
43 | x = devm_kcalloc(...) | ||
44 | | | ||
45 | x = devm_kstrdup(...) | ||
46 | | | ||
47 | x = devm_kmemdup(...) | ||
48 | | | ||
49 | x = devm_get_free_pages(...) | ||
50 | | | ||
51 | x = devm_request_irq(...) | ||
52 | | | ||
53 | x = devm_ioremap(...) | ||
54 | | | ||
55 | x = devm_ioport_map(...) | ||
56 | ) | ||
57 | |||
58 | @safe depends on context || org || report exists@ | ||
59 | expression x; | ||
60 | position p; | ||
61 | @@ | ||
62 | |||
63 | ( | ||
64 | x = kmalloc(...) | ||
65 | | | ||
66 | x = kvasprintf(...) | ||
67 | | | ||
68 | x = kasprintf(...) | ||
69 | | | ||
70 | x = kzalloc(...) | ||
71 | | | ||
72 | x = kmalloc_array(...) | ||
73 | | | ||
74 | x = kcalloc(...) | ||
75 | | | ||
76 | x = kstrdup(...) | ||
77 | | | ||
78 | x = kmemdup(...) | ||
79 | | | ||
80 | x = get_free_pages(...) | ||
81 | | | ||
82 | x = request_irq(...) | ||
83 | | | ||
84 | x = ioremap(...) | ||
85 | | | ||
86 | x = ioport_map(...) | ||
87 | ) | ||
88 | ... | ||
89 | ( | ||
90 | kfree@p(x) | ||
91 | | | ||
92 | kfree_sensitive@p(x) | ||
93 | | | ||
94 | krealloc@p(x, ...) | ||
95 | | | ||
96 | free_pages@p(x, ...) | ||
97 | | | ||
98 | free_page@p(x) | ||
99 | | | ||
100 | free_irq@p(x) | ||
101 | | | ||
102 | iounmap@p(x) | ||
103 | | | ||
104 | ioport_unmap@p(x) | ||
105 | ) | ||
106 | |||
107 | @pb@ | ||
108 | expression r.x; | ||
109 | position p != safe.p; | ||
110 | @@ | ||
111 | |||
112 | ( | ||
113 | * kfree@p(x) | ||
114 | | | ||
115 | * kfree_sensitive@p(x) | ||
116 | | | ||
117 | * krealloc@p(x, ...) | ||
118 | | | ||
119 | * free_pages@p(x, ...) | ||
120 | | | ||
121 | * free_page@p(x) | ||
122 | | | ||
123 | * free_irq@p(x) | ||
124 | | | ||
125 | * iounmap@p(x) | ||
126 | | | ||
127 | * ioport_unmap@p(x) | ||
128 | ) | ||
129 | |||
130 | @script:python depends on org@ | ||
131 | p << pb.p; | ||
132 | @@ | ||
133 | |||
134 | msg="WARNING: invalid free of devm_ allocated data" | ||
135 | coccilib.org.print_todo(p[0], msg) | ||
136 | |||
137 | @script:python depends on report@ | ||
138 | p << pb.p; | ||
139 | @@ | ||
140 | |||
141 | msg="WARNING: invalid free of devm_ allocated data" | ||
142 | coccilib.report.print_report(p[0], msg) | ||
143 | |||
diff --git a/scripts/coccinelle/free/ifnullfree.cocci b/scripts/coccinelle/free/ifnullfree.cocci new file mode 100644 index 000000000..285b92d5c --- /dev/null +++ b/scripts/coccinelle/free/ifnullfree.cocci | |||
@@ -0,0 +1,67 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0-only | ||
2 | /// NULL check before some freeing functions is not needed. | ||
3 | /// | ||
4 | /// Based on checkpatch warning | ||
5 | /// "kfree(NULL) is safe this check is probably not required" | ||
6 | /// and kfreeaddr.cocci by Julia Lawall. | ||
7 | /// | ||
8 | // Copyright: (C) 2014 Fabian Frederick. | ||
9 | // Comments: - | ||
10 | // Options: --no-includes --include-headers | ||
11 | |||
12 | virtual patch | ||
13 | virtual org | ||
14 | virtual report | ||
15 | virtual context | ||
16 | |||
17 | @r2 depends on patch@ | ||
18 | expression E; | ||
19 | @@ | ||
20 | - if (E != NULL) | ||
21 | ( | ||
22 | kfree(E); | ||
23 | | | ||
24 | kvfree(E); | ||
25 | | | ||
26 | kfree_sensitive(E); | ||
27 | | | ||
28 | kvfree_sensitive(E, ...); | ||
29 | | | ||
30 | vfree(E); | ||
31 | | | ||
32 | debugfs_remove(E); | ||
33 | | | ||
34 | debugfs_remove_recursive(E); | ||
35 | | | ||
36 | usb_free_urb(E); | ||
37 | | | ||
38 | kmem_cache_destroy(E); | ||
39 | | | ||
40 | mempool_destroy(E); | ||
41 | | | ||
42 | dma_pool_destroy(E); | ||
43 | ) | ||
44 | |||
45 | @r depends on context || report || org @ | ||
46 | expression E; | ||
47 | position p; | ||
48 | @@ | ||
49 | |||
50 | * if (E != NULL) | ||
51 | * \(kfree@p\|kvfree@p\|kfree_sensitive@p\|kvfree_sensitive@p\|vfree@p\| | ||
52 | * debugfs_remove@p\|debugfs_remove_recursive@p\| | ||
53 | * usb_free_urb@p\|kmem_cache_destroy@p\|mempool_destroy@p\| | ||
54 | * dma_pool_destroy@p\)(E, ...); | ||
55 | |||
56 | @script:python depends on org@ | ||
57 | p << r.p; | ||
58 | @@ | ||
59 | |||
60 | cocci.print_main("NULL check before that freeing function is not needed", p) | ||
61 | |||
62 | @script:python depends on report@ | ||
63 | p << r.p; | ||
64 | @@ | ||
65 | |||
66 | msg = "WARNING: NULL check before some freeing functions is not needed." | ||
67 | coccilib.report.print_report(p[0], msg) | ||
diff --git a/scripts/coccinelle/free/iounmap.cocci b/scripts/coccinelle/free/iounmap.cocci new file mode 100644 index 000000000..63b81d0c9 --- /dev/null +++ b/scripts/coccinelle/free/iounmap.cocci | |||
@@ -0,0 +1,68 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0-only | ||
2 | /// Find missing iounmaps. | ||
3 | /// | ||
4 | //# This only signals a missing iounmap when there is an iounmap later | ||
5 | //# in the same function. | ||
6 | //# False positives can be due to loops. | ||
7 | // | ||
8 | // Confidence: Moderate | ||
9 | // Copyright: (C) 2012 Julia Lawall, INRIA/LIP6. | ||
10 | // Copyright: (C) 2012 Gilles Muller, INRIA/LiP6. | ||
11 | // URL: http://coccinelle.lip6.fr/ | ||
12 | // Comments: | ||
13 | // Options: | ||
14 | |||
15 | virtual context | ||
16 | virtual org | ||
17 | virtual report | ||
18 | |||
19 | @iom@ | ||
20 | expression e; | ||
21 | statement S,S1; | ||
22 | int ret; | ||
23 | position p1,p2,p3; | ||
24 | @@ | ||
25 | |||
26 | e = \(ioremap@p1\)(...) | ||
27 | ... when != iounmap(e) | ||
28 | if (<+...e...+>) S | ||
29 | ... when any | ||
30 | when != iounmap(e) | ||
31 | when != if (...) { ... iounmap(e); ... } | ||
32 | ( | ||
33 | if (ret == 0) S1 | ||
34 | | | ||
35 | if (...) | ||
36 | { ... | ||
37 | return 0; } | ||
38 | | | ||
39 | if (...) | ||
40 | { ... | ||
41 | return <+...e...+>; } | ||
42 | | | ||
43 | *if@p2 (...) | ||
44 | { ... when != iounmap(e) | ||
45 | when forall | ||
46 | return@p3 ...; } | ||
47 | ) | ||
48 | ... when any | ||
49 | iounmap(e); | ||
50 | |||
51 | @script:python depends on org@ | ||
52 | p1 << iom.p1; | ||
53 | p2 << iom.p2; | ||
54 | p3 << iom.p3; | ||
55 | @@ | ||
56 | |||
57 | cocci.print_main("ioremap",p1) | ||
58 | cocci.print_secs("if",p2) | ||
59 | cocci.print_secs("needed iounmap",p3) | ||
60 | |||
61 | @script:python depends on report@ | ||
62 | p1 << iom.p1; | ||
63 | p2 << iom.p2; | ||
64 | p3 << iom.p3; | ||
65 | @@ | ||
66 | |||
67 | msg = "ERROR: missing iounmap; ioremap on line %s and execution via conditional on line %s" % (p1[0].line,p2[0].line) | ||
68 | coccilib.report.print_report(p3[0],msg) | ||
diff --git a/scripts/coccinelle/free/kfree.cocci b/scripts/coccinelle/free/kfree.cocci new file mode 100644 index 000000000..168568386 --- /dev/null +++ b/scripts/coccinelle/free/kfree.cocci | |||
@@ -0,0 +1,134 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0-only | ||
2 | /// Find a use after free. | ||
3 | //# Values of variables may imply that some | ||
4 | //# execution paths are not possible, resulting in false positives. | ||
5 | //# Another source of false positives are macros such as | ||
6 | //# SCTP_DBG_OBJCNT_DEC that do not actually evaluate their argument | ||
7 | /// | ||
8 | // Confidence: Moderate | ||
9 | // Copyright: (C) 2010-2012 Nicolas Palix. | ||
10 | // Copyright: (C) 2010-2012 Julia Lawall, INRIA/LIP6. | ||
11 | // Copyright: (C) 2010-2012 Gilles Muller, INRIA/LiP6. | ||
12 | // URL: http://coccinelle.lip6.fr/ | ||
13 | // Comments: | ||
14 | // Options: --no-includes --include-headers | ||
15 | |||
16 | virtual org | ||
17 | virtual report | ||
18 | |||
19 | @free@ | ||
20 | expression E; | ||
21 | position p1; | ||
22 | @@ | ||
23 | |||
24 | ( | ||
25 | * kfree@p1(E) | ||
26 | | | ||
27 | * kfree_sensitive@p1(E) | ||
28 | ) | ||
29 | |||
30 | @print expression@ | ||
31 | constant char [] c; | ||
32 | expression free.E,E2; | ||
33 | type T; | ||
34 | position p; | ||
35 | identifier f; | ||
36 | @@ | ||
37 | |||
38 | ( | ||
39 | f(...,c,...,(T)E@p,...) | ||
40 | | | ||
41 | E@p == E2 | ||
42 | | | ||
43 | E@p != E2 | ||
44 | | | ||
45 | E2 == E@p | ||
46 | | | ||
47 | E2 != E@p | ||
48 | | | ||
49 | !E@p | ||
50 | | | ||
51 | E@p || ... | ||
52 | ) | ||
53 | |||
54 | @sz@ | ||
55 | expression free.E; | ||
56 | position p; | ||
57 | @@ | ||
58 | |||
59 | sizeof(<+...E@p...+>) | ||
60 | |||
61 | @loop exists@ | ||
62 | expression E; | ||
63 | identifier l; | ||
64 | position ok; | ||
65 | @@ | ||
66 | |||
67 | while (1) { ... | ||
68 | ( | ||
69 | * kfree@ok(E) | ||
70 | | | ||
71 | * kfree_sensitive@ok(E) | ||
72 | ) | ||
73 | ... when != break; | ||
74 | when != goto l; | ||
75 | when forall | ||
76 | } | ||
77 | |||
78 | @r exists@ | ||
79 | expression free.E, subE<=free.E, E2; | ||
80 | expression E1; | ||
81 | iterator iter; | ||
82 | statement S; | ||
83 | position free.p1!=loop.ok,p2!={print.p,sz.p}; | ||
84 | @@ | ||
85 | |||
86 | ( | ||
87 | * kfree@p1(E,...) | ||
88 | | | ||
89 | * kfree_sensitive@p1(E,...) | ||
90 | ) | ||
91 | ... | ||
92 | ( | ||
93 | iter(...,subE,...) S // no use | ||
94 | | | ||
95 | list_remove_head(E1,subE,...) | ||
96 | | | ||
97 | subE = E2 | ||
98 | | | ||
99 | subE++ | ||
100 | | | ||
101 | ++subE | ||
102 | | | ||
103 | --subE | ||
104 | | | ||
105 | subE-- | ||
106 | | | ||
107 | &subE | ||
108 | | | ||
109 | BUG(...) | ||
110 | | | ||
111 | BUG_ON(...) | ||
112 | | | ||
113 | return_VALUE(...) | ||
114 | | | ||
115 | return_ACPI_STATUS(...) | ||
116 | | | ||
117 | E@p2 // bad use | ||
118 | ) | ||
119 | |||
120 | @script:python depends on org@ | ||
121 | p1 << free.p1; | ||
122 | p2 << r.p2; | ||
123 | @@ | ||
124 | |||
125 | cocci.print_main("kfree",p1) | ||
126 | cocci.print_secs("ref",p2) | ||
127 | |||
128 | @script:python depends on report@ | ||
129 | p1 << free.p1; | ||
130 | p2 << r.p2; | ||
131 | @@ | ||
132 | |||
133 | msg = "ERROR: reference preceded by free on line %s" % (p1[0].line) | ||
134 | coccilib.report.print_report(p2[0],msg) | ||
diff --git a/scripts/coccinelle/free/kfreeaddr.cocci b/scripts/coccinelle/free/kfreeaddr.cocci new file mode 100644 index 000000000..142af6337 --- /dev/null +++ b/scripts/coccinelle/free/kfreeaddr.cocci | |||
@@ -0,0 +1,37 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0-only | ||
2 | /// Free of a structure field | ||
3 | /// | ||
4 | // Confidence: High | ||
5 | // Copyright: (C) 2013 Julia Lawall, INRIA/LIP6. | ||
6 | // URL: http://coccinelle.lip6.fr/ | ||
7 | // Comments: | ||
8 | // Options: --no-includes --include-headers | ||
9 | |||
10 | virtual org | ||
11 | virtual report | ||
12 | virtual context | ||
13 | |||
14 | @r depends on context || report || org @ | ||
15 | expression e; | ||
16 | identifier f; | ||
17 | position p; | ||
18 | @@ | ||
19 | |||
20 | ( | ||
21 | * kfree@p(&e->f) | ||
22 | | | ||
23 | * kfree_sensitive@p(&e->f) | ||
24 | ) | ||
25 | |||
26 | @script:python depends on org@ | ||
27 | p << r.p; | ||
28 | @@ | ||
29 | |||
30 | cocci.print_main("kfree",p) | ||
31 | |||
32 | @script:python depends on report@ | ||
33 | p << r.p; | ||
34 | @@ | ||
35 | |||
36 | msg = "ERROR: invalid free of structure field" | ||
37 | coccilib.report.print_report(p[0],msg) | ||
diff --git a/scripts/coccinelle/free/pci_free_consistent.cocci b/scripts/coccinelle/free/pci_free_consistent.cocci new file mode 100644 index 000000000..d51e92556 --- /dev/null +++ b/scripts/coccinelle/free/pci_free_consistent.cocci | |||
@@ -0,0 +1,53 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0-only | ||
2 | /// Find missing pci_free_consistent for every pci_alloc_consistent. | ||
3 | /// | ||
4 | // Confidence: Moderate | ||
5 | // Copyright: (C) 2013 Petr Strnad. | ||
6 | // URL: http://coccinelle.lip6.fr/ | ||
7 | // Keywords: pci_free_consistent, pci_alloc_consistent | ||
8 | // Options: --no-includes --include-headers | ||
9 | |||
10 | virtual report | ||
11 | virtual org | ||
12 | |||
13 | @search@ | ||
14 | local idexpression id; | ||
15 | expression x,y,z,e; | ||
16 | position p1,p2; | ||
17 | type T; | ||
18 | @@ | ||
19 | |||
20 | id = pci_alloc_consistent@p1(x,y,&z) | ||
21 | ... when != e = id | ||
22 | if (id == NULL || ...) { ... return ...; } | ||
23 | ... when != pci_free_consistent(x,y,id,z) | ||
24 | when != if (id) { ... pci_free_consistent(x,y,id,z) ... } | ||
25 | when != if (y) { ... pci_free_consistent(x,y,id,z) ... } | ||
26 | when != e = (T)id | ||
27 | when exists | ||
28 | ( | ||
29 | return 0; | ||
30 | | | ||
31 | return 1; | ||
32 | | | ||
33 | return id; | ||
34 | | | ||
35 | return@p2 ...; | ||
36 | ) | ||
37 | |||
38 | @script:python depends on report@ | ||
39 | p1 << search.p1; | ||
40 | p2 << search.p2; | ||
41 | @@ | ||
42 | |||
43 | msg = "ERROR: missing pci_free_consistent; pci_alloc_consistent on line %s and return without freeing on line %s" % (p1[0].line,p2[0].line) | ||
44 | coccilib.report.print_report(p2[0],msg) | ||
45 | |||
46 | @script:python depends on org@ | ||
47 | p1 << search.p1; | ||
48 | p2 << search.p2; | ||
49 | @@ | ||
50 | |||
51 | msg = "ERROR: missing pci_free_consistent; pci_alloc_consistent on line %s and return without freeing on line %s" % (p1[0].line,p2[0].line) | ||
52 | cocci.print_main(msg,p1) | ||
53 | cocci.print_secs("",p2) | ||
diff --git a/scripts/coccinelle/free/put_device.cocci b/scripts/coccinelle/free/put_device.cocci new file mode 100644 index 000000000..120921366 --- /dev/null +++ b/scripts/coccinelle/free/put_device.cocci | |||
@@ -0,0 +1,56 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0 | ||
2 | /// Find missing put_device for every of_find_device_by_node. | ||
3 | /// | ||
4 | // Confidence: Moderate | ||
5 | // Copyright: (C) 2018-2019 Wen Yang, ZTE. | ||
6 | // Comments: | ||
7 | // Options: --no-includes --include-headers | ||
8 | |||
9 | virtual report | ||
10 | virtual org | ||
11 | |||
12 | @search exists@ | ||
13 | local idexpression id; | ||
14 | expression x,e,e1; | ||
15 | position p1,p2; | ||
16 | type T,T1,T2,T3; | ||
17 | @@ | ||
18 | |||
19 | id = of_find_device_by_node@p1(x) | ||
20 | ... when != e = id | ||
21 | if (id == NULL || ...) { ... return ...; } | ||
22 | ... when != put_device(&id->dev) | ||
23 | when != platform_device_put(id) | ||
24 | when != of_dev_put(id) | ||
25 | when != if (id) { ... put_device(&id->dev) ... } | ||
26 | when != e1 = (T)id | ||
27 | when != e1 = (T)(&id->dev) | ||
28 | when != e1 = get_device(&id->dev) | ||
29 | when != e1 = (T1)platform_get_drvdata(id) | ||
30 | ( | ||
31 | return | ||
32 | ( id | ||
33 | | (T2)dev_get_drvdata(&id->dev) | ||
34 | | (T3)platform_get_drvdata(id) | ||
35 | | &id->dev | ||
36 | ); | ||
37 | | return@p2 ...; | ||
38 | ) | ||
39 | |||
40 | @script:python depends on report@ | ||
41 | p1 << search.p1; | ||
42 | p2 << search.p2; | ||
43 | @@ | ||
44 | |||
45 | coccilib.report.print_report(p2[0], | ||
46 | "ERROR: missing put_device; call of_find_device_by_node on line " | ||
47 | + p1[0].line | ||
48 | + ", but without a corresponding object release within this function.") | ||
49 | |||
50 | @script:python depends on org@ | ||
51 | p1 << search.p1; | ||
52 | p2 << search.p2; | ||
53 | @@ | ||
54 | |||
55 | cocci.print_main("of_find_device_by_node", p1) | ||
56 | cocci.print_secs("needed put_device", p2) | ||