subr_poison.c 2.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. /* $OpenBSD: subr_poison.c,v 1.13 2015/03/14 03:38:50 jsg Exp $ */
  2. /*
  3. * Copyright (c) 2013 Ted Unangst <tedu@openbsd.org>
  4. *
  5. * Permission to use, copy, modify, and distribute this software for any
  6. * purpose with or without fee is hereby granted, provided that the above
  7. * copyright notice and this permission notice appear in all copies.
  8. *
  9. * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
  10. * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  11. * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
  12. * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  13. * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  14. * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  15. * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  16. */
  17. #include <sys/types.h>
  18. #include <sys/param.h>
  19. #include <uvm/uvm_extern.h>
  20. /*
  21. * The POISON is used as known text to copy into free objects so
  22. * that modifications after frees can be detected.
  23. */
  24. #ifdef DEADBEEF0
  25. #define POISON0 ((unsigned) DEADBEEF0)
  26. #else
  27. #define POISON0 ((unsigned) 0xdeadbeef)
  28. #endif
  29. #ifdef DEADBEEF1
  30. #define POISON1 ((unsigned) DEADBEEF1)
  31. #else
  32. #define POISON1 ((unsigned) 0xdeafbead)
  33. #endif
  34. #define POISON_SIZE 64
  35. uint32_t
  36. poison_value(void *v)
  37. {
  38. ulong l = (u_long)v;
  39. l = l >> PAGE_SHIFT;
  40. switch (l & 3) {
  41. case 0:
  42. return POISON0;
  43. case 1:
  44. return POISON1;
  45. case 2:
  46. return (POISON0 & 0xffff0000) | (~POISON0 & 0x0000ffff);
  47. case 3:
  48. return (POISON1 & 0xffff0000) | (~POISON1 & 0x0000ffff);
  49. }
  50. return 0;
  51. }
  52. void
  53. poison_mem(void *v, size_t len)
  54. {
  55. uint32_t *ip = v;
  56. size_t i;
  57. uint32_t poison;
  58. poison = poison_value(v);
  59. if (len > POISON_SIZE)
  60. len = POISON_SIZE;
  61. len = len / sizeof(*ip);
  62. for (i = 0; i < len; i++)
  63. ip[i] = poison;
  64. }
  65. int
  66. poison_check(void *v, size_t len, size_t *pidx, uint32_t *pval)
  67. {
  68. uint32_t *ip = v;
  69. size_t i;
  70. uint32_t poison;
  71. poison = poison_value(v);
  72. if (len > POISON_SIZE)
  73. len = POISON_SIZE;
  74. len = len / sizeof(*ip);
  75. for (i = 0; i < len; i++) {
  76. if (ip[i] != poison) {
  77. *pidx = i;
  78. *pval = poison;
  79. return 1;
  80. }
  81. }
  82. return 0;
  83. }