mini_lock.cocci 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  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: https://coccinelle.gitlabpages.inria.fr/website
  14. // Comments:
  15. // Options: --no-includes --include-headers
  16. virtual context
  17. virtual org
  18. virtual report
  19. @prelocked@
  20. position p1,p;
  21. expression E1;
  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. |
  40. read_lock_irq@p1
  41. |
  42. write_lock_irq@p1
  43. |
  44. read_lock_irqsave@p1
  45. |
  46. write_lock_irqsave@p1
  47. |
  48. spin_lock_irq@p1
  49. |
  50. spin_lock_irqsave@p1
  51. ) (E1@p,...);
  52. @looped@
  53. position r;
  54. @@
  55. for(...;...;...) { <+... return@r ...; ...+> }
  56. @err exists@
  57. expression E1;
  58. position prelocked.p;
  59. position up != prelocked.p1;
  60. position r!=looped.r;
  61. identifier lock,unlock;
  62. @@
  63. *lock(E1@p,...);
  64. ... when != E1
  65. when any
  66. if (...) {
  67. ... when != E1
  68. * return@r ...;
  69. }
  70. ... when != E1
  71. when any
  72. *unlock@up(E1,...);
  73. @script:python depends on org@
  74. p << prelocked.p1;
  75. lock << err.lock;
  76. unlock << err.unlock;
  77. p2 << err.r;
  78. @@
  79. cocci.print_main(lock,p)
  80. cocci.print_secs(unlock,p2)
  81. @script:python depends on report@
  82. p << prelocked.p1;
  83. lock << err.lock;
  84. unlock << err.unlock;
  85. p2 << err.r;
  86. @@
  87. msg = "preceding lock on line %s" % (p[0].line)
  88. coccilib.report.print_report(p2[0],msg)