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