source: trunk/src/sh_mem.c@ 255

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

Add code to check for stale file records on close() and fclose(), fix sl_close() to handle open stream (ticket #163).

File size: 8.5 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
[138]121 SH_MUTEX_RECURSIVE_INIT(mutex_mem);
122 SH_MUTEX_RECURSIVE_LOCK(mutex_mem);
[134]123
[1]124 if (Alloc_Count == Free_Count)
125 {
126 sh_error_handle ((-1), FIL__, __LINE__, 0, MSG_MSTAMP,
127 Mem_Max, Mem_Current);
[134]128 goto out;
[1]129 }
130
131 sh_error_handle (SH_ERR_INFO, FIL__, __LINE__, 0, MSG_MSTAMP2,
132 Alloc_Count, Free_Count, Max_Alloc_Count);
133 sh_error_handle (SH_ERR_INFO, FIL__, __LINE__, 0, MSG_MSTAMP,
134 Mem_Max, Mem_Current);
135
136 this = memlist;
137
138 while (this != NULL)
139 {
140 sh_error_handle (SH_ERR_WARN, FIL__, __LINE__, 0, MSG_E_NOTFREE,
141 this->size, this->file, this->line);
142 this = this->next;
143 }
[134]144 out:
[144]145 ; /* label at end of compound statement */
[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
[138]157 SH_MUTEX_RECURSIVE_INIT(mutex_mem);
158 SH_MUTEX_RECURSIVE_LOCK(mutex_mem);
[149]159
[1]160 sh_error_handle ((-1), FIL__, __LINE__, 0, MSG_MSTAMP,
161 Mem_Max, Mem_Current);
162
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
259
[170]260void sh_mem_free (void * aa, char * file, int line)
[1]261{
[170]262 memlist_t * this;
263 memlist_t * before;
[153]264 unsigned long size = 0;
[170]265 void * a;
[1]266 SL_ENTER(_("sh_mem_free"));
267
[138]268 SH_MUTEX_RECURSIVE_INIT(mutex_mem);
269 SH_MUTEX_RECURSIVE_LOCK(mutex_mem);
[149]270
[170]271 a = aa;
272 this = memlist;
273 before = memlist;
274
[1]275 if ( a == NULL )
276 {
277 sh_error_handle ((-1), FIL__, __LINE__, 0, MSG_E_MNULL,
278 file, line);
[134]279 goto out;
[1]280 }
281
282 /* -- Find record. --
283 */
284 while (this != NULL)
285 {
286 if (this->address == a)
287 break;
288 before = this;
289 this = this->next;
290 }
291
292 if (this == NULL)
293 {
294 sh_error_handle ((-1), FIL__, __LINE__, 0, MSG_E_MREC,
295 file, line);
[134]296 goto out;
[1]297 }
298 else
299 {
300 a = this->real_address;
301
302 if ( this->address[this->size] != CHECKBYTE )
303 {
304 sh_error_handle ((-1), FIL__, __LINE__, 0, MSG_E_MOVER,
305 this->file, this->line, file, line);
306 }
307 if ( this->real_address[SH_MEMMULT-1] != CHECKBYTE )
308 sh_error_handle ((-1), FIL__, __LINE__, 0, MSG_E_MUNDER,
309 this->file, this->line, file, line);
310
311 size = this->size;
312
313 if (this == memlist)
314 memlist = this->next;
315 else
316 before->next = this->next;
317 }
318
319 free(a);
320 if (this)
[170]321 free(this);
[1]322 ++Free_Count;
323 --Now_Alloc_Count;
324
325 Mem_Current -= size;
[134]326 out:
[144]327 ; /* label at end of compound statement */
[138]328 SH_MUTEX_RECURSIVE_UNLOCK(mutex_mem);
[1]329 SL_RET0(_("sh_mem_free"));
330}
331
332#else
333
334void sh_mem_free (void * a)
335{
336 SL_ENTER(_("sh_mem_free"));
337
338 if (a)
339 {
340 free(a);
341 }
342 else
343 {
344 sh_error_handle ((-1), FIL__, __LINE__, 0, MSG_E_MNULL);
345 }
346 SL_RET0(_("sh_mem_free"));
347}
348
349void * sh_mem_malloc (size_t size)
350{
351 void * theAddress;
352
353 SL_ENTER(_("sh_mem_malloc"));
354
355 theAddress = malloc(size);
356
[149]357 if ( theAddress != NULL )
[1]358 {
[149]359 SL_RETURN( theAddress, _("sh_mem_malloc"));
360 }
361 else
362 {
363 (void) safe_logger(0, 0, NULL);
364
[1]365 /* use _exit() rather than exit() - we malloc() in atexit()
366 */
[149]367 _exit (EXIT_FAILURE);
[1]368 }
369}
370#endif
Note: See TracBrowser for help on using the repository browser.