git: c6e072f15c98 - stable/14 - memfd_create: don't allocate heap memory

From: Brooks Davis <brooks_at_FreeBSD.org>
Date: Thu, 21 Dec 2023 18:17:46 UTC
The branch stable/14 has been updated by brooks:

URL: https://cgit.FreeBSD.org/src/commit/?id=c6e072f15c98097bdfb9583345f910220f97093e

commit c6e072f15c98097bdfb9583345f910220f97093e
Author:     Brooks Davis <brooks@FreeBSD.org>
AuthorDate: 2023-11-27 17:07:06 +0000
Commit:     Brooks Davis <brooks@FreeBSD.org>
CommitDate: 2023-12-21 18:13:19 +0000

    memfd_create: don't allocate heap memory
    
    Rather than calling calloc() to allocate space for a page size array to
    pass to getpagesizes(), just follow the getpagesizes() implementation
    and allocate MAXPAGESIZES elements on the stack.  This avoids the need
    for the allocation.
    
    While this does mean that a new libc is required to take advantage of a
    new huge page size, that was already true due to getpagesizes() using a
    static buffer of MAXPAGESIZES elements.
    
    Reviewed by:    kevans, imp, emaste
    Sponsored by:   DARPA
    Differential Revision:  https://reviews.freebsd.org/D42710
    
    (cherry picked from commit c96772227b7dfcaf4eec4d07acb5c916643aca3a)
---
 lib/libc/gen/memfd_create.c | 16 +++-------------
 1 file changed, 3 insertions(+), 13 deletions(-)

diff --git a/lib/libc/gen/memfd_create.c b/lib/libc/gen/memfd_create.c
index b26d638656a4..78131f46d7b1 100644
--- a/lib/libc/gen/memfd_create.c
+++ b/lib/libc/gen/memfd_create.c
@@ -35,7 +35,6 @@
 #include <errno.h>
 #include <fcntl.h>
 #include <stdio.h>
-#include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
 
@@ -52,7 +51,8 @@ int
 memfd_create(const char *name, unsigned int flags)
 {
 	char memfd_name[NAME_MAX + 1];
-	size_t namelen, *pgs, pgsize;
+	size_t pgs[MAXPAGESIZES];
+	size_t namelen, pgsize;
 	struct shm_largepage_conf slc;
 	int error, fd, npgs, oflags, pgidx, saved_errno, shmflags;
 
@@ -92,16 +92,9 @@ memfd_create(const char *name, unsigned int flags)
 	if (fd == -1 || (flags & MFD_HUGETLB) == 0)
 		return (fd);
 
-	pgs = NULL;
-	npgs = getpagesizes(NULL, 0);
+	npgs = getpagesizes(pgs, nitems(pgs));
 	if (npgs == -1)
 		goto clean;
-	pgs = calloc(npgs, sizeof(size_t));
-	if (pgs == NULL)
-		goto clean;
-	error = getpagesizes(pgs, npgs);
-	if (error == -1)
-		goto clean;
 	pgsize = (size_t)1 << ((flags & MFD_HUGE_MASK) >> MFD_HUGE_SHIFT);
 	for (pgidx = 0; pgidx < npgs; pgidx++) {
 		if (pgsize == pgs[pgidx])
@@ -111,8 +104,6 @@ memfd_create(const char *name, unsigned int flags)
 		errno = EOPNOTSUPP;
 		goto clean;
 	}
-	free(pgs);
-	pgs = NULL;
 
 	memset(&slc, 0, sizeof(slc));
 	slc.psind = pgidx;
@@ -125,7 +116,6 @@ memfd_create(const char *name, unsigned int flags)
 clean:
 	saved_errno = errno;
 	close(fd);
-	free(pgs);
 	errno = saved_errno;
 	return (-1);
 }