source: trunk/src/sh_mem.c@ 137

Last change on this file since 137 was 137, checked in by rainer, 17 years ago

Fix compile errors.

File size: 12.1 KB
RevLine 
[1]1/* SAMHAIN file system integrity testing */
2/* Copyright (C) 1999, 2000 Rainer Wichmann */
3/* */
4/* This program is free software; you can redistribute it */
5/* and/or modify */
6/* it under the terms of the GNU General Public License as */
7/* published by */
8/* the Free Software Foundation; either version 2 of the License, or */
9/* (at your option) any later version. */
10/* */
11/* This program is distributed in the hope that it will be useful, */
12/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
13/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
14/* GNU General Public License for more details. */
15/* */
16/* You should have received a copy of the GNU General Public License */
17/* along with this program; if not, write to the Free Software */
18/* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
19
20#include "config_xor.h"
21
[137]22/* With glibc, _XOPEN_SOURCE 500 is required for
23 * pthread_mutexattr_settype/PTHREAD_MUTEX_RECURSIVE
24 */
25#if defined(HAVE_PTHREAD) && defined(MEM_DEBUG)
26#define _XOPEN_SOURCE 500
27#endif
[1]28
29#include <stdio.h>
30#include <stdlib.h>
31#include <string.h>
32#include <sys/types.h>
33#include <unistd.h>
34
35
36#ifdef HAVE_MEMORY_H
37#include <memory.h>
38#endif
39
[11]40#define SH_REAL_SET
41
[1]42#include "samhain.h"
43#include "sh_error.h"
44#include "sh_utils.h"
45#include "sh_mem.h"
[134]46#include "sh_pthread.h"
[1]47
[22]48extern int safe_logger (int signal, int method, char * details);
[1]49
50#undef FIL__
51#define FIL__ _("sh_mem.c")
52static int eblock = 0;
53
54#ifdef MEM_DEBUG
55
56#define CHECKBYTE 0x7F
57
58/* Memory alignment; should be 16 bytes on 64 bit machines.
59 * -> 32 bytes overhead/allocation
60 */
61#define SH_MEMMULT 16
62
63
64typedef struct mem_struct {
65 struct mem_struct *next; /* link to next struct */
66 char * real_address; /* address assigned */
67 char * address; /* address returned */
68 unsigned long size; /* size allocated */
69 char file[20]; /* Allocation file name */
70 int line; /* Allocation line number */
71} memlist_t;
72
73memlist_t * memlist = NULL;
74
75int Free_Count = 0, Alloc_Count = 0;
76int Now_Alloc_Count = 0, Max_Alloc_Count = 0;
77unsigned long Mem_Current = 0, Mem_Max = 0;
78
79#if 0
80#define MEM_DETAILS
81#endif
82
83#ifdef MEM_DETAILS
84int max_upto_032 = 0;
85int max_upto_064 = 0;
86int max_upto_128 = 0;
87int max_upto_256 = 0;
88int max_upto_512 = 0;
89int max_upto_1024 = 0;
90int max_upto_4096 = 0;
91int max_upto_inf = 0;
92
93int now_upto_032 = 0;
94int now_upto_064 = 0;
95int now_upto_128 = 0;
96int now_upto_256 = 0;
97int now_upto_512 = 0;
98int now_upto_1024 = 0;
99int now_upto_4096 = 0;
100int now_upto_inf = 0;
101
102int tot_upto_032 = 0;
103int tot_upto_064 = 0;
104int tot_upto_128 = 0;
105int tot_upto_256 = 0;
106int tot_upto_512 = 0;
107int tot_upto_1024 = 0;
108int tot_upto_4096 = 0;
109int tot_upto_inf = 0;
110#endif
111
[134]112#ifdef HAVE_PTHREAD
113static pthread_once_t mem_is_initialized = PTHREAD_ONCE_INIT;
114static pthread_mutex_t mutex_mem;
115
[137]116static void initialize_mem(void)
[134]117{
118 pthread_mutexattr_t mta;
119 pthread_mutexattr_settype(&mta, PTHREAD_MUTEX_RECURSIVE);
120 pthread_mutex_init(&mutex_mem, &mta);
121 pthread_mutexattr_destroy(&mta);
[137]122 return;
[134]123}
124#define MEM_MUTEX_INIT (void) pthread_once(&mem_is_initialized, initialize_mem)
125#else
126#define MEM_MUTEX_INIT ((void)0)
127#endif
128
[1]129#ifdef MEM_LOG
130void sh_mem_dump ()
131{
132 memlist_t * this = memlist;
133
134
[134]135 FILE * fd;
[1]136
[134]137 MEM_MUTEX_INIT;
138 SH_MUTEX_LOCK(mutex_mem);
139
140 fd = fopen(MEM_LOG, "w");
141
[1]142 while (this != NULL)
143 {
144 fprintf (fd, "%20s %5d %ld\n", this->file, this->line, this->size);
145 this = this->next;
146 }
147 fclose(fd);
[134]148 SH_MUTEX_UNLOCK(mutex_mem);
[1]149 return;
150}
151#else
152void sh_mem_dump ()
153{
154 return;
155}
156#endif
157
158void sh_mem_stat ()
159{
160 memlist_t * this;
161
162
163 SL_ENTER(_("sh_mem_stat"));
164
[134]165 MEM_MUTEX_INIT;
166 SH_MUTEX_LOCK(mutex_mem);
167
[1]168 if (Alloc_Count == Free_Count)
169 {
170 sh_error_handle ((-1), FIL__, __LINE__, 0, MSG_MSTAMP,
171 Mem_Max, Mem_Current);
[134]172 goto out;
[1]173 }
174
175 sh_error_handle (SH_ERR_INFO, FIL__, __LINE__, 0, MSG_MSTAMP2,
176 Alloc_Count, Free_Count, Max_Alloc_Count);
177 sh_error_handle (SH_ERR_INFO, FIL__, __LINE__, 0, MSG_MSTAMP,
178 Mem_Max, Mem_Current);
179
180#ifdef MEM_DETAILS
181 fprintf(stderr, "\n");
182 fprintf(stderr, "__SIZE_____TOTAL___MAXIMUM___\n");
183 fprintf(stderr, " 32 %6d %6d\n", tot_upto_032, max_upto_032);
184 fprintf(stderr, " 64 %6d %6d\n", tot_upto_064, max_upto_064);
185 fprintf(stderr, " 128 %6d %6d\n", tot_upto_128, max_upto_128);
186 fprintf(stderr, " 256 %6d %6d\n", tot_upto_256, max_upto_256);
187 fprintf(stderr, " 512 %6d %6d\n", tot_upto_512, max_upto_512);
188 fprintf(stderr, " 1024 %6d %6d\n", tot_upto_1024, max_upto_1024);
189 fprintf(stderr, " 4096 %6d %6d\n", tot_upto_4096, max_upto_4096);
190 fprintf(stderr, " inf %6d %6d\n", tot_upto_inf, max_upto_inf);
191 fprintf(stderr, "\n");
192#endif
193
194 this = memlist;
195
196 while (this != NULL)
197 {
198 sh_error_handle (SH_ERR_WARN, FIL__, __LINE__, 0, MSG_E_NOTFREE,
199 this->size, this->file, this->line);
200 this = this->next;
201 }
[134]202 out:
203 SH_MUTEX_UNLOCK(mutex_mem);
[1]204 SL_RET0(_("sh_mem_stat"));
205}
206
207void sh_mem_check ()
208{
209 memlist_t * this;
210 long nerr = 0;
211
212 SL_ENTER(_("sh_mem_check"));
213
[134]214 MEM_MUTEX_INIT;
215 SH_MUTEX_LOCK(mutex_mem);
[1]216 sh_error_handle ((-1), FIL__, __LINE__, 0, MSG_MSTAMP,
217 Mem_Max, Mem_Current);
218
219 this = memlist;
220
221 while (this != NULL)
222 {
223 if ( this->address == NULL )
224 {
225 sh_error_handle ((-1), FIL__, __LINE__, 0, MSG_E_MNULL);
226 ++nerr;
227 }
228 else
229 {
230 if ( this->address[this->size] != CHECKBYTE )
231 {
232 sh_error_handle ((-1), FIL__, __LINE__, 0, MSG_E_MOVER,
233 this->file, this->line, FIL__, __LINE__);
234 ++nerr;
235 }
236 if ( this->real_address[SH_MEMMULT-1] != CHECKBYTE )
237 {
238 sh_error_handle ((-1), FIL__, __LINE__, 0, MSG_E_MUNDER,
239 this->file, this->line, FIL__, __LINE__);
240 ++nerr;
241 }
242 }
243 this = this->next;
244 }
245
246 /* if (nerr > 0) abort(); */
247
[134]248 SH_MUTEX_UNLOCK(mutex_mem);
[1]249 SL_RET0(_("sh_mem_check"));
250}
251
252void * sh_mem_malloc (size_t size, char * file, int line)
253{
254 void * the_realAddress;
255 void * theAddress;
256 memlist_t * this;
257
258 SL_ENTER(_("sh_mem_malloc"));
259
[134]260 MEM_MUTEX_INIT;
261 SH_MUTEX_LOCK(mutex_mem);
[1]262 the_realAddress = malloc(size + 2 * SH_MEMMULT);
263
264 if ( the_realAddress == NULL )
265 {
266 if (eblock == 0)
267 {
268 eblock = 1;
[22]269 (void) safe_logger (0, 0, NULL);
[1]270 /*
271 sh_error_handle ((-1), FIL__, __LINE__, 0, MSG_E_MMEM,
272 file, line);
273 */
274 eblock = 0;
275 }
276 /* use _exit() rather than exit() - we malloc() in atexit() functions
277 */
278 _exit (42);
279 }
280
281 /* --- Set check bytes. ---
282 */
283 theAddress = ((char *) the_realAddress + SH_MEMMULT);
284
285 memset(the_realAddress, CHECKBYTE, SH_MEMMULT);
286 memset(theAddress, CHECKBYTE, size + 1);
287 memset(theAddress, 0, 1);
288
289 ++Alloc_Count;
290 ++Now_Alloc_Count;
291
292 if (Max_Alloc_Count < Now_Alloc_Count)
293 Max_Alloc_Count = Now_Alloc_Count;
294
295#ifdef MEM_DETAILS
296 if (size <= 32)
297 {
298 ++now_upto_032;
299 ++tot_upto_032;
300 if (now_upto_032 > max_upto_032) max_upto_032 = now_upto_032;
301 }
302 else if (size <= 64)
303 {
304 ++now_upto_064;
305 ++tot_upto_064;
306 if (now_upto_064 > max_upto_064) max_upto_064 = now_upto_064;
307 }
308 else if (size <= 128)
309 {
310 ++now_upto_128;
311 ++tot_upto_128;
312 if (now_upto_128 > max_upto_128) max_upto_128 = now_upto_128;
313 }
314 else if (size <= 256)
315 {
316 ++now_upto_256;
317 ++tot_upto_256;
318 if (now_upto_256 > max_upto_256) max_upto_256 = now_upto_256;
319 }
320 else if (size <= 512)
321 {
322 ++now_upto_512;
323 ++tot_upto_512;
324 if (now_upto_512 > max_upto_512) max_upto_512 = now_upto_512;
325 }
326 else if (size <= 1024)
327 {
328 ++now_upto_1024;
329 ++tot_upto_1024;
330 if (now_upto_1024 > max_upto_1024) max_upto_1024 = now_upto_1024;
331 }
332 else if (size <= 4096)
333 {
334 ++now_upto_4096;
335 ++tot_upto_4096;
336 if (now_upto_4096 > max_upto_4096) max_upto_4096 = now_upto_4096;
337 }
338 else
339 {
340 ++now_upto_inf;
341 ++tot_upto_inf;
342 if (now_upto_inf > max_upto_inf) max_upto_inf = now_upto_inf;
343
344 fprintf(stderr, "\n___BIGSIZE___");
345 fprintf(stderr, " %6d -> %16s %10d \n", size, file, line);
346 fprintf(stderr, "\n");
347
348 }
349#endif
350
351 Mem_Current += size;
352 Mem_Max = ( (Mem_Current > Mem_Max) ? Mem_Current : Mem_Max);
353
354 this = (memlist_t *) malloc (sizeof(memlist_t));
355
356 if ( this == NULL)
357 {
358 if (eblock == 0)
359 {
360 eblock = 1;
[22]361 (void) safe_logger(0, 0, NULL);
[1]362 /*
363 sh_error_handle ((-1), FIL__, __LINE__, 0, MSG_E_MMEM,
364 file, line);
365 */
366 eblock = 0;
367 }
[134]368 _exit(42);
[1]369 }
370
371 /* make list entry */
372
373 this->real_address = the_realAddress;
374 this->address = theAddress;
375 this->size = size;
376 this->line = line;
377 sl_strlcpy(this->file, file, 20);
378
379 this->next = memlist;
380 memlist = this;
381
[134]382 SH_MUTEX_UNLOCK(mutex_mem);
[1]383 SL_RETURN( theAddress, _("sh_mem_malloc"));
384}
385
386
387void sh_mem_free (void * a, char * file, int line)
388{
389 memlist_t * this = memlist;
390 memlist_t * before = memlist;
391 unsigned long size = 0;
392
393 SL_ENTER(_("sh_mem_free"));
394
[134]395 MEM_MUTEX_INIT;
396 SH_MUTEX_LOCK(mutex_mem);
[1]397 if ( a == NULL )
398 {
399 sh_error_handle ((-1), FIL__, __LINE__, 0, MSG_E_MNULL,
400 file, line);
[134]401 goto out;
[1]402 }
403
404 /* -- Find record. --
405 */
406 while (this != NULL)
407 {
408 if (this->address == a)
409 break;
410 before = this;
411 this = this->next;
412 }
413
414 if (this == NULL)
415 {
416 sh_error_handle ((-1), FIL__, __LINE__, 0, MSG_E_MREC,
417 file, line);
[134]418 goto out;
[1]419 }
420 else
421 {
422 a = this->real_address;
423
424 if ( this->address[this->size] != CHECKBYTE )
425 {
426 sh_error_handle ((-1), FIL__, __LINE__, 0, MSG_E_MOVER,
427 this->file, this->line, file, line);
428 }
429 if ( this->real_address[SH_MEMMULT-1] != CHECKBYTE )
430 sh_error_handle ((-1), FIL__, __LINE__, 0, MSG_E_MUNDER,
431 this->file, this->line, file, line);
432
433 size = this->size;
434
435 if (this == memlist)
436 memlist = this->next;
437 else
438 before->next = this->next;
439 }
440
441 free(a);
442 if (this)
443 free(this);
444 ++Free_Count;
445 --Now_Alloc_Count;
446
447#ifdef MEM_DETAILS
448 if (size <= 32)
449 --now_upto_032;
450 else if (size <= 64)
451 --now_upto_064;
452 else if (size <= 128)
453 --now_upto_128;
454 else if (size <= 256)
455 --now_upto_256;
456 else if (size <= 512)
457 --now_upto_512;
458 else if (size <= 1024)
459 --now_upto_1024;
460 else if (size <= 4096)
461 --now_upto_4096;
462 else
463 --now_upto_inf;
464#endif
465
466 Mem_Current -= size;
[134]467 out:
468 SH_MUTEX_UNLOCK(mutex_mem);
[1]469 SL_RET0(_("sh_mem_free"));
470}
471
472#else
473
474void sh_mem_free (void * a)
475{
476 SL_ENTER(_("sh_mem_free"));
477
478 if (a)
479 {
480 free(a);
481 }
482 else
483 {
484 sh_error_handle ((-1), FIL__, __LINE__, 0, MSG_E_MNULL);
485 }
486 SL_RET0(_("sh_mem_free"));
487}
488
489void * sh_mem_malloc (size_t size)
490{
491 void * theAddress;
492
493 SL_ENTER(_("sh_mem_malloc"));
494
495 theAddress = malloc(size);
496
497 if ( theAddress == NULL )
498 {
499 if (eblock == 0)
500 {
501 eblock = 1;
[22]502 (void) safe_logger(0, 0, NULL);
[1]503 /*
504 sh_error_handle ((-1), FIL__, __LINE__, 0, MSG_E_MMEM);
505 */
506 eblock = 0;
507 }
508 /* use _exit() rather than exit() - we malloc() in atexit()
509 */
510 _exit (42);
511 }
512 /* memset (theAddress, 0, 1); *//* needs testing */
513
514 SL_RETURN( theAddress, _("sh_mem_malloc"));
515}
516#endif
Note: See TracBrowser for help on using the repository browser.