1 /*
2 Bacula(R) - The Network Backup Solution
3
4 Copyright (C) 2000-2020 Kern Sibbald
5
6 The original author of Bacula is Kern Sibbald, with contributions
7 from many others, a complete list can be found in the file AUTHORS.
8
9 You may use this file and others of this release according to the
10 license defined in the LICENSE file, which includes the Affero General
11 Public License, v3.0 ("AGPLv3") and some additional permissions and
12 terms pursuant to its AGPLv3 Section 7.
13
14 This notice must be preserved when any source code is
15 conveyed and/or propagated.
16
17 Bacula(R) is a registered trademark of Kern Sibbald.
18 */
19 /*
20
21 S M A R T A L L O C
22 Smart Memory Allocator
23
24 Evolved over several years, starting with the initial
25 SMARTALLOC code for AutoSketch in 1986, guided by the Blind
26 Watchbreaker, John Walker. Isolated in this general-purpose
27 form in September of 1989. Updated with be more POSIX
28 compliant and to include Web-friendly HTML documentation in
29 October of 1998 by the same culprit. For additional
30 information and the current version visit the Web page:
31
32 http://www.fourmilab.ch/smartall/
33
34 */
35
36 #define LOCKMGR_COMPLIANT
37
38 #include "bacula.h"
39 /* Use the real routines here */
40 #undef realloc
41 #undef calloc
42 #undef malloc
43 #undef free
44
45 /* We normally turn off debugging here.
46 * If you want it, simply #ifdef all the
47 * following off.
48 */
49 #ifdef no_debug_xxxxx
50 #undef Dmsg1
51 #undef Dmsg2
52 #undef Dmsg3
53 #undef Dmsg4
54 #define Dmsg1(l,f,a1)
55 #define Dmsg2(l,f,a1,a2)
56 #define Dmsg3(l,f,a1,a2,a3)
57 #define Dmsg4(l,f,a1,a2,a3,a4)
58 #endif
59
60
61 uint64_t sm_max_bytes = 0;
62 uint64_t sm_bytes = 0;
63 uint32_t sm_max_buffers = 0;
64 uint32_t sm_buffers = 0;
65
66 #ifdef SMARTALLOC
67
68 static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
69
70 extern char my_name[]; /* daemon name */
71
72 #define EOS '\0' /* End of string sentinel */
73 #define sm_min(a, b) ((a) < (b) ? (a) : (b))
74
75 /* Queue data structures */
76
77 /* Memory allocation control structures and storage. */
78
79 struct abufhead {
80 struct b_queue abq; /* Links on allocated queue */
81 uint32_t ablen; /* Buffer length in bytes */
82 const char *abfname; /* File name pointer */
83 uint32_t ablineno; /* Line number of allocation */
84 bool abin_use; /* set when malloced and cleared when free */
85 };
86
87 static struct b_queue abqueue = { /* Allocated buffer queue */
88 &abqueue, &abqueue
89 };
90
91
92 static bool bufimode = false; /* Buffers not tracked when True */
93
94 #define HEAD_SIZE BALIGN(sizeof(struct abufhead))
95
96
97 /* SMALLOC -- Allocate buffer, enqueing on the orphaned buffer
98 tracking list. */
99
smalloc(const char * fname,int lineno,unsigned int nbytes)100 static void *smalloc(const char *fname, int lineno, unsigned int nbytes)
101 {
102 char *buf;
103
104 /* Note: Unix MALLOC actually permits a zero length to be
105 passed and allocates a valid block with zero user bytes.
106 Such a block can later be expanded with realloc(). We
107 disallow this based on the belief that it's better to make
108 a special case and allocate one byte in the rare case this
109 is desired than to miss all the erroneous occurrences where
110 buffer length calculation code results in a zero. */
111
112 if (nbytes == 0) {
113 Tmsg3(0, "Invalid memory allocation. %u bytes %s:%d\n", nbytes, fname, lineno);
114 ASSERT(nbytes > 0);
115 }
116
117 nbytes += HEAD_SIZE + 1;
118 if ((buf = (char *)malloc(nbytes)) != NULL) {
119 struct abufhead *head = (struct abufhead *)buf;
120 P(mutex);
121 /* Enqueue buffer on allocated list */
122 qinsert(&abqueue, (struct b_queue *) buf);
123 head->ablen = nbytes;
124 head->abfname = bufimode ? NULL : fname;
125 head->ablineno = (uint32_t)lineno;
126 head->abin_use = true;
127 /* Emplace end-clobber detector at end of buffer */
128 buf[nbytes - 1] = (uint8_t)((((intptr_t) buf) & 0xFF) ^ 0xC5);
129 buf += HEAD_SIZE; /* Increment to user data start */
130 if (++sm_buffers > sm_max_buffers) {
131 sm_max_buffers = sm_buffers;
132 }
133 sm_bytes += nbytes;
134 if (sm_bytes > sm_max_bytes) {
135 sm_max_bytes = sm_bytes;
136 }
137 V(mutex);
138 } else {
139 Emsg0(M_ABORT, 0, _("Out of memory\n"));
140 }
141 Dmsg4(DT_MEMORY|1050, "smalloc %d at %p from %s:%d\n", nbytes, buf, fname, lineno);
142 #if SMALLOC_SANITY_CHECK > 0
143 if (sm_bytes > SMALLOC_SANITY_CHECK) {
144 Emsg0(M_ABORT, 0, _("Too much memory used."));
145 }
146 #endif
147 return (void *)buf;
148 }
149
150 /* SM_NEW_OWNER -- Update the File and line number for a buffer
151 This is to accomodate mem_pool. */
152
sm_new_owner(const char * fname,int lineno,char * buf)153 void sm_new_owner(const char *fname, int lineno, char *buf)
154 {
155 buf -= HEAD_SIZE; /* Decrement to header */
156 P(mutex);
157 ((struct abufhead *)buf)->abfname = bufimode ? NULL : fname;
158 ((struct abufhead *)buf)->ablineno = (uint32_t) lineno;
159 ((struct abufhead *)buf)->abin_use = true;
160 V(mutex);
161 return;
162 }
163
164 /* Print a debug message with the owner of a smartalloc buffer */
sm_get_owner(int64_t dbglvl,char * buf)165 void sm_get_owner(int64_t dbglvl, char *buf)
166 {
167 /* Decrement to header */
168 struct abufhead *h = (struct abufhead *) (buf - HEAD_SIZE);
169 Dmsg3(dbglvl, "%p from %s:%d\n",
170 buf + HEAD_SIZE,
171 NPRT(h->abfname),
172 h->ablineno);
173 }
174
175 /* SM_FREE -- Update free pool availability. FREE is never called
176 except through this interface or by actuallyfree().
177 free(x) is defined to generate a call to this
178 routine. */
179
sm_free(const char * file,int line,void * fp)180 void sm_free(const char *file, int line, void *fp)
181 {
182 char *cp = (char *) fp;
183 struct b_queue *qp;
184 uint32_t lineno = line;
185
186 if (cp == NULL) {
187 Emsg2(M_ABORT, 0, _("Attempt to free NULL called from %s:%d\n"), file, lineno);
188 }
189
190 cp -= HEAD_SIZE;
191 qp = (struct b_queue *)cp;
192 struct abufhead *head = (struct abufhead *)cp;
193
194 P(mutex);
195 Dmsg4(DT_MEMORY|1050, "sm_free %d at %p from %s:%d\n",
196 head->ablen, fp,
197 get_basename(head->abfname), head->ablineno);
198
199 if (!head->abin_use) {
200 V(mutex);
201 Emsg2(M_ABORT, 0, _("in-use bit not set: double free from %s:%d\n"), file, lineno);
202 }
203 head->abin_use = false;
204
205 /* The following assertions will catch virtually every release
206 of an address which isn't an allocated buffer. */
207 if (qp->qnext->qprev != qp) {
208 V(mutex);
209 Emsg2(M_ABORT, 0, _("qp->qnext->qprev != qp called from %s:%d\n"), file, lineno);
210 }
211 if (qp->qprev->qnext != qp) {
212 V(mutex);
213 Emsg2(M_ABORT, 0, _("qp->qprev->qnext != qp called from %s:%d\n"), file, lineno);
214 }
215
216 /* The following assertion detects storing off the end of the
217 allocated space in the buffer by comparing the end of buffer
218 checksum with the address of the buffer. */
219
220 if (((unsigned char *)cp)[head->ablen - 1] != ((((intptr_t) cp) & 0xFF) ^ 0xC5)) {
221 V(mutex);
222 Emsg6(M_ABORT, 0, _("Overrun buffer: len=%d addr=%p allocated: %s:%d called from %s:%d\n"),
223 head->ablen, fp, get_basename(head->abfname), head->ablineno, file, line);
224 }
225 if (sm_buffers > 0) {
226 sm_buffers--;
227 sm_bytes -= head->ablen;
228 }
229
230 qdchain(qp);
231 V(mutex);
232
233 /* Now we wipe the contents of the just-released buffer with
234 "designer garbage" (Duff Kurland's phrase) of alternating
235 bits. This is intended to ruin the day for any miscreant who
236 attempts to access data through a pointer into storage that's
237 been previously released.
238
239 Modified, kes May, 2007 to not zap the header. This allows us
240 to check the in_use bit and detect doubly freed buffers.
241 */
242
243 memset(cp+HEAD_SIZE, 0xAA, (int)(head->ablen - HEAD_SIZE));
244
245 free(cp);
246 }
247
248 /* SM_MALLOC -- Allocate buffer. NULL is returned if no memory
249 was available. */
250
sm_malloc(const char * fname,int lineno,unsigned int nbytes)251 void *sm_malloc(const char *fname, int lineno, unsigned int nbytes)
252 {
253 void *buf;
254
255 if ((buf = smalloc(fname, lineno, nbytes)) != NULL) {
256
257 /* To catch sloppy code that assumes buffers obtained from
258 malloc() are zeroed, we preset the buffer contents to
259 "designer garbage" consisting of alternating bits.
260
261 Removed 10 May 2020 KES
262
263 memset(buf, 0x55, (int) nbytes);
264 */
265 memset(buf, 0, (int) nbytes); /* clear the memory */
266 } else {
267 Emsg0(M_ABORT, 0, _("Out of memory\n"));
268 }
269 return buf;
270 }
271
272 /* SM_CALLOC -- Allocate an array and clear it to zero. */
273
sm_calloc(const char * fname,int lineno,unsigned int nelem,unsigned int elsize)274 void *sm_calloc(const char *fname, int lineno,
275 unsigned int nelem, unsigned int elsize)
276 {
277 void *buf;
278
279 if ((buf = smalloc(fname, lineno, nelem * elsize)) != NULL) {
280 memset(buf, 0, (int) (nelem * elsize));
281 } else {
282 Emsg0(M_ABORT, 0, _("Out of memory\n"));
283 }
284 return buf;
285 }
286
287 /* SM_REALLOC -- Adjust the size of a previously allocated buffer.
288 Note that the trick of "resurrecting" a previously
289 freed buffer with realloc() is NOT supported by this
290 function. Further, because of the need to maintain
291 our control storage, SM_REALLOC must always allocate
292 a new block and copy the data in the old block.
293 This may result in programs which make heavy use of
294 realloc() running much slower than normally. */
295
sm_realloc(const char * fname,int lineno,void * ptr,unsigned int size)296 void *sm_realloc(const char *fname, int lineno, void *ptr, unsigned int size)
297 {
298 unsigned osize;
299 void *buf;
300 char *cp = (char *) ptr;
301
302 Dmsg4(DT_MEMORY|1050, "sm_realloc %s:%d %p %d\n", get_basename(fname), (uint32_t)lineno, ptr, size);
303 if (size <= 0) {
304 e_msg(fname, lineno, M_ABORT, 0, _("sm_realloc size: %d\n"), size);
305 }
306
307 /* If the old block pointer is NULL, treat realloc() as a
308 malloc(). SVID is silent on this, but many C libraries
309 permit this. */
310 if (ptr == NULL) {
311 return sm_malloc(fname, lineno, size);
312 }
313
314 /* If the old and new sizes are the same, be a nice guy and just
315 return the buffer passed in. */
316 cp -= HEAD_SIZE;
317 struct abufhead *head = (struct abufhead *)cp;
318 osize = head->ablen - (HEAD_SIZE + 1);
319 if (size == osize) {
320 return ptr;
321 }
322
323 /* Sizes differ. Allocate a new buffer of the requested size.
324 If we can't obtain such a buffer, act as defined in SVID:
325 return NULL from realloc() and leave the buffer in PTR
326 intact. */
327
328 // sm_buffers--;
329 // sm_bytes -= head->ablen;
330
331 if ((buf = smalloc(fname, lineno, size)) != NULL) {
332 memcpy(buf, ptr, (int)sm_min(size, osize));
333 /* If the new buffer is larger than the old, fill the balance
334 of it with "designer garbage". */
335 if (size > osize) {
336 /*
337 Removed 10 May 2020 KES
338 memset(((char *) buf) + osize, 0x55, (int) (size - osize));
339 */
340
341 memset(((char *) buf) + osize, 0, (int) (size - osize));
342 }
343
344 /* All done. Free and dechain the original buffer. */
345 sm_free(fname, lineno, ptr);
346 }
347 Dmsg4(DT_MEMORY|1060, _("sm_realloc %d at %p from %s:%d\n"), size, buf, get_basename(fname), (uint32_t)lineno);
348 return buf;
349 }
350
351 /* ACTUALLYMALLOC -- Call the system malloc() function to obtain
352 storage which will eventually be released
353 by system or library routines not compiled
354 using SMARTALLOC. */
355
actuallymalloc(unsigned int size)356 void *actuallymalloc(unsigned int size)
357 {
358 return malloc(size);
359 }
360
361 /* ACTUALLYCALLOC -- Call the system calloc() function to obtain
362 storage which will eventually be released
363 by system or library routines not compiled
364 using SMARTALLOC. */
365
actuallycalloc(unsigned int nelem,unsigned int elsize)366 void *actuallycalloc(unsigned int nelem, unsigned int elsize)
367 {
368 return calloc(nelem, elsize);
369 }
370
371 /* ACTUALLYREALLOC -- Call the system realloc() function to obtain
372 storage which will eventually be released
373 by system or library routines not compiled
374 using SMARTALLOC. */
375
actuallyrealloc(void * ptr,unsigned int size)376 void *actuallyrealloc(void *ptr, unsigned int size)
377 {
378 Dmsg2(DT_MEMORY|1040, "Actuallyrealloc %p %d\n", ptr, size);
379 return realloc(ptr, size);
380 }
381
382 /* ACTUALLYFREE -- Interface to system free() function to release
383 buffers allocated by low-level routines. */
384
actuallyfree(void * cp)385 void actuallyfree(void *cp)
386 {
387 free(cp);
388 }
389
390 /* SM_DUMP -- Print orphaned buffers (and dump them if BUFDUMP is
391 * True).
392 */
sm_dump(bool bufdump,bool in_use)393 void sm_dump(bool bufdump, bool in_use)
394 {
395 struct abufhead *ap;
396
397 P(mutex);
398
399 ap = (struct abufhead *)abqueue.qnext;
400
401 while (ap != (struct abufhead *) &abqueue) {
402
403 if ((ap == NULL) ||
404 (ap->abq.qnext->qprev != (struct b_queue *) ap) ||
405 (ap->abq.qprev->qnext != (struct b_queue *) ap)) {
406 Pmsg1(0, _(
407 "\nOrphaned buffers exist. Dump terminated following\n"
408 " discovery of bad links in chain of orphaned buffers.\n"
409 " Buffer address with bad links: %p\n"), ap);
410 break;
411 }
412
413 if (ap->abfname != NULL) {
414 char errmsg[500];
415 uint32_t memsize = ap->ablen - (HEAD_SIZE + 1);
416 char *cp = ((char *)ap) + HEAD_SIZE;
417
418 Pmsg6(0, "%s buffer: %s %d bytes at %p from %s:%d\n",
419 in_use?"In use":"Orphaned",
420 my_name, memsize, cp, get_basename(ap->abfname), ap->ablineno);
421 if (bufdump) {
422 char buf[20];
423 unsigned llen = 0;
424
425 errmsg[0] = EOS;
426 while (memsize) {
427 if (llen >= 16) {
428 bstrncat(errmsg, "\n", sizeof(errmsg));
429 llen = 0;
430 Pmsg1(0, "%s", errmsg);
431 errmsg[0] = EOS;
432 }
433 bsnprintf(buf, sizeof(buf), " %02X",
434 (*cp++) & 0xFF);
435 bstrncat(errmsg, buf, sizeof(errmsg));
436 llen++;
437 memsize--;
438 }
439 Pmsg1(0, "%s\n", errmsg);
440 }
441 }
442 ap = (struct abufhead *) ap->abq.qnext;
443 }
444 V(mutex);
445 }
446
447 #undef sm_check
448 /* SM_CHECK -- Check the buffers and dump if any damage exists. */
sm_check(const char * fname,int lineno,bool bufdump)449 void sm_check(const char *fname, int lineno, bool bufdump)
450 {
451 if (!sm_check_rtn(fname, lineno, bufdump)) {
452 Emsg2(M_ABORT, 0, _("Damaged buffer found. Called from %s:%d\n"),
453 get_basename(fname), (uint32_t)lineno);
454 }
455 }
456
457 #undef sm_check_rtn
458 /* SM_CHECK_RTN -- Check the buffers and return 1 if OK otherwise 0 */
sm_check_rtn(const char * fname,int lineno,bool bufdump)459 int sm_check_rtn(const char *fname, int lineno, bool bufdump)
460 {
461 struct abufhead *ap;
462 int bad, badbuf = 0;
463
464 P(mutex);
465 ap = (struct abufhead *) abqueue.qnext;
466 while (ap != (struct abufhead *)&abqueue) {
467 bad = 0;
468 if (ap != NULL) {
469 if (ap->abq.qnext->qprev != (struct b_queue *)ap) {
470 bad = 0x1;
471 }
472 if (ap->abq.qprev->qnext != (struct b_queue *)ap) {
473 bad |= 0x2;
474 }
475 if (((unsigned char *) ap)[((struct abufhead *)ap)->ablen - 1] !=
476 ((((intptr_t) ap) & 0xFF) ^ 0xC5)) {
477 bad |= 0x4;
478 }
479 } else {
480 bad = 0x8;
481 }
482 badbuf |= bad;
483 if (bad) {
484 Pmsg2(0,
485 _("\nDamaged buffers found at %s:%d\n"), get_basename(fname), (uint32_t)lineno);
486
487 if (bad & 0x1) {
488 Pmsg0(0, _(" discovery of bad prev link.\n"));
489 }
490 if (bad & 0x2) {
491 Pmsg0(0, _(" discovery of bad next link.\n"));
492 }
493 if (bad & 0x4) {
494 Pmsg0(0, _(" discovery of data overrun.\n"));
495 }
496 if (bad & 0x8) {
497 Pmsg0(0, _(" NULL pointer.\n"));
498 }
499
500 if (!ap) {
501 goto get_out;
502 }
503 Pmsg1(0, _(" Buffer address: %p\n"), ap);
504
505 if (ap->abfname != NULL) {
506 uint32_t memsize = ap->ablen - (HEAD_SIZE + 1);
507 char errmsg[80];
508
509 Pmsg4(0,
510 _("Damaged buffer: %6u bytes allocated at line %d of %s %s\n"),
511 memsize, ap->ablineno, my_name, get_basename(ap->abfname)
512 );
513 if (bufdump) {
514 unsigned llen = 0;
515 char *cp = ((char *) ap) + HEAD_SIZE;
516
517 errmsg[0] = EOS;
518 while (memsize) {
519 if (llen >= 16) {
520 strcat(errmsg, "\n");
521 llen = 0;
522 Pmsg1(0, "%s", errmsg);
523 errmsg[0] = EOS;
524 }
525 if (*cp < 0x20) {
526 sprintf(errmsg + strlen(errmsg), " %02X",
527 (*cp++) & 0xFF);
528 } else {
529 sprintf(errmsg + strlen(errmsg), " %c ",
530 (*cp++) & 0xFF);
531 }
532 llen++;
533 memsize--;
534 }
535 Pmsg1(0, "%s\n", errmsg);
536 }
537 }
538 }
539 ap = (struct abufhead *)ap->abq.qnext;
540 }
541 get_out:
542 V(mutex);
543 return badbuf ? 0 : 1;
544 }
545
546
547 /* SM_STATIC -- Orphaned buffer detection can be disabled (for such
548 items as buffers allocated during initialisation) by
549 calling sm_static(1). Normal orphaned buffer
550 detection can be re-enabled with sm_static(0). Note
551 that all the other safeguards still apply to buffers
552 allocated when sm_static(1) mode is in effect. */
553
sm_static(bool mode)554 void sm_static(bool mode)
555 {
556 bufimode = mode;
557 }
558
559 /*
560 * Here we overload C++'s global new and delete operators
561 * so that the memory is allocated through smartalloc.
562 */
563
564 #ifdef xxx
new(size_t size)565 void * operator new(size_t size)
566 {
567 // Dmsg1(000, "new called %d\n", size);
568 return sm_malloc(__FILE__, __LINE__, size);
569 }
570
delete(void * buf)571 void operator delete(void *buf)
572 {
573 // Dmsg1(000, "free called %p\n", buf);
574 sm_free(__FILE__, __LINE__, buf);
575 }
576 #endif
577
578 #endif
579
580 /* Avoid aggressive optimization */
bmemset(void * s,int c,size_t n)581 void *bmemset(void *s, int c, size_t n)
582 {
583 void *ret = memset(s, c, n);
584 return ret;
585 }
586