kfree_sensitive.cocci 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. ///
  3. /// Use kfree_sensitive, kvfree_sensitive rather than memset or
  4. /// memzero_explicit followed by kfree.
  5. ///
  6. // Confidence: High
  7. // Copyright: (C) 2020 Denis Efremov ISPRAS
  8. // Options: --no-includes --include-headers
  9. //
  10. // Keywords: kfree_sensitive, kvfree_sensitive
  11. //
  12. virtual context
  13. virtual patch
  14. virtual org
  15. virtual report
  16. @initialize:python@
  17. @@
  18. # kmalloc_oob_in_memset uses memset to explicitly trigger out-of-bounds access
  19. filter = frozenset(['kmalloc_oob_in_memset',
  20. 'kfree_sensitive', 'kvfree_sensitive'])
  21. def relevant(p):
  22. return not (filter & {el.current_element for el in p})
  23. @cond@
  24. position ok;
  25. @@
  26. if (...)
  27. \(memset@ok\|memzero_explicit@ok\)(...);
  28. @r depends on !patch forall@
  29. expression E;
  30. position p : script:python() { relevant(p) };
  31. position m != cond.ok;
  32. type T;
  33. @@
  34. (
  35. * memset@m((T)E, 0, ...);
  36. |
  37. * memzero_explicit@m((T)E, ...);
  38. )
  39. ... when != E
  40. when strict
  41. * \(kfree\|vfree\|kvfree\)(E)@p;
  42. @rp_memzero depends on patch@
  43. expression E, size;
  44. position p : script:python() { relevant(p) };
  45. position m != cond.ok;
  46. type T;
  47. @@
  48. - memzero_explicit@m((T)E, size);
  49. ... when != E
  50. when strict
  51. (
  52. - kfree(E)@p;
  53. + kfree_sensitive(E);
  54. |
  55. - \(vfree\|kvfree\)(E)@p;
  56. + kvfree_sensitive(E, size);
  57. )
  58. @rp_memset depends on patch@
  59. expression E, size;
  60. position p : script:python() { relevant(p) };
  61. position m != cond.ok;
  62. type T;
  63. @@
  64. - memset@m((T)E, 0, size);
  65. ... when != E
  66. when strict
  67. (
  68. - kfree(E)@p;
  69. + kfree_sensitive(E);
  70. |
  71. - \(vfree\|kvfree\)(E)@p;
  72. + kvfree_sensitive(E, size);
  73. )
  74. @script:python depends on report@
  75. p << r.p;
  76. m << r.m;
  77. @@
  78. msg = "WARNING opportunity for kfree_sensitive/kvfree_sensitive (memset at line %s)"
  79. coccilib.report.print_report(p[0], msg % (m[0].line))
  80. @script:python depends on org@
  81. p << r.p;
  82. m << r.m;
  83. @@
  84. msg = "WARNING opportunity for kfree_sensitive/kvfree_sensitive (memset at line %s)"
  85. coccilib.org.print_todo(p[0], msg % (m[0].line))