source: trunk/src/sh_mem.c@ 143

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

Bugfixes and threaded process check.

File size: 11.6 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 SH_MUTEX_RECURSIVE_UNLOCK(mutex_mem);
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
198 SH_MUTEX_RECURSIVE_INIT(mutex_mem);
199 SH_MUTEX_RECURSIVE_LOCK(mutex_mem);
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
232 SH_MUTEX_RECURSIVE_UNLOCK(mutex_mem);
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
244 SH_MUTEX_RECURSIVE_INIT(mutex_mem);
245 SH_MUTEX_RECURSIVE_LOCK(mutex_mem);
246 the_realAddress = malloc(size + 2 * SH_MEMMULT);
247
248 if ( the_realAddress == NULL )
249 {
250 if (eblock == 0)
251 {
252 eblock = 1;
253 (void) safe_logger (0, 0, NULL);
254 eblock = 0;
255 }
256 /* use _exit() rather than exit() - we malloc() in atexit() functions
257 */
258 _exit (42);
259 }
260
261 /* --- Set check bytes. ---
262 */
263 theAddress = ((char *) the_realAddress + SH_MEMMULT);
264
265 memset(the_realAddress, CHECKBYTE, SH_MEMMULT);
266 memset(theAddress, CHECKBYTE, size + 1);
267 memset(theAddress, 0, 1);
268
269 ++Alloc_Count;
270 ++Now_Alloc_Count;
271
272 if (Max_Alloc_Count < Now_Alloc_Count)
273 Max_Alloc_Count = Now_Alloc_Count;
274
275#ifdef MEM_DETAILS
276 if (size <= 32)
277 {
278 ++now_upto_032;
279 ++tot_upto_032;
280 if (now_upto_032 > max_upto_032) max_upto_032 = now_upto_032;
281 }
282 else if (size <= 64)
283 {
284 ++now_upto_064;
285 ++tot_upto_064;
286 if (now_upto_064 > max_upto_064) max_upto_064 = now_upto_064;
287 }
288 else if (size <= 128)
289 {
290 ++now_upto_128;
291 ++tot_upto_128;
292 if (now_upto_128 > max_upto_128) max_upto_128 = now_upto_128;
293 }
294 else if (size <= 256)
295 {
296 ++now_upto_256;
297 ++tot_upto_256;
298 if (now_upto_256 > max_upto_256) max_upto_256 = now_upto_256;
299 }
300 else if (size <= 512)
301 {
302 ++now_upto_512;
303 ++tot_upto_512;
304 if (now_upto_512 > max_upto_512) max_upto_512 = now_upto_512;
305 }
306 else if (size <= 1024)
307 {
308 ++now_upto_1024;
309 ++tot_upto_1024;
310 if (now_upto_1024 > max_upto_1024) max_upto_1024 = now_upto_1024;
311 }
312 else if (size <= 4096)
313 {
314 ++now_upto_4096;
315 ++tot_upto_4096;
316 if (now_upto_4096 > max_upto_4096) max_upto_4096 = now_upto_4096;
317 }
318 else
319 {
320 ++now_upto_inf;
321 ++tot_upto_inf;
322 if (now_upto_inf > max_upto_inf) max_upto_inf = now_upto_inf;
323
324 fprintf(stderr, "\n___BIGSIZE___");
325 fprintf(stderr, " %6d -> %16s %10d \n", size, file, line);
326 fprintf(stderr, "\n");
327
328 }
329#endif
330
331 Mem_Current += size;
332 Mem_Max = ( (Mem_Current > Mem_Max) ? Mem_Current : Mem_Max);
333
334 this = (memlist_t *) malloc (sizeof(memlist_t));
335
336 if ( this == NULL)
337 {
338 if (eblock == 0)
339 {
340 eblock = 1;
341 (void) safe_logger(0, 0, NULL);
342 eblock = 0;
343 }
344 _exit(42);
345 }
346 else
347 {
348 /* make list entry */
349
350 this->real_address = the_realAddress;
351 this->address = theAddress;
352 this->size = size;
353 this->line = line;
354 sl_strlcpy(this->file, file, 20);
355
356 this->next = memlist;
357 memlist = this;
358 }
359
360 SH_MUTEX_RECURSIVE_UNLOCK(mutex_mem);
361 SL_RETURN( theAddress, _("sh_mem_malloc"));
362}
363
364
365void sh_mem_free (void * a, char * file, int line)
366{
367 memlist_t * this = memlist;
368 memlist_t * before = memlist;
369 unsigned long size = 0;
370
371 SL_ENTER(_("sh_mem_free"));
372
373 SH_MUTEX_RECURSIVE_INIT(mutex_mem);
374 SH_MUTEX_RECURSIVE_LOCK(mutex_mem);
375 if ( a == NULL )
376 {
377 sh_error_handle ((-1), FIL__, __LINE__, 0, MSG_E_MNULL,
378 file, line);
379 goto out;
380 }
381
382 /* -- Find record. --
383 */
384 while (this != NULL)
385 {
386 if (this->address == a)
387 break;
388 before = this;
389 this = this->next;
390 }
391
392 if (this == NULL)
393 {
394 sh_error_handle ((-1), FIL__, __LINE__, 0, MSG_E_MREC,
395 file, line);
396 goto out;
397 }
398 else
399 {
400 a = this->real_address;
401
402 if ( this->address[this->size] != CHECKBYTE )
403 {
404 sh_error_handle ((-1), FIL__, __LINE__, 0, MSG_E_MOVER,
405 this->file, this->line, file, line);
406 }
407 if ( this->real_address[SH_MEMMULT-1] != CHECKBYTE )
408 sh_error_handle ((-1), FIL__, __LINE__, 0, MSG_E_MUNDER,
409 this->file, this->line, file, line);
410
411 size = this->size;
412
413 if (this == memlist)
414 memlist = this->next;
415 else
416 before->next = this->next;
417 }
418
419 free(a);
420 if (this)
421 free(this);
422 ++Free_Count;
423 --Now_Alloc_Count;
424
425#ifdef MEM_DETAILS
426 if (size <= 32)
427 --now_upto_032;
428 else if (size <= 64)
429 --now_upto_064;
430 else if (size <= 128)
431 --now_upto_128;
432 else if (size <= 256)
433 --now_upto_256;
434 else if (size <= 512)
435 --now_upto_512;
436 else if (size <= 1024)
437 --now_upto_1024;
438 else if (size <= 4096)
439 --now_upto_4096;
440 else
441 --now_upto_inf;
442#endif
443
444 Mem_Current -= size;
445 out:
446 SH_MUTEX_RECURSIVE_UNLOCK(mutex_mem);
447 SL_RET0(_("sh_mem_free"));
448}
449
450#else
451
452void sh_mem_free (void * a)
453{
454 SL_ENTER(_("sh_mem_free"));
455
456 if (a)
457 {
458 free(a);
459 }
460 else
461 {
462 sh_error_handle ((-1), FIL__, __LINE__, 0, MSG_E_MNULL);
463 }
464 SL_RET0(_("sh_mem_free"));
465}
466
467void * sh_mem_malloc (size_t size)
468{
469 void * theAddress;
470
471 SL_ENTER(_("sh_mem_malloc"));
472
473 theAddress = malloc(size);
474
475 if ( theAddress == NULL )
476 {
477 if (eblock == 0)
478 {
479 eblock = 1;
480 (void) safe_logger(0, 0, NULL);
481 eblock = 0;
482 }
483 /* use _exit() rather than exit() - we malloc() in atexit()
484 */
485 _exit (42);
486 }
487 /* memset (theAddress, 0, 1); *//* needs testing */
488
489 SL_RETURN( theAddress, _("sh_mem_malloc"));
490}
491#endif
Note: See TracBrowser for help on using the repository browser.