source: branches/samhain-2_2-branch/src/sh_mem.c@ 541

Last change on this file since 541 was 22, checked in by rainer, 19 years ago

Minor code revisions.

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