xref: /linux/scripts/coccinelle/locks/double_lock.cocci (revision 3a2c4d55e32ad65efebdb6de44eef3bfa08bb49d)
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: https://coccinelle.gitlabpages.inria.fr/website
11// Comments:
12// Options: --no-includes --include-headers
13
14virtual org
15virtual report
16
17@locked@
18position p1;
19expression E1;
20position p;
21@@
22
23(
24mutex_lock@p1
25|
26mutex_trylock@p1
27|
28spin_lock@p1
29|
30spin_trylock@p1
31|
32read_lock@p1
33|
34read_trylock@p1
35|
36write_lock@p1
37|
38write_trylock@p1
39) (E1@p,...);
40
41@r_candidate exists@
42expression x <= locked.E1;
43expression locked.E1;
44expression E2;
45identifier lock;
46position locked.p,p1,p2;
47@@
48
49lock@p1 (E1@p,...);
50... when != E1
51    when != \(x = E2\|&x\)
52lock@p2 (E1,...);
53
54@balanced depends on r_candidate@
55position p1 != locked.p1;
56position locked.p;
57identifier lock,unlock;
58expression x <= locked.E1;
59expression E,locked.E1;
60expression E2;
61@@
62
63if (E) {
64 <+... when != E1
65 lock(E1@p,...)
66 ...+>
67}
68... when != E1
69    when != \(x = E2\|&x\)
70    when forall
71if (E) {
72 <+... when != E1
73 unlock@p1(E1,...)
74 ...+>
75}
76
77@r depends on !balanced exists@
78expression x <= locked.E1;
79expression locked.E1;
80expression E2;
81identifier lock;
82position locked.p,p1,p2;
83@@
84
85lock@p1 (E1@p,...);
86... when != E1
87    when != \(x = E2\|&x\)
88lock@p2 (E1,...);
89
90@script:python depends on org@
91p1 << r.p1;
92p2 << r.p2;
93lock << r.lock;
94@@
95
96cocci.print_main(lock,p1)
97cocci.print_secs("second lock",p2)
98
99@script:python depends on report@
100p1 << r.p1;
101p2 << r.p2;
102lock << r.lock;
103@@
104
105msg = "second lock on line %s" % (p2[0].line)
106coccilib.report.print_report(p1[0],msg)
107