]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
libvirt_nss: Allocate buffer in aiforaf() dynamically
authorMichal Privoznik <mprivozn@redhat.com>
Wed, 21 May 2025 16:14:51 +0000 (18:14 +0200)
committerMichal Privoznik <mprivozn@redhat.com>
Thu, 22 May 2025 13:44:12 +0000 (15:44 +0200)
While we were trying to decrease stack usage of some functions,
in v9.8.0-rc1~217 we introduced a couple of internal blocks to
the aiforaf() and declared some variables inside those blocks
hoping the compiler will reuse the stack for each block. While in
general this might be a good strategy, specifically in case of
NSS_NAME(gethostbyname2) this is a terrible thing to do.

Problem is, NSS_NAME(gethostbyname2) is given a caller allocated
buffer and an address of a pointer where the resolved address is
stored. And you've probably guessed it already: upon successful
return, the pointer is set to point somewhere inside the buffer.

Now, if the buffer doesn't live long enough, which in our case it
does not (since it was left in the previous block), we should
refrain from dereferencing the resolved pointer.

Just allocate the buffer on the heap.

Fixes: 9e5f2fe4021ada74adbe34ca03be60812c91f334
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
tools/nss/libvirt_nss.c

index c1e51441b284de8828244bdfe711666501e8f845..6ee328a8df005c3a9b32b08a4eff11a874a4b798 100644 (file)
@@ -464,18 +464,17 @@ aiforaf(const char *name,
     struct hostent resolved;
     int err;
     char **addrList;
+    g_autofree char *buf = NULL;
+    const size_t buf_size = 1024;
+    int herr;
 
-    /* Note: The do-while blocks in this function are used to scope off large
-     * stack allocated buffers, which are not needed at the same time */
-    do {
-        char buf[1024] = { 0 };
-        int herr;
-
-        if (NSS_NAME(gethostbyname2)(name, af, &resolved,
-                                     buf, sizeof(buf),
-                                     &err, &herr) != NS_SUCCESS)
-            return;
-    } while (false);
+    if (!(buf = calloc(buf_size, sizeof(*buf))))
+        return;
+
+    if (NSS_NAME(gethostbyname2)(name, af, &resolved,
+                                 buf, buf_size,
+                                 &err, &herr) != NS_SUCCESS)
+        return;
 
     addrList = resolved.h_addr_list;
     while (*addrList) {