The FreeRADIUS server  $Id: 15bac2a4c627c01d1aa2047687b3418955ac7f00 $
talloc.c
Go to the documentation of this file.
1 /*
2  * This library is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU Lesser General Public
4  * License as published by the Free Software Foundation; either
5  * version 2.1 of the License, or (at your option) any later version.
6  *
7  * This library is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
10  * Lesser General Public License for more details.
11  *
12  * You should have received a copy of the GNU Lesser General Public
13  * License along with this library; if not, write to the Free Software
14  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
15  */
16 
17 /** Functions which we wish were included in the standard talloc distribution
18  *
19  * @file src/lib/util/talloc.c
20  *
21  * @copyright 2017 The FreeRADIUS server project
22  * @copyright 2017 Arran Cudbard-Bell (a.cudbardb@freeradius.org)
23  */
24 RCSID("$Id: 4625ca1d38d3341c6b8475f480310ff3fb369d01 $")
25 
26 #include <freeradius-devel/util/atexit.h>
27 #include <freeradius-devel/util/debug.h>
28 #include <freeradius-devel/util/dlist.h>
29 #include <freeradius-devel/util/sbuff.h>
30 #include <freeradius-devel/util/strerror.h>
31 #include <freeradius-devel/util/syserror.h>
32 
33 #include <talloc.h>
34 #include <stdatomic.h>
35 
36 static TALLOC_CTX *global_ctx;
37 static _Thread_local TALLOC_CTX *thread_local_ctx;
38 
39 /** A wrapper that can be passed to tree or hash alloc functions that take a #fr_free_t
40  */
42 {
44 }
45 
46 /** Retrieve the current talloc NULL ctx
47  *
48  * Talloc doesn't provide a function to retrieve the top level memory tracking context.
49  * This function does that...
50  *
51  * @return the current talloc NULL context or NULL if memory tracking is not enabled.
52  */
53 void *talloc_null_ctx(void)
54 {
55  TALLOC_CTX *null_ctx;
56  bool *tmp;
57 
58  tmp = talloc(NULL, bool);
59  null_ctx = talloc_parent(tmp);
60  talloc_free(tmp);
61 
62  return null_ctx;
63 }
64 
65 /** Called with the fire_ctx is freed
66  *
67  */
69 {
70  if (d->ds) {
71  talloc_set_destructor(d->ds, NULL); /* Disarm the disarmer */
72  TALLOC_FREE(d->ds); /* Free the disarm trigger ctx */
73  }
74 
75  return d->func(d->fire, d->uctx);
76 }
77 
78 /** Called when the disarm_ctx ctx is freed
79  *
80  */
82 {
83  talloc_set_destructor(ds->d, NULL); /* Disarm the destructor */
84  return talloc_free(ds->d); /* Free memory allocated to the destructor */
85 }
86 
87 /** Add an additional destructor to a talloc chunk
88  *
89  * @param[in] fire_ctx When this ctx is freed the destructor function
90  * will be called.
91  * @param[in] disarm_ctx When this ctx is freed the destructor will be
92  * disarmed. May be NULL. #talloc_destructor_disarm
93  * may be used to disarm the destructor too.
94  * @param[in] func to call when the fire_ctx is freed.
95  * @param[in] uctx data to pass to the above function.
96  * @return
97  * - A handle to access the destructor on success.
98  * - NULL on failure.
99  */
100 fr_talloc_destructor_t *talloc_destructor_add(TALLOC_CTX *fire_ctx, TALLOC_CTX *disarm_ctx,
101  fr_talloc_free_func_t func, void const *uctx)
102 {
104 
105  if (!fire_ctx) {
106  fr_strerror_const("No firing ctx provided when setting destructor");
107  return NULL;
108  }
109 
110  d = talloc(fire_ctx, fr_talloc_destructor_t);
111  if (!d) {
112  oom:
113  fr_strerror_const("Out of Memory");
114  return NULL;
115  }
116 
117  d->fire = fire_ctx;
118  d->func = func;
119  memcpy(&d->uctx, &uctx, sizeof(d->uctx));
120 
121  if (disarm_ctx) {
123 
124  ds = talloc(disarm_ctx, fr_talloc_destructor_disarm_t);
125  if (!ds) {
126  talloc_free(d);
127  goto oom;
128  }
129  ds->d = d;
130  d->ds = ds;
131  talloc_set_destructor(ds, _talloc_destructor_disarm);
132  }
133 
134  talloc_set_destructor(d, _talloc_destructor_fire);
135 
136  return d;
137 }
138 
139 /** Disarm a destructor and free all memory allocated in the trigger ctxs
140  *
141  */
143 {
144  if (d->ds) {
145  talloc_set_destructor(d->ds, NULL); /* Disarm the disarmer */
146  TALLOC_FREE(d->ds); /* Free the disarmer ctx */
147  }
148 
149  talloc_set_destructor(d, NULL); /* Disarm the destructor */
150  talloc_free(d); /* Free the destructor ctx */
151 }
152 
153 static int _talloc_link_ctx_free(UNUSED void *parent, void *child)
154 {
155  talloc_free(child);
156 
157  return 0;
158 }
159 
160 /** Link two different parent and child contexts, so the child is freed before the parent
161  *
162  * @note This is not thread safe. Do not free parent before threads are joined, do not call from a
163  * child thread.
164  *
165  * @param parent who's fate the child should share.
166  * @param child bound to parent's lifecycle.
167  * @return
168  * - 0 on success.
169  * - -1 on failure.
170  */
171 int talloc_link_ctx(TALLOC_CTX *parent, TALLOC_CTX *child)
172 {
173  if (!talloc_destructor_add(parent, child, _talloc_link_ctx_free, child)) return -1;
174 
175  return 0;
176 }
177 
178 /** Return a page aligned talloc memory array
179  *
180  * Because we can't intercept talloc's malloc() calls, we need to do some tricks
181  * in order to get the first allocation in the array page aligned, and to limit
182  * the size of the array to a multiple of the page size.
183  *
184  * The reason for wanting a page aligned talloc array, is it allows us to
185  * mprotect() the pages that belong to the array.
186  *
187  * Talloc chunks appear to be allocated within the protected region, so this should
188  * catch frees too.
189  *
190  * @param[in] ctx to allocate array memory in.
191  * @param[out] start The first aligned address in the array.
192  * @param[in] alignment What alignment the memory chunk should have.
193  * @param[in] size How big to make the array. Will be corrected to a multiple
194  * of the page size. The actual array size will be size
195  * rounded to a multiple of the (page_size), + page_size
196  * @return
197  * - A talloc chunk on success.
198  * - NULL on failure.
199  */
200 TALLOC_CTX *talloc_aligned_array(TALLOC_CTX *ctx, void **start, size_t alignment, size_t size)
201 {
202  size_t rounded;
203  size_t array_size;
204  void *next;
205  TALLOC_CTX *array;
206 
207  rounded = ROUND_UP(size, alignment); /* Round up to a multiple of the page size */
208  if (rounded == 0) rounded = alignment;
209 
210  array_size = rounded + alignment;
211  array = talloc_array(ctx, uint8_t, array_size); /* Over allocate */
212  if (!array) {
213  fr_strerror_const("Out of memory");
214  return NULL;
215  }
216 
217  next = (void *)ROUND_UP((uintptr_t)array, alignment); /* Round up address to the next multiple */
218  *start = next;
219 
220  return array;
221 }
222 
223 /** How big the chunk header is
224  *
225  * Non-zero portion will always fit in a uint8_t, so we don't need to worry about atomicity.
226  */
227 static size_t t_hdr_size;
228 
229 /** Calculate the size of talloc chunk headers, once, on startup
230  *
231  */
232 static void _talloc_hdr_size(void)
233 {
234  TALLOC_CTX *pool;
235  void *chunk;
236 
237  pool = talloc_pool(NULL, 1024); /* Allocate 1k of memory, this will always be bigger than the chunk header */
238  if (unlikely(pool == NULL)) {
239  oom:
240  fr_strerror_const("Out of memory");
241  return;
242  }
243  chunk = talloc_size(pool, 1); /* Get the starting address */
244  if (unlikely(chunk == NULL)) goto oom;
245 
246  /*
247  * Sanity check... make sure the chunk is within the pool
248  * if it's not, we're in trouble.
249  */
250  if (!fr_cond_assert((chunk > pool) && ((uintptr_t)chunk < ((uintptr_t)pool + 1024)))) {
251  fr_strerror_const("Initial allocation outside of pool memory");
252  return;
253  }
254 
255  /*
256  * Talloc returns the address after the chunk header, so
257  * the address of the pool is <malloc address> + <hdr_size>.
258  *
259  * If we allocate a chunk inside the pool, then the address
260  * of the chunk will be <malloc address> + <hdr_size> + <hdr_size>.
261  * If we subtrace the chunk from the pool address, we get
262  * the size of the talloc header.
263  */
264  t_hdr_size = (uintptr_t)chunk - (uintptr_t)pool;
265 
266  talloc_free(pool); /* Free the memory we used */
267 }
268 
269 /** Calculate the size of the talloc chunk header
270  *
271  * @return
272  * - >0 the size of the talloc chunk header.
273  * - -1 on error.
274  */
276 {
277  static pthread_once_t once_control = PTHREAD_ONCE_INIT;
278 
279  if (t_hdr_size > 0) return t_hdr_size; /* We've already calculated it */
280 
281  if (pthread_once(&once_control, _talloc_hdr_size) != 0) {
282  fr_strerror_printf("pthread_once failed: %s", fr_syserror(errno));
283  return -1;
284  }
285  if (t_hdr_size == 0) return -1; /* Callback should set error */
286 
287  return t_hdr_size;
288 }
289 
290 /** Return a page aligned talloc memory pool
291  *
292  * Because we can't intercept talloc's malloc() calls, we need to do some tricks
293  * in order to get the first allocation in the pool page aligned, and to limit
294  * the size of the pool to a multiple of the page size.
295  *
296  * The reason for wanting a page aligned talloc pool, is it allows us to
297  * mprotect() the pages that belong to the pool.
298  *
299  * Talloc chunks appear to be allocated within the protected region, so this should
300  * catch frees too.
301  *
302  * @param[in] ctx to allocate pool memory in.
303  * @param[out] start A page aligned address within the pool. This can be passed
304  * to mprotect().
305  * @param[out] end_len how many bytes to protect.
306  * @param[in] headers how much room we should allocate for talloc headers.
307  * This value should usually be >= 1.
308  * @param[in] size How big to make the pool. Will be corrected to a multiple
309  * of the page size. The actual pool size will be size
310  * rounded to a multiple of the (page_size), + page_size
311  */
312 TALLOC_CTX *talloc_page_aligned_pool(TALLOC_CTX *ctx, void **start, size_t *end_len, unsigned int headers, size_t size)
313 {
314  size_t rounded, alloced, page_size = (size_t)getpagesize();
315  size_t hdr_size;
316  void *next;
317  TALLOC_CTX *pool;
318 
319  hdr_size = talloc_hdr_size();
320  size += (hdr_size * headers); /* Add more space for the chunks headers of the pool's children */
321  size += hdr_size; /* Add one more header to the pool for the padding allocation */
322 
323  /*
324  * Allocate enough space for the padding header the other headers
325  * and the actual data, and sure it's a multiple of the page_size.
326  *
327  * |<--- page_size --->|<-- page_size -->|
328  * |<-- hdr_size -->|<-- size -->|
329  */
330  if (size % page_size == 0) {
331  rounded = size;
332  } else {
333  rounded = ROUND_UP(size, page_size);
334  }
335 
336  /*
337  * Add another page, so that we can align the first allocation in
338  * the pool to a page boundary. We have no idea what chunk malloc
339  * will give to talloc, and what the first address after adding the
340  * pools header will be
341  */
342  alloced = rounded + page_size;
343  pool = talloc_pool(ctx, alloced);
344  if (!pool) {
345  fr_strerror_const("Out of memory");
346  return NULL;
347  }
348 
349  /*
350  * If we didn't get lucky, and the first address in the pool is
351  * not the start of a page, we need to allocate some padding to
352  * get the first allocation in the pool to be on or after the
353  * start of the next page.
354  */
355  if ((uintptr_t)pool % page_size != 0) {
356  size_t pad_size;
357  void *padding;
358 
359  next = (void *)ROUND_UP((uintptr_t)pool, page_size); /* Round up address to the next page */
360 
361  /*
362  * We don't care if the first address if on a page
363  * boundary, just that it comes after one.
364  */
365  pad_size = ((uintptr_t)next - (uintptr_t)pool);
366  if (pad_size > hdr_size) {
367  pad_size -= hdr_size; /* Save ~111 bytes by not over-padding */
368  } else {
369  pad_size = 0; /* Allocate as few bytes as possible */
370  }
371 
372  padding = talloc_size(pool, pad_size);
373  if (!fr_cond_assert(((uintptr_t)padding + (uintptr_t)pad_size) >= (uintptr_t)next)) {
374  fr_strerror_const("Failed padding pool memory");
375  return NULL;
376  }
377  } else {
378  next = pool;
379  }
380 
381  *start = next; /* This is the address we feed into mprotect */
382  *end_len = rounded; /* This is how much memory we protect */
383 
384  /*
385  * Start address must be page aligned
386  */
387  fr_assert(((uintptr_t)*start % page_size) == 0);
388 
389  /*
390  * For our sanity, length must be a multiple of the page size.
391  * mprotect will silently protect an entire additional page
392  * if length is not a multiple of page size.
393  */
394  fr_assert(((uintptr_t)*end_len % page_size) == 0);
395 
396  /*
397  * We can't protect pages before the pool
398  */
399  fr_assert(*start >= pool);
400 
401  /*
402  * We can't protect pages after the pool
403  */
404  fr_assert(((uintptr_t)*start + *end_len) <= ((uintptr_t)pool + alloced));
405 
406  return pool;
407 }
408 
409 /** Call talloc_memdup, setting the type on the new chunk correctly
410  *
411  * @param[in] ctx The talloc context to hang the result off.
412  * @param[in] in The data you want to duplicate.
413  * @param[in] inlen the length of the data to be duplicated.
414  * @return
415  * - Duplicated data.
416  * - NULL on error.
417  *
418  * @hidecallergraph
419  */
420 uint8_t *talloc_typed_memdup(TALLOC_CTX *ctx, uint8_t const *in, size_t inlen)
421 {
422  uint8_t *n;
423 
424  n = talloc_memdup(ctx, in, inlen);
425  if (unlikely(!n)) return NULL;
426  talloc_set_type(n, uint8_t);
427 
428  return n;
429 }
430 
431 /** Call talloc_strdup, setting the type on the new chunk correctly
432  *
433  * For some bizarre reason the talloc string functions don't set the
434  * memory chunk type to char, which causes all kinds of issues with
435  * verifying fr_pair_ts.
436  *
437  * @param[in] ctx The talloc context to hang the result off.
438  * @param[in] p The string you want to duplicate.
439  * @return
440  * - Duplicated string.
441  * - NULL on error.
442  *
443  * @hidecallergraph
444  */
445 char *talloc_typed_strdup(TALLOC_CTX *ctx, char const *p)
446 {
447  char *n;
448 
449  n = talloc_strdup(ctx, p);
450  if (unlikely(!n)) return NULL;
451  talloc_set_type(n, char);
452 
453  return n;
454 }
455 
456 /** Call talloc_strndup, setting the type on the new chunk correctly
457  *
458  * This function is similar to talloc_typed_strdup but gets the chunk
459  * length using talloc functions.
460  *
461  * @param[in] ctx The talloc context to hang the result off.
462  * @param[in] p The string you want to duplicate.
463  * @return
464  * - Duplicated string.
465  * - NULL on error.
466  *
467  * @hidecallergraph
468  */
469 char *talloc_typed_strdup_buffer(TALLOC_CTX *ctx, char const *p)
470 {
471  char *n;
472 
473  n = talloc_strndup(ctx, p, talloc_array_length(p) - 1);
474  if (unlikely(!n)) return NULL;
475  talloc_set_type(n, char);
476 
477  return n;
478 }
479 
480 /** Call talloc vasprintf, setting the type on the new chunk correctly
481  *
482  * For some bizarre reason the talloc string functions don't set the
483  * memory chunk type to char, which causes all kinds of issues with
484  * verifying fr_pair_ts.
485  *
486  * @param[in] ctx The talloc context to hang the result off.
487  * @param[in] fmt The format string.
488  * @return
489  * - Formatted string.
490  * - NULL on error.
491  */
492 char *talloc_typed_asprintf(TALLOC_CTX *ctx, char const *fmt, ...)
493 {
494  char *n;
495  va_list ap;
496 
497  va_start(ap, fmt);
498  n = talloc_vasprintf(ctx, fmt, ap);
499  va_end(ap);
500  if (unlikely(!n)) return NULL;
501  talloc_set_type(n, char);
502 
503  return n;
504 }
505 
506 /** Call talloc vasprintf, setting the type on the new chunk correctly
507  *
508  * For some bizarre reason the talloc string functions don't set the
509  * memory chunk type to char, which causes all kinds of issues with
510  * verifying fr_pair_ts.
511  *
512  * @param[in] ctx The talloc context to hang the result off.
513  * @param[in] fmt The format string.
514  * @param[in] ap varadic arguments.
515  * @return
516  * - Formatted string.
517  * - NULL on error.
518  */
519 char *talloc_typed_vasprintf(TALLOC_CTX *ctx, char const *fmt, va_list ap)
520 {
521  char *n;
522 
523  n = talloc_vasprintf(ctx, fmt, ap);
524  if (unlikely(!n)) return NULL;
525  talloc_set_type(n, char);
526 
527  return n;
528 }
529 
530 /** Binary safe strdup function
531  *
532  * @param[in] ctx the talloc context to allocate new buffer in.
533  * @param[in] in String to dup, may contain embedded '\0'.
534  * @return duped string.
535  */
536 char *talloc_bstrdup(TALLOC_CTX *ctx, char const *in)
537 {
538  char *p;
539  size_t inlen = talloc_array_length(in);
540 
541  if (inlen == 0) inlen = 1;
542 
543  p = talloc_array(ctx, char, inlen);
544  if (unlikely(!p)) return NULL;
545 
546  /*
547  * C99 (7.21.1/2) - Length zero results in noop
548  *
549  * But ubsan still flags this, grrr.
550  */
551  if (inlen > 0) memcpy(p, in, inlen - 1);
552  p[inlen - 1] = '\0';
553 
554  return p;
555 }
556 
557 /** Binary safe strndup function
558  *
559  * @param[in] ctx he talloc context to allocate new buffer in.
560  * @param[in] in String to dup, may contain embedded '\0'.
561  * @param[in] inlen Number of bytes to dup.
562  * @return duped string.
563  */
564 char *talloc_bstrndup(TALLOC_CTX *ctx, char const *in, size_t inlen)
565 {
566  char *p;
567 
568  p = talloc_array(ctx, char, inlen + 1);
569  if (unlikely(!p)) return NULL;
570 
571  /*
572  * C99 (7.21.1/2) - Length zero results in noop
573  *
574  * But ubsan still flags this, grrr.
575  */
576  if (inlen > 0) memcpy(p, in, inlen);
577  p[inlen] = '\0';
578 
579  return p;
580 }
581 
582 /** Append a bstr to a bstr
583  *
584  * @param[in] ctx to allocated.
585  * @param[in] to string to append to.
586  * @param[in] from string to append from.
587  * @param[in] from_len Length of from.
588  * @return
589  * - Realloced buffer containing both to and from.
590  * - NULL on failure. To will still be valid.
591  */
592 char *talloc_bstr_append(TALLOC_CTX *ctx, char *to, char const *from, size_t from_len)
593 {
594  char *n;
595  size_t to_len = 0;
596 
597  if (to) {
598  to_len = talloc_array_length(to);
599  if (to[to_len - 1] == '\0') to_len--; /* Inlen should be length of input string */
600  }
601 
602  n = talloc_realloc_size(ctx, to, to_len + from_len + 1);
603  if (!n) {
604  fr_strerror_printf("Extending bstr buffer to %zu bytes failed", to_len + from_len + 1);
605  return NULL;
606  }
607 
608  memcpy(n + to_len, from, from_len);
609  n[to_len + from_len] = '\0';
610  talloc_set_type(n, char);
611 
612  return n;
613 }
614 
615 /** Trim a bstr (char) buffer
616  *
617  * Reallocs to inlen + 1 and '\0' terminates the string buffer.
618  *
619  * @param[in] ctx to realloc buffer into.
620  * @param[in] in string to trim. Will be invalid after
621  * this function returns. If NULL a new zero terminated
622  * buffer of inlen bytes will be allocated.
623  * @param[in] inlen Length to trim string to.
624  * @return
625  * - The realloced string on success. in then points to invalid memory.
626  * - NULL on failure. In will still be valid.
627  */
628 char *talloc_bstr_realloc(TALLOC_CTX *ctx, char *in, size_t inlen)
629 {
630  char *n;
631 
632  if (!in) {
633  n = talloc_array(ctx, char, inlen);
634  n[0] = '\0';
635  return n;
636  }
637 
638  n = talloc_realloc_size(ctx, in, inlen + 1);
639  if (unlikely(!n)) return NULL;
640 
641  n[inlen] = '\0';
642  talloc_set_type(n, char);
643 
644  return n;
645 }
646 
647 /** Concatenate to + from
648  *
649  * @param[in] ctx to allocate realloced buffer in.
650  * @param[in] to talloc string buffer to append to.
651  * @param[in] from talloc string buffer to append.
652  * @return
653  * - NULL if to or from are NULL or if the realloc fails.
654  * Note: You'll still need to free to if this function
655  * returns NULL.
656  * - The concatenation of to + from. After this function
657  * returns to may point to invalid memory and should
658  * not be used.
659  */
660 char *talloc_buffer_append_buffer(TALLOC_CTX *ctx, char *to, char const *from)
661 {
662  size_t to_len, from_len, total_len;
663  char *out;
664 
665  if (!to || !from) return NULL;
666 
667  to_len = talloc_array_length(to);
668  from_len = talloc_array_length(from);
669  total_len = to_len + (from_len - 1);
670 
671  out = talloc_realloc(ctx, to, char, total_len);
672  if (!out) return NULL;
673 
674  memcpy(out + (to_len - 1), from, from_len);
675  out[total_len - 1] = '\0';
676 
677  return out;
678 }
679 
680 /** Concatenate to + ...
681  *
682  * @param[in] ctx to allocate realloced buffer in.
683  * @param[in] to talloc string buffer to append to.
684  * @param[in] argc how many variadic arguments were passed.
685  * @param[in] ... talloc string buffer(s) to append.
686  * Arguments can be NULL to simplify
687  * calling logic.
688  * @return
689  * - NULL if to or from are NULL or if the realloc fails.
690  * Note: You'll still need to free to if this function
691  * returns NULL.
692  * - The concatenation of to + from. After this function
693  * returns to may point to invalid memory and should
694  * not be used.
695  */
696 char *talloc_buffer_append_variadic_buffer(TALLOC_CTX *ctx, char *to, int argc, ...)
697 {
698  va_list ap_val, ap_len;
699  int i;
700 
701  size_t to_len, total_len = 0;
702  char *out, *p;
703 
704  if (!to) return NULL;
705 
706  va_start(ap_val, argc);
707  va_copy(ap_len, ap_val);
708 
709  total_len += to_len = talloc_array_length(to) - 1;
710 
711  /*
712  * Figure out how much we need to realloc
713  */
714  for (i = 0; i < argc; i++) {
715  char *arg;
716 
717  arg = va_arg(ap_len, char *);
718  if (!arg) continue;
719 
720  total_len += (talloc_array_length(arg) - 1);
721  }
722 
723  /*
724  * It's a noop...
725  */
726  if (total_len == to_len) {
727  va_end(ap_val);
728  va_end(ap_len);
729  return to;
730  }
731 
732  out = talloc_realloc(ctx, to, char, total_len + 1);
733  if (!out) goto finish;
734 
735  p = out + to_len;
736 
737  /*
738  * Copy the args in
739  */
740  for (i = 0; i < argc; i++) {
741  char *arg;
742  size_t len;
743 
744  arg = va_arg(ap_val, char *);
745  if (!arg) continue;
746 
747  len = talloc_array_length(arg) - 1;
748 
749  memcpy(p, arg, len);
750  p += len;
751  }
752  *p = '\0';
753 
754 finish:
755  va_end(ap_val);
756  va_end(ap_len);
757 
758  return out;
759 }
760 
761 /** Compares two talloced uint8_t arrays with memcmp
762  *
763  * Talloc arrays carry their length as part of the structure, so can be passed to a generic
764  * comparison function.
765  *
766  * @param a Pointer to first array.
767  * @param b Pointer to second array.
768  * @return
769  * - 0 if the arrays match.
770  * - a positive or negative integer otherwise.
771  */
772 int talloc_memcmp_array(uint8_t const *a, uint8_t const *b)
773 {
774  size_t a_len, b_len;
775 
776  a_len = talloc_array_length(a);
777  b_len = talloc_array_length(b);
778 
779  if (a_len > b_len) return +1;
780  if (a_len < b_len) return -1;
781 
782  return memcmp(a, b, a_len);
783 }
784 
785 /** Compares two talloced char arrays with memcmp
786  *
787  * Talloc arrays carry their length as part of the structure, so can be passed to a generic
788  * comparison function.
789  *
790  * @param a Pointer to first array.
791  * @param b Pointer to second array.
792  * @return
793  * - 0 if the arrays match.
794  * - a positive or negative integer otherwise.
795  */
796 int talloc_memcmp_bstr(char const *a, char const *b)
797 {
798  size_t a_len, b_len;
799 
800  a_len = talloc_array_length(a);
801  b_len = talloc_array_length(b);
802 
803  if (a_len > b_len) return +1;
804  if (a_len < b_len) return -1;
805 
806  return memcmp(a, b, a_len);
807 }
808 
809 /** Decrease the reference count on a ptr
810  *
811  * Ptr will be freed if count reaches zero.
812  *
813  * This is equivalent to talloc 1.0 behaviour of talloc_free.
814  *
815  * @param ptr to decrement ref count for.
816  * @return
817  * - 0 The memory was freed.
818  * - >0 How many references remain.
819  */
820 int talloc_decrease_ref_count(void const *ptr)
821 {
822  size_t ref_count;
823  void *to_free;
824 
825  if (!ptr) return 0;
826 
827  memcpy(&to_free, &ptr, sizeof(to_free));
828 
829  ref_count = talloc_reference_count(to_free);
830  if (ref_count == 0) {
831  talloc_free(to_free);
832  } else {
833  talloc_unlink(talloc_parent(ptr), to_free);
834  }
835 
836  return ref_count;
837 }
838 
839 /** Add a NULL pointer to an array of pointers
840  *
841  * This is needed by some 3rd party libraries which take NULL terminated
842  * arrays for arguments.
843  *
844  * If allocation fails, NULL will be returned and the original array
845  * will not be touched.
846  *
847  * @param[in] array to null terminate. Will be invalidated (realloced).
848  * @return
849  * - NULL if array is NULL, or if reallocation fails.
850  * - A realloced version of array with an additional NULL element.
851  */
853 {
854  size_t len;
855  TALLOC_CTX *ctx;
856  void **new;
857  size_t size;
858 
859  if (!array) return NULL;
860 
861  len = talloc_array_length(array);
862  ctx = talloc_parent(array);
863  size = talloc_get_size(array) / talloc_array_length(array);
864 
865  new = _talloc_realloc_array(ctx, array, size, len + 1, talloc_get_name(array));
866  if (!new) return NULL;
867 
868  new[len] = NULL;
869 
870  return new;
871 }
872 
873 /** Remove a NULL termination pointer from an array of pointers
874  *
875  * If the end of the array is not NULL, NULL will be returned (error).
876  *
877  * @param[in] array to null strip. Will be invalidated (realloced).
878  * @return
879  * - NULL if array is NULL, if terminating element is not NULL, or reallocation fails.
880  * - A realloced version of array without the terminating NULL element.
881  */
883 {
884  size_t len;
885  TALLOC_CTX *ctx;
886  void **new;
887  size_t size;
888 
889  if (!array) return NULL;
890 
891  len = talloc_array_length(array);
892  ctx = talloc_parent(array);
893  size = talloc_get_size(array) / talloc_array_length(array);
894 
895  if ((len - 1) == 0) return NULL;
896 
897  if (array[len - 1] != NULL) return NULL;
898 
899  new = _talloc_realloc_array(ctx, array, size, len - 1, talloc_get_name(array));
900  if (!new) return NULL;
901 
902  return new;
903 }
904 
905 /** Concat an array of strings (not NULL terminated), with a string separator
906  *
907  * @param[out] out Where to write the resulting string.
908  * @param[in] array of strings to concat.
909  * @param[in] sep to insert between elements. May be NULL.
910  * @return
911  * - >= 0 on success - length of the string created.
912  * - <0 on failure. How many bytes we would need.
913  */
914 fr_slen_t talloc_array_concat(fr_sbuff_t *out, char const * const *array, char const *sep)
915 {
916  fr_sbuff_t our_out = FR_SBUFF(out);
917  size_t len = talloc_array_length(array);
918  char const * const * p;
919  char const * const * end;
920  fr_sbuff_escape_rules_t e_rules = {
921  .name = __FUNCTION__,
922  .chr = '\\'
923  };
924 
925  if (sep) e_rules.subs[(uint8_t)*sep] = *sep;
926 
927  for (p = array, end = array + len;
928  (p < end);
929  p++) {
930  if (*p) FR_SBUFF_RETURN(fr_sbuff_in_escape, &our_out, *p, strlen(*p), &e_rules);
931 
932  if (sep && ((p + 1) < end)) {
933  FR_SBUFF_RETURN(fr_sbuff_in_strcpy, &our_out, sep);
934  }
935  }
936 
937  FR_SBUFF_SET_RETURN(out, &our_out);
938 }
939 
940 /** Callback to free the autofree ctx on global exit
941  *
942  */
943 static int _autofree_on_exit(void *af)
944 {
945  talloc_set_destructor(af, NULL);
946  return talloc_free(af);
947 }
948 
949 /** Ensures in the autofree ctx is manually freed, things don't explode atexit
950  *
951  */
952 static int _autofree_global_destructor(TALLOC_CTX *af)
953 {
954  return fr_atexit_global_disarm(true, _autofree_on_exit, af);
955 }
956 
958 {
959  TALLOC_CTX *af = global_ctx;
960 
961  if (!af) {
962  af = talloc_init_const("global_autofree_context");
963  talloc_set_destructor(af, _autofree_global_destructor);
964  if (unlikely(!af)) return NULL;
965 
967  global_ctx = af;
968  }
969 
970  return af;
971 }
972 
973 /** Ensures in the autofree ctx is manually freed, things don't explode atexit
974  *
975  */
976 static int _autofree_thread_local_destructor(TALLOC_CTX *af)
977 {
979 }
980 
981 /** Get a thread-safe autofreed ctx that will be freed when the thread or process exits
982  *
983  * @note This should be used in place of talloc_autofree_context (which is now deprecated)
984  * @note Will not be thread-safe if NULL tracking is enabled.
985  *
986  * @return A talloc ctx which will be freed when the thread or process exits.
987  */
989 {
990  TALLOC_CTX *af = thread_local_ctx;
991 
992  if (!af) {
993  af = talloc_init_const("thread_local_autofree_context");
994  talloc_set_destructor(af, _autofree_thread_local_destructor);
995  if (unlikely(!af)) return NULL;
996 
998  }
999 
1000  return af;
1001 }
1002 
1003 
1006 };
1007 
1009 {
1010  while (list->next != NULL) {
1011  TALLOC_CHILD_CTX *entry = list->next;
1012  TALLOC_CHILD_CTX *next = entry->next;
1013 
1014  if (talloc_free(entry) < 0) return -1;
1015 
1016  list->next = next;
1017  }
1018 
1019  return 0;
1020 }
1021 
1022 /** Allocate and initialize a TALLOC_CHILD_CTX
1023  *
1024  * The TALLOC_CHILD_CTX ensures ordering for allocators and
1025  * destructors. When a TALLOC_CHILD_CTX is created, it is added to
1026  * parent, in LIFO order. In contrast, the basic talloc operations
1027  * do not guarantee any kind of order.
1028  *
1029  * When the TALLOC_CHILD_CTX is freed, the children are freed in FILO
1030  * order. That process ensures that the children are freed before
1031  * the parent, and that the younger siblings are freed before the
1032  * older siblings.
1033  *
1034  * The idea is that if we have an initializer for A, which in turn
1035  * initializes B and C. When the memory is freed, we should do the
1036  * operations in the reverse order.
1037  */
1039 {
1040  TALLOC_CHILD_CTX *child;
1041 
1042  child = talloc_zero(ctx, TALLOC_CHILD_CTX);
1043  if (!child) return NULL;
1044 
1045  talloc_set_destructor(child, _child_ctx_free);
1046  return child;
1047 }
1048 
1049 /** Allocate a TALLOC_CHILD_CTX from a parent.
1050  *
1051  */
1053 {
1054  TALLOC_CHILD_CTX *child;
1055 
1056  child = talloc(parent, TALLOC_CHILD_CTX);
1057  if (!child) return NULL;
1058 
1059  child->next = parent->next;
1060  parent->next = child;
1061  return child;
1062 }
va_end(args)
int n
Definition: acutest.h:577
static int const char * fmt
Definition: acutest.h:573
va_start(args, fmt)
unsigned int fr_atexit_global_disarm(bool uctx_scope, fr_atexit_t func, void const *uctx)
Remove a specific global destructor (without executing it)
Definition: atexit.c:229
#define fr_atexit_thread_local_disarm(...)
Definition: atexit.h:231
#define fr_atexit_global(_func, _uctx)
Add a free function to the global free list.
Definition: atexit.h:59
#define fr_atexit_thread_local(_name, _free, _uctx)
Definition: atexit.h:221
#define RCSID(id)
Definition: build.h:481
#define unlikely(_x)
Definition: build.h:379
#define UNUSED
Definition: build.h:313
next
Definition: dcursor.h:178
fr_dcursor_eval_t void const * uctx
Definition: dcursor.h:546
#define fr_cond_assert(_x)
Calls panic_action ifndef NDEBUG, else logs error and evaluates to value of _x.
Definition: debug.h:139
static fr_slen_t in
Definition: dict.h:821
talloc_free(reap)
#define ROUND_UP(_num, _mul)
Round up - Works in all cases, but is slower.
Definition: math.h:148
long int ssize_t
Definition: merged_model.c:24
unsigned char uint8_t
Definition: merged_model.c:30
ssize_t fr_slen_t
Definition: merged_model.c:35
unsigned long int size_t
Definition: merged_model.c:25
static size_t array[MY_ARRAY_SIZE]
ssize_t fr_sbuff_in_strcpy(fr_sbuff_t *sbuff, char const *str)
Copy bytes into the sbuff up to the first \0.
Definition: sbuff.c:1432
ssize_t fr_sbuff_in_escape(fr_sbuff_t *sbuff, char const *in, size_t inlen, fr_sbuff_escape_rules_t const *e_rules)
Print an escaped string to an sbuff.
Definition: sbuff.c:1598
#define FR_SBUFF_RETURN(_func, _sbuff,...)
#define FR_SBUFF(_sbuff_or_marker)
fr_assert(0)
char const * fr_syserror(int num)
Guaranteed to be thread-safe version of strerror.
Definition: syserror.c:243
TALLOC_CTX * talloc_autofree_context_thread_local(void)
Get a thread-safe autofreed ctx that will be freed when the thread or process exits.
Definition: talloc.c:988
static int _talloc_destructor_fire(fr_talloc_destructor_t *d)
Called with the fire_ctx is freed.
Definition: talloc.c:68
char * talloc_bstrdup(TALLOC_CTX *ctx, char const *in)
Binary safe strdup function.
Definition: talloc.c:536
TALLOC_CHILD_CTX * talloc_child_ctx_init(TALLOC_CTX *ctx)
Allocate and initialize a TALLOC_CHILD_CTX.
Definition: talloc.c:1038
static int _talloc_link_ctx_free(UNUSED void *parent, void *child)
Definition: talloc.c:153
char * talloc_typed_vasprintf(TALLOC_CTX *ctx, char const *fmt, va_list ap)
Call talloc vasprintf, setting the type on the new chunk correctly.
Definition: talloc.c:519
static TALLOC_CTX * global_ctx
Definition: talloc.c:36
uint8_t * talloc_typed_memdup(TALLOC_CTX *ctx, uint8_t const *in, size_t inlen)
Call talloc_memdup, setting the type on the new chunk correctly.
Definition: talloc.c:420
static int _autofree_on_exit(void *af)
Callback to free the autofree ctx on global exit.
Definition: talloc.c:943
char * talloc_typed_strdup(TALLOC_CTX *ctx, char const *p)
Call talloc_strdup, setting the type on the new chunk correctly.
Definition: talloc.c:445
char * talloc_buffer_append_variadic_buffer(TALLOC_CTX *ctx, char *to, int argc,...)
Concatenate to + ...
Definition: talloc.c:696
void * talloc_null_ctx(void)
Retrieve the current talloc NULL ctx.
Definition: talloc.c:53
struct talloc_child_ctx_s * next
Definition: talloc.c:1005
char * talloc_buffer_append_buffer(TALLOC_CTX *ctx, char *to, char const *from)
Concatenate to + from.
Definition: talloc.c:660
fr_slen_t talloc_array_concat(fr_sbuff_t *out, char const *const *array, char const *sep)
Concat an array of strings (not NULL terminated), with a string separator.
Definition: talloc.c:914
ssize_t talloc_hdr_size(void)
Calculate the size of the talloc chunk header.
Definition: talloc.c:275
static int _autofree_thread_local_destructor(TALLOC_CTX *af)
Ensures in the autofree ctx is manually freed, things don't explode atexit.
Definition: talloc.c:976
char * talloc_bstrndup(TALLOC_CTX *ctx, char const *in, size_t inlen)
Binary safe strndup function.
Definition: talloc.c:564
int talloc_memcmp_array(uint8_t const *a, uint8_t const *b)
Compares two talloced uint8_t arrays with memcmp.
Definition: talloc.c:772
TALLOC_CHILD_CTX * talloc_child_ctx_alloc(TALLOC_CHILD_CTX *parent)
Allocate a TALLOC_CHILD_CTX from a parent.
Definition: talloc.c:1052
TALLOC_CTX * talloc_autofree_context_global(void)
Definition: talloc.c:957
char * talloc_bstr_realloc(TALLOC_CTX *ctx, char *in, size_t inlen)
Trim a bstr (char) buffer.
Definition: talloc.c:628
static int _talloc_destructor_disarm(fr_talloc_destructor_disarm_t *ds)
Called when the disarm_ctx ctx is freed.
Definition: talloc.c:81
TALLOC_CTX * talloc_page_aligned_pool(TALLOC_CTX *ctx, void **start, size_t *end_len, unsigned int headers, size_t size)
Return a page aligned talloc memory pool.
Definition: talloc.c:312
int talloc_link_ctx(TALLOC_CTX *parent, TALLOC_CTX *child)
Link two different parent and child contexts, so the child is freed before the parent.
Definition: talloc.c:171
char * talloc_bstr_append(TALLOC_CTX *ctx, char *to, char const *from, size_t from_len)
Append a bstr to a bstr.
Definition: talloc.c:592
static void _talloc_hdr_size(void)
Calculate the size of talloc chunk headers, once, on startup.
Definition: talloc.c:232
static _Thread_local TALLOC_CTX * thread_local_ctx
Definition: talloc.c:37
char * talloc_typed_strdup_buffer(TALLOC_CTX *ctx, char const *p)
Call talloc_strndup, setting the type on the new chunk correctly.
Definition: talloc.c:469
void ** talloc_array_null_strip(void **array)
Remove a NULL termination pointer from an array of pointers.
Definition: talloc.c:882
static size_t t_hdr_size
How big the chunk header is.
Definition: talloc.c:227
TALLOC_CTX * talloc_aligned_array(TALLOC_CTX *ctx, void **start, size_t alignment, size_t size)
Return a page aligned talloc memory array.
Definition: talloc.c:200
static int _child_ctx_free(TALLOC_CHILD_CTX *list)
Definition: talloc.c:1008
void ** talloc_array_null_terminate(void **array)
Add a NULL pointer to an array of pointers.
Definition: talloc.c:852
char * talloc_typed_asprintf(TALLOC_CTX *ctx, char const *fmt,...)
Call talloc vasprintf, setting the type on the new chunk correctly.
Definition: talloc.c:492
void talloc_free_data(void *data)
A wrapper that can be passed to tree or hash alloc functions that take a fr_free_t.
Definition: talloc.c:41
int talloc_decrease_ref_count(void const *ptr)
Decrease the reference count on a ptr.
Definition: talloc.c:820
void talloc_destructor_disarm(fr_talloc_destructor_t *d)
Disarm a destructor and free all memory allocated in the trigger ctxs.
Definition: talloc.c:142
fr_talloc_destructor_t * talloc_destructor_add(TALLOC_CTX *fire_ctx, TALLOC_CTX *disarm_ctx, fr_talloc_free_func_t func, void const *uctx)
Add an additional destructor to a talloc chunk.
Definition: talloc.c:100
int talloc_memcmp_bstr(char const *a, char const *b)
Compares two talloced char arrays with memcmp.
Definition: talloc.c:796
static int _autofree_global_destructor(TALLOC_CTX *af)
Ensures in the autofree ctx is manually freed, things don't explode atexit.
Definition: talloc.c:952
Functions which we wish were included in the standard talloc distribution.
fr_talloc_free_func_t func
Free function.
Definition: talloc.h:92
fr_talloc_destructor_t * d
Destructor to disarm.
Definition: talloc.h:102
static TALLOC_CTX * talloc_init_const(char const *name)
Allocate a top level chunk with a constant name.
Definition: talloc.h:112
void * uctx
uctx to pass to free function.
Definition: talloc.h:93
void * fire
Parent chunk.
Definition: talloc.h:90
int(* fr_talloc_free_func_t)(void *fire_ctx, void *uctx)
Definition: talloc.h:80
fr_talloc_destructor_disarm_t * ds
Chunk to free.
Definition: talloc.h:94
Structure to record a destructor to disarm if a child talloc chunk is freed.
Definition: talloc.h:101
Structure to record a destructor operation on a specific talloc chunk.
Definition: talloc.h:89
static fr_slen_t parent
Definition: pair.h:851
#define fr_strerror_printf(_fmt,...)
Log to thread local error buffer.
Definition: strerror.h:64
#define fr_strerror_const(_msg)
Definition: strerror.h:223
FR_SBUFF_SET_RETURN(sbuff, &our_sbuff)
static fr_slen_t data
Definition: value.h:1265
static size_t char fr_sbuff_t size_t inlen
Definition: value.h:997
static size_t char ** out
Definition: value.h:997