RCSID("$Id$")
#include <freeradius-devel/util/debug.h>
+#include <freeradius-devel/util/dlist.h>
+#include <freeradius-devel/util/misc.h>
#include <freeradius-devel/util/strerror.h>
#include <freeradius-devel/util/talloc.h>
-#include <freeradius-devel/util/dlist.h>
#include <string.h>
#include <unistd.h>
return 0;
}
+/** Return a page aligned talloc memory array
+ *
+ * Because we can't intercept talloc's malloc() calls, we need to do some tricks
+ * in order to get the first allocation in the array page aligned, and to limit
+ * the size of the array to a multiple of the page size.
+ *
+ * The reason for wanting a page aligned talloc array, is it allows us to
+ * mprotect() the pages that belong to the array.
+ *
+ * Talloc chunks appear to be allocated within the protected region, so this should
+ * catch frees too.
+ *
+ * @param[in] ctx to allocate array memory in.
+ * @param[out] start The first aligned address in the array.
+ * @param[in] alignment What alignment the memory chunk should have.
+ * @param[in] size How big to make the array. Will be corrected to a multiple
+ * of the page size. The actual array size will be size
+ * rounded to a multiple of the (page_size), + page_size
+ * @return
+ * - A talloc chunk on success.
+ * - NULL on failure.
+ */
+TALLOC_CTX *talloc_aligned_array(TALLOC_CTX *ctx, void **start, size_t alignment, size_t size)
+{
+ size_t rounded;
+ size_t array_size;
+ void *next;
+ TALLOC_CTX *array;
+
+ rounded = ROUND_UP(size, alignment); /* Round up to a multiple of the page size */
+ if (rounded == 0) rounded = alignment;
+
+ array_size = rounded + alignment;
+ array = talloc_array(ctx, uint8_t, array_size); /* Over allocate */
+ if (!array) {
+ fr_strerror_printf("Out of memory");
+ return NULL;
+ }
+
+ next = (void *)ROUND_UP((uintptr_t)array, alignment); /* Round up address to the next multiple */
+ *start = next;
+
+ return array;
+}
+
/** Return a page aligned talloc memory pool
*
* Because we can't intercept talloc's malloc() calls, we need to do some tricks
void *next, *chunk;
TALLOC_CTX *pool;
-#define ROUND_UP(_num, _mul) (((((_num) + ((_mul) - 1))) / (_mul)) * (_mul))
-
rounded = ROUND_UP(size, page_size); /* Round up to a multiple of the page size */
if (rounded == 0) rounded = page_size;