source: trunk/src/sh_mem.c @ 138

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

More fixes for compile and runtime errors.

File size: 11.8 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#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
33#define SH_REAL_SET
34
35#include "samhain.h"
36#include "sh_error.h"
37#include "sh_utils.h"
38#include "sh_mem.h"
39#include "sh_pthread.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 HAVE_PTHREAD
106
107SH_MUTEX_RECURSIVE(mutex_mem);
108
109#else
110#define MEM_MUTEX_INIT ((void)0)
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          /*
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;
345          (void) safe_logger(0, 0, NULL);
346          /*
347          sh_error_handle ((-1), FIL__, __LINE__, 0, MSG_E_MMEM,
348                           file, line);
349          */
350          eblock = 0;
351        }
352      _exit(42);
353    }
354  else
355    {
356      /* make list entry */
357
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);
363
364      this->next = memlist;
365      memlist = this;
366    }
367
368  SH_MUTEX_RECURSIVE_UNLOCK(mutex_mem);
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
381  SH_MUTEX_RECURSIVE_INIT(mutex_mem);
382  SH_MUTEX_RECURSIVE_LOCK(mutex_mem);
383  if ( a == NULL ) 
384    {
385      sh_error_handle ((-1), FIL__, __LINE__, 0, MSG_E_MNULL,
386                       file, line);
387      goto out;
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);
404      goto out;
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;
453 out:
454  SH_MUTEX_RECURSIVE_UNLOCK(mutex_mem);
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;
488          (void) safe_logger(0, 0, NULL);
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.