array_size_dup.cocci 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. ///
  3. /// Check for array_size(), array3_size(), struct_size() duplicates.
  4. /// These patterns are detected:
  5. /// 1. An opencoded expression is used before array_size() to compute the same size
  6. /// 2. An opencoded expression is used after array_size() to compute the same size
  7. /// From security point of view only first case is relevant. These functions
  8. /// perform arithmetic overflow check. Thus, if we use an opencoded expression
  9. /// before a call to the *_size() function we can miss an overflow.
  10. ///
  11. // Confidence: High
  12. // Copyright: (C) 2020 Denis Efremov ISPRAS
  13. // Options: --no-includes --include-headers --no-loops
  14. virtual context
  15. virtual report
  16. virtual org
  17. @as@
  18. expression E1, E2;
  19. @@
  20. array_size(E1, E2)
  21. @as_next@
  22. expression subE1 <= as.E1;
  23. expression subE2 <= as.E2;
  24. expression as.E1, as.E2, E3;
  25. assignment operator aop;
  26. position p1, p2;
  27. @@
  28. * E1 * E2@p1
  29. ... when != \(subE1\|subE2\) aop E3
  30. when != &\(subE1\|subE2\)
  31. * array_size(E1, E2)@p2
  32. @script:python depends on report@
  33. p1 << as_next.p1;
  34. p2 << as_next.p2;
  35. @@
  36. msg = "WARNING: array_size is used later (line %s) to compute the same size" % (p2[0].line)
  37. coccilib.report.print_report(p1[0], msg)
  38. @script:python depends on org@
  39. p1 << as_next.p1;
  40. p2 << as_next.p2;
  41. @@
  42. msg = "WARNING: array_size is used later (line %s) to compute the same size" % (p2[0].line)
  43. coccilib.org.print_todo(p1[0], msg)
  44. @as_prev@
  45. expression subE1 <= as.E1;
  46. expression subE2 <= as.E2;
  47. expression as.E1, as.E2, E3;
  48. assignment operator aop;
  49. position p1, p2;
  50. @@
  51. * array_size(E1, E2)@p1
  52. ... when != \(subE1\|subE2\) aop E3
  53. when != &\(subE1\|subE2\)
  54. * E1 * E2@p2
  55. @script:python depends on report@
  56. p1 << as_prev.p1;
  57. p2 << as_prev.p2;
  58. @@
  59. msg = "WARNING: array_size is already used (line %s) to compute the same size" % (p1[0].line)
  60. coccilib.report.print_report(p2[0], msg)
  61. @script:python depends on org@
  62. p1 << as_prev.p1;
  63. p2 << as_prev.p2;
  64. @@
  65. msg = "WARNING: array_size is already used (line %s) to compute the same size" % (p1[0].line)
  66. coccilib.org.print_todo(p2[0], msg)
  67. @as3@
  68. expression E1, E2, E3;
  69. @@
  70. array3_size(E1, E2, E3)
  71. @as3_next@
  72. expression subE1 <= as3.E1;
  73. expression subE2 <= as3.E2;
  74. expression subE3 <= as3.E3;
  75. expression as3.E1, as3.E2, as3.E3, E4;
  76. assignment operator aop;
  77. position p1, p2;
  78. @@
  79. * E1 * E2 * E3@p1
  80. ... when != \(subE1\|subE2\|subE3\) aop E4
  81. when != &\(subE1\|subE2\|subE3\)
  82. * array3_size(E1, E2, E3)@p2
  83. @script:python depends on report@
  84. p1 << as3_next.p1;
  85. p2 << as3_next.p2;
  86. @@
  87. msg = "WARNING: array3_size is used later (line %s) to compute the same size" % (p2[0].line)
  88. coccilib.report.print_report(p1[0], msg)
  89. @script:python depends on org@
  90. p1 << as3_next.p1;
  91. p2 << as3_next.p2;
  92. @@
  93. msg = "WARNING: array3_size is used later (line %s) to compute the same size" % (p2[0].line)
  94. coccilib.org.print_todo(p1[0], msg)
  95. @as3_prev@
  96. expression subE1 <= as3.E1;
  97. expression subE2 <= as3.E2;
  98. expression subE3 <= as3.E3;
  99. expression as3.E1, as3.E2, as3.E3, E4;
  100. assignment operator aop;
  101. position p1, p2;
  102. @@
  103. * array3_size(E1, E2, E3)@p1
  104. ... when != \(subE1\|subE2\|subE3\) aop E4
  105. when != &\(subE1\|subE2\|subE3\)
  106. * E1 * E2 * E3@p2
  107. @script:python depends on report@
  108. p1 << as3_prev.p1;
  109. p2 << as3_prev.p2;
  110. @@
  111. msg = "WARNING: array3_size is already used (line %s) to compute the same size" % (p1[0].line)
  112. coccilib.report.print_report(p2[0], msg)
  113. @script:python depends on org@
  114. p1 << as3_prev.p1;
  115. p2 << as3_prev.p2;
  116. @@
  117. msg = "WARNING: array3_size is already used (line %s) to compute the same size" % (p1[0].line)
  118. coccilib.org.print_todo(p2[0], msg)
  119. @ss@
  120. expression E1, E2, E3;
  121. @@
  122. struct_size(E1, E2, E3)
  123. @ss_next@
  124. expression subE3 <= ss.E3;
  125. expression ss.E1, ss.E2, ss.E3, E4;
  126. assignment operator aop;
  127. position p1, p2;
  128. @@
  129. * E1 * E2 + E3@p1
  130. ... when != subE3 aop E4
  131. when != &subE3
  132. * struct_size(E1, E2, E3)@p2
  133. @script:python depends on report@
  134. p1 << ss_next.p1;
  135. p2 << ss_next.p2;
  136. @@
  137. msg = "WARNING: struct_size is used later (line %s) to compute the same size" % (p2[0].line)
  138. coccilib.report.print_report(p1[0], msg)
  139. @script:python depends on org@
  140. p1 << ss_next.p1;
  141. p2 << ss_next.p2;
  142. @@
  143. msg = "WARNING: struct_size is used later (line %s) to compute the same size" % (p2[0].line)
  144. coccilib.org.print_todo(p1[0], msg)
  145. @ss_prev@
  146. expression subE3 <= ss.E3;
  147. expression ss.E1, ss.E2, ss.E3, E4;
  148. assignment operator aop;
  149. position p1, p2;
  150. @@
  151. * struct_size(E1, E2, E3)@p1
  152. ... when != subE3 aop E4
  153. when != &subE3
  154. * E1 * E2 + E3@p2
  155. @script:python depends on report@
  156. p1 << ss_prev.p1;
  157. p2 << ss_prev.p2;
  158. @@
  159. msg = "WARNING: struct_size is already used (line %s) to compute the same size" % (p1[0].line)
  160. coccilib.report.print_report(p2[0], msg)
  161. @script:python depends on org@
  162. p1 << ss_prev.p1;
  163. p2 << ss_prev.p2;
  164. @@
  165. msg = "WARNING: struct_size is already used (line %s) to compute the same size" % (p1[0].line)
  166. coccilib.org.print_todo(p2[0], msg)