From a7651aa406a370fdcf431a215485040ba84c2d01 Mon Sep 17 00:00:00 2001 From: q66 Date: Thu, 22 Aug 2024 08:51:23 +0200 Subject: [PATCH] libnuma: fix nodemask allocation size for get_mempolicy This prevents buffer corrpution which manifests as firefox failing to play videos with mimalloc in hardened mode (as the get_mempolicy will corrupt the metadata). The documentation for get_mempolicy specifies the following: ``` unsigned long nodemask[(.maxnode + ULONG_WIDTH - 1) / ULONG_WIDTH] ``` where maxnode is the following argument. Since we are calling get_mempolicy with `nodemask_sz + 1`, that means the size will be `(nodemask_sz + 1 + ULONG_WIDTH - 1) / ULONG_WIDTH)` i.e. `(nodemask_sz + ULONG_WIDTH) / ULONG_WIDTH` or `nodemask_sz / ULONG_WIDTH + 1`. Since `ULONG_WIDTH` is `sizeof ulong * 8`, and the nodemask is an array of ulong, that means the allocation size should be: ``` sizeof ulong * (nodemask_sz / (sizeof ulong * 8) + 1) ``` which is equal to: ``` sizeof ulong + nodemask_size / 8 ``` That means we need an extra ulong in the buffer. --- libnuma.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libnuma.c b/libnuma.c index 89a17e0..5d99e81 100644 --- a/libnuma.c +++ b/libnuma.c @@ -427,7 +427,7 @@ set_nodemask_size(void) nodemask_sz = 16; do { nodemask_sz <<= 1; - mask = realloc(mask, nodemask_sz / 8); + mask = realloc(mask, nodemask_sz / 8 + sizeof(unsigned long)); if (!mask) return; } while (get_mempolicy(&pol, mask, nodemask_sz + 1, 0, 0) < 0 && errno == EINVAL &&