Hi, Here a little patch for the use-after-free memory pool, allowing to identify them.
Kind regards.
From 7f599d96c248ea6b7a67168ea68b31470c08b61d Mon Sep 17 00:00:00 2001 From: David Carlier <devne...@gmail.com> Date: Sun, 10 Apr 2022 10:47:16 +0100 Subject: [PATCH] BUILD/MEDIUM: pool UAF's pool set an id on Linux 5.17 and onwards. With DEBUG_UAF DEBUG option, pools are created via anonymous pages thus setting an ID upon them for debugging purpose. --- src/pool.c | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/src/pool.c b/src/pool.c index fe10badbd..d2c092243 100644 --- a/src/pool.c +++ b/src/pool.c @@ -13,6 +13,14 @@ #include <sys/mman.h> #include <errno.h> +#if defined(__linux__) +#include <sys/prctl.h> +#if !defined(PR_SET_VMA) +#define PR_SET_VMA 0x53564d41 +#define PR_SET_VMA_ANON_NAME 0 +#endif +#endif + #include <haproxy/activity.h> #include <haproxy/api.h> #include <haproxy/applet-t.h> @@ -770,10 +778,25 @@ void __pool_free(struct pool_head *pool, void *ptr) void *pool_alloc_area_uaf(size_t size) { size_t pad = (4096 - size) & 0xFF0; + size_t tsize = (size + 4095) & -4096; void *ret; - ret = mmap(NULL, (size + 4095) & -4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0); + ret = mmap(NULL, tsize, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0); if (ret != MAP_FAILED) { +#if defined(__linux__) + /* setting a id upon the whole page + * as long CONFIG_ANON_VMA_NAME is set (since 5.17) + * it copies (max 80 valid chars) in the kernel space + * so in /proc/<pid>/maps the pools appear as + * `<start>-<end> rw-p 00000000 00:00 0 [anon:HAProxy debug UAF pool]` + * if it fails because of kernel version or the aforementioned config + * not set (like Fedora) it s inconsequential. + */ + (void)prctl(PR_SET_VMA, PR_SET_VMA_ANON_NAME, + (uintptr_t)ret, + tsize, + (uintptr_t)"HAProxy debug UAF pool"); +#endif /* let's dereference the page before returning so that the real * allocation in the system is performed without holding the lock. */ -- 2.34.1