source: trunk/src/sh_mem.c@ 256

Last change on this file since 256 was 256, checked in by katerina, 15 years ago

Evaluated glob patterns at each check (ticket #173).

File size: 8.6 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
[139]22#if defined(HAVE_PTHREAD_MUTEX_RECURSIVE)
23#define _XOPEN_SOURCE 500
24#endif
25
[1]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
[11]37#define SH_REAL_SET
38
[1]39#include "samhain.h"
40#include "sh_error.h"
41#include "sh_utils.h"
42#include "sh_mem.h"
[134]43#include "sh_pthread.h"
[1]44
[170]45extern int safe_logger (int thesignal, int method, char * details);
[1]46
47#undef FIL__
48#define FIL__ _("sh_mem.c")
49
50#ifdef MEM_DEBUG
51
52#define CHECKBYTE 0x7F
53
54/* Memory alignment; should be 16 bytes on 64 bit machines.
55 * -> 32 bytes overhead/allocation
56 */
57#define SH_MEMMULT 16
58
59
60typedef struct mem_struct {
61 struct mem_struct *next; /* link to next struct */
62 char * real_address; /* address assigned */
63 char * address; /* address returned */
64 unsigned long size; /* size allocated */
65 char file[20]; /* Allocation file name */
66 int line; /* Allocation line number */
67} memlist_t;
68
69memlist_t * memlist = NULL;
70
71int Free_Count = 0, Alloc_Count = 0;
72int Now_Alloc_Count = 0, Max_Alloc_Count = 0;
73unsigned long Mem_Current = 0, Mem_Max = 0;
74
[134]75#ifdef HAVE_PTHREAD
[138]76SH_MUTEX_RECURSIVE(mutex_mem);
[134]77#endif
78
[149]79/* define MEM_LOG to an absolute filename to enable this */
[1]80#ifdef MEM_LOG
81void sh_mem_dump ()
82{
83 memlist_t * this = memlist;
[134]84 FILE * fd;
[1]85
[138]86 SH_MUTEX_RECURSIVE_INIT(mutex_mem);
87 SH_MUTEX_RECURSIVE_LOCK(mutex_mem);
[134]88
89 fd = fopen(MEM_LOG, "w");
[149]90 if (!fd)
91 {
92 perror(MEM_LOG);
93 _exit(EXIT_FAILURE);
94 }
[134]95
[1]96 while (this != NULL)
97 {
[149]98 fprintf (fd, "## %20s %5d %ld\n", this->file, this->line, this->size);
99 fprintf (fd, "%10p %8ld\n", (void *)this->address, this->size);
[1]100 this = this->next;
101 }
[252]102 sl_fclose(FIL__, __LINE__, fd);
[149]103
[138]104 SH_MUTEX_RECURSIVE_UNLOCK(mutex_mem);
[149]105 _exit(EXIT_SUCCESS);
[1]106}
107#else
108void sh_mem_dump ()
109{
110 return;
111}
112#endif
113
114void sh_mem_stat ()
115{
116 memlist_t * this;
117
118
119 SL_ENTER(_("sh_mem_stat"));
120
[134]121
[1]122 if (Alloc_Count == Free_Count)
123 {
124 sh_error_handle ((-1), FIL__, __LINE__, 0, MSG_MSTAMP,
125 Mem_Max, Mem_Current);
[256]126 SL_RET0(_("sh_mem_stat"));
[1]127 }
128
129 sh_error_handle (SH_ERR_INFO, FIL__, __LINE__, 0, MSG_MSTAMP2,
130 Alloc_Count, Free_Count, Max_Alloc_Count);
131 sh_error_handle (SH_ERR_INFO, FIL__, __LINE__, 0, MSG_MSTAMP,
132 Mem_Max, Mem_Current);
133
[256]134 SH_MUTEX_RECURSIVE_INIT(mutex_mem);
135 SH_MUTEX_RECURSIVE_LOCK(mutex_mem);
136
[1]137 this = memlist;
138
139 while (this != NULL)
140 {
141 sh_error_handle (SH_ERR_WARN, FIL__, __LINE__, 0, MSG_E_NOTFREE,
142 this->size, this->file, this->line);
143 this = this->next;
144 }
[256]145
[138]146 SH_MUTEX_RECURSIVE_UNLOCK(mutex_mem);
[1]147 SL_RET0(_("sh_mem_stat"));
148}
149
150void sh_mem_check ()
151{
152 memlist_t * this;
153 long nerr = 0;
154
155 SL_ENTER(_("sh_mem_check"));
156
[256]157 sh_error_handle ((-1), FIL__, __LINE__, 0, MSG_MSTAMP,
158 Mem_Max, Mem_Current);
159
[138]160 SH_MUTEX_RECURSIVE_INIT(mutex_mem);
161 SH_MUTEX_RECURSIVE_LOCK(mutex_mem);
[149]162
[1]163 this = memlist;
164
165 while (this != NULL)
166 {
167 if ( this->address == NULL )
168 {
169 sh_error_handle ((-1), FIL__, __LINE__, 0, MSG_E_MNULL);
170 ++nerr;
171 }
172 else
173 {
174 if ( this->address[this->size] != CHECKBYTE )
175 {
176 sh_error_handle ((-1), FIL__, __LINE__, 0, MSG_E_MOVER,
177 this->file, this->line, FIL__, __LINE__);
178 ++nerr;
179 }
180 if ( this->real_address[SH_MEMMULT-1] != CHECKBYTE )
181 {
182 sh_error_handle ((-1), FIL__, __LINE__, 0, MSG_E_MUNDER,
183 this->file, this->line, FIL__, __LINE__);
184 ++nerr;
185 }
186 }
187 this = this->next;
188 }
189
190
[138]191 SH_MUTEX_RECURSIVE_UNLOCK(mutex_mem);
[1]192 SL_RET0(_("sh_mem_check"));
193}
194
195void * sh_mem_malloc (size_t size, char * file, int line)
196{
197 void * the_realAddress;
198 void * theAddress;
199 memlist_t * this;
200
201 SL_ENTER(_("sh_mem_malloc"));
202
[138]203 SH_MUTEX_RECURSIVE_INIT(mutex_mem);
204 SH_MUTEX_RECURSIVE_LOCK(mutex_mem);
[1]205 the_realAddress = malloc(size + 2 * SH_MEMMULT);
206
207 if ( the_realAddress == NULL )
208 {
[149]209 (void) safe_logger (0, 0, NULL);
210
[1]211 /* use _exit() rather than exit() - we malloc() in atexit() functions
212 */
[149]213 _exit (EXIT_FAILURE);
[1]214 }
215
216 /* --- Set check bytes. ---
217 */
218 theAddress = ((char *) the_realAddress + SH_MEMMULT);
219
220 memset(the_realAddress, CHECKBYTE, SH_MEMMULT);
221 memset(theAddress, CHECKBYTE, size + 1);
222 memset(theAddress, 0, 1);
223
224 ++Alloc_Count;
225 ++Now_Alloc_Count;
226
227 if (Max_Alloc_Count < Now_Alloc_Count)
228 Max_Alloc_Count = Now_Alloc_Count;
229
230 Mem_Current += size;
231 Mem_Max = ( (Mem_Current > Mem_Max) ? Mem_Current : Mem_Max);
232
233 this = (memlist_t *) malloc (sizeof(memlist_t));
234
235 if ( this == NULL)
236 {
[149]237 (void) safe_logger(0, 0, NULL);
238
239 _exit(EXIT_FAILURE);
[1]240 }
[138]241 else
242 {
243 /* make list entry */
[1]244
[138]245 this->real_address = the_realAddress;
246 this->address = theAddress;
247 this->size = size;
248 this->line = line;
249 sl_strlcpy(this->file, file, 20);
[1]250
[138]251 this->next = memlist;
252 memlist = this;
253 }
[1]254
[138]255 SH_MUTEX_RECURSIVE_UNLOCK(mutex_mem);
[1]256 SL_RETURN( theAddress, _("sh_mem_malloc"));
257}
258
[256]259static void ** sh_mem_dummy_a;
[1]260
[170]261void sh_mem_free (void * aa, char * file, int line)
[1]262{
[170]263 memlist_t * this;
264 memlist_t * before;
[153]265 unsigned long size = 0;
[170]266 void * a;
[256]267 volatile int flag = 0;
268
[1]269 SL_ENTER(_("sh_mem_free"));
270
[256]271 a = aa;
272 sh_mem_dummy_a = &a;
[149]273
[256]274
[1]275 if ( a == NULL )
276 {
277 sh_error_handle ((-1), FIL__, __LINE__, 0, MSG_E_MNULL,
278 file, line);
[256]279 SL_RET0(_("sh_mem_free"));
[1]280 }
281
[256]282 SH_MUTEX_RECURSIVE_INIT(mutex_mem);
283 SH_MUTEX_RECURSIVE_LOCK(mutex_mem);
284
285 this = memlist;
286 before = memlist;
287
[1]288 /* -- Find record. --
289 */
290 while (this != NULL)
291 {
292 if (this->address == a)
293 break;
294 before = this;
295 this = this->next;
296 }
297
298 if (this == NULL)
299 {
[256]300 flag = 1;
[134]301 goto out;
[1]302 }
303 else
304 {
305 a = this->real_address;
306
307 if ( this->address[this->size] != CHECKBYTE )
308 {
309 sh_error_handle ((-1), FIL__, __LINE__, 0, MSG_E_MOVER,
310 this->file, this->line, file, line);
311 }
312 if ( this->real_address[SH_MEMMULT-1] != CHECKBYTE )
313 sh_error_handle ((-1), FIL__, __LINE__, 0, MSG_E_MUNDER,
314 this->file, this->line, file, line);
315
316 size = this->size;
317
318 if (this == memlist)
319 memlist = this->next;
320 else
321 before->next = this->next;
322 }
323
324 free(a);
325 if (this)
[170]326 free(this);
[1]327 ++Free_Count;
328 --Now_Alloc_Count;
329
330 Mem_Current -= size;
[134]331 out:
[144]332 ; /* label at end of compound statement */
[138]333 SH_MUTEX_RECURSIVE_UNLOCK(mutex_mem);
[256]334 if (flag != 0)
335 sh_error_handle ((-1), FIL__, __LINE__, 0, MSG_E_MREC,
336 file, line);
[1]337 SL_RET0(_("sh_mem_free"));
338}
339
340#else
341
342void sh_mem_free (void * a)
343{
344 SL_ENTER(_("sh_mem_free"));
345
346 if (a)
347 {
348 free(a);
349 }
350 else
351 {
352 sh_error_handle ((-1), FIL__, __LINE__, 0, MSG_E_MNULL);
353 }
354 SL_RET0(_("sh_mem_free"));
355}
356
357void * sh_mem_malloc (size_t size)
358{
359 void * theAddress;
360
361 SL_ENTER(_("sh_mem_malloc"));
362
363 theAddress = malloc(size);
364
[149]365 if ( theAddress != NULL )
[1]366 {
[149]367 SL_RETURN( theAddress, _("sh_mem_malloc"));
368 }
369 else
370 {
371 (void) safe_logger(0, 0, NULL);
372
[1]373 /* use _exit() rather than exit() - we malloc() in atexit()
374 */
[149]375 _exit (EXIT_FAILURE);
[1]376 }
377}
378#endif
Note: See TracBrowser for help on using the repository browser.