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