source: trunk/src/sh_mem.c@ 587

Last change on this file since 587 was 587, checked in by katerina, 21 hours ago

Fix for ticket #475 (compiler warnings about unused variables).

File size: 10.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#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 thesignal, int method, char * details);
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
75#ifdef HAVE_PTHREAD
76SH_MUTEX_RECURSIVE(mutex_mem);
77#endif
78
79/* define MEM_LOG to enable this */
80/* #define MEM_LOG 1 */
81#ifdef MEM_LOG
82void sh_mem_dump ()
83{
84 memlist_t * this = memlist;
85 FILE * fd;
86 static unsigned int nr = 0;
87 char filename[256];
88
89 snprintf(filename, sizeof(filename), "sh_mem_dump.%04u.%lu", nr, (unsigned long) sh.pid);
90
91 SH_MUTEX_RECURSIVE_INIT(mutex_mem);
92 SH_MUTEX_RECURSIVE_LOCK(mutex_mem);
93
94 fd = fopen(filename, "w");
95 if (!fd)
96 {
97 perror(filename);
98 _exit(EXIT_FAILURE);
99 }
100
101 while (this != NULL)
102 {
103 fprintf (fd, "## %20s %5d %ld\n", this->file, this->line, this->size);
104 fprintf (fd, "%10p %8ld\n", (void *)this->address, this->size);
105 this = this->next;
106 }
107 sl_fclose(FIL__, __LINE__, fd);
108
109 SH_MUTEX_RECURSIVE_UNLOCK(mutex_mem);
110 ++nr;
111 /* _exit(EXIT_SUCCESS); */
112 return;
113}
114#else
115void sh_mem_dump ()
116{
117 return;
118}
119#endif
120
121memlist_t ** sh_dummy_114_merrlist;
122
123void sh_mem_stat ()
124{
125 memlist_t * this;
126 memlist_t * merrlist = NULL;
127
128 SL_ENTER(_("sh_mem_stat"));
129
130 sh_dummy_114_merrlist = (memlist_t **) &merrlist;
131
132 if (Alloc_Count == Free_Count)
133 {
134 sh_error_handle ((-1), FIL__, __LINE__, 0, MSG_MSTAMP,
135 Mem_Max, Mem_Current);
136 SL_RET0(_("sh_mem_stat"));
137 }
138
139 sh_error_handle (SH_ERR_INFO, FIL__, __LINE__, 0, MSG_MSTAMP2,
140 Alloc_Count, Free_Count, Max_Alloc_Count);
141 sh_error_handle (SH_ERR_INFO, FIL__, __LINE__, 0, MSG_MSTAMP,
142 Mem_Max, Mem_Current);
143
144 SH_MUTEX_RECURSIVE_INIT(mutex_mem);
145 SH_MUTEX_RECURSIVE_LOCK(mutex_mem);
146
147 this = memlist;
148
149 while (this != NULL)
150 {
151 memlist_t * merr = calloc(1,sizeof(memlist_t));
152
153 memcpy(merr, this, sizeof(memlist_t));
154 merr->next = merrlist;
155 merrlist = merr;
156
157 this = this->next;
158 }
159
160 SH_MUTEX_RECURSIVE_UNLOCK(mutex_mem);
161
162 while (merrlist != NULL)
163 {
164 memlist_t * tmp = merrlist;
165 merrlist = merrlist->next;
166
167 sh_error_handle (SH_ERR_WARN, FIL__, __LINE__, 0, MSG_E_NOTFREE,
168 tmp->size, tmp->file, tmp->line);
169 free(tmp);
170 }
171
172 SL_RET0(_("sh_mem_stat"));
173}
174
175memlist_t ** sh_dummy_168_merrlist;
176
177void sh_mem_check ()
178{
179 memlist_t * this;
180 memlist_t * merrlist = NULL;
181 memlist_t * merr;
182
183 SL_ENTER(_("sh_mem_check"));
184
185 sh_dummy_168_merrlist = (memlist_t **) &merrlist;
186
187 sh_error_handle ((-1), FIL__, __LINE__, 0, MSG_MSTAMP,
188 Mem_Max, Mem_Current);
189
190 SH_MUTEX_RECURSIVE_INIT(mutex_mem);
191 SH_MUTEX_RECURSIVE_LOCK(mutex_mem);
192
193 this = memlist;
194
195 while (this != NULL)
196 {
197 if ( this->address == NULL )
198 {
199 merr = calloc (1,sizeof(memlist_t));
200
201 memcpy(merr, this, sizeof(memlist_t));
202 merr->size = 2;
203
204 merr->next = merrlist;
205 merrlist = merr;
206 }
207 else
208 {
209 if ( this->address[this->size] != CHECKBYTE )
210 {
211 merr = calloc(1, sizeof(memlist_t));
212
213 memcpy(merr, this, sizeof(memlist_t));
214 merr->size = 1;
215
216 merr->next = merrlist;
217 merrlist = merr;
218 }
219 if ( this->real_address[SH_MEMMULT-1] != CHECKBYTE )
220 {
221 merr = calloc(1, sizeof(memlist_t));
222
223 memcpy(merr, this, sizeof(memlist_t));
224 merr->size = 0;
225
226 merr->next = merrlist;
227 merrlist = merr;
228 }
229 }
230 this = this->next;
231 }
232
233
234 SH_MUTEX_RECURSIVE_UNLOCK(mutex_mem);
235
236 while (merrlist != NULL)
237 {
238 memlist_t * tmp = merrlist;
239 merrlist = merrlist->next;
240
241 if (tmp->size == 2)
242 sh_error_handle ((-1), FIL__, __LINE__, 0, MSG_E_MNULL,
243 tmp->file, tmp->line, FIL__, __LINE__);
244 if (tmp->size == 1)
245 sh_error_handle ((-1), FIL__, __LINE__, 0, MSG_E_MOVER,
246 tmp->file, tmp->line, FIL__, __LINE__);
247 else
248 sh_error_handle ((-1), FIL__, __LINE__, 0, MSG_E_MUNDER,
249 tmp->file, tmp->line, FIL__, __LINE__);
250 free(tmp);
251 SH_ABORT;
252 _exit (EXIT_FAILURE);
253 }
254
255 SL_RET0(_("sh_mem_check"));
256}
257
258void * sh_mem_malloc (size_t size, char * file, int line)
259{
260 void * the_realAddress;
261 void * theAddress;
262 memlist_t * this;
263
264 SL_ENTER(_("sh_mem_malloc"));
265
266 SH_MUTEX_RECURSIVE_INIT(mutex_mem);
267 SH_MUTEX_RECURSIVE_LOCK(mutex_mem);
268
269 the_realAddress = calloc(1,size + 2 * SH_MEMMULT);
270
271 if ( the_realAddress == NULL )
272 {
273 (void) safe_logger (0, 0, NULL);
274
275 /* use _exit() rather than exit() - we malloc() in atexit() functions
276 */
277 _exit (EXIT_FAILURE);
278 }
279
280 /* --- Set check bytes. ---
281 */
282 theAddress = ((char *) the_realAddress + SH_MEMMULT);
283
284 memset(the_realAddress, CHECKBYTE, SH_MEMMULT);
285 memset(theAddress, CHECKBYTE, size + 1);
286 memset(theAddress, 0, 1);
287
288 ++Alloc_Count;
289 ++Now_Alloc_Count;
290
291 if (Max_Alloc_Count < Now_Alloc_Count)
292 Max_Alloc_Count = Now_Alloc_Count;
293
294 Mem_Current += size;
295 Mem_Max = ( (Mem_Current > Mem_Max) ? Mem_Current : Mem_Max);
296
297 this = calloc(1,sizeof(memlist_t));
298
299 if ( this == NULL)
300 {
301 (void) safe_logger(0, 0, NULL);
302
303 _exit(EXIT_FAILURE);
304 }
305 else
306 {
307 /* make list entry */
308
309 this->real_address = the_realAddress;
310 this->address = theAddress;
311 this->size = size;
312 this->line = line;
313 sl_strlcpy(this->file, file, 20);
314
315 this->next = memlist;
316 memlist = this;
317 }
318
319 SH_MUTEX_RECURSIVE_UNLOCK(mutex_mem);
320 SL_RETURN( theAddress, _("sh_mem_malloc"));
321}
322
323void ** sh_mem_dummy_a;
324memlist_t ** sh_mem_merr_3;
325
326void sh_mem_free (void * aa, char * file, int line)
327{
328 memlist_t * this;
329 memlist_t * before;
330 memlist_t * merr;
331 memlist_t * merrlist = NULL;
332 unsigned long size = 0;
333 void * a;
334 volatile int flag = 0;
335
336 SL_ENTER(_("sh_mem_free"));
337
338 a = aa;
339 sh_mem_dummy_a = &a;
340 sh_mem_merr_3 = (memlist_t **) &merrlist;
341
342
343 if ( a == NULL )
344 {
345 sh_error_handle ((-1), FIL__, __LINE__, 0, MSG_E_MNULL,
346 file, line, FIL__, __LINE__);
347 SH_ABORT;
348 _exit (EXIT_FAILURE);
349 SL_RET0(_("sh_mem_free"));
350 }
351
352 SH_MUTEX_RECURSIVE_INIT(mutex_mem);
353 SH_MUTEX_RECURSIVE_LOCK(mutex_mem);
354
355 this = memlist;
356 before = memlist;
357
358 /* -- Find record. --
359 */
360 while (this != NULL)
361 {
362 if (this->address == a)
363 break;
364 before = this;
365 this = this->next;
366 }
367
368 if (this == NULL)
369 {
370 flag = 1;
371 goto out;
372 }
373 else
374 {
375 a = this->real_address;
376
377 if ( this->address[this->size] != CHECKBYTE )
378 {
379 merr = calloc(1, sizeof(memlist_t));
380
381 memcpy(merr, this, sizeof(memlist_t));
382 merr->size = 1;
383
384 merr->next = merrlist;
385 merrlist = merr;
386 }
387
388 if ( this->real_address[SH_MEMMULT-1] != CHECKBYTE )
389 {
390 merr = calloc(1,sizeof(memlist_t));
391
392 memcpy(merr, this, sizeof(memlist_t));
393 merr->size = 0;
394
395 merr->next = merrlist;
396 merrlist = merr;
397 }
398
399 size = this->size;
400
401 if (this == memlist)
402 memlist = this->next;
403 else
404 before->next = this->next;
405 }
406
407 free(a);
408 if (this)
409 free(this);
410
411 ++Free_Count;
412 --Now_Alloc_Count;
413
414 Mem_Current -= size;
415 out:
416 ; /* label at end of compound statement */
417 SH_MUTEX_RECURSIVE_UNLOCK(mutex_mem);
418
419 while (merrlist != NULL)
420 {
421 memlist_t * tmp = merrlist;
422 merrlist = merrlist->next;
423
424 if (tmp->size == 1)
425 sh_error_handle ((-1), FIL__, __LINE__, 0, MSG_E_MOVER,
426 tmp->file, tmp->line, file, line);
427 else
428 sh_error_handle ((-1), FIL__, __LINE__, 0, MSG_E_MUNDER,
429 tmp->file, tmp->line, file, line);
430 free(tmp);
431 SH_ABORT;
432 _exit (EXIT_FAILURE);
433 }
434
435 if (flag != 0)
436 sh_error_handle ((-1), FIL__, __LINE__, 0, MSG_E_MREC,
437 file, line);
438
439 SL_RET0(_("sh_mem_free"));
440}
441
442#else
443
444void sh_mem_free (void * a)
445{
446 SL_ENTER(_("sh_mem_free"));
447
448 if (a)
449 {
450 free(a);
451 }
452 else
453 {
454 sh_error_handle ((-1), FIL__, __LINE__, 0, MSG_E_MNULL);
455 SH_ABORT;
456 }
457 SL_RET0(_("sh_mem_free"));
458}
459
460void * sh_mem_malloc (size_t size)
461{
462 void * theAddress;
463
464 SL_ENTER(_("sh_mem_malloc"));
465
466 theAddress = calloc(1,size);
467
468 if ( theAddress != NULL )
469 {
470 SL_RETURN( theAddress, _("sh_mem_malloc"));
471 }
472 else
473 {
474 (void) safe_logger(0, 0, NULL);
475
476 /* use _exit() rather than exit() - we malloc() in atexit()
477 */
478 SH_ABORT;
479 _exit (EXIT_FAILURE);
480 }
481}
482#endif
Note: See TracBrowser for help on using the repository browser.