source: trunk/src/sh_mem.c@ 145

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

Fix some more queer compile problems.

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