From: Michal Privoznik <mpriv...@redhat.com> 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 <mpriv...@redhat.com> --- tools/nss/libvirt_nss.c | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/tools/nss/libvirt_nss.c b/tools/nss/libvirt_nss.c index c1e51441b2..6ee328a8df 100644 --- a/tools/nss/libvirt_nss.c +++ b/tools/nss/libvirt_nss.c @@ -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 (!(buf = calloc(buf_size, sizeof(*buf)))) + return; - if (NSS_NAME(gethostbyname2)(name, af, &resolved, - buf, sizeof(buf), - &err, &herr) != NS_SUCCESS) - return; - } while (false); + if (NSS_NAME(gethostbyname2)(name, af, &resolved, + buf, buf_size, + &err, &herr) != NS_SUCCESS) + return; addrList = resolved.h_addr_list; while (*addrList) { -- 2.49.0