malloc.c 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244
  1. /*
  2. voltlogger_oscilloscope
  3. Copyright (C) 2015 Dmitry Yu Okunev <dyokunev@ut.mephi.ru> 0x8E30679C
  4. This program is free software: you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published by
  6. the Free Software Foundation, either version 3 of the License, or
  7. (at your option) any later version.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with this program. If not, see <http://www.gnu.org/licenses/>.
  14. */
  15. #include "macros.h"
  16. #include "configuration.h"
  17. #include <stdlib.h>
  18. #include <string.h>
  19. #ifdef CAPABILITIES_SUPPORT
  20. # include <unistd.h>
  21. # include <sys/mman.h>
  22. # ifdef SECCOMP_SUPPORT
  23. # include <sys/stat.h>
  24. # include <fcntl.h>
  25. # endif
  26. #endif
  27. #include <sys/ipc.h> // shmget()
  28. #include <sys/shm.h> // shmget()
  29. #include "malloc.h"
  30. #include "error.h"
  31. #include "configuration.h"
  32. #ifdef CAPABILITIES_SUPPORT
  33. long pagesize;
  34. # ifdef SECCOMP_SUPPORT
  35. int devzero_fd;
  36. # endif
  37. #endif
  38. void *xmalloc(size_t size) {
  39. debug(20, "(%li)", size);
  40. #ifdef PARANOID
  41. size++; // Just in case
  42. #endif
  43. void *ret = malloc(size);
  44. if (ret == NULL)
  45. critical("(%li): Cannot allocate memory.", size);
  46. #ifdef PARANOID
  47. memset(ret, 0, size);
  48. #endif
  49. return ret;
  50. }
  51. void *xcalloc(size_t nmemb, size_t size) {
  52. debug(20, "(%li, %li)", nmemb, size);
  53. #ifdef PARANOID
  54. nmemb++; // Just in case
  55. size++; // Just in case
  56. #endif
  57. void *ret = calloc(nmemb, size);
  58. if (ret == NULL)
  59. critical("(%li): Cannot allocate memory.", size);
  60. // memset(ret, 0, nmemb*size); // Just in case
  61. return ret;
  62. }
  63. void *xrealloc(void *oldptr, size_t size) {
  64. debug(20, "(%p, %li)", oldptr, size);
  65. #ifdef PARANOID
  66. size++; // Just in case
  67. #endif
  68. void *ret = realloc(oldptr, size);
  69. if (ret == NULL)
  70. critical("(%p, %li): Cannot reallocate memory.", oldptr, size);
  71. return ret;
  72. }
  73. #ifdef CAPABILITIES_SUPPORT
  74. void *malloc_align(size_t size) {
  75. size_t total_size;
  76. void *ret = NULL;
  77. debug(20, "(%li)", size);
  78. # ifdef PARANOID
  79. size++; // Just in case
  80. # endif
  81. total_size = size;
  82. # ifdef PARANOID
  83. total_size += pagesize-1;
  84. total_size /= pagesize;
  85. total_size *= pagesize;
  86. # endif
  87. if (posix_memalign(&ret, pagesize, total_size))
  88. critical("(%li): Cannot allocate memory.", size);
  89. # ifdef PARANOID
  90. if (ret == NULL)
  91. critical("(%li): ptr == NULL.", size);
  92. # endif
  93. // memset(ret, 0, nmemb*size); // Just in case
  94. return ret;
  95. }
  96. void *calloc_align(size_t nmemb, size_t size) {
  97. size_t total_size;
  98. void *ret;
  99. debug(20, "(%li, %li)", nmemb, size);
  100. # ifdef PARANOID
  101. nmemb++; // Just in case
  102. size++; // Just in case
  103. # endif
  104. total_size = nmemb*size;
  105. ret = malloc_align(total_size);
  106. memset(ret, 0, total_size);
  107. return ret;
  108. }
  109. char *strdup_protect(const char *src, int prot) {
  110. size_t len = strlen(src);
  111. char *dst = malloc_align(len);
  112. strcpy(dst, src);
  113. if (mprotect(dst, len, prot))
  114. critical("(%p, 0x%o): Got error from mprotect(%p, %lu, 0x%o)", src, prot, dst, len, prot);
  115. return dst;
  116. }
  117. # ifdef SECCOMP_SUPPORT
  118. int is_protected(void *addr) {
  119. char *_addr = addr, t;
  120. int is_protected;
  121. t = *_addr;
  122. is_protected = (read(devzero_fd, addr, 1) == -1);
  123. if (!is_protected)
  124. *_addr = t;
  125. return is_protected;
  126. }
  127. # endif
  128. #endif
  129. int memory_init() {
  130. #ifdef CAPABILITIES_SUPPORT
  131. pagesize = sysconf(_SC_PAGE_SIZE);
  132. if (pagesize == -1)
  133. critical("Got error from sysconf(_SC_PAGE_SIZE)");
  134. # ifdef SECCOMP_SUPPORT
  135. devzero_fd = open(DEVZERO, O_RDONLY);
  136. if (devzero_fd == -1)
  137. critical("Got error while open(\""DEVZERO"\", O_RDONLY)");
  138. # endif
  139. #endif
  140. return 0;
  141. }
  142. void *shm_malloc_try(size_t size) {
  143. void *ret;
  144. #ifdef PARANOID
  145. size++;
  146. #endif
  147. int privileged_shmid = shmget(0, size, IPC_PRIVATE|IPC_CREAT|0600);
  148. struct shmid_ds shmid_ds;
  149. if (privileged_shmid == -1) return NULL;
  150. ret = shmat(privileged_shmid, NULL, 0);
  151. if ((long)ret == -1) return NULL;
  152. debug(15, "ret == %p", ret);
  153. // Forbidding access for others to the pointer
  154. shmctl(privileged_shmid, IPC_STAT, &shmid_ds);
  155. shmid_ds.shm_perm.mode = 0;
  156. shmctl(privileged_shmid, IPC_SET, &shmid_ds);
  157. // Checking that nobody else attached to the shared memory before access forbidding
  158. shmctl(privileged_shmid, IPC_STAT, &shmid_ds);
  159. if (shmid_ds.shm_lpid != shmid_ds.shm_cpid) {
  160. error("A process (pid %u) attached to my shared memory. It's a security problem. Emergency exit.");
  161. shmdt (ret);
  162. return NULL;
  163. }
  164. return ret;
  165. }
  166. void *shm_malloc(size_t size) {
  167. void *ret;
  168. ret = shm_malloc_try(size);
  169. critical_on (ret == NULL);
  170. return ret;
  171. }
  172. void *shm_calloc(size_t nmemb, size_t size) {
  173. void *ret;
  174. size_t total_size;
  175. #ifdef PARANOID
  176. nmemb++;
  177. size++;
  178. #endif
  179. total_size = nmemb * size;
  180. ret = shm_malloc(total_size);
  181. critical_on (ret == NULL);
  182. memset(ret, 0, total_size);
  183. return ret;
  184. }
  185. void shm_free(void *ptr) {
  186. debug(25, "(%p)", ptr);
  187. shmdt(ptr);
  188. }