diff options
author | 2025-03-08 22:04:20 +0800 | |
---|---|---|
committer | 2025-03-08 22:04:20 +0800 | |
commit | a07bb8fd1299070229f0e8f3dcb57ffd5ef9870a (patch) | |
tree | 84f21bd0bf7071bc5fc7dd989e77d7ceb5476682 /scripts/coccinelle/locks | |
download | ohosKernel-a07bb8fd1299070229f0e8f3dcb57ffd5ef9870a.tar.gz ohosKernel-a07bb8fd1299070229f0e8f3dcb57ffd5ef9870a.zip |
Initial commit: OpenHarmony-v4.0-ReleaseOpenHarmony-v4.0-Release
Diffstat (limited to 'scripts/coccinelle/locks')
-rw-r--r-- | scripts/coccinelle/locks/call_kern.cocci | 106 | ||||
-rw-r--r-- | scripts/coccinelle/locks/double_lock.cocci | 93 | ||||
-rw-r--r-- | scripts/coccinelle/locks/flags.cocci | 81 | ||||
-rw-r--r-- | scripts/coccinelle/locks/mini_lock.cocci | 99 |
4 files changed, 379 insertions, 0 deletions
diff --git a/scripts/coccinelle/locks/call_kern.cocci b/scripts/coccinelle/locks/call_kern.cocci new file mode 100644 index 000000000..5ca0d81b0 --- /dev/null +++ b/scripts/coccinelle/locks/call_kern.cocci | |||
@@ -0,0 +1,106 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0-only | ||
2 | /// Find functions that refer to GFP_KERNEL but are called with locks held. | ||
3 | //# The proposed change of converting the GFP_KERNEL is not necessarily the | ||
4 | //# correct one. It may be desired to unlock the lock, or to not call the | ||
5 | //# function under the lock in the first place. | ||
6 | /// | ||
7 | // Confidence: Moderate | ||
8 | // Copyright: (C) 2012 Nicolas Palix. | ||
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: --no-includes --include-headers | ||
14 | |||
15 | virtual patch | ||
16 | virtual context | ||
17 | virtual org | ||
18 | virtual report | ||
19 | |||
20 | @gfp exists@ | ||
21 | identifier fn; | ||
22 | position p; | ||
23 | @@ | ||
24 | |||
25 | fn(...) { | ||
26 | ... when != read_unlock_irq(...) | ||
27 | when != write_unlock_irq(...) | ||
28 | when != read_unlock_irqrestore(...) | ||
29 | when != write_unlock_irqrestore(...) | ||
30 | when != spin_unlock(...) | ||
31 | when != spin_unlock_irq(...) | ||
32 | when != spin_unlock_irqrestore(...) | ||
33 | when != local_irq_enable(...) | ||
34 | when any | ||
35 | GFP_KERNEL@p | ||
36 | ... when any | ||
37 | } | ||
38 | |||
39 | @locked exists@ | ||
40 | identifier gfp.fn; | ||
41 | position p1,p2; | ||
42 | @@ | ||
43 | |||
44 | ( | ||
45 | read_lock_irq@p1 | ||
46 | | | ||
47 | write_lock_irq@p1 | ||
48 | | | ||
49 | read_lock_irqsave@p1 | ||
50 | | | ||
51 | write_lock_irqsave@p1 | ||
52 | | | ||
53 | spin_lock@p1 | ||
54 | | | ||
55 | spin_trylock@p1 | ||
56 | | | ||
57 | spin_lock_irq@p1 | ||
58 | | | ||
59 | spin_lock_irqsave@p1 | ||
60 | | | ||
61 | local_irq_disable@p1 | ||
62 | ) | ||
63 | (...) | ||
64 | ... when != read_unlock_irq(...) | ||
65 | when != write_unlock_irq(...) | ||
66 | when != read_unlock_irqrestore(...) | ||
67 | when != write_unlock_irqrestore(...) | ||
68 | when != spin_unlock(...) | ||
69 | when != spin_unlock_irq(...) | ||
70 | when != spin_unlock_irqrestore(...) | ||
71 | when != local_irq_enable(...) | ||
72 | fn@p2(...) | ||
73 | |||
74 | @depends on locked && patch@ | ||
75 | position gfp.p; | ||
76 | @@ | ||
77 | |||
78 | - GFP_KERNEL@p | ||
79 | + GFP_ATOMIC | ||
80 | |||
81 | @depends on locked && !patch@ | ||
82 | position gfp.p; | ||
83 | @@ | ||
84 | |||
85 | * GFP_KERNEL@p | ||
86 | |||
87 | @script:python depends on !patch && org@ | ||
88 | p << gfp.p; | ||
89 | fn << gfp.fn; | ||
90 | p1 << locked.p1; | ||
91 | p2 << locked.p2; | ||
92 | @@ | ||
93 | |||
94 | cocci.print_main("lock",p1) | ||
95 | cocci.print_secs("call",p2) | ||
96 | cocci.print_secs("GFP_KERNEL",p) | ||
97 | |||
98 | @script:python depends on !patch && report@ | ||
99 | p << gfp.p; | ||
100 | fn << gfp.fn; | ||
101 | p1 << locked.p1; | ||
102 | p2 << locked.p2; | ||
103 | @@ | ||
104 | |||
105 | msg = "ERROR: function %s called on line %s inside lock on line %s but uses GFP_KERNEL" % (fn,p2[0].line,p1[0].line) | ||
106 | coccilib.report.print_report(p[0], msg) | ||
diff --git a/scripts/coccinelle/locks/double_lock.cocci b/scripts/coccinelle/locks/double_lock.cocci new file mode 100644 index 000000000..9e88a5789 --- /dev/null +++ b/scripts/coccinelle/locks/double_lock.cocci | |||
@@ -0,0 +1,93 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0-only | ||
2 | /// Find double locks. False positives may occur when some paths cannot | ||
3 | /// occur at execution, due to the values of variables, and when there is | ||
4 | /// an intervening function call that releases the lock. | ||
5 | /// | ||
6 | // Confidence: Moderate | ||
7 | // Copyright: (C) 2010 Nicolas Palix, DIKU. | ||
8 | // Copyright: (C) 2010 Julia Lawall, DIKU. | ||
9 | // Copyright: (C) 2010 Gilles Muller, INRIA/LiP6. | ||
10 | // URL: http://coccinelle.lip6.fr/ | ||
11 | // Comments: | ||
12 | // Options: --no-includes --include-headers | ||
13 | |||
14 | virtual org | ||
15 | virtual report | ||
16 | |||
17 | @locked@ | ||
18 | position p1; | ||
19 | expression E1; | ||
20 | position p; | ||
21 | @@ | ||
22 | |||
23 | ( | ||
24 | mutex_lock@p1 | ||
25 | | | ||
26 | mutex_trylock@p1 | ||
27 | | | ||
28 | spin_lock@p1 | ||
29 | | | ||
30 | spin_trylock@p1 | ||
31 | | | ||
32 | read_lock@p1 | ||
33 | | | ||
34 | read_trylock@p1 | ||
35 | | | ||
36 | write_lock@p1 | ||
37 | | | ||
38 | write_trylock@p1 | ||
39 | ) (E1@p,...); | ||
40 | |||
41 | @balanced@ | ||
42 | position p1 != locked.p1; | ||
43 | position locked.p; | ||
44 | identifier lock,unlock; | ||
45 | expression x <= locked.E1; | ||
46 | expression E,locked.E1; | ||
47 | expression E2; | ||
48 | @@ | ||
49 | |||
50 | if (E) { | ||
51 | <+... when != E1 | ||
52 | lock(E1@p,...) | ||
53 | ...+> | ||
54 | } | ||
55 | ... when != E1 | ||
56 | when != \(x = E2\|&x\) | ||
57 | when forall | ||
58 | if (E) { | ||
59 | <+... when != E1 | ||
60 | unlock@p1(E1,...) | ||
61 | ...+> | ||
62 | } | ||
63 | |||
64 | @r depends on !balanced exists@ | ||
65 | expression x <= locked.E1; | ||
66 | expression locked.E1; | ||
67 | expression E2; | ||
68 | identifier lock; | ||
69 | position locked.p,p1,p2; | ||
70 | @@ | ||
71 | |||
72 | lock@p1 (E1@p,...); | ||
73 | ... when != E1 | ||
74 | when != \(x = E2\|&x\) | ||
75 | lock@p2 (E1,...); | ||
76 | |||
77 | @script:python depends on org@ | ||
78 | p1 << r.p1; | ||
79 | p2 << r.p2; | ||
80 | lock << r.lock; | ||
81 | @@ | ||
82 | |||
83 | cocci.print_main(lock,p1) | ||
84 | cocci.print_secs("second lock",p2) | ||
85 | |||
86 | @script:python depends on report@ | ||
87 | p1 << r.p1; | ||
88 | p2 << r.p2; | ||
89 | lock << r.lock; | ||
90 | @@ | ||
91 | |||
92 | msg = "second lock on line %s" % (p2[0].line) | ||
93 | coccilib.report.print_report(p1[0],msg) | ||
diff --git a/scripts/coccinelle/locks/flags.cocci b/scripts/coccinelle/locks/flags.cocci new file mode 100644 index 000000000..7f990cd55 --- /dev/null +++ b/scripts/coccinelle/locks/flags.cocci | |||
@@ -0,0 +1,81 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0-only | ||
2 | /// Find nested lock+irqsave functions that use the same flags variables | ||
3 | /// | ||
4 | // Confidence: High | ||
5 | // Copyright: (C) 2010-2012 Nicolas Palix. | ||
6 | // Copyright: (C) 2010-2012 Julia Lawall, INRIA/LIP6. | ||
7 | // Copyright: (C) 2010-2012 Gilles Muller, INRIA/LiP6. | ||
8 | // URL: http://coccinelle.lip6.fr/ | ||
9 | // Comments: | ||
10 | // Options: --no-includes --include-headers | ||
11 | |||
12 | virtual context | ||
13 | virtual org | ||
14 | virtual report | ||
15 | |||
16 | @r exists@ | ||
17 | expression lock1,lock2,flags; | ||
18 | position p1,p2; | ||
19 | @@ | ||
20 | |||
21 | ( | ||
22 | spin_lock_irqsave@p1(lock1,flags) | ||
23 | | | ||
24 | read_lock_irqsave@p1(lock1,flags) | ||
25 | | | ||
26 | write_lock_irqsave@p1(lock1,flags) | ||
27 | ) | ||
28 | ... when != flags | ||
29 | ( | ||
30 | spin_lock_irqsave(lock1,flags) | ||
31 | | | ||
32 | read_lock_irqsave(lock1,flags) | ||
33 | | | ||
34 | write_lock_irqsave(lock1,flags) | ||
35 | | | ||
36 | spin_lock_irqsave@p2(lock2,flags) | ||
37 | | | ||
38 | read_lock_irqsave@p2(lock2,flags) | ||
39 | | | ||
40 | write_lock_irqsave@p2(lock2,flags) | ||
41 | ) | ||
42 | |||
43 | @d exists@ | ||
44 | expression f <= r.flags; | ||
45 | expression lock1,lock2,flags; | ||
46 | position r.p1, r.p2; | ||
47 | @@ | ||
48 | |||
49 | ( | ||
50 | *spin_lock_irqsave@p1(lock1,flags) | ||
51 | | | ||
52 | *read_lock_irqsave@p1(lock1,flags) | ||
53 | | | ||
54 | *write_lock_irqsave@p1(lock1,flags) | ||
55 | ) | ||
56 | ... when != f | ||
57 | ( | ||
58 | *spin_lock_irqsave@p2(lock2,flags) | ||
59 | | | ||
60 | *read_lock_irqsave@p2(lock2,flags) | ||
61 | | | ||
62 | *write_lock_irqsave@p2(lock2,flags) | ||
63 | ) | ||
64 | |||
65 | // ---------------------------------------------------------------------- | ||
66 | |||
67 | @script:python depends on d && org@ | ||
68 | p1 << r.p1; | ||
69 | p2 << r.p2; | ||
70 | @@ | ||
71 | |||
72 | cocci.print_main("original lock",p1) | ||
73 | cocci.print_secs("nested lock+irqsave that reuses flags",p2) | ||
74 | |||
75 | @script:python depends on d && report@ | ||
76 | p1 << r.p1; | ||
77 | p2 << r.p2; | ||
78 | @@ | ||
79 | |||
80 | msg="ERROR: nested lock+irqsave that reuses flags from line %s." % (p1[0].line) | ||
81 | coccilib.report.print_report(p2[0], msg) | ||
diff --git a/scripts/coccinelle/locks/mini_lock.cocci b/scripts/coccinelle/locks/mini_lock.cocci new file mode 100644 index 000000000..c3ad098f4 --- /dev/null +++ b/scripts/coccinelle/locks/mini_lock.cocci | |||
@@ -0,0 +1,99 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0-only | ||
2 | /// Find missing unlocks. This semantic match considers the specific case | ||
3 | /// where the unlock is missing from an if branch, and there is a lock | ||
4 | /// before the if and an unlock after the if. False positives are due to | ||
5 | /// cases where the if branch represents a case where the function is | ||
6 | /// supposed to exit with the lock held, or where there is some preceding | ||
7 | /// function call that releases the lock. | ||
8 | /// | ||
9 | // Confidence: Moderate | ||
10 | // Copyright: (C) 2010-2012 Nicolas Palix. | ||
11 | // Copyright: (C) 2010-2012 Julia Lawall, INRIA/LIP6. | ||
12 | // Copyright: (C) 2010-2012 Gilles Muller, INRIA/LiP6. | ||
13 | // URL: http://coccinelle.lip6.fr/ | ||
14 | // Comments: | ||
15 | // Options: --no-includes --include-headers | ||
16 | |||
17 | virtual context | ||
18 | virtual org | ||
19 | virtual report | ||
20 | |||
21 | @prelocked@ | ||
22 | position p1,p; | ||
23 | expression E1; | ||
24 | @@ | ||
25 | |||
26 | ( | ||
27 | mutex_lock@p1 | ||
28 | | | ||
29 | mutex_trylock@p1 | ||
30 | | | ||
31 | spin_lock@p1 | ||
32 | | | ||
33 | spin_trylock@p1 | ||
34 | | | ||
35 | read_lock@p1 | ||
36 | | | ||
37 | read_trylock@p1 | ||
38 | | | ||
39 | write_lock@p1 | ||
40 | | | ||
41 | write_trylock@p1 | ||
42 | | | ||
43 | read_lock_irq@p1 | ||
44 | | | ||
45 | write_lock_irq@p1 | ||
46 | | | ||
47 | read_lock_irqsave@p1 | ||
48 | | | ||
49 | write_lock_irqsave@p1 | ||
50 | | | ||
51 | spin_lock_irq@p1 | ||
52 | | | ||
53 | spin_lock_irqsave@p1 | ||
54 | ) (E1@p,...); | ||
55 | |||
56 | @looped@ | ||
57 | position r; | ||
58 | @@ | ||
59 | |||
60 | for(...;...;...) { <+... return@r ...; ...+> } | ||
61 | |||
62 | @err exists@ | ||
63 | expression E1; | ||
64 | position prelocked.p; | ||
65 | position up != prelocked.p1; | ||
66 | position r!=looped.r; | ||
67 | identifier lock,unlock; | ||
68 | @@ | ||
69 | |||
70 | *lock(E1@p,...); | ||
71 | ... when != E1 | ||
72 | when any | ||
73 | if (...) { | ||
74 | ... when != E1 | ||
75 | * return@r ...; | ||
76 | } | ||
77 | ... when != E1 | ||
78 | when any | ||
79 | *unlock@up(E1,...); | ||
80 | |||
81 | @script:python depends on org@ | ||
82 | p << prelocked.p1; | ||
83 | lock << err.lock; | ||
84 | unlock << err.unlock; | ||
85 | p2 << err.r; | ||
86 | @@ | ||
87 | |||
88 | cocci.print_main(lock,p) | ||
89 | cocci.print_secs(unlock,p2) | ||
90 | |||
91 | @script:python depends on report@ | ||
92 | p << prelocked.p1; | ||
93 | lock << err.lock; | ||
94 | unlock << err.unlock; | ||
95 | p2 << err.r; | ||
96 | @@ | ||
97 | |||
98 | msg = "preceding lock on line %s" % (p[0].line) | ||
99 | coccilib.report.print_report(p2[0],msg) | ||