memory.c 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. /*
  2. * PuTTY's memory allocation wrappers.
  3. */
  4. #include <assert.h>
  5. #include <stdlib.h>
  6. #include <limits.h>
  7. #include "defs.h"
  8. #include "puttymem.h"
  9. #include "misc.h"
  10. void *safemalloc(size_t factor1, size_t factor2, size_t addend)
  11. {
  12. if (factor1 > SIZE_MAX / factor2)
  13. goto fail;
  14. size_t product = factor1 * factor2;
  15. if (addend > SIZE_MAX)
  16. goto fail;
  17. if (product > SIZE_MAX - addend)
  18. goto fail;
  19. size_t size = product + addend;
  20. if (size == 0)
  21. size = 1;
  22. void *p;
  23. #ifdef MINEFIELD
  24. p = minefield_c_malloc(size);
  25. #else
  26. p = malloc(size);
  27. #endif
  28. if (!p)
  29. goto fail;
  30. return p;
  31. fail:
  32. out_of_memory();
  33. }
  34. void *saferealloc(void *ptr, size_t n, size_t size)
  35. {
  36. void *p;
  37. if (n > INT_MAX / size) {
  38. p = NULL;
  39. } else {
  40. size *= n;
  41. if (!ptr) {
  42. #ifdef MINEFIELD
  43. p = minefield_c_malloc(size);
  44. #else
  45. p = malloc(size);
  46. #endif
  47. } else {
  48. #ifdef MINEFIELD
  49. p = minefield_c_realloc(ptr, size);
  50. #else
  51. p = realloc(ptr, size);
  52. #endif
  53. }
  54. }
  55. if (!p)
  56. out_of_memory();
  57. return p;
  58. }
  59. void safefree(void *ptr)
  60. {
  61. if (ptr) {
  62. #ifdef MINEFIELD
  63. minefield_c_free(ptr);
  64. #else
  65. free(ptr);
  66. #endif
  67. }
  68. }
  69. void *safegrowarray(void *ptr, size_t *allocated, size_t eltsize,
  70. size_t oldlen, size_t extralen, bool secret)
  71. {
  72. /* The largest value we can safely multiply by eltsize */
  73. assert(eltsize > 0);
  74. size_t maxsize = (~(size_t)0) / eltsize;
  75. size_t oldsize = *allocated;
  76. /* Range-check the input values */
  77. assert(oldsize <= maxsize);
  78. assert(oldlen <= maxsize);
  79. assert(extralen <= maxsize - oldlen);
  80. /* If the size is already enough, don't bother doing anything! */
  81. if (oldsize > oldlen + extralen)
  82. return ptr;
  83. /* Find out how much we need to grow the array by. */
  84. size_t increment = (oldlen + extralen) - oldsize;
  85. /* Invent a new size. We want to grow the array by at least
  86. * 'increment' elements; by at least a fixed number of bytes (to
  87. * get things started when sizes are small); and by some constant
  88. * factor of its old size (to avoid repeated calls to this
  89. * function taking quadratic time overall). */
  90. if (increment < 256 / eltsize)
  91. increment = 256 / eltsize;
  92. if (increment < oldsize / 16)
  93. increment = oldsize / 16;
  94. /* But we also can't grow beyond maxsize. */
  95. size_t maxincr = maxsize - oldsize;
  96. if (increment > maxincr)
  97. increment = maxincr;
  98. size_t newsize = oldsize + increment;
  99. void *toret;
  100. if (secret) {
  101. toret = safemalloc(newsize, eltsize, 0);
  102. if (oldsize) {
  103. memcpy(toret, ptr, oldsize * eltsize);
  104. smemclr(ptr, oldsize * eltsize);
  105. sfree(ptr);
  106. }
  107. } else {
  108. toret = saferealloc(ptr, newsize, eltsize);
  109. }
  110. *allocated = newsize;
  111. return toret;
  112. }