source: trunk/src/sh_mem.c@ 138

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

More fixes for compile and runtime errors.

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