source: trunk/src/sh_mem.c@ 575

Last change on this file since 575 was 516, checked in by katerina, 8 years ago

Fix for ticket #409 and #410 (unprivileged suidcheck and gcc 6.2 compiler warnings).

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