Line data Source code
1 : /*
2 : Samba Unix SMB/CIFS implementation.
3 :
4 : Samba trivial allocation library - new interface
5 :
6 : NOTE: Please read talloc_guide.txt for full documentation
7 :
8 : Copyright (C) Andrew Tridgell 2004
9 : Copyright (C) Stefan Metzmacher 2006
10 :
11 : ** NOTE! The following LGPL license applies to the talloc
12 : ** library. This does NOT imply that all of Samba is released
13 : ** under the LGPL
14 :
15 : This library is free software; you can redistribute it and/or
16 : modify it under the terms of the GNU Lesser General Public
17 : License as published by the Free Software Foundation; either
18 : version 3 of the License, or (at your option) any later version.
19 :
20 : This library is distributed in the hope that it will be useful,
21 : but WITHOUT ANY WARRANTY; without even the implied warranty of
22 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
23 : Lesser General Public License for more details.
24 :
25 : You should have received a copy of the GNU Lesser General Public
26 : License along with this library; if not, see <http://www.gnu.org/licenses/>.
27 : */
28 :
29 : /*
30 : inspired by http://swapped.cc/halloc/
31 : */
32 :
33 : #include "replace.h"
34 : #include "talloc.h"
35 :
36 : #ifdef HAVE_SYS_AUXV_H
37 : #include <sys/auxv.h>
38 : #endif
39 :
40 : #if (TALLOC_VERSION_MAJOR != TALLOC_BUILD_VERSION_MAJOR)
41 : #error "TALLOC_VERSION_MAJOR != TALLOC_BUILD_VERSION_MAJOR"
42 : #endif
43 :
44 : #if (TALLOC_VERSION_MINOR != TALLOC_BUILD_VERSION_MINOR)
45 : #error "TALLOC_VERSION_MINOR != TALLOC_BUILD_VERSION_MINOR"
46 : #endif
47 :
48 : /* Special macros that are no-ops except when run under Valgrind on
49 : * x86. They've moved a little bit from valgrind 1.0.4 to 1.9.4 */
50 : #ifdef HAVE_VALGRIND_MEMCHECK_H
51 : /* memcheck.h includes valgrind.h */
52 : #include <valgrind/memcheck.h>
53 : #elif defined(HAVE_VALGRIND_H)
54 : #include <valgrind.h>
55 : #endif
56 :
57 : #define MAX_TALLOC_SIZE 0x10000000
58 :
59 : #define TALLOC_FLAG_FREE 0x01
60 : #define TALLOC_FLAG_LOOP 0x02
61 : #define TALLOC_FLAG_POOL 0x04 /* This is a talloc pool */
62 : #define TALLOC_FLAG_POOLMEM 0x08 /* This is allocated in a pool */
63 :
64 : /*
65 : * Bits above this are random, used to make it harder to fake talloc
66 : * headers during an attack. Try not to change this without good reason.
67 : */
68 : #define TALLOC_FLAG_MASK 0x0F
69 :
70 : #define TALLOC_MAGIC_REFERENCE ((const char *)1)
71 :
72 : #define TALLOC_MAGIC_BASE 0xe814ec70
73 : #define TALLOC_MAGIC_NON_RANDOM ( \
74 : ~TALLOC_FLAG_MASK & ( \
75 : TALLOC_MAGIC_BASE + \
76 : (TALLOC_BUILD_VERSION_MAJOR << 24) + \
77 : (TALLOC_BUILD_VERSION_MINOR << 16) + \
78 : (TALLOC_BUILD_VERSION_RELEASE << 8)))
79 : static unsigned int talloc_magic = TALLOC_MAGIC_NON_RANDOM;
80 :
81 : /* by default we abort when given a bad pointer (such as when talloc_free() is called
82 : on a pointer that came from malloc() */
83 : #ifndef TALLOC_ABORT
84 : #define TALLOC_ABORT(reason) abort()
85 : #endif
86 :
87 : #ifndef discard_const_p
88 : #if defined(__intptr_t_defined) || defined(HAVE_INTPTR_T)
89 : # define discard_const_p(type, ptr) ((type *)((intptr_t)(ptr)))
90 : #else
91 : # define discard_const_p(type, ptr) ((type *)(ptr))
92 : #endif
93 : #endif
94 :
95 : /* these macros gain us a few percent of speed on gcc */
96 : #if (__GNUC__ >= 3)
97 : /* the strange !! is to ensure that __builtin_expect() takes either 0 or 1
98 : as its first argument */
99 : #ifndef likely
100 : #define likely(x) __builtin_expect(!!(x), 1)
101 : #endif
102 : #ifndef unlikely
103 : #define unlikely(x) __builtin_expect(!!(x), 0)
104 : #endif
105 : #else
106 : #ifndef likely
107 : #define likely(x) (x)
108 : #endif
109 : #ifndef unlikely
110 : #define unlikely(x) (x)
111 : #endif
112 : #endif
113 :
114 : /* this null_context is only used if talloc_enable_leak_report() or
115 : talloc_enable_leak_report_full() is called, otherwise it remains
116 : NULL
117 : */
118 : static void *null_context;
119 : static bool talloc_report_null;
120 : static bool talloc_report_null_full;
121 : static void *autofree_context;
122 :
123 : static void talloc_setup_atexit(void);
124 :
125 : /* used to enable fill of memory on free, which can be useful for
126 : * catching use after free errors when valgrind is too slow
127 : */
128 : static struct {
129 : bool initialised;
130 : bool enabled;
131 : uint8_t fill_value;
132 : } talloc_fill;
133 :
134 : #define TALLOC_FILL_ENV "TALLOC_FREE_FILL"
135 :
136 : /*
137 : * do not wipe the header, to allow the
138 : * double-free logic to still work
139 : */
140 : #define TC_INVALIDATE_FULL_FILL_CHUNK(_tc) do { \
141 : if (unlikely(talloc_fill.enabled)) { \
142 : size_t _flen = (_tc)->size; \
143 : char *_fptr = (char *)TC_PTR_FROM_CHUNK(_tc); \
144 : memset(_fptr, talloc_fill.fill_value, _flen); \
145 : } \
146 : } while (0)
147 :
148 : #if defined(DEVELOPER) && defined(VALGRIND_MAKE_MEM_NOACCESS)
149 : /* Mark the whole chunk as not accessable */
150 : #define TC_INVALIDATE_FULL_VALGRIND_CHUNK(_tc) do { \
151 : size_t _flen = TC_HDR_SIZE + (_tc)->size; \
152 : char *_fptr = (char *)(_tc); \
153 : VALGRIND_MAKE_MEM_NOACCESS(_fptr, _flen); \
154 : } while(0)
155 : #else
156 : #define TC_INVALIDATE_FULL_VALGRIND_CHUNK(_tc) do { } while (0)
157 : #endif
158 :
159 : #define TC_INVALIDATE_FULL_CHUNK(_tc) do { \
160 : TC_INVALIDATE_FULL_FILL_CHUNK(_tc); \
161 : TC_INVALIDATE_FULL_VALGRIND_CHUNK(_tc); \
162 : } while (0)
163 :
164 : #define TC_INVALIDATE_SHRINK_FILL_CHUNK(_tc, _new_size) do { \
165 : if (unlikely(talloc_fill.enabled)) { \
166 : size_t _flen = (_tc)->size - (_new_size); \
167 : char *_fptr = (char *)TC_PTR_FROM_CHUNK(_tc); \
168 : _fptr += (_new_size); \
169 : memset(_fptr, talloc_fill.fill_value, _flen); \
170 : } \
171 : } while (0)
172 :
173 : #if defined(DEVELOPER) && defined(VALGRIND_MAKE_MEM_NOACCESS)
174 : /* Mark the unused bytes not accessable */
175 : #define TC_INVALIDATE_SHRINK_VALGRIND_CHUNK(_tc, _new_size) do { \
176 : size_t _flen = (_tc)->size - (_new_size); \
177 : char *_fptr = (char *)TC_PTR_FROM_CHUNK(_tc); \
178 : _fptr += (_new_size); \
179 : VALGRIND_MAKE_MEM_NOACCESS(_fptr, _flen); \
180 : } while (0)
181 : #else
182 : #define TC_INVALIDATE_SHRINK_VALGRIND_CHUNK(_tc, _new_size) do { } while (0)
183 : #endif
184 :
185 : #define TC_INVALIDATE_SHRINK_CHUNK(_tc, _new_size) do { \
186 : TC_INVALIDATE_SHRINK_FILL_CHUNK(_tc, _new_size); \
187 : TC_INVALIDATE_SHRINK_VALGRIND_CHUNK(_tc, _new_size); \
188 : } while (0)
189 :
190 : #define TC_UNDEFINE_SHRINK_FILL_CHUNK(_tc, _new_size) do { \
191 : if (unlikely(talloc_fill.enabled)) { \
192 : size_t _flen = (_tc)->size - (_new_size); \
193 : char *_fptr = (char *)TC_PTR_FROM_CHUNK(_tc); \
194 : _fptr += (_new_size); \
195 : memset(_fptr, talloc_fill.fill_value, _flen); \
196 : } \
197 : } while (0)
198 :
199 : #if defined(DEVELOPER) && defined(VALGRIND_MAKE_MEM_UNDEFINED)
200 : /* Mark the unused bytes as undefined */
201 : #define TC_UNDEFINE_SHRINK_VALGRIND_CHUNK(_tc, _new_size) do { \
202 : size_t _flen = (_tc)->size - (_new_size); \
203 : char *_fptr = (char *)TC_PTR_FROM_CHUNK(_tc); \
204 : _fptr += (_new_size); \
205 : VALGRIND_MAKE_MEM_UNDEFINED(_fptr, _flen); \
206 : } while (0)
207 : #else
208 : #define TC_UNDEFINE_SHRINK_VALGRIND_CHUNK(_tc, _new_size) do { } while (0)
209 : #endif
210 :
211 : #define TC_UNDEFINE_SHRINK_CHUNK(_tc, _new_size) do { \
212 : TC_UNDEFINE_SHRINK_FILL_CHUNK(_tc, _new_size); \
213 : TC_UNDEFINE_SHRINK_VALGRIND_CHUNK(_tc, _new_size); \
214 : } while (0)
215 :
216 : #if defined(DEVELOPER) && defined(VALGRIND_MAKE_MEM_UNDEFINED)
217 : /* Mark the new bytes as undefined */
218 : #define TC_UNDEFINE_GROW_VALGRIND_CHUNK(_tc, _new_size) do { \
219 : size_t _old_used = TC_HDR_SIZE + (_tc)->size; \
220 : size_t _new_used = TC_HDR_SIZE + (_new_size); \
221 : size_t _flen = _new_used - _old_used; \
222 : char *_fptr = _old_used + (char *)(_tc); \
223 : VALGRIND_MAKE_MEM_UNDEFINED(_fptr, _flen); \
224 : } while (0)
225 : #else
226 : #define TC_UNDEFINE_GROW_VALGRIND_CHUNK(_tc, _new_size) do { } while (0)
227 : #endif
228 :
229 : #define TC_UNDEFINE_GROW_CHUNK(_tc, _new_size) do { \
230 : TC_UNDEFINE_GROW_VALGRIND_CHUNK(_tc, _new_size); \
231 : } while (0)
232 :
233 : struct talloc_reference_handle {
234 : struct talloc_reference_handle *next, *prev;
235 : void *ptr;
236 : const char *location;
237 : };
238 :
239 : struct talloc_memlimit {
240 : struct talloc_chunk *parent;
241 : struct talloc_memlimit *upper;
242 : size_t max_size;
243 : size_t cur_size;
244 : };
245 :
246 : static inline bool talloc_memlimit_check(struct talloc_memlimit *limit, size_t size);
247 : static inline void talloc_memlimit_grow(struct talloc_memlimit *limit,
248 : size_t size);
249 : static inline void talloc_memlimit_shrink(struct talloc_memlimit *limit,
250 : size_t size);
251 : static inline void tc_memlimit_update_on_free(struct talloc_chunk *tc);
252 :
253 : static inline void _tc_set_name_const(struct talloc_chunk *tc,
254 : const char *name);
255 : static struct talloc_chunk *_vasprintf_tc(const void *t,
256 : const char *fmt,
257 : va_list ap);
258 :
259 : typedef int (*talloc_destructor_t)(void *);
260 :
261 : struct talloc_pool_hdr;
262 :
263 : struct talloc_chunk {
264 : /*
265 : * flags includes the talloc magic, which is randomised to
266 : * make overwrite attacks harder
267 : */
268 : unsigned flags;
269 :
270 : /*
271 : * If you have a logical tree like:
272 : *
273 : * <parent>
274 : * / | \
275 : * / | \
276 : * / | \
277 : * <child 1> <child 2> <child 3>
278 : *
279 : * The actual talloc tree is:
280 : *
281 : * <parent>
282 : * |
283 : * <child 1> - <child 2> - <child 3>
284 : *
285 : * The children are linked with next/prev pointers, and
286 : * child 1 is linked to the parent with parent/child
287 : * pointers.
288 : */
289 :
290 : struct talloc_chunk *next, *prev;
291 : struct talloc_chunk *parent, *child;
292 : struct talloc_reference_handle *refs;
293 : talloc_destructor_t destructor;
294 : const char *name;
295 : size_t size;
296 :
297 : /*
298 : * limit semantics:
299 : * if 'limit' is set it means all *new* children of the context will
300 : * be limited to a total aggregate size ox max_size for memory
301 : * allocations.
302 : * cur_size is used to keep track of the current use
303 : */
304 : struct talloc_memlimit *limit;
305 :
306 : /*
307 : * For members of a pool (i.e. TALLOC_FLAG_POOLMEM is set), "pool"
308 : * is a pointer to the struct talloc_chunk of the pool that it was
309 : * allocated from. This way children can quickly find the pool to chew
310 : * from.
311 : */
312 : struct talloc_pool_hdr *pool;
313 : };
314 :
315 : union talloc_chunk_cast_u {
316 : uint8_t *ptr;
317 : struct talloc_chunk *chunk;
318 : };
319 :
320 : /* 16 byte alignment seems to keep everyone happy */
321 : #define TC_ALIGN16(s) (((s)+15)&~15)
322 : #define TC_HDR_SIZE TC_ALIGN16(sizeof(struct talloc_chunk))
323 : #define TC_PTR_FROM_CHUNK(tc) ((void *)(TC_HDR_SIZE + (char*)tc))
324 :
325 0 : _PUBLIC_ int talloc_version_major(void)
326 : {
327 0 : return TALLOC_VERSION_MAJOR;
328 : }
329 :
330 0 : _PUBLIC_ int talloc_version_minor(void)
331 : {
332 0 : return TALLOC_VERSION_MINOR;
333 : }
334 :
335 2 : _PUBLIC_ int talloc_test_get_magic(void)
336 : {
337 2 : return talloc_magic;
338 : }
339 :
340 25173346908 : static inline void _talloc_chunk_set_free(struct talloc_chunk *tc,
341 : const char *location)
342 : {
343 : /*
344 : * Mark this memory as free, and also over-stamp the talloc
345 : * magic with the old-style magic.
346 : *
347 : * Why? This tries to avoid a memory read use-after-free from
348 : * disclosing our talloc magic, which would then allow an
349 : * attacker to prepare a valid header and so run a destructor.
350 : *
351 : */
352 25173346908 : tc->flags = TALLOC_MAGIC_NON_RANDOM | TALLOC_FLAG_FREE
353 25173346908 : | (tc->flags & TALLOC_FLAG_MASK);
354 :
355 : /* we mark the freed memory with where we called the free
356 : * from. This means on a double free error we can report where
357 : * the first free came from
358 : */
359 25173346908 : if (location) {
360 23396157655 : tc->name = location;
361 : }
362 25173346908 : }
363 :
364 1777189253 : static inline void _talloc_chunk_set_not_free(struct talloc_chunk *tc)
365 : {
366 : /*
367 : * Mark this memory as not free.
368 : *
369 : * Why? This is memory either in a pool (and so available for
370 : * talloc's re-use or after the realloc(). We need to mark
371 : * the memory as free() before any realloc() call as we can't
372 : * write to the memory after that.
373 : *
374 : * We put back the normal magic instead of the 'not random'
375 : * magic.
376 : */
377 :
378 1777189253 : tc->flags = talloc_magic |
379 1777189253 : ((tc->flags & TALLOC_FLAG_MASK) & ~TALLOC_FLAG_FREE);
380 1777189253 : }
381 :
382 : static void (*talloc_log_fn)(const char *message);
383 :
384 67913 : _PUBLIC_ void talloc_set_log_fn(void (*log_fn)(const char *message))
385 : {
386 67913 : talloc_log_fn = log_fn;
387 67913 : }
388 :
389 : #ifdef HAVE_CONSTRUCTOR_ATTRIBUTE
390 : #define CONSTRUCTOR __attribute__((constructor))
391 : #elif defined(HAVE_PRAGMA_INIT)
392 : #define CONSTRUCTOR
393 : #pragma init (talloc_lib_init)
394 : #endif
395 : #if defined(HAVE_CONSTRUCTOR_ATTRIBUTE) || defined(HAVE_PRAGMA_INIT)
396 : void talloc_lib_init(void) CONSTRUCTOR;
397 36844 : void talloc_lib_init(void)
398 : {
399 : uint32_t random_value;
400 : #if defined(HAVE_GETAUXVAL) && defined(AT_RANDOM)
401 : uint8_t *p;
402 : /*
403 : * Use the kernel-provided random values used for
404 : * ASLR. This won't change per-exec, which is ideal for us
405 : */
406 36844 : p = (uint8_t *) getauxval(AT_RANDOM);
407 36844 : if (p) {
408 : /*
409 : * We get 16 bytes from getauxval. By calling rand(),
410 : * a totally insecure PRNG, but one that will
411 : * deterministically have a different value when called
412 : * twice, we ensure that if two talloc-like libraries
413 : * are somehow loaded in the same address space, that
414 : * because we choose different bytes, we will keep the
415 : * protection against collision of multiple talloc
416 : * libs.
417 : *
418 : * This protection is important because the effects of
419 : * passing a talloc pointer from one to the other may
420 : * be very hard to determine.
421 : */
422 36844 : int offset = rand() % (16 - sizeof(random_value));
423 36844 : memcpy(&random_value, p + offset, sizeof(random_value));
424 : } else
425 : #endif
426 : {
427 : /*
428 : * Otherwise, hope the location we are loaded in
429 : * memory is randomised by someone else
430 : */
431 0 : random_value = ((uintptr_t)talloc_lib_init & 0xFFFFFFFF);
432 : }
433 36844 : talloc_magic = random_value & ~TALLOC_FLAG_MASK;
434 36844 : }
435 : #else
436 : #warning "No __attribute__((constructor)) support found on this platform, additional talloc security measures not available"
437 : #endif
438 :
439 13 : static void talloc_lib_atexit(void)
440 : {
441 13 : TALLOC_FREE(autofree_context);
442 :
443 13 : if (talloc_total_size(null_context) == 0) {
444 1 : return;
445 : }
446 :
447 12 : if (talloc_report_null_full) {
448 0 : talloc_report_full(null_context, stderr);
449 12 : } else if (talloc_report_null) {
450 12 : talloc_report(null_context, stderr);
451 : }
452 : }
453 :
454 16 : static void talloc_setup_atexit(void)
455 : {
456 : static bool done;
457 :
458 16 : if (done) {
459 3 : return;
460 : }
461 :
462 13 : atexit(talloc_lib_atexit);
463 13 : done = true;
464 : }
465 :
466 : static void talloc_log(const char *fmt, ...) PRINTF_ATTRIBUTE(1,2);
467 6 : static void talloc_log(const char *fmt, ...)
468 : {
469 : va_list ap;
470 : char *message;
471 :
472 6 : if (!talloc_log_fn) {
473 0 : return;
474 : }
475 :
476 6 : va_start(ap, fmt);
477 6 : message = talloc_vasprintf(NULL, fmt, ap);
478 6 : va_end(ap);
479 :
480 6 : talloc_log_fn(message);
481 6 : talloc_free(message);
482 : }
483 :
484 0 : static void talloc_log_stderr(const char *message)
485 : {
486 0 : fprintf(stderr, "%s", message);
487 0 : }
488 :
489 0 : _PUBLIC_ void talloc_set_log_stderr(void)
490 : {
491 0 : talloc_set_log_fn(talloc_log_stderr);
492 0 : }
493 :
494 : static void (*talloc_abort_fn)(const char *reason);
495 :
496 27317 : _PUBLIC_ void talloc_set_abort_fn(void (*abort_fn)(const char *reason))
497 : {
498 27317 : talloc_abort_fn = abort_fn;
499 27317 : }
500 :
501 0 : static void talloc_abort(const char *reason)
502 : {
503 0 : talloc_log("%s\n", reason);
504 :
505 0 : if (!talloc_abort_fn) {
506 0 : TALLOC_ABORT(reason);
507 : }
508 :
509 0 : talloc_abort_fn(reason);
510 0 : }
511 :
512 0 : static void talloc_abort_access_after_free(void)
513 : {
514 0 : talloc_abort("Bad talloc magic value - access after free");
515 0 : }
516 :
517 0 : static void talloc_abort_unknown_value(void)
518 : {
519 0 : talloc_abort("Bad talloc magic value - unknown value");
520 0 : }
521 :
522 : /* panic if we get a bad magic value */
523 54118612836 : static inline struct talloc_chunk *talloc_chunk_from_ptr(const void *ptr)
524 : {
525 54118612836 : const char *pp = (const char *)ptr;
526 54118612836 : struct talloc_chunk *tc = discard_const_p(struct talloc_chunk, pp - TC_HDR_SIZE);
527 54118612836 : if (unlikely((tc->flags & (TALLOC_FLAG_FREE | ~TALLOC_FLAG_MASK)) != talloc_magic)) {
528 0 : if ((tc->flags & (TALLOC_FLAG_FREE | ~TALLOC_FLAG_MASK))
529 : == (TALLOC_MAGIC_NON_RANDOM | TALLOC_FLAG_FREE)) {
530 0 : talloc_log("talloc: access after free error - first free may be at %s\n", tc->name);
531 0 : talloc_abort_access_after_free();
532 0 : return NULL;
533 : }
534 :
535 0 : talloc_abort_unknown_value();
536 0 : return NULL;
537 : }
538 54118612836 : return tc;
539 : }
540 :
541 : /* hook into the front of the list */
542 : #define _TLIST_ADD(list, p) \
543 : do { \
544 : if (!(list)) { \
545 : (list) = (p); \
546 : (p)->next = (p)->prev = NULL; \
547 : } else { \
548 : (list)->prev = (p); \
549 : (p)->next = (list); \
550 : (p)->prev = NULL; \
551 : (list) = (p); \
552 : }\
553 : } while (0)
554 :
555 : /* remove an element from a list - element doesn't have to be in list. */
556 : #define _TLIST_REMOVE(list, p) \
557 : do { \
558 : if ((p) == (list)) { \
559 : (list) = (p)->next; \
560 : if (list) (list)->prev = NULL; \
561 : } else { \
562 : if ((p)->prev) (p)->prev->next = (p)->next; \
563 : if ((p)->next) (p)->next->prev = (p)->prev; \
564 : } \
565 : if ((p) && ((p) != (list))) (p)->next = (p)->prev = NULL; \
566 : } while (0)
567 :
568 :
569 : /*
570 : return the parent chunk of a pointer
571 : */
572 983728208 : static inline struct talloc_chunk *talloc_parent_chunk(const void *ptr)
573 : {
574 : struct talloc_chunk *tc;
575 :
576 983728208 : if (unlikely(ptr == NULL)) {
577 362947 : return NULL;
578 : }
579 :
580 983365261 : tc = talloc_chunk_from_ptr(ptr);
581 1194246120 : while (tc->prev) tc=tc->prev;
582 :
583 983365261 : return tc->parent;
584 : }
585 :
586 450442089 : _PUBLIC_ void *talloc_parent(const void *ptr)
587 : {
588 450442089 : struct talloc_chunk *tc = talloc_parent_chunk(ptr);
589 450442089 : return tc? TC_PTR_FROM_CHUNK(tc) : NULL;
590 : }
591 :
592 : /*
593 : find parents name
594 : */
595 0 : _PUBLIC_ const char *talloc_parent_name(const void *ptr)
596 : {
597 0 : struct talloc_chunk *tc = talloc_parent_chunk(ptr);
598 0 : return tc? tc->name : NULL;
599 : }
600 :
601 : /*
602 : A pool carries an in-pool object count count in the first 16 bytes.
603 : bytes. This is done to support talloc_steal() to a parent outside of the
604 : pool. The count includes the pool itself, so a talloc_free() on a pool will
605 : only destroy the pool if the count has dropped to zero. A talloc_free() of a
606 : pool member will reduce the count, and eventually also call free(3) on the
607 : pool memory.
608 :
609 : The object count is not put into "struct talloc_chunk" because it is only
610 : relevant for talloc pools and the alignment to 16 bytes would increase the
611 : memory footprint of each talloc chunk by those 16 bytes.
612 : */
613 :
614 : struct talloc_pool_hdr {
615 : void *end;
616 : unsigned int object_count;
617 : size_t poolsize;
618 : };
619 :
620 : union talloc_pool_hdr_cast_u {
621 : uint8_t *ptr;
622 : struct talloc_pool_hdr *hdr;
623 : };
624 :
625 : #define TP_HDR_SIZE TC_ALIGN16(sizeof(struct talloc_pool_hdr))
626 :
627 426062669 : static inline struct talloc_pool_hdr *talloc_pool_from_chunk(struct talloc_chunk *c)
628 : {
629 426062669 : union talloc_chunk_cast_u tcc = { .chunk = c };
630 426062669 : union talloc_pool_hdr_cast_u tphc = { tcc.ptr - TP_HDR_SIZE };
631 426062669 : return tphc.hdr;
632 : }
633 :
634 860692829 : static inline struct talloc_chunk *talloc_chunk_from_pool(struct talloc_pool_hdr *h)
635 : {
636 860692829 : union talloc_pool_hdr_cast_u tphc = { .hdr = h };
637 860692829 : union talloc_chunk_cast_u tcc = { .ptr = tphc.ptr + TP_HDR_SIZE };
638 860692829 : return tcc.chunk;
639 : }
640 :
641 515649357 : static inline void *tc_pool_end(struct talloc_pool_hdr *pool_hdr)
642 : {
643 515649357 : struct talloc_chunk *tc = talloc_chunk_from_pool(pool_hdr);
644 515649357 : return (char *)tc + TC_HDR_SIZE + pool_hdr->poolsize;
645 : }
646 :
647 515642431 : static inline size_t tc_pool_space_left(struct talloc_pool_hdr *pool_hdr)
648 : {
649 515642431 : return (char *)tc_pool_end(pool_hdr) - (char *)pool_hdr->end;
650 : }
651 :
652 : /* If tc is inside a pool, this gives the next neighbour. */
653 346877713 : static inline void *tc_next_chunk(struct talloc_chunk *tc)
654 : {
655 346877713 : return (char *)tc + TC_ALIGN16(TC_HDR_SIZE + tc->size);
656 : }
657 :
658 75726874 : static inline void *tc_pool_first_chunk(struct talloc_pool_hdr *pool_hdr)
659 : {
660 75726874 : struct talloc_chunk *tc = talloc_chunk_from_pool(pool_hdr);
661 75726874 : return tc_next_chunk(tc);
662 : }
663 :
664 : /* Mark the whole remaining pool as not accessable */
665 155622811 : static inline void tc_invalidate_pool(struct talloc_pool_hdr *pool_hdr)
666 : {
667 155622811 : size_t flen = tc_pool_space_left(pool_hdr);
668 :
669 155622811 : if (unlikely(talloc_fill.enabled)) {
670 0 : memset(pool_hdr->end, talloc_fill.fill_value, flen);
671 : }
672 :
673 : #if defined(DEVELOPER) && defined(VALGRIND_MAKE_MEM_NOACCESS)
674 : VALGRIND_MAKE_MEM_NOACCESS(pool_hdr->end, flen);
675 : #endif
676 155622811 : }
677 :
678 : /*
679 : Allocate from a pool
680 : */
681 :
682 23356613564 : static inline struct talloc_chunk *tc_alloc_pool(struct talloc_chunk *parent,
683 : size_t size, size_t prefix_len)
684 : {
685 23356613564 : struct talloc_pool_hdr *pool_hdr = NULL;
686 : union talloc_chunk_cast_u tcc;
687 : size_t space_left;
688 : struct talloc_chunk *result;
689 : size_t chunk_size;
690 :
691 23356613564 : if (parent == NULL) {
692 0 : return NULL;
693 : }
694 :
695 23356613564 : if (parent->flags & TALLOC_FLAG_POOL) {
696 188839986 : pool_hdr = talloc_pool_from_chunk(parent);
697 : }
698 23167773578 : else if (parent->flags & TALLOC_FLAG_POOLMEM) {
699 168460006 : pool_hdr = parent->pool;
700 : }
701 :
702 23356613564 : if (pool_hdr == NULL) {
703 22999313572 : return NULL;
704 : }
705 :
706 357299992 : space_left = tc_pool_space_left(pool_hdr);
707 :
708 : /*
709 : * Align size to 16 bytes
710 : */
711 357299992 : chunk_size = TC_ALIGN16(size + prefix_len);
712 :
713 357299992 : if (space_left < chunk_size) {
714 86888590 : return NULL;
715 : }
716 :
717 270411402 : tcc = (union talloc_chunk_cast_u) {
718 270411402 : .ptr = ((uint8_t *)pool_hdr->end) + prefix_len
719 : };
720 270411402 : result = tcc.chunk;
721 :
722 : #if defined(DEVELOPER) && defined(VALGRIND_MAKE_MEM_UNDEFINED)
723 : VALGRIND_MAKE_MEM_UNDEFINED(pool_hdr->end, chunk_size);
724 : #endif
725 :
726 270411402 : pool_hdr->end = (void *)((char *)pool_hdr->end + chunk_size);
727 :
728 270411402 : result->flags = talloc_magic | TALLOC_FLAG_POOLMEM;
729 270411402 : result->pool = pool_hdr;
730 :
731 270411402 : pool_hdr->object_count++;
732 :
733 270411402 : return result;
734 : }
735 :
736 : /*
737 : Allocate a bit of memory as a child of an existing pointer
738 : */
739 23534966093 : static inline void *__talloc_with_prefix(const void *context,
740 : size_t size,
741 : size_t prefix_len,
742 : struct talloc_chunk **tc_ret)
743 : {
744 23534966093 : struct talloc_chunk *tc = NULL;
745 23534966093 : struct talloc_memlimit *limit = NULL;
746 23534966093 : size_t total_len = TC_HDR_SIZE + size + prefix_len;
747 23534966093 : struct talloc_chunk *parent = NULL;
748 :
749 23534966093 : if (unlikely(context == NULL)) {
750 233499460 : context = null_context;
751 : }
752 :
753 23534966093 : if (unlikely(size >= MAX_TALLOC_SIZE)) {
754 1 : return NULL;
755 : }
756 :
757 23534966092 : if (unlikely(total_len < TC_HDR_SIZE)) {
758 0 : return NULL;
759 : }
760 :
761 23534966092 : if (likely(context != NULL)) {
762 23355422605 : parent = talloc_chunk_from_ptr(context);
763 :
764 23355422605 : if (parent->limit != NULL) {
765 25 : limit = parent->limit;
766 : }
767 :
768 23355422605 : tc = tc_alloc_pool(parent, TC_HDR_SIZE+size, prefix_len);
769 : }
770 :
771 23534966092 : if (tc == NULL) {
772 23264586047 : uint8_t *ptr = NULL;
773 : union talloc_chunk_cast_u tcc;
774 :
775 : /*
776 : * Only do the memlimit check/update on actual allocation.
777 : */
778 23264586047 : if (!talloc_memlimit_check(limit, total_len)) {
779 6 : errno = ENOMEM;
780 12 : return NULL;
781 : }
782 :
783 23264586041 : ptr = malloc(total_len);
784 23264586041 : if (unlikely(ptr == NULL)) {
785 0 : return NULL;
786 : }
787 23264586041 : tcc = (union talloc_chunk_cast_u) { .ptr = ptr + prefix_len };
788 23264586041 : tc = tcc.chunk;
789 23264586041 : tc->flags = talloc_magic;
790 23264586041 : tc->pool = NULL;
791 :
792 23264586041 : talloc_memlimit_grow(limit, total_len);
793 : }
794 :
795 23534966086 : tc->limit = limit;
796 23534966086 : tc->size = size;
797 23534966086 : tc->destructor = NULL;
798 23534966086 : tc->child = NULL;
799 23534966086 : tc->name = NULL;
800 23534966086 : tc->refs = NULL;
801 :
802 23534966086 : if (likely(context != NULL)) {
803 23355422599 : if (parent->child) {
804 16947748879 : parent->child->parent = NULL;
805 16947748879 : tc->next = parent->child;
806 16947748879 : tc->next->prev = tc;
807 : } else {
808 6407673720 : tc->next = NULL;
809 : }
810 23355422599 : tc->parent = parent;
811 23355422599 : tc->prev = NULL;
812 23355422599 : parent->child = tc;
813 : } else {
814 179543487 : tc->next = tc->prev = tc->parent = NULL;
815 : }
816 :
817 23534966086 : *tc_ret = tc;
818 23534966086 : return TC_PTR_FROM_CHUNK(tc);
819 : }
820 :
821 23455069974 : static inline void *__talloc(const void *context,
822 : size_t size,
823 : struct talloc_chunk **tc)
824 : {
825 23455069974 : return __talloc_with_prefix(context, size, 0, tc);
826 : }
827 :
828 : /*
829 : * Create a talloc pool
830 : */
831 :
832 79896119 : static inline void *_talloc_pool(const void *context, size_t size)
833 : {
834 : struct talloc_chunk *tc;
835 : struct talloc_pool_hdr *pool_hdr;
836 : void *result;
837 :
838 79896119 : result = __talloc_with_prefix(context, size, TP_HDR_SIZE, &tc);
839 :
840 79896119 : if (unlikely(result == NULL)) {
841 0 : return NULL;
842 : }
843 :
844 79896119 : pool_hdr = talloc_pool_from_chunk(tc);
845 :
846 79896119 : tc->flags |= TALLOC_FLAG_POOL;
847 79896119 : tc->size = 0;
848 :
849 79896119 : pool_hdr->object_count = 1;
850 79896119 : pool_hdr->end = result;
851 79896119 : pool_hdr->poolsize = size;
852 :
853 79896119 : tc_invalidate_pool(pool_hdr);
854 :
855 79896119 : return result;
856 : }
857 :
858 731891 : _PUBLIC_ void *talloc_pool(const void *context, size_t size)
859 : {
860 731891 : return _talloc_pool(context, size);
861 : }
862 :
863 : /*
864 : * Create a talloc pool correctly sized for a basic size plus
865 : * a number of subobjects whose total size is given. Essentially
866 : * a custom allocator for talloc to reduce fragmentation.
867 : */
868 :
869 79164228 : _PUBLIC_ void *_talloc_pooled_object(const void *ctx,
870 : size_t type_size,
871 : const char *type_name,
872 : unsigned num_subobjects,
873 : size_t total_subobjects_size)
874 : {
875 : size_t poolsize, subobjects_slack, tmp;
876 : struct talloc_chunk *tc;
877 : struct talloc_pool_hdr *pool_hdr;
878 : void *ret;
879 :
880 79164228 : poolsize = type_size + total_subobjects_size;
881 :
882 79164228 : if ((poolsize < type_size) || (poolsize < total_subobjects_size)) {
883 0 : goto overflow;
884 : }
885 :
886 79164228 : if (num_subobjects == UINT_MAX) {
887 0 : goto overflow;
888 : }
889 79164228 : num_subobjects += 1; /* the object body itself */
890 :
891 : /*
892 : * Alignment can increase the pool size by at most 15 bytes per object
893 : * plus alignment for the object itself
894 : */
895 79164228 : subobjects_slack = (TC_HDR_SIZE + TP_HDR_SIZE + 15) * num_subobjects;
896 79164228 : if (subobjects_slack < num_subobjects) {
897 0 : goto overflow;
898 : }
899 :
900 79164228 : tmp = poolsize + subobjects_slack;
901 148964426 : if ((tmp < poolsize) || (tmp < subobjects_slack)) {
902 0 : goto overflow;
903 : }
904 79164228 : poolsize = tmp;
905 :
906 79164228 : ret = _talloc_pool(ctx, poolsize);
907 79164228 : if (ret == NULL) {
908 0 : return NULL;
909 : }
910 :
911 79164228 : tc = talloc_chunk_from_ptr(ret);
912 79164228 : tc->size = type_size;
913 :
914 79164228 : pool_hdr = talloc_pool_from_chunk(tc);
915 :
916 : #if defined(DEVELOPER) && defined(VALGRIND_MAKE_MEM_UNDEFINED)
917 : VALGRIND_MAKE_MEM_UNDEFINED(pool_hdr->end, type_size);
918 : #endif
919 :
920 79164228 : pool_hdr->end = ((char *)pool_hdr->end + TC_ALIGN16(type_size));
921 :
922 79164228 : _tc_set_name_const(tc, type_name);
923 79164228 : return ret;
924 :
925 0 : overflow:
926 0 : return NULL;
927 : }
928 :
929 : /*
930 : setup a destructor to be called on free of a pointer
931 : the destructor should return 0 on success, or -1 on failure.
932 : if the destructor fails then the free is failed, and the memory can
933 : be continued to be used
934 : */
935 1197527212 : _PUBLIC_ void _talloc_set_destructor(const void *ptr, int (*destructor)(void *))
936 : {
937 1197527212 : struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
938 1197527212 : tc->destructor = destructor;
939 1197527212 : }
940 :
941 : /*
942 : increase the reference count on a piece of memory.
943 : */
944 5 : _PUBLIC_ int talloc_increase_ref_count(const void *ptr)
945 : {
946 5 : if (unlikely(!talloc_reference(null_context, ptr))) {
947 0 : return -1;
948 : }
949 5 : return 0;
950 : }
951 :
952 : /*
953 : helper for talloc_reference()
954 :
955 : this is referenced by a function pointer and should not be inline
956 : */
957 197177229 : static int talloc_reference_destructor(struct talloc_reference_handle *handle)
958 : {
959 197177229 : struct talloc_chunk *ptr_tc = talloc_chunk_from_ptr(handle->ptr);
960 197177229 : _TLIST_REMOVE(ptr_tc->refs, handle);
961 197177229 : return 0;
962 : }
963 :
964 : /*
965 : more efficient way to add a name to a pointer - the name must point to a
966 : true string constant
967 : */
968 27755494196 : static inline void _tc_set_name_const(struct talloc_chunk *tc,
969 : const char *name)
970 : {
971 27755494196 : tc->name = name;
972 27755494196 : }
973 :
974 : /*
975 : internal talloc_named_const()
976 : */
977 17264309549 : static inline void *_talloc_named_const(const void *context, size_t size, const char *name)
978 : {
979 : void *ptr;
980 : struct talloc_chunk *tc;
981 :
982 17264309549 : ptr = __talloc(context, size, &tc);
983 17264309549 : if (unlikely(ptr == NULL)) {
984 6 : return NULL;
985 : }
986 :
987 17264309543 : _tc_set_name_const(tc, name);
988 :
989 17264309543 : return ptr;
990 : }
991 :
992 : /*
993 : make a secondary reference to a pointer, hanging off the given context.
994 : the pointer remains valid until both the original caller and this given
995 : context are freed.
996 :
997 : the major use for this is when two different structures need to reference the
998 : same underlying data, and you want to be able to free the two instances separately,
999 : and in either order
1000 : */
1001 197732935 : _PUBLIC_ void *_talloc_reference_loc(const void *context, const void *ptr, const char *location)
1002 : {
1003 : struct talloc_chunk *tc;
1004 : struct talloc_reference_handle *handle;
1005 197732935 : if (unlikely(ptr == NULL)) return NULL;
1006 :
1007 197278727 : tc = talloc_chunk_from_ptr(ptr);
1008 197278727 : handle = (struct talloc_reference_handle *)_talloc_named_const(context,
1009 : sizeof(struct talloc_reference_handle),
1010 : TALLOC_MAGIC_REFERENCE);
1011 197278727 : if (unlikely(handle == NULL)) return NULL;
1012 :
1013 : /* note that we hang the destructor off the handle, not the
1014 : main context as that allows the caller to still setup their
1015 : own destructor on the context if they want to */
1016 197278727 : talloc_set_destructor(handle, talloc_reference_destructor);
1017 197278727 : handle->ptr = discard_const_p(void, ptr);
1018 197278727 : handle->location = location;
1019 197278727 : _TLIST_ADD(tc->refs, handle);
1020 197278727 : return handle->ptr;
1021 : }
1022 :
1023 : static void *_talloc_steal_internal(const void *new_ctx, const void *ptr);
1024 :
1025 266274134 : static inline void _tc_free_poolmem(struct talloc_chunk *tc,
1026 : const char *location)
1027 : {
1028 : struct talloc_pool_hdr *pool;
1029 : struct talloc_chunk *pool_tc;
1030 : void *next_tc;
1031 :
1032 266274134 : pool = tc->pool;
1033 266274134 : pool_tc = talloc_chunk_from_pool(pool);
1034 266274134 : next_tc = tc_next_chunk(tc);
1035 :
1036 266274134 : _talloc_chunk_set_free(tc, location);
1037 :
1038 266274134 : TC_INVALIDATE_FULL_CHUNK(tc);
1039 :
1040 266274134 : if (unlikely(pool->object_count == 0)) {
1041 0 : talloc_abort("Pool object count zero!");
1042 0 : return;
1043 : }
1044 :
1045 266274134 : pool->object_count--;
1046 :
1047 266274134 : if (unlikely(pool->object_count == 1
1048 : && !(pool_tc->flags & TALLOC_FLAG_FREE))) {
1049 : /*
1050 : * if there is just one object left in the pool
1051 : * and pool->flags does not have TALLOC_FLAG_FREE,
1052 : * it means this is the pool itself and
1053 : * the rest is available for new objects
1054 : * again.
1055 : */
1056 75719948 : pool->end = tc_pool_first_chunk(pool);
1057 75719948 : tc_invalidate_pool(pool);
1058 75719948 : return;
1059 : }
1060 :
1061 190554186 : if (unlikely(pool->object_count == 0)) {
1062 : /*
1063 : * we mark the freed memory with where we called the free
1064 : * from. This means on a double free error we can report where
1065 : * the first free came from
1066 : */
1067 19308986 : pool_tc->name = location;
1068 :
1069 19308986 : if (pool_tc->flags & TALLOC_FLAG_POOLMEM) {
1070 774 : _tc_free_poolmem(pool_tc, location);
1071 : } else {
1072 : /*
1073 : * The tc_memlimit_update_on_free()
1074 : * call takes into account the
1075 : * prefix TP_HDR_SIZE allocated before
1076 : * the pool talloc_chunk.
1077 : */
1078 19308212 : tc_memlimit_update_on_free(pool_tc);
1079 19308212 : TC_INVALIDATE_FULL_CHUNK(pool_tc);
1080 19308212 : free(pool);
1081 : }
1082 19308986 : return;
1083 : }
1084 :
1085 171245200 : if (pool->end == next_tc) {
1086 : /*
1087 : * if pool->pool still points to end of
1088 : * 'tc' (which is stored in the 'next_tc' variable),
1089 : * we can reclaim the memory of 'tc'.
1090 : */
1091 94178948 : pool->end = tc;
1092 94178948 : return;
1093 : }
1094 :
1095 : /*
1096 : * Do nothing. The memory is just "wasted", waiting for the pool
1097 : * itself to be freed.
1098 : */
1099 : }
1100 :
1101 : static inline void _tc_free_children_internal(struct talloc_chunk *tc,
1102 : void *ptr,
1103 : const char *location);
1104 :
1105 : static inline int _talloc_free_internal(void *ptr, const char *location);
1106 :
1107 : /*
1108 : internal free call that takes a struct talloc_chunk *.
1109 : */
1110 23382132886 : static inline int _tc_free_internal(struct talloc_chunk *tc,
1111 : const char *location)
1112 : {
1113 : void *ptr_to_free;
1114 23382132886 : void *ptr = TC_PTR_FROM_CHUNK(tc);
1115 :
1116 23382132886 : if (unlikely(tc->refs)) {
1117 : int is_child;
1118 : /* check if this is a reference from a child or
1119 : * grandchild back to it's parent or grandparent
1120 : *
1121 : * in that case we need to remove the reference and
1122 : * call another instance of talloc_free() on the current
1123 : * pointer.
1124 : */
1125 15029275 : is_child = talloc_is_parent(tc->refs, ptr);
1126 15029275 : _talloc_free_internal(tc->refs, location);
1127 15029275 : if (is_child) {
1128 35115 : return _talloc_free_internal(ptr, location);
1129 : }
1130 14994160 : return -1;
1131 : }
1132 :
1133 23367103611 : if (unlikely(tc->flags & TALLOC_FLAG_LOOP)) {
1134 : /* we have a free loop - stop looping */
1135 359 : return 0;
1136 : }
1137 :
1138 23367103252 : if (unlikely(tc->destructor)) {
1139 953778313 : talloc_destructor_t d = tc->destructor;
1140 :
1141 : /*
1142 : * Protect the destructor against some overwrite
1143 : * attacks, by explicitly checking it has the right
1144 : * magic here.
1145 : */
1146 953778313 : if (talloc_chunk_from_ptr(ptr) != tc) {
1147 : /*
1148 : * This can't actually happen, the
1149 : * call itself will panic.
1150 : */
1151 0 : TALLOC_ABORT("talloc_chunk_from_ptr failed!");
1152 : }
1153 :
1154 953778313 : if (d == (talloc_destructor_t)-1) {
1155 614387 : return -1;
1156 : }
1157 953163926 : tc->destructor = (talloc_destructor_t)-1;
1158 953163926 : if (d(ptr) == -1) {
1159 : /*
1160 : * Only replace the destructor pointer if
1161 : * calling the destructor didn't modify it.
1162 : */
1163 236605344 : if (tc->destructor == (talloc_destructor_t)-1) {
1164 236605282 : tc->destructor = d;
1165 : }
1166 236605344 : return -1;
1167 : }
1168 716558582 : tc->destructor = NULL;
1169 : }
1170 :
1171 23129883521 : if (tc->parent) {
1172 21634210638 : _TLIST_REMOVE(tc->parent->child, tc);
1173 21634210638 : if (tc->parent->child) {
1174 15078585703 : tc->parent->child->parent = tc->parent;
1175 : }
1176 : } else {
1177 1495672883 : if (tc->prev) tc->prev->next = tc->next;
1178 1495672883 : if (tc->next) tc->next->prev = tc->prev;
1179 1495672883 : tc->prev = tc->next = NULL;
1180 : }
1181 :
1182 23129883521 : tc->flags |= TALLOC_FLAG_LOOP;
1183 :
1184 23129883521 : _tc_free_children_internal(tc, ptr, location);
1185 :
1186 23129883521 : _talloc_chunk_set_free(tc, location);
1187 :
1188 23129883521 : if (tc->flags & TALLOC_FLAG_POOL) {
1189 : struct talloc_pool_hdr *pool;
1190 :
1191 78162335 : pool = talloc_pool_from_chunk(tc);
1192 :
1193 78162335 : if (unlikely(pool->object_count == 0)) {
1194 0 : talloc_abort("Pool object count zero!");
1195 0 : return 0;
1196 : }
1197 :
1198 78162335 : pool->object_count--;
1199 :
1200 78162335 : if (likely(pool->object_count != 0)) {
1201 19322145 : return 0;
1202 : }
1203 :
1204 : /*
1205 : * With object_count==0, a pool becomes a normal piece of
1206 : * memory to free. If it's allocated inside a pool, it needs
1207 : * to be freed as poolmem, else it needs to be just freed.
1208 : */
1209 58840190 : ptr_to_free = pool;
1210 : } else {
1211 23051721186 : ptr_to_free = tc;
1212 : }
1213 :
1214 23110561376 : if (tc->flags & TALLOC_FLAG_POOLMEM) {
1215 265082404 : _tc_free_poolmem(tc, location);
1216 265082404 : return 0;
1217 : }
1218 :
1219 22845478972 : tc_memlimit_update_on_free(tc);
1220 :
1221 22845478972 : TC_INVALIDATE_FULL_CHUNK(tc);
1222 22845478972 : free(ptr_to_free);
1223 22845478972 : return 0;
1224 : }
1225 :
1226 : /*
1227 : internal talloc_free call
1228 : */
1229 3783069741 : static inline int _talloc_free_internal(void *ptr, const char *location)
1230 : {
1231 : struct talloc_chunk *tc;
1232 :
1233 3783069741 : if (unlikely(ptr == NULL)) {
1234 0 : return -1;
1235 : }
1236 :
1237 : /* possibly initialised the talloc fill value */
1238 3783069741 : if (unlikely(!talloc_fill.initialised)) {
1239 34654 : const char *fill = getenv(TALLOC_FILL_ENV);
1240 34654 : if (fill != NULL) {
1241 0 : talloc_fill.enabled = true;
1242 0 : talloc_fill.fill_value = strtoul(fill, NULL, 0);
1243 : }
1244 34654 : talloc_fill.initialised = true;
1245 : }
1246 :
1247 3783069741 : tc = talloc_chunk_from_ptr(ptr);
1248 3783069741 : return _tc_free_internal(tc, location);
1249 : }
1250 :
1251 : static inline size_t _talloc_total_limit_size(const void *ptr,
1252 : struct talloc_memlimit *old_limit,
1253 : struct talloc_memlimit *new_limit);
1254 :
1255 : /*
1256 : move a lump of memory from one talloc context to another return the
1257 : ptr on success, or NULL if it could not be transferred.
1258 : passing NULL as ptr will always return NULL with no side effects.
1259 : */
1260 1696819908 : static void *_talloc_steal_internal(const void *new_ctx, const void *ptr)
1261 : {
1262 : struct talloc_chunk *tc, *new_tc;
1263 1696819908 : size_t ctx_size = 0;
1264 :
1265 1696819908 : if (unlikely(!ptr)) {
1266 0 : return NULL;
1267 : }
1268 :
1269 1696819908 : if (unlikely(new_ctx == NULL)) {
1270 21540411 : new_ctx = null_context;
1271 : }
1272 :
1273 1696819908 : tc = talloc_chunk_from_ptr(ptr);
1274 :
1275 1696819908 : if (tc->limit != NULL) {
1276 :
1277 2 : ctx_size = _talloc_total_limit_size(ptr, NULL, NULL);
1278 :
1279 : /* Decrement the memory limit from the source .. */
1280 2 : talloc_memlimit_shrink(tc->limit->upper, ctx_size);
1281 :
1282 2 : if (tc->limit->parent == tc) {
1283 0 : tc->limit->upper = NULL;
1284 : } else {
1285 2 : tc->limit = NULL;
1286 : }
1287 : }
1288 :
1289 1696819908 : if (unlikely(new_ctx == NULL)) {
1290 21463995 : if (tc->parent) {
1291 21455409 : _TLIST_REMOVE(tc->parent->child, tc);
1292 21455409 : if (tc->parent->child) {
1293 87350 : tc->parent->child->parent = tc->parent;
1294 : }
1295 : } else {
1296 8586 : if (tc->prev) tc->prev->next = tc->next;
1297 8586 : if (tc->next) tc->next->prev = tc->prev;
1298 : }
1299 :
1300 21463995 : tc->parent = tc->next = tc->prev = NULL;
1301 21463995 : return discard_const_p(void, ptr);
1302 : }
1303 :
1304 1675355913 : new_tc = talloc_chunk_from_ptr(new_ctx);
1305 :
1306 1675355913 : if (unlikely(tc == new_tc || tc->parent == new_tc)) {
1307 45929498 : return discard_const_p(void, ptr);
1308 : }
1309 :
1310 1629426415 : if (tc->parent) {
1311 1308112489 : _TLIST_REMOVE(tc->parent->child, tc);
1312 1308112489 : if (tc->parent->child) {
1313 318156686 : tc->parent->child->parent = tc->parent;
1314 : }
1315 : } else {
1316 321313926 : if (tc->prev) tc->prev->next = tc->next;
1317 321313926 : if (tc->next) tc->next->prev = tc->prev;
1318 321313926 : tc->prev = tc->next = NULL;
1319 : }
1320 :
1321 1629426415 : tc->parent = new_tc;
1322 1629426415 : if (new_tc->child) new_tc->child->parent = NULL;
1323 1629426415 : _TLIST_ADD(new_tc->child, tc);
1324 :
1325 1629426415 : if (tc->limit || new_tc->limit) {
1326 2 : ctx_size = _talloc_total_limit_size(ptr, tc->limit,
1327 : new_tc->limit);
1328 : /* .. and increment it in the destination. */
1329 2 : if (new_tc->limit) {
1330 2 : talloc_memlimit_grow(new_tc->limit, ctx_size);
1331 : }
1332 : }
1333 :
1334 1629426415 : return discard_const_p(void, ptr);
1335 : }
1336 :
1337 : /*
1338 : move a lump of memory from one talloc context to another return the
1339 : ptr on success, or NULL if it could not be transferred.
1340 : passing NULL as ptr will always return NULL with no side effects.
1341 : */
1342 2737561055 : _PUBLIC_ void *_talloc_steal_loc(const void *new_ctx, const void *ptr, const char *location)
1343 : {
1344 : struct talloc_chunk *tc;
1345 :
1346 2737561055 : if (unlikely(ptr == NULL)) {
1347 1280092060 : return NULL;
1348 : }
1349 :
1350 1457468995 : tc = talloc_chunk_from_ptr(ptr);
1351 :
1352 1457468995 : if (unlikely(tc->refs != NULL) && talloc_parent(ptr) != new_ctx) {
1353 : struct talloc_reference_handle *h;
1354 :
1355 0 : talloc_log("WARNING: talloc_steal with references at %s\n",
1356 : location);
1357 :
1358 0 : for (h=tc->refs; h; h=h->next) {
1359 0 : talloc_log("\treference at %s\n",
1360 : h->location);
1361 : }
1362 : }
1363 :
1364 : #if 0
1365 : /* this test is probably too expensive to have on in the
1366 : normal build, but it useful for debugging */
1367 : if (talloc_is_parent(new_ctx, ptr)) {
1368 : talloc_log("WARNING: stealing into talloc child at %s\n", location);
1369 : }
1370 : #endif
1371 :
1372 1457468995 : return _talloc_steal_internal(new_ctx, ptr);
1373 : }
1374 :
1375 : /*
1376 : this is like a talloc_steal(), but you must supply the old
1377 : parent. This resolves the ambiguity in a talloc_steal() which is
1378 : called on a context that has more than one parent (via references)
1379 :
1380 : The old parent can be either a reference or a parent
1381 : */
1382 4731385 : _PUBLIC_ void *talloc_reparent(const void *old_parent, const void *new_parent, const void *ptr)
1383 : {
1384 : struct talloc_chunk *tc;
1385 : struct talloc_reference_handle *h;
1386 :
1387 4731385 : if (unlikely(ptr == NULL)) {
1388 3459955 : return NULL;
1389 : }
1390 :
1391 1271430 : if (old_parent == talloc_parent(ptr)) {
1392 1249068 : return _talloc_steal_internal(new_parent, ptr);
1393 : }
1394 :
1395 22362 : tc = talloc_chunk_from_ptr(ptr);
1396 22362 : for (h=tc->refs;h;h=h->next) {
1397 0 : if (talloc_parent(h) == old_parent) {
1398 0 : if (_talloc_steal_internal(new_parent, h) != h) {
1399 0 : return NULL;
1400 : }
1401 0 : return discard_const_p(void, ptr);
1402 : }
1403 : }
1404 :
1405 : /* it wasn't a parent */
1406 22362 : return NULL;
1407 : }
1408 :
1409 : /*
1410 : remove a secondary reference to a pointer. This undo's what
1411 : talloc_reference() has done. The context and pointer arguments
1412 : must match those given to a talloc_reference()
1413 : */
1414 57055058 : static inline int talloc_unreference(const void *context, const void *ptr)
1415 : {
1416 57055058 : struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
1417 : struct talloc_reference_handle *h;
1418 :
1419 57055058 : if (unlikely(context == NULL)) {
1420 51357012 : context = null_context;
1421 : }
1422 :
1423 58454876 : for (h=tc->refs;h;h=h->next) {
1424 2806433 : struct talloc_chunk *p = talloc_parent_chunk(h);
1425 2806433 : if (p == NULL) {
1426 0 : if (context == NULL) break;
1427 2806433 : } else if (TC_PTR_FROM_CHUNK(p) == context) {
1428 1406615 : break;
1429 : }
1430 : }
1431 57055058 : if (h == NULL) {
1432 55648443 : return -1;
1433 : }
1434 :
1435 1406615 : return _talloc_free_internal(h, __location__);
1436 : }
1437 :
1438 : /*
1439 : remove a specific parent context from a pointer. This is a more
1440 : controlled variant of talloc_free()
1441 : */
1442 :
1443 : /* coverity[ -tainted_data_sink : arg-1 ] */
1444 57463804 : _PUBLIC_ int talloc_unlink(const void *context, void *ptr)
1445 : {
1446 : struct talloc_chunk *tc_p, *new_p, *tc_c;
1447 : void *new_parent;
1448 :
1449 57463804 : if (ptr == NULL) {
1450 1791826 : return -1;
1451 : }
1452 :
1453 55671978 : if (context == NULL) {
1454 51485985 : context = null_context;
1455 : }
1456 :
1457 55671978 : if (talloc_unreference(context, ptr) == 0) {
1458 23535 : return 0;
1459 : }
1460 :
1461 55648443 : if (context != NULL) {
1462 4291431 : tc_c = talloc_chunk_from_ptr(context);
1463 : } else {
1464 51357012 : tc_c = NULL;
1465 : }
1466 55648443 : if (tc_c != talloc_parent_chunk(ptr)) {
1467 101659 : return -1;
1468 : }
1469 :
1470 55546784 : tc_p = talloc_chunk_from_ptr(ptr);
1471 :
1472 55546784 : if (tc_p->refs == NULL) {
1473 54163704 : return _talloc_free_internal(ptr, __location__);
1474 : }
1475 :
1476 1383080 : new_p = talloc_parent_chunk(tc_p->refs);
1477 1383080 : if (new_p) {
1478 1383080 : new_parent = TC_PTR_FROM_CHUNK(new_p);
1479 : } else {
1480 0 : new_parent = NULL;
1481 : }
1482 :
1483 1383080 : if (talloc_unreference(new_parent, ptr) != 0) {
1484 0 : return -1;
1485 : }
1486 :
1487 1383080 : _talloc_steal_internal(new_parent, ptr);
1488 :
1489 1383080 : return 0;
1490 : }
1491 :
1492 : /*
1493 : add a name to an existing pointer - va_list version
1494 : */
1495 : static inline const char *tc_set_name_v(struct talloc_chunk *tc,
1496 : const char *fmt,
1497 : va_list ap) PRINTF_ATTRIBUTE(2,0);
1498 :
1499 16890733 : static inline const char *tc_set_name_v(struct talloc_chunk *tc,
1500 : const char *fmt,
1501 : va_list ap)
1502 : {
1503 16890733 : struct talloc_chunk *name_tc = _vasprintf_tc(TC_PTR_FROM_CHUNK(tc),
1504 : fmt,
1505 : ap);
1506 16890733 : if (likely(name_tc)) {
1507 16890733 : tc->name = TC_PTR_FROM_CHUNK(name_tc);
1508 16890733 : _tc_set_name_const(name_tc, ".name");
1509 : } else {
1510 0 : tc->name = NULL;
1511 : }
1512 16890733 : return tc->name;
1513 : }
1514 :
1515 : /*
1516 : add a name to an existing pointer
1517 : */
1518 12743911 : _PUBLIC_ const char *talloc_set_name(const void *ptr, const char *fmt, ...)
1519 : {
1520 12743911 : struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
1521 : const char *name;
1522 : va_list ap;
1523 12743911 : va_start(ap, fmt);
1524 12743911 : name = tc_set_name_v(tc, fmt, ap);
1525 12743911 : va_end(ap);
1526 12743911 : return name;
1527 : }
1528 :
1529 :
1530 : /*
1531 : create a named talloc pointer. Any talloc pointer can be named, and
1532 : talloc_named() operates just like talloc() except that it allows you
1533 : to name the pointer.
1534 : */
1535 3304130 : _PUBLIC_ void *talloc_named(const void *context, size_t size, const char *fmt, ...)
1536 : {
1537 : va_list ap;
1538 : void *ptr;
1539 : const char *name;
1540 : struct talloc_chunk *tc;
1541 :
1542 3304130 : ptr = __talloc(context, size, &tc);
1543 3304130 : if (unlikely(ptr == NULL)) return NULL;
1544 :
1545 3304130 : va_start(ap, fmt);
1546 3304130 : name = tc_set_name_v(tc, fmt, ap);
1547 3304130 : va_end(ap);
1548 :
1549 3304130 : if (unlikely(name == NULL)) {
1550 0 : _talloc_free_internal(ptr, __location__);
1551 0 : return NULL;
1552 : }
1553 :
1554 3304130 : return ptr;
1555 : }
1556 :
1557 : /*
1558 : return the name of a talloc ptr, or "UNNAMED"
1559 : */
1560 7832148557 : static inline const char *__talloc_get_name(const void *ptr)
1561 : {
1562 7832148557 : struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
1563 7832148506 : if (unlikely(tc->name == TALLOC_MAGIC_REFERENCE)) {
1564 0 : return ".reference";
1565 : }
1566 7832148506 : if (likely(tc->name)) {
1567 7832148476 : return tc->name;
1568 : }
1569 30 : return "UNNAMED";
1570 : }
1571 :
1572 333878 : _PUBLIC_ const char *talloc_get_name(const void *ptr)
1573 : {
1574 333878 : return __talloc_get_name(ptr);
1575 : }
1576 :
1577 : /*
1578 : check if a pointer has the given name. If it does, return the pointer,
1579 : otherwise return NULL
1580 : */
1581 5792072314 : _PUBLIC_ void *talloc_check_name(const void *ptr, const char *name)
1582 : {
1583 : const char *pname;
1584 5792072314 : if (unlikely(ptr == NULL)) return NULL;
1585 5781894058 : pname = __talloc_get_name(ptr);
1586 5781894058 : if (likely(pname == name || strcmp(pname, name) == 0)) {
1587 5762064451 : return discard_const_p(void, ptr);
1588 : }
1589 19829607 : return NULL;
1590 : }
1591 :
1592 0 : static void talloc_abort_type_mismatch(const char *location,
1593 : const char *name,
1594 : const char *expected)
1595 : {
1596 : const char *reason;
1597 :
1598 0 : reason = talloc_asprintf(NULL,
1599 : "%s: Type mismatch: name[%s] expected[%s]",
1600 : location,
1601 : name?name:"NULL",
1602 : expected);
1603 0 : if (!reason) {
1604 0 : reason = "Type mismatch";
1605 : }
1606 :
1607 0 : talloc_abort(reason);
1608 0 : }
1609 :
1610 2049920153 : _PUBLIC_ void *_talloc_get_type_abort(const void *ptr, const char *name, const char *location)
1611 : {
1612 : const char *pname;
1613 :
1614 2049920153 : if (unlikely(ptr == NULL)) {
1615 0 : talloc_abort_type_mismatch(location, NULL, name);
1616 0 : return NULL;
1617 : }
1618 :
1619 2049920153 : pname = __talloc_get_name(ptr);
1620 2049920102 : if (likely(pname == name || strcmp(pname, name) == 0)) {
1621 2049920102 : return discard_const_p(void, ptr);
1622 : }
1623 :
1624 0 : talloc_abort_type_mismatch(location, pname, name);
1625 0 : return NULL;
1626 : }
1627 :
1628 : /*
1629 : this is for compatibility with older versions of talloc
1630 : */
1631 842692 : _PUBLIC_ void *talloc_init(const char *fmt, ...)
1632 : {
1633 : va_list ap;
1634 : void *ptr;
1635 : const char *name;
1636 : struct talloc_chunk *tc;
1637 :
1638 842692 : ptr = __talloc(NULL, 0, &tc);
1639 842692 : if (unlikely(ptr == NULL)) return NULL;
1640 :
1641 842692 : va_start(ap, fmt);
1642 842692 : name = tc_set_name_v(tc, fmt, ap);
1643 842692 : va_end(ap);
1644 :
1645 842692 : if (unlikely(name == NULL)) {
1646 0 : _talloc_free_internal(ptr, __location__);
1647 0 : return NULL;
1648 : }
1649 :
1650 842692 : return ptr;
1651 : }
1652 :
1653 23171676418 : static inline void _tc_free_children_internal(struct talloc_chunk *tc,
1654 : void *ptr,
1655 : const char *location)
1656 : {
1657 65942415981 : while (tc->child) {
1658 : /* we need to work out who will own an abandoned child
1659 : if it cannot be freed. In priority order, the first
1660 : choice is owner of any remaining reference to this
1661 : pointer, the second choice is our parent, and the
1662 : final choice is the null context. */
1663 19599063145 : void *child = TC_PTR_FROM_CHUNK(tc->child);
1664 19599063145 : const void *new_parent = null_context;
1665 19599063145 : if (unlikely(tc->child->refs)) {
1666 15004730 : struct talloc_chunk *p = talloc_parent_chunk(tc->child->refs);
1667 15004730 : if (p) new_parent = TC_PTR_FROM_CHUNK(p);
1668 : }
1669 19599063145 : if (unlikely(_tc_free_internal(tc->child, location) == -1)) {
1670 236718827 : if (talloc_parent_chunk(child) != tc) {
1671 : /*
1672 : * Destructor already reparented this child.
1673 : * No further reparenting needed.
1674 : */
1675 62 : continue;
1676 : }
1677 236718765 : if (new_parent == null_context) {
1678 221724606 : struct talloc_chunk *p = talloc_parent_chunk(ptr);
1679 221724606 : if (p) new_parent = TC_PTR_FROM_CHUNK(p);
1680 : }
1681 236718765 : _talloc_steal_internal(new_parent, child);
1682 : }
1683 : }
1684 23171676418 : }
1685 :
1686 : /*
1687 : this is a replacement for the Samba3 talloc_destroy_pool functionality. It
1688 : should probably not be used in new code. It's in here to keep the talloc
1689 : code consistent across Samba 3 and 4.
1690 : */
1691 41792897 : _PUBLIC_ void talloc_free_children(void *ptr)
1692 : {
1693 41792897 : struct talloc_chunk *tc_name = NULL;
1694 : struct talloc_chunk *tc;
1695 :
1696 41792897 : if (unlikely(ptr == NULL)) {
1697 0 : return;
1698 : }
1699 :
1700 41792897 : tc = talloc_chunk_from_ptr(ptr);
1701 :
1702 : /* we do not want to free the context name if it is a child .. */
1703 41792897 : if (likely(tc->child)) {
1704 67706038 : for (tc_name = tc->child; tc_name; tc_name = tc_name->next) {
1705 40086242 : if (tc->name == TC_PTR_FROM_CHUNK(tc_name)) break;
1706 : }
1707 27619849 : if (tc_name) {
1708 53 : _TLIST_REMOVE(tc->child, tc_name);
1709 53 : if (tc->child) {
1710 53 : tc->child->parent = tc;
1711 : }
1712 : }
1713 : }
1714 :
1715 41792897 : _tc_free_children_internal(tc, ptr, __location__);
1716 :
1717 : /* .. so we put it back after all other children have been freed */
1718 41792897 : if (tc_name) {
1719 53 : if (tc->child) {
1720 0 : tc->child->parent = NULL;
1721 : }
1722 53 : tc_name->parent = tc;
1723 53 : _TLIST_ADD(tc->child, tc_name);
1724 : }
1725 : }
1726 :
1727 : /*
1728 : Allocate a bit of memory as a child of an existing pointer
1729 : */
1730 0 : _PUBLIC_ void *_talloc(const void *context, size_t size)
1731 : {
1732 : struct talloc_chunk *tc;
1733 0 : return __talloc(context, size, &tc);
1734 : }
1735 :
1736 : /*
1737 : externally callable talloc_set_name_const()
1738 : */
1739 2038878735 : _PUBLIC_ void talloc_set_name_const(const void *ptr, const char *name)
1740 : {
1741 2038878735 : _tc_set_name_const(talloc_chunk_from_ptr(ptr), name);
1742 2038878735 : }
1743 :
1744 : /*
1745 : create a named talloc pointer. Any talloc pointer can be named, and
1746 : talloc_named() operates just like talloc() except that it allows you
1747 : to name the pointer.
1748 : */
1749 2208315246 : _PUBLIC_ void *talloc_named_const(const void *context, size_t size, const char *name)
1750 : {
1751 2208315246 : return _talloc_named_const(context, size, name);
1752 : }
1753 :
1754 : /*
1755 : free a talloc pointer. This also frees all child pointers of this
1756 : pointer recursively
1757 :
1758 : return 0 if the memory is actually freed, otherwise -1. The memory
1759 : will not be freed if the ref_count is > 1 or the destructor (if
1760 : any) returns non-zero
1761 : */
1762 4263401797 : _PUBLIC_ int _talloc_free(void *ptr, const char *location)
1763 : {
1764 : struct talloc_chunk *tc;
1765 :
1766 4263401797 : if (unlikely(ptr == NULL)) {
1767 550696824 : return -1;
1768 : }
1769 :
1770 3712704973 : tc = talloc_chunk_from_ptr(ptr);
1771 :
1772 3712704973 : if (unlikely(tc->refs != NULL)) {
1773 : struct talloc_reference_handle *h;
1774 :
1775 269941 : if (talloc_parent(ptr) == null_context && tc->refs->next == NULL) {
1776 : /* in this case we do know which parent should
1777 : get this pointer, as there is really only
1778 : one parent */
1779 269939 : return talloc_unlink(null_context, ptr);
1780 : }
1781 :
1782 2 : talloc_log("ERROR: talloc_free with references at %s\n",
1783 : location);
1784 :
1785 6 : for (h=tc->refs; h; h=h->next) {
1786 4 : talloc_log("\treference at %s\n",
1787 : h->location);
1788 : }
1789 2 : return -1;
1790 : }
1791 :
1792 3712435032 : return _talloc_free_internal(ptr, location);
1793 : }
1794 :
1795 :
1796 :
1797 : /*
1798 : A talloc version of realloc. The context argument is only used if
1799 : ptr is NULL
1800 : */
1801 3548099443 : _PUBLIC_ void *_talloc_realloc(const void *context, void *ptr, size_t size, const char *name)
1802 : {
1803 : struct talloc_chunk *tc;
1804 : void *new_ptr;
1805 3548099443 : bool malloced = false;
1806 3548099443 : struct talloc_pool_hdr *pool_hdr = NULL;
1807 3548099443 : size_t old_size = 0;
1808 3548099443 : size_t new_size = 0;
1809 :
1810 : /* size zero is equivalent to free() */
1811 3548099443 : if (unlikely(size == 0)) {
1812 149683 : talloc_unlink(context, ptr);
1813 149683 : return NULL;
1814 : }
1815 :
1816 3547949760 : if (unlikely(size >= MAX_TALLOC_SIZE)) {
1817 1 : return NULL;
1818 : }
1819 :
1820 : /* realloc(NULL) is equivalent to malloc() */
1821 3547949759 : if (ptr == NULL) {
1822 480458658 : return _talloc_named_const(context, size, name);
1823 : }
1824 :
1825 3067491101 : tc = talloc_chunk_from_ptr(ptr);
1826 :
1827 : /* don't allow realloc on referenced pointers */
1828 3067491101 : if (unlikely(tc->refs)) {
1829 1 : return NULL;
1830 : }
1831 :
1832 : /* don't let anybody try to realloc a talloc_pool */
1833 3067491100 : if (unlikely(tc->flags & TALLOC_FLAG_POOL)) {
1834 0 : return NULL;
1835 : }
1836 :
1837 : /* handle realloc inside a talloc_pool */
1838 3067491100 : if (unlikely(tc->flags & TALLOC_FLAG_POOLMEM)) {
1839 3207634 : pool_hdr = tc->pool;
1840 : }
1841 :
1842 : /* don't shrink if we have less than 1k to gain */
1843 3067491100 : if (size < tc->size && tc->limit == NULL) {
1844 712636200 : if (pool_hdr) {
1845 126043 : void *next_tc = tc_next_chunk(tc);
1846 126043 : TC_INVALIDATE_SHRINK_CHUNK(tc, size);
1847 126043 : tc->size = size;
1848 126043 : if (next_tc == pool_hdr->end) {
1849 : /* note: tc->size has changed, so this works */
1850 126037 : pool_hdr->end = tc_next_chunk(tc);
1851 : }
1852 126043 : return ptr;
1853 708609054 : } else if ((tc->size - size) < 1024) {
1854 : /*
1855 : * if we call TC_INVALIDATE_SHRINK_CHUNK() here
1856 : * we would need to call TC_UNDEFINE_GROW_CHUNK()
1857 : * after each realloc call, which slows down
1858 : * testing a lot :-(.
1859 : *
1860 : * That is why we only mark memory as undefined here.
1861 : */
1862 704410647 : TC_UNDEFINE_SHRINK_CHUNK(tc, size);
1863 :
1864 : /* do not shrink if we have less than 1k to gain */
1865 704410647 : tc->size = size;
1866 704410647 : return ptr;
1867 : }
1868 2358756003 : } else if (tc->size == size) {
1869 : /*
1870 : * do not change the pointer if it is exactly
1871 : * the same size.
1872 : */
1873 585765157 : return ptr;
1874 : }
1875 :
1876 : /*
1877 : * by resetting magic we catch users of the old memory
1878 : *
1879 : * We mark this memory as free, and also over-stamp the talloc
1880 : * magic with the old-style magic.
1881 : *
1882 : * Why? This tries to avoid a memory read use-after-free from
1883 : * disclosing our talloc magic, which would then allow an
1884 : * attacker to prepare a valid header and so run a destructor.
1885 : *
1886 : * What else? We have to re-stamp back a valid normal magic
1887 : * on this memory once realloc() is done, as it will have done
1888 : * a memcpy() into the new valid memory. We can't do this in
1889 : * reverse as that would be a real use-after-free.
1890 : */
1891 1777189253 : _talloc_chunk_set_free(tc, NULL);
1892 :
1893 1777189253 : if (pool_hdr) {
1894 : struct talloc_chunk *pool_tc;
1895 3042464 : void *next_tc = tc_next_chunk(tc);
1896 3042464 : size_t old_chunk_size = TC_ALIGN16(TC_HDR_SIZE + tc->size);
1897 3042464 : size_t new_chunk_size = TC_ALIGN16(TC_HDR_SIZE + size);
1898 : size_t space_needed;
1899 : size_t space_left;
1900 3042464 : unsigned int chunk_count = pool_hdr->object_count;
1901 :
1902 3042464 : pool_tc = talloc_chunk_from_pool(pool_hdr);
1903 3042464 : if (!(pool_tc->flags & TALLOC_FLAG_FREE)) {
1904 3035689 : chunk_count -= 1;
1905 : }
1906 :
1907 3042464 : if (chunk_count == 1) {
1908 : /*
1909 : * optimize for the case where 'tc' is the only
1910 : * chunk in the pool.
1911 : */
1912 6926 : char *start = tc_pool_first_chunk(pool_hdr);
1913 6926 : space_needed = new_chunk_size;
1914 6926 : space_left = (char *)tc_pool_end(pool_hdr) - start;
1915 :
1916 6926 : if (space_left >= space_needed) {
1917 6744 : size_t old_used = TC_HDR_SIZE + tc->size;
1918 6744 : size_t new_used = TC_HDR_SIZE + size;
1919 6744 : new_ptr = start;
1920 :
1921 : #if defined(DEVELOPER) && defined(VALGRIND_MAKE_MEM_UNDEFINED)
1922 : {
1923 : /*
1924 : * The area from
1925 : * start -> tc may have
1926 : * been freed and thus been marked as
1927 : * VALGRIND_MEM_NOACCESS. Set it to
1928 : * VALGRIND_MEM_UNDEFINED so we can
1929 : * copy into it without valgrind errors.
1930 : * We can't just mark
1931 : * new_ptr -> new_ptr + old_used
1932 : * as this may overlap on top of tc,
1933 : * (which is why we use memmove, not
1934 : * memcpy below) hence the MIN.
1935 : */
1936 : size_t undef_len = MIN((((char *)tc) - ((char *)new_ptr)),old_used);
1937 : VALGRIND_MAKE_MEM_UNDEFINED(new_ptr, undef_len);
1938 : }
1939 : #endif
1940 :
1941 6744 : memmove(new_ptr, tc, old_used);
1942 :
1943 6744 : tc = (struct talloc_chunk *)new_ptr;
1944 : TC_UNDEFINE_GROW_CHUNK(tc, size);
1945 :
1946 : /*
1947 : * first we do not align the pool pointer
1948 : * because we want to invalidate the padding
1949 : * too.
1950 : */
1951 6744 : pool_hdr->end = new_used + (char *)new_ptr;
1952 6744 : tc_invalidate_pool(pool_hdr);
1953 :
1954 : /* now the aligned pointer */
1955 6744 : pool_hdr->end = new_chunk_size + (char *)new_ptr;
1956 6744 : goto got_new_ptr;
1957 : }
1958 :
1959 182 : next_tc = NULL;
1960 : }
1961 :
1962 3035720 : if (new_chunk_size == old_chunk_size) {
1963 : TC_UNDEFINE_GROW_CHUNK(tc, size);
1964 262600 : _talloc_chunk_set_not_free(tc);
1965 262600 : tc->size = size;
1966 262600 : return ptr;
1967 : }
1968 :
1969 2773120 : if (next_tc == pool_hdr->end) {
1970 : /*
1971 : * optimize for the case where 'tc' is the last
1972 : * chunk in the pool.
1973 : */
1974 2719628 : space_needed = new_chunk_size - old_chunk_size;
1975 2719628 : space_left = tc_pool_space_left(pool_hdr);
1976 :
1977 2719628 : if (space_left >= space_needed) {
1978 : TC_UNDEFINE_GROW_CHUNK(tc, size);
1979 1582161 : _talloc_chunk_set_not_free(tc);
1980 1582161 : tc->size = size;
1981 1582161 : pool_hdr->end = tc_next_chunk(tc);
1982 1582161 : return ptr;
1983 : }
1984 : }
1985 :
1986 1190959 : new_ptr = tc_alloc_pool(tc, size + TC_HDR_SIZE, 0);
1987 :
1988 1190959 : if (new_ptr == NULL) {
1989 : /*
1990 : * Couldn't allocate from pool (pool size
1991 : * counts as already allocated for memlimit
1992 : * purposes). We must check memory limit
1993 : * before any real malloc.
1994 : */
1995 1159602 : if (tc->limit) {
1996 : /*
1997 : * Note we're doing an extra malloc,
1998 : * on top of the pool size, so account
1999 : * for size only, not the difference
2000 : * between old and new size.
2001 : */
2002 4 : if (!talloc_memlimit_check(tc->limit, size)) {
2003 3 : _talloc_chunk_set_not_free(tc);
2004 3 : errno = ENOMEM;
2005 3 : return NULL;
2006 : }
2007 : }
2008 1159599 : new_ptr = malloc(TC_HDR_SIZE+size);
2009 1159599 : malloced = true;
2010 1159599 : new_size = size;
2011 : }
2012 :
2013 1190956 : if (new_ptr) {
2014 1190956 : memcpy(new_ptr, tc, MIN(tc->size,size) + TC_HDR_SIZE);
2015 :
2016 1190956 : _tc_free_poolmem(tc, __location__ "_talloc_realloc");
2017 : }
2018 : }
2019 : else {
2020 : /* We're doing realloc here, so record the difference. */
2021 1774146789 : old_size = tc->size;
2022 1774146789 : new_size = size;
2023 : /*
2024 : * We must check memory limit
2025 : * before any real realloc.
2026 : */
2027 1774146789 : if (tc->limit && (size > old_size)) {
2028 1 : if (!talloc_memlimit_check(tc->limit,
2029 : (size - old_size))) {
2030 1 : _talloc_chunk_set_not_free(tc);
2031 1 : errno = ENOMEM;
2032 1 : return NULL;
2033 : }
2034 : }
2035 1774146788 : new_ptr = realloc(tc, size + TC_HDR_SIZE);
2036 : }
2037 1775344488 : got_new_ptr:
2038 :
2039 1775344488 : if (unlikely(!new_ptr)) {
2040 : /*
2041 : * Ok, this is a strange spot. We have to put back
2042 : * the old talloc_magic and any flags, except the
2043 : * TALLOC_FLAG_FREE as this was not free'ed by the
2044 : * realloc() call after all
2045 : */
2046 0 : _talloc_chunk_set_not_free(tc);
2047 0 : return NULL;
2048 : }
2049 :
2050 : /*
2051 : * tc is now the new value from realloc(), the old memory we
2052 : * can't access any more and was preemptively marked as
2053 : * TALLOC_FLAG_FREE before the call. Now we mark it as not
2054 : * free again
2055 : */
2056 1775344488 : tc = (struct talloc_chunk *)new_ptr;
2057 1775344488 : _talloc_chunk_set_not_free(tc);
2058 1775344488 : if (malloced) {
2059 1159599 : tc->flags &= ~TALLOC_FLAG_POOLMEM;
2060 : }
2061 1775344488 : if (tc->parent) {
2062 1287651109 : tc->parent->child = tc;
2063 : }
2064 1775344488 : if (tc->child) {
2065 974143096 : tc->child->parent = tc;
2066 : }
2067 :
2068 1775344488 : if (tc->prev) {
2069 485347788 : tc->prev->next = tc;
2070 : }
2071 1775344488 : if (tc->next) {
2072 1108793357 : tc->next->prev = tc;
2073 : }
2074 :
2075 1775344488 : if (new_size > old_size) {
2076 1771107979 : talloc_memlimit_grow(tc->limit, new_size - old_size);
2077 4236509 : } else if (new_size < old_size) {
2078 4198408 : talloc_memlimit_shrink(tc->limit, old_size - new_size);
2079 : }
2080 :
2081 1775344488 : tc->size = size;
2082 1775344488 : _tc_set_name_const(tc, name);
2083 :
2084 1775344488 : return TC_PTR_FROM_CHUNK(tc);
2085 : }
2086 :
2087 : /*
2088 : a wrapper around talloc_steal() for situations where you are moving a pointer
2089 : between two structures, and want the old pointer to be set to NULL
2090 : */
2091 200048446 : _PUBLIC_ void *_talloc_move(const void *new_ctx, const void *_pptr)
2092 : {
2093 200048446 : const void **pptr = discard_const_p(const void *,_pptr);
2094 200048446 : void *ret = talloc_steal(new_ctx, discard_const_p(void, *pptr));
2095 200048446 : (*pptr) = NULL;
2096 200048446 : return ret;
2097 : }
2098 :
2099 : enum talloc_mem_count_type {
2100 : TOTAL_MEM_SIZE,
2101 : TOTAL_MEM_BLOCKS,
2102 : TOTAL_MEM_LIMIT,
2103 : };
2104 :
2105 119702312 : static inline size_t _talloc_total_mem_internal(const void *ptr,
2106 : enum talloc_mem_count_type type,
2107 : struct talloc_memlimit *old_limit,
2108 : struct talloc_memlimit *new_limit)
2109 : {
2110 119702312 : size_t total = 0;
2111 : struct talloc_chunk *c, *tc;
2112 :
2113 119702312 : if (ptr == NULL) {
2114 4 : ptr = null_context;
2115 : }
2116 119702312 : if (ptr == NULL) {
2117 1 : return 0;
2118 : }
2119 :
2120 119702311 : tc = talloc_chunk_from_ptr(ptr);
2121 :
2122 119702311 : if (old_limit || new_limit) {
2123 7 : if (tc->limit && tc->limit->upper == old_limit) {
2124 0 : tc->limit->upper = new_limit;
2125 : }
2126 : }
2127 :
2128 : /* optimize in the memlimits case */
2129 119702320 : if (type == TOTAL_MEM_LIMIT &&
2130 14 : tc->limit != NULL &&
2131 7 : tc->limit != old_limit &&
2132 2 : tc->limit->parent == tc) {
2133 0 : return tc->limit->cur_size;
2134 : }
2135 :
2136 119702311 : if (tc->flags & TALLOC_FLAG_LOOP) {
2137 77759157 : return 0;
2138 : }
2139 :
2140 41943154 : tc->flags |= TALLOC_FLAG_LOOP;
2141 :
2142 41943154 : if (old_limit || new_limit) {
2143 7 : if (old_limit == tc->limit) {
2144 7 : tc->limit = new_limit;
2145 : }
2146 : }
2147 :
2148 41943154 : switch (type) {
2149 149066 : case TOTAL_MEM_SIZE:
2150 149066 : if (likely(tc->name != TALLOC_MAGIC_REFERENCE)) {
2151 149046 : total = tc->size;
2152 : }
2153 149066 : break;
2154 41794079 : case TOTAL_MEM_BLOCKS:
2155 41794079 : total++;
2156 41794079 : break;
2157 9 : case TOTAL_MEM_LIMIT:
2158 9 : if (likely(tc->name != TALLOC_MAGIC_REFERENCE)) {
2159 : /*
2160 : * Don't count memory allocated from a pool
2161 : * when calculating limits. Only count the
2162 : * pool itself.
2163 : */
2164 9 : if (!(tc->flags & TALLOC_FLAG_POOLMEM)) {
2165 8 : if (tc->flags & TALLOC_FLAG_POOL) {
2166 : /*
2167 : * If this is a pool, the allocated
2168 : * size is in the pool header, and
2169 : * remember to add in the prefix
2170 : * length.
2171 : */
2172 1 : struct talloc_pool_hdr *pool_hdr
2173 0 : = talloc_pool_from_chunk(tc);
2174 1 : total = pool_hdr->poolsize +
2175 : TC_HDR_SIZE +
2176 : TP_HDR_SIZE;
2177 : } else {
2178 7 : total = tc->size + TC_HDR_SIZE;
2179 : }
2180 : }
2181 : }
2182 9 : break;
2183 : }
2184 42058286 : for (c = tc->child; c; c = c->next) {
2185 115132 : total += _talloc_total_mem_internal(TC_PTR_FROM_CHUNK(c), type,
2186 : old_limit, new_limit);
2187 : }
2188 :
2189 41943154 : tc->flags &= ~TALLOC_FLAG_LOOP;
2190 :
2191 41943154 : return total;
2192 : }
2193 :
2194 : /*
2195 : return the total size of a talloc pool (subtree)
2196 : */
2197 34632 : _PUBLIC_ size_t talloc_total_size(const void *ptr)
2198 : {
2199 34632 : return _talloc_total_mem_internal(ptr, TOTAL_MEM_SIZE, NULL, NULL);
2200 : }
2201 :
2202 : /*
2203 : return the total number of blocks in a talloc pool (subtree)
2204 : */
2205 119552539 : _PUBLIC_ size_t talloc_total_blocks(const void *ptr)
2206 : {
2207 119552539 : return _talloc_total_mem_internal(ptr, TOTAL_MEM_BLOCKS, NULL, NULL);
2208 : }
2209 :
2210 : /*
2211 : return the number of external references to a pointer
2212 : */
2213 2287 : _PUBLIC_ size_t talloc_reference_count(const void *ptr)
2214 : {
2215 2287 : struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
2216 : struct talloc_reference_handle *h;
2217 2287 : size_t ret = 0;
2218 :
2219 2305 : for (h=tc->refs;h;h=h->next) {
2220 18 : ret++;
2221 : }
2222 2287 : return ret;
2223 : }
2224 :
2225 : /*
2226 : report on memory usage by all children of a pointer, giving a full tree view
2227 : */
2228 559 : _PUBLIC_ void talloc_report_depth_cb(const void *ptr, int depth, int max_depth,
2229 : void (*callback)(const void *ptr,
2230 : int depth, int max_depth,
2231 : int is_ref,
2232 : void *private_data),
2233 : void *private_data)
2234 : {
2235 : struct talloc_chunk *c, *tc;
2236 :
2237 559 : if (ptr == NULL) {
2238 103 : ptr = null_context;
2239 : }
2240 559 : if (ptr == NULL) return;
2241 :
2242 460 : tc = talloc_chunk_from_ptr(ptr);
2243 :
2244 460 : if (tc->flags & TALLOC_FLAG_LOOP) {
2245 0 : return;
2246 : }
2247 :
2248 460 : callback(ptr, depth, max_depth, 0, private_data);
2249 :
2250 460 : if (max_depth >= 0 && depth >= max_depth) {
2251 126 : return;
2252 : }
2253 :
2254 334 : tc->flags |= TALLOC_FLAG_LOOP;
2255 703 : for (c=tc->child;c;c=c->next) {
2256 369 : if (c->name == TALLOC_MAGIC_REFERENCE) {
2257 8 : struct talloc_reference_handle *h = (struct talloc_reference_handle *)TC_PTR_FROM_CHUNK(c);
2258 8 : callback(h->ptr, depth + 1, max_depth, 1, private_data);
2259 : } else {
2260 361 : talloc_report_depth_cb(TC_PTR_FROM_CHUNK(c), depth + 1, max_depth, callback, private_data);
2261 : }
2262 : }
2263 334 : tc->flags &= ~TALLOC_FLAG_LOOP;
2264 : }
2265 :
2266 468 : static void talloc_report_depth_FILE_helper(const void *ptr, int depth, int max_depth, int is_ref, void *_f)
2267 : {
2268 468 : const char *name = __talloc_get_name(ptr);
2269 : struct talloc_chunk *tc;
2270 468 : FILE *f = (FILE *)_f;
2271 :
2272 468 : if (is_ref) {
2273 8 : fprintf(f, "%*sreference to: %s\n", depth*4, "", name);
2274 8 : return;
2275 : }
2276 :
2277 460 : tc = talloc_chunk_from_ptr(ptr);
2278 460 : if (tc->limit && tc->limit->parent == tc) {
2279 71 : fprintf(f, "%*s%-30s is a memlimit context"
2280 : " (max_size = %lu bytes, cur_size = %lu bytes)\n",
2281 : depth*4, "",
2282 : name,
2283 71 : (unsigned long)tc->limit->max_size,
2284 71 : (unsigned long)tc->limit->cur_size);
2285 : }
2286 :
2287 460 : if (depth == 0) {
2288 99 : fprintf(f,"%stalloc report on '%s' (total %6lu bytes in %3lu blocks)\n",
2289 : (max_depth < 0 ? "full " :""), name,
2290 99 : (unsigned long)talloc_total_size(ptr),
2291 99 : (unsigned long)talloc_total_blocks(ptr));
2292 99 : return;
2293 : }
2294 :
2295 710 : fprintf(f, "%*s%-30s contains %6lu bytes in %3lu blocks (ref %d) %p\n",
2296 : depth*4, "",
2297 : name,
2298 361 : (unsigned long)talloc_total_size(ptr),
2299 361 : (unsigned long)talloc_total_blocks(ptr),
2300 361 : (int)talloc_reference_count(ptr), ptr);
2301 :
2302 : #if 0
2303 : fprintf(f, "content: ");
2304 : if (talloc_total_size(ptr)) {
2305 : int tot = talloc_total_size(ptr);
2306 : int i;
2307 :
2308 : for (i = 0; i < tot; i++) {
2309 : if ((((char *)ptr)[i] > 31) && (((char *)ptr)[i] < 126)) {
2310 : fprintf(f, "%c", ((char *)ptr)[i]);
2311 : } else {
2312 : fprintf(f, "~%02x", ((char *)ptr)[i]);
2313 : }
2314 : }
2315 : }
2316 : fprintf(f, "\n");
2317 : #endif
2318 : }
2319 :
2320 : /*
2321 : report on memory usage by all children of a pointer, giving a full tree view
2322 : */
2323 198 : _PUBLIC_ void talloc_report_depth_file(const void *ptr, int depth, int max_depth, FILE *f)
2324 : {
2325 198 : if (f) {
2326 198 : talloc_report_depth_cb(ptr, depth, max_depth, talloc_report_depth_FILE_helper, f);
2327 198 : fflush(f);
2328 : }
2329 198 : }
2330 :
2331 : /*
2332 : report on memory usage by all children of a pointer, giving a full tree view
2333 : */
2334 83 : _PUBLIC_ void talloc_report_full(const void *ptr, FILE *f)
2335 : {
2336 83 : talloc_report_depth_file(ptr, 0, -1, f);
2337 83 : }
2338 :
2339 : /*
2340 : report on memory usage by all children of a pointer
2341 : */
2342 115 : _PUBLIC_ void talloc_report(const void *ptr, FILE *f)
2343 : {
2344 115 : talloc_report_depth_file(ptr, 0, 1, f);
2345 115 : }
2346 :
2347 : /*
2348 : enable tracking of the NULL context
2349 : */
2350 19703 : _PUBLIC_ void talloc_enable_null_tracking(void)
2351 : {
2352 19703 : if (null_context == NULL) {
2353 19699 : null_context = _talloc_named_const(NULL, 0, "null_context");
2354 19699 : if (autofree_context != NULL) {
2355 0 : talloc_reparent(NULL, null_context, autofree_context);
2356 : }
2357 : }
2358 19703 : }
2359 :
2360 : /*
2361 : enable tracking of the NULL context, not moving the autofree context
2362 : into the NULL context. This is needed for the talloc testsuite
2363 : */
2364 37 : _PUBLIC_ void talloc_enable_null_tracking_no_autofree(void)
2365 : {
2366 37 : if (null_context == NULL) {
2367 36 : null_context = _talloc_named_const(NULL, 0, "null_context");
2368 : }
2369 37 : }
2370 :
2371 : /*
2372 : disable tracking of the NULL context
2373 : */
2374 38 : _PUBLIC_ void talloc_disable_null_tracking(void)
2375 : {
2376 38 : if (null_context != NULL) {
2377 : /* we have to move any children onto the real NULL
2378 : context */
2379 : struct talloc_chunk *tc, *tc2;
2380 36 : tc = talloc_chunk_from_ptr(null_context);
2381 36 : for (tc2 = tc->child; tc2; tc2=tc2->next) {
2382 0 : if (tc2->parent == tc) tc2->parent = NULL;
2383 0 : if (tc2->prev == tc) tc2->prev = NULL;
2384 : }
2385 36 : for (tc2 = tc->next; tc2; tc2=tc2->next) {
2386 0 : if (tc2->parent == tc) tc2->parent = NULL;
2387 0 : if (tc2->prev == tc) tc2->prev = NULL;
2388 : }
2389 36 : tc->child = NULL;
2390 36 : tc->next = NULL;
2391 : }
2392 38 : talloc_free(null_context);
2393 38 : null_context = NULL;
2394 38 : }
2395 :
2396 : /*
2397 : enable leak reporting on exit
2398 : */
2399 13 : _PUBLIC_ void talloc_enable_leak_report(void)
2400 : {
2401 13 : talloc_enable_null_tracking();
2402 13 : talloc_report_null = true;
2403 13 : talloc_setup_atexit();
2404 13 : }
2405 :
2406 : /*
2407 : enable full leak reporting on exit
2408 : */
2409 1 : _PUBLIC_ void talloc_enable_leak_report_full(void)
2410 : {
2411 1 : talloc_enable_null_tracking();
2412 1 : talloc_report_null_full = true;
2413 1 : talloc_setup_atexit();
2414 1 : }
2415 :
2416 : /*
2417 : talloc and zero memory.
2418 : */
2419 5031546385 : _PUBLIC_ void *_talloc_zero(const void *ctx, size_t size, const char *name)
2420 : {
2421 5031546385 : void *p = _talloc_named_const(ctx, size, name);
2422 :
2423 5031546385 : if (p) {
2424 5031546385 : memset(p, '\0', size);
2425 : }
2426 :
2427 5031546385 : return p;
2428 : }
2429 :
2430 : /*
2431 : memdup with a talloc.
2432 : */
2433 4370937565 : _PUBLIC_ void *_talloc_memdup(const void *t, const void *p, size_t size, const char *name)
2434 : {
2435 4370937565 : void *newp = NULL;
2436 :
2437 4370937565 : if (likely(size > 0) && unlikely(p == NULL)) {
2438 0 : return NULL;
2439 : }
2440 :
2441 4370937565 : newp = _talloc_named_const(t, size, name);
2442 4370937565 : if (likely(newp != NULL) && likely(size > 0)) {
2443 4370348240 : memcpy(newp, p, size);
2444 : }
2445 :
2446 4370937565 : return newp;
2447 : }
2448 :
2449 5836690701 : static inline char *__talloc_strlendup(const void *t, const char *p, size_t len)
2450 : {
2451 : char *ret;
2452 : struct talloc_chunk *tc;
2453 :
2454 5836690701 : ret = (char *)__talloc(t, len + 1, &tc);
2455 5836690701 : if (unlikely(!ret)) return NULL;
2456 :
2457 5836690700 : memcpy(ret, p, len);
2458 5836690700 : ret[len] = 0;
2459 :
2460 5836690700 : _tc_set_name_const(tc, ret);
2461 5836690700 : return ret;
2462 : }
2463 :
2464 : /*
2465 : strdup with a talloc
2466 : */
2467 4735631530 : _PUBLIC_ char *talloc_strdup(const void *t, const char *p)
2468 : {
2469 4735631530 : if (unlikely(!p)) return NULL;
2470 4735267602 : return __talloc_strlendup(t, p, strlen(p));
2471 : }
2472 :
2473 : /*
2474 : strndup with a talloc
2475 : */
2476 1101423167 : _PUBLIC_ char *talloc_strndup(const void *t, const char *p, size_t n)
2477 : {
2478 1101423167 : if (unlikely(!p)) return NULL;
2479 1101423099 : return __talloc_strlendup(t, p, strnlen(p, n));
2480 : }
2481 :
2482 206784450 : static inline char *__talloc_strlendup_append(char *s, size_t slen,
2483 : const char *a, size_t alen)
2484 : {
2485 : char *ret;
2486 :
2487 206784450 : ret = talloc_realloc(NULL, s, char, slen + alen + 1);
2488 206784450 : if (unlikely(!ret)) return NULL;
2489 :
2490 : /* append the string and the trailing \0 */
2491 206784450 : memcpy(&ret[slen], a, alen);
2492 206784450 : ret[slen+alen] = 0;
2493 :
2494 206784450 : _tc_set_name_const(talloc_chunk_from_ptr(ret), ret);
2495 206784450 : return ret;
2496 : }
2497 :
2498 : /*
2499 : * Appends at the end of the string.
2500 : */
2501 313656 : _PUBLIC_ char *talloc_strdup_append(char *s, const char *a)
2502 : {
2503 313656 : if (unlikely(!s)) {
2504 0 : return talloc_strdup(NULL, a);
2505 : }
2506 :
2507 313656 : if (unlikely(!a)) {
2508 0 : return s;
2509 : }
2510 :
2511 313656 : return __talloc_strlendup_append(s, strlen(s), a, strlen(a));
2512 : }
2513 :
2514 : /*
2515 : * Appends at the end of the talloc'ed buffer,
2516 : * not the end of the string.
2517 : */
2518 206470792 : _PUBLIC_ char *talloc_strdup_append_buffer(char *s, const char *a)
2519 : {
2520 : size_t slen;
2521 :
2522 206470792 : if (unlikely(!s)) {
2523 0 : return talloc_strdup(NULL, a);
2524 : }
2525 :
2526 206470792 : if (unlikely(!a)) {
2527 0 : return s;
2528 : }
2529 :
2530 206470792 : slen = talloc_get_size(s);
2531 206470792 : if (likely(slen > 0)) {
2532 206470792 : slen--;
2533 : }
2534 :
2535 206470792 : return __talloc_strlendup_append(s, slen, a, strlen(a));
2536 : }
2537 :
2538 : /*
2539 : * Appends at the end of the string.
2540 : */
2541 0 : _PUBLIC_ char *talloc_strndup_append(char *s, const char *a, size_t n)
2542 : {
2543 0 : if (unlikely(!s)) {
2544 0 : return talloc_strndup(NULL, a, n);
2545 : }
2546 :
2547 0 : if (unlikely(!a)) {
2548 0 : return s;
2549 : }
2550 :
2551 0 : return __talloc_strlendup_append(s, strlen(s), a, strnlen(a, n));
2552 : }
2553 :
2554 : /*
2555 : * Appends at the end of the talloc'ed buffer,
2556 : * not the end of the string.
2557 : */
2558 2 : _PUBLIC_ char *talloc_strndup_append_buffer(char *s, const char *a, size_t n)
2559 : {
2560 : size_t slen;
2561 :
2562 2 : if (unlikely(!s)) {
2563 0 : return talloc_strndup(NULL, a, n);
2564 : }
2565 :
2566 2 : if (unlikely(!a)) {
2567 0 : return s;
2568 : }
2569 :
2570 2 : slen = talloc_get_size(s);
2571 2 : if (likely(slen > 0)) {
2572 2 : slen--;
2573 : }
2574 :
2575 2 : return __talloc_strlendup_append(s, slen, a, strnlen(a, n));
2576 : }
2577 :
2578 : #ifndef HAVE_VA_COPY
2579 : #ifdef HAVE___VA_COPY
2580 : #define va_copy(dest, src) __va_copy(dest, src)
2581 : #else
2582 : #define va_copy(dest, src) (dest) = (src)
2583 : #endif
2584 : #endif
2585 :
2586 : static struct talloc_chunk *_vasprintf_tc(const void *t,
2587 : const char *fmt,
2588 : va_list ap) PRINTF_ATTRIBUTE(2,0);
2589 :
2590 349922902 : static struct talloc_chunk *_vasprintf_tc(const void *t,
2591 : const char *fmt,
2592 : va_list ap)
2593 : {
2594 : int vlen;
2595 : size_t len;
2596 : char *ret;
2597 : va_list ap2;
2598 : struct talloc_chunk *tc;
2599 : char buf[1024];
2600 :
2601 : /* this call looks strange, but it makes it work on older solaris boxes */
2602 349922902 : va_copy(ap2, ap);
2603 349922902 : vlen = vsnprintf(buf, sizeof(buf), fmt, ap2);
2604 349922902 : va_end(ap2);
2605 349922902 : if (unlikely(vlen < 0)) {
2606 0 : return NULL;
2607 : }
2608 349922902 : len = vlen;
2609 349922902 : if (unlikely(len + 1 < len)) {
2610 0 : return NULL;
2611 : }
2612 :
2613 349922902 : ret = (char *)__talloc(t, len+1, &tc);
2614 349922902 : if (unlikely(!ret)) return NULL;
2615 :
2616 349922902 : if (len < sizeof(buf)) {
2617 349922712 : memcpy(ret, buf, len+1);
2618 : } else {
2619 190 : va_copy(ap2, ap);
2620 190 : vsnprintf(ret, len+1, fmt, ap2);
2621 190 : va_end(ap2);
2622 : }
2623 :
2624 349922902 : _tc_set_name_const(tc, ret);
2625 349922902 : return tc;
2626 : }
2627 :
2628 333032169 : _PUBLIC_ char *talloc_vasprintf(const void *t, const char *fmt, va_list ap)
2629 : {
2630 333032169 : struct talloc_chunk *tc = _vasprintf_tc(t, fmt, ap);
2631 333032169 : if (tc == NULL) {
2632 0 : return NULL;
2633 : }
2634 333032169 : return TC_PTR_FROM_CHUNK(tc);
2635 : }
2636 :
2637 :
2638 : /*
2639 : Perform string formatting, and return a pointer to newly allocated
2640 : memory holding the result, inside a memory pool.
2641 : */
2642 165276432 : _PUBLIC_ char *talloc_asprintf(const void *t, const char *fmt, ...)
2643 : {
2644 : va_list ap;
2645 : char *ret;
2646 :
2647 165276432 : va_start(ap, fmt);
2648 165276432 : ret = talloc_vasprintf(t, fmt, ap);
2649 165276432 : va_end(ap);
2650 165276432 : return ret;
2651 : }
2652 :
2653 : static inline char *__talloc_vaslenprintf_append(char *s, size_t slen,
2654 : const char *fmt, va_list ap)
2655 : PRINTF_ATTRIBUTE(3,0);
2656 :
2657 187508417 : static inline char *__talloc_vaslenprintf_append(char *s, size_t slen,
2658 : const char *fmt, va_list ap)
2659 : {
2660 : ssize_t alen;
2661 : va_list ap2;
2662 : char c;
2663 :
2664 187508417 : va_copy(ap2, ap);
2665 187508417 : alen = vsnprintf(&c, 1, fmt, ap2);
2666 187508417 : va_end(ap2);
2667 :
2668 187508417 : if (alen <= 0) {
2669 : /* Either the vsnprintf failed or the format resulted in
2670 : * no characters being formatted. In the former case, we
2671 : * ought to return NULL, in the latter we ought to return
2672 : * the original string. Most current callers of this
2673 : * function expect it to never return NULL.
2674 : */
2675 0 : return s;
2676 : }
2677 :
2678 187508417 : s = talloc_realloc(NULL, s, char, slen + alen + 1);
2679 187508417 : if (!s) return NULL;
2680 :
2681 187508417 : va_copy(ap2, ap);
2682 187508417 : vsnprintf(s + slen, alen + 1, fmt, ap2);
2683 187508417 : va_end(ap2);
2684 :
2685 187508417 : _tc_set_name_const(talloc_chunk_from_ptr(s), s);
2686 187508417 : return s;
2687 : }
2688 :
2689 : /**
2690 : * Realloc @p s to append the formatted result of @p fmt and @p ap,
2691 : * and return @p s, which may have moved. Good for gradually
2692 : * accumulating output into a string buffer. Appends at the end
2693 : * of the string.
2694 : **/
2695 3918248 : _PUBLIC_ char *talloc_vasprintf_append(char *s, const char *fmt, va_list ap)
2696 : {
2697 3918248 : if (unlikely(!s)) {
2698 8 : return talloc_vasprintf(NULL, fmt, ap);
2699 : }
2700 :
2701 3918240 : return __talloc_vaslenprintf_append(s, strlen(s), fmt, ap);
2702 : }
2703 :
2704 : /**
2705 : * Realloc @p s to append the formatted result of @p fmt and @p ap,
2706 : * and return @p s, which may have moved. Always appends at the
2707 : * end of the talloc'ed buffer, not the end of the string.
2708 : **/
2709 183590245 : _PUBLIC_ char *talloc_vasprintf_append_buffer(char *s, const char *fmt, va_list ap)
2710 : {
2711 : size_t slen;
2712 :
2713 183590245 : if (unlikely(!s)) {
2714 68 : return talloc_vasprintf(NULL, fmt, ap);
2715 : }
2716 :
2717 183590177 : slen = talloc_get_size(s);
2718 183590177 : if (likely(slen > 0)) {
2719 183590177 : slen--;
2720 : }
2721 :
2722 183590177 : return __talloc_vaslenprintf_append(s, slen, fmt, ap);
2723 : }
2724 :
2725 : /*
2726 : Realloc @p s to append the formatted result of @p fmt and return @p
2727 : s, which may have moved. Good for gradually accumulating output
2728 : into a string buffer.
2729 : */
2730 1103528 : _PUBLIC_ char *talloc_asprintf_append(char *s, const char *fmt, ...)
2731 : {
2732 : va_list ap;
2733 :
2734 1103528 : va_start(ap, fmt);
2735 1103528 : s = talloc_vasprintf_append(s, fmt, ap);
2736 1103528 : va_end(ap);
2737 1103528 : return s;
2738 : }
2739 :
2740 : /*
2741 : Realloc @p s to append the formatted result of @p fmt and return @p
2742 : s, which may have moved. Good for gradually accumulating output
2743 : into a buffer.
2744 : */
2745 146508081 : _PUBLIC_ char *talloc_asprintf_append_buffer(char *s, const char *fmt, ...)
2746 : {
2747 : va_list ap;
2748 :
2749 146508081 : va_start(ap, fmt);
2750 146508081 : s = talloc_vasprintf_append_buffer(s, fmt, ap);
2751 146508081 : va_end(ap);
2752 146508081 : return s;
2753 : }
2754 :
2755 : /*
2756 : alloc an array, checking for integer overflow in the array size
2757 : */
2758 4975753234 : _PUBLIC_ void *_talloc_array(const void *ctx, size_t el_size, unsigned count, const char *name)
2759 : {
2760 4975753234 : if (count >= MAX_TALLOC_SIZE/el_size) {
2761 3 : return NULL;
2762 : }
2763 4975753231 : return _talloc_named_const(ctx, el_size * count, name);
2764 : }
2765 :
2766 : /*
2767 : alloc an zero array, checking for integer overflow in the array size
2768 : */
2769 682977822 : _PUBLIC_ void *_talloc_zero_array(const void *ctx, size_t el_size, unsigned count, const char *name)
2770 : {
2771 682977822 : if (count >= MAX_TALLOC_SIZE/el_size) {
2772 0 : return NULL;
2773 : }
2774 682977822 : return _talloc_zero(ctx, el_size * count, name);
2775 : }
2776 :
2777 : /*
2778 : realloc an array, checking for integer overflow in the array size
2779 : */
2780 3548089451 : _PUBLIC_ void *_talloc_realloc_array(const void *ctx, void *ptr, size_t el_size, unsigned count, const char *name)
2781 : {
2782 3548089451 : if (count >= MAX_TALLOC_SIZE/el_size) {
2783 1 : return NULL;
2784 : }
2785 3548089450 : return _talloc_realloc(ctx, ptr, el_size * count, name);
2786 : }
2787 :
2788 : /*
2789 : a function version of talloc_realloc(), so it can be passed as a function pointer
2790 : to libraries that want a realloc function (a realloc function encapsulates
2791 : all the basic capabilities of an allocation library, which is why this is useful)
2792 : */
2793 3 : _PUBLIC_ void *talloc_realloc_fn(const void *context, void *ptr, size_t size)
2794 : {
2795 3 : return _talloc_realloc(context, ptr, size, NULL);
2796 : }
2797 :
2798 :
2799 2 : static int talloc_autofree_destructor(void *ptr)
2800 : {
2801 2 : autofree_context = NULL;
2802 2 : return 0;
2803 : }
2804 :
2805 : /*
2806 : return a context which will be auto-freed on exit
2807 : this is useful for reducing the noise in leak reports
2808 : */
2809 2 : _PUBLIC_ void *talloc_autofree_context(void)
2810 : {
2811 2 : if (autofree_context == NULL) {
2812 2 : autofree_context = _talloc_named_const(NULL, 0, "autofree_context");
2813 2 : talloc_set_destructor(autofree_context, talloc_autofree_destructor);
2814 2 : talloc_setup_atexit();
2815 : }
2816 2 : return autofree_context;
2817 : }
2818 :
2819 1194476479 : _PUBLIC_ size_t talloc_get_size(const void *context)
2820 : {
2821 : struct talloc_chunk *tc;
2822 :
2823 1194476479 : if (context == NULL) {
2824 3995232 : return 0;
2825 : }
2826 :
2827 1190481247 : tc = talloc_chunk_from_ptr(context);
2828 :
2829 1190481247 : return tc->size;
2830 : }
2831 :
2832 : /*
2833 : find a parent of this context that has the given name, if any
2834 : */
2835 0 : _PUBLIC_ void *talloc_find_parent_byname(const void *context, const char *name)
2836 : {
2837 : struct talloc_chunk *tc;
2838 :
2839 0 : if (context == NULL) {
2840 0 : return NULL;
2841 : }
2842 :
2843 0 : tc = talloc_chunk_from_ptr(context);
2844 0 : while (tc) {
2845 0 : if (tc->name && strcmp(tc->name, name) == 0) {
2846 0 : return TC_PTR_FROM_CHUNK(tc);
2847 : }
2848 0 : while (tc && tc->prev) tc = tc->prev;
2849 0 : if (tc) {
2850 0 : tc = tc->parent;
2851 : }
2852 : }
2853 0 : return NULL;
2854 : }
2855 :
2856 : /*
2857 : show the parentage of a context
2858 : */
2859 0 : _PUBLIC_ void talloc_show_parents(const void *context, FILE *file)
2860 : {
2861 : struct talloc_chunk *tc;
2862 :
2863 0 : if (context == NULL) {
2864 0 : fprintf(file, "talloc no parents for NULL\n");
2865 0 : return;
2866 : }
2867 :
2868 0 : tc = talloc_chunk_from_ptr(context);
2869 0 : fprintf(file, "talloc parents of '%s'\n", __talloc_get_name(context));
2870 0 : while (tc) {
2871 0 : fprintf(file, "\t'%s'\n", __talloc_get_name(TC_PTR_FROM_CHUNK(tc)));
2872 0 : while (tc && tc->prev) tc = tc->prev;
2873 0 : if (tc) {
2874 0 : tc = tc->parent;
2875 : }
2876 : }
2877 0 : fflush(file);
2878 : }
2879 :
2880 : /*
2881 : return 1 if ptr is a parent of context
2882 : */
2883 15029275 : static int _talloc_is_parent(const void *context, const void *ptr, int depth)
2884 : {
2885 : struct talloc_chunk *tc;
2886 :
2887 15029275 : if (context == NULL) {
2888 0 : return 0;
2889 : }
2890 :
2891 15029275 : tc = talloc_chunk_from_ptr(context);
2892 72225187 : while (tc) {
2893 42201752 : if (depth <= 0) {
2894 0 : return 0;
2895 : }
2896 42201752 : if (TC_PTR_FROM_CHUNK(tc) == ptr) return 1;
2897 52437146 : while (tc && tc->prev) tc = tc->prev;
2898 42166637 : if (tc) {
2899 42166637 : tc = tc->parent;
2900 42166637 : depth--;
2901 : }
2902 : }
2903 14994160 : return 0;
2904 : }
2905 :
2906 : /*
2907 : return 1 if ptr is a parent of context
2908 : */
2909 15029275 : _PUBLIC_ int talloc_is_parent(const void *context, const void *ptr)
2910 : {
2911 15029275 : return _talloc_is_parent(context, ptr, TALLOC_MAX_DEPTH);
2912 : }
2913 :
2914 : /*
2915 : return the total size of memory used by this context and all children
2916 : */
2917 9 : static inline size_t _talloc_total_limit_size(const void *ptr,
2918 : struct talloc_memlimit *old_limit,
2919 : struct talloc_memlimit *new_limit)
2920 : {
2921 9 : return _talloc_total_mem_internal(ptr, TOTAL_MEM_LIMIT,
2922 : old_limit, new_limit);
2923 : }
2924 :
2925 23264586052 : static inline bool talloc_memlimit_check(struct talloc_memlimit *limit, size_t size)
2926 : {
2927 : struct talloc_memlimit *l;
2928 :
2929 23264586065 : for (l = limit; l != NULL; l = l->upper) {
2930 46 : if (l->max_size != 0 &&
2931 41 : ((l->max_size <= l->cur_size) ||
2932 18 : (l->max_size - l->cur_size < size))) {
2933 10 : return false;
2934 : }
2935 : }
2936 :
2937 23264586042 : return true;
2938 : }
2939 :
2940 : /*
2941 : Update memory limits when freeing a talloc_chunk.
2942 : */
2943 22864787184 : static void tc_memlimit_update_on_free(struct talloc_chunk *tc)
2944 : {
2945 : size_t limit_shrink_size;
2946 :
2947 22864787184 : if (!tc->limit) {
2948 22864787174 : return;
2949 : }
2950 :
2951 : /*
2952 : * Pool entries don't count. Only the pools
2953 : * themselves are counted as part of the memory
2954 : * limits. Note that this also takes care of
2955 : * nested pools which have both flags
2956 : * TALLOC_FLAG_POOLMEM|TALLOC_FLAG_POOL set.
2957 : */
2958 10 : if (tc->flags & TALLOC_FLAG_POOLMEM) {
2959 0 : return;
2960 : }
2961 :
2962 : /*
2963 : * If we are part of a memory limited context hierarchy
2964 : * we need to subtract the memory used from the counters
2965 : */
2966 :
2967 10 : limit_shrink_size = tc->size+TC_HDR_SIZE;
2968 :
2969 : /*
2970 : * If we're deallocating a pool, take into
2971 : * account the prefix size added for the pool.
2972 : */
2973 :
2974 10 : if (tc->flags & TALLOC_FLAG_POOL) {
2975 1 : limit_shrink_size += TP_HDR_SIZE;
2976 : }
2977 :
2978 10 : talloc_memlimit_shrink(tc->limit, limit_shrink_size);
2979 :
2980 10 : if (tc->limit->parent == tc) {
2981 5 : free(tc->limit);
2982 : }
2983 :
2984 10 : tc->limit = NULL;
2985 : }
2986 :
2987 : /*
2988 : Increase memory limit accounting after a malloc/realloc.
2989 : */
2990 25035694022 : static void talloc_memlimit_grow(struct talloc_memlimit *limit,
2991 : size_t size)
2992 : {
2993 : struct talloc_memlimit *l;
2994 :
2995 25035694037 : for (l = limit; l != NULL; l = l->upper) {
2996 15 : size_t new_cur_size = l->cur_size + size;
2997 15 : if (new_cur_size < l->cur_size) {
2998 0 : talloc_abort("logic error in talloc_memlimit_grow\n");
2999 0 : return;
3000 : }
3001 15 : l->cur_size = new_cur_size;
3002 : }
3003 : }
3004 :
3005 : /*
3006 : Decrease memory limit accounting after a free/realloc.
3007 : */
3008 4198420 : static void talloc_memlimit_shrink(struct talloc_memlimit *limit,
3009 : size_t size)
3010 : {
3011 : struct talloc_memlimit *l;
3012 :
3013 4198442 : for (l = limit; l != NULL; l = l->upper) {
3014 22 : if (l->cur_size < size) {
3015 0 : talloc_abort("logic error in talloc_memlimit_shrink\n");
3016 0 : return;
3017 : }
3018 22 : l->cur_size = l->cur_size - size;
3019 : }
3020 : }
3021 :
3022 9 : _PUBLIC_ int talloc_set_memlimit(const void *ctx, size_t max_size)
3023 : {
3024 9 : struct talloc_chunk *tc = talloc_chunk_from_ptr(ctx);
3025 : struct talloc_memlimit *orig_limit;
3026 9 : struct talloc_memlimit *limit = NULL;
3027 :
3028 9 : if (tc->limit && tc->limit->parent == tc) {
3029 4 : tc->limit->max_size = max_size;
3030 4 : return 0;
3031 : }
3032 5 : orig_limit = tc->limit;
3033 :
3034 5 : limit = malloc(sizeof(struct talloc_memlimit));
3035 5 : if (limit == NULL) {
3036 0 : return 1;
3037 : }
3038 5 : limit->parent = tc;
3039 5 : limit->max_size = max_size;
3040 5 : limit->cur_size = _talloc_total_limit_size(ctx, tc->limit, limit);
3041 :
3042 5 : if (orig_limit) {
3043 3 : limit->upper = orig_limit;
3044 : } else {
3045 2 : limit->upper = NULL;
3046 : }
3047 :
3048 5 : return 0;
3049 : }
|