[PATCH 7/8] nss: aiforaf: Decrease stack size by scoping off large buffers.

Peter Krempa posted 8 patches 2 years, 5 months ago
[PATCH 7/8] nss: aiforaf: Decrease stack size by scoping off large buffers.
Posted by Peter Krempa 2 years, 5 months ago
The 'buf', 'sa' and 'hints' stack allocated helper variables are never
used together. Decrease the stack memory usage by scoping them off into
do-while blocks.

In this instance we do not want to use dynamic allocation as this is the
NSS module.

Signed-off-by: Peter Krempa <pkrempa@redhat.com>
---
 tools/nss/libvirt_nss.c | 97 +++++++++++++++++++++++------------------
 1 file changed, 54 insertions(+), 43 deletions(-)

diff --git a/tools/nss/libvirt_nss.c b/tools/nss/libvirt_nss.c
index 37720bf4ae..dff3c034bf 100644
--- a/tools/nss/libvirt_nss.c
+++ b/tools/nss/libvirt_nss.c
@@ -470,61 +470,72 @@ aiforaf(const char *name,
         struct addrinfo **aip)
 {
     struct hostent resolved;
-    char buf[1024] = { 0 };
     int err;
-    int herr;
-    struct addrinfo hints;
-    struct addrinfo *res0;
-    struct addrinfo *res;
     char **addrList;

-    if (NSS_NAME(gethostbyname2)(name, af, &resolved,
-                                 buf, sizeof(buf),
-                                 &err, &herr) != NS_SUCCESS)
-        return;
+    /* 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);

     addrList = resolved.h_addr_list;
     while (*addrList) {
-        union {
-            struct sockaddr sa;
-            struct sockaddr_in sin;
-            struct sockaddr_in6 sin6;
-        } sa = { 0 };
-        socklen_t salen;
         void *address = *addrList;
         char host[NI_MAXHOST];
+        struct addrinfo *res0;
+        struct addrinfo *res;
+
+        do  {
+            union {
+                struct sockaddr sa;
+                struct sockaddr_in sin;
+                struct sockaddr_in6 sin6;
+            } sa = { 0 };
+            socklen_t salen;
+
+            if (resolved.h_addrtype == AF_INET) {
+                sa.sin.sin_family = AF_INET;
+                memcpy(&sa.sin.sin_addr.s_addr,
+                       address,
+                       FAMILY_ADDRESS_SIZE(AF_INET));
+                salen = sizeof(sa.sin);
+            } else {
+                sa.sin6.sin6_family = AF_INET6;
+                memcpy(&sa.sin6.sin6_addr.s6_addr,
+                       address,
+                       FAMILY_ADDRESS_SIZE(AF_INET6));
+                salen = sizeof(sa.sin6);
+            }

-        if (resolved.h_addrtype == AF_INET) {
-            sa.sin.sin_family = AF_INET;
-            memcpy(&sa.sin.sin_addr.s_addr,
-                   address,
-                   FAMILY_ADDRESS_SIZE(AF_INET));
-            salen = sizeof(sa.sin);
-        } else {
-            sa.sin6.sin6_family = AF_INET6;
-            memcpy(&sa.sin6.sin6_addr.s6_addr,
-                   address,
-                   FAMILY_ADDRESS_SIZE(AF_INET6));
-            salen = sizeof(sa.sin6);
-        }
+            if ((err = getnameinfo(&sa.sa, salen,
+                                   host, sizeof(host),
+                                   NULL, 0,
+                                   NI_NUMERICHOST | NI_NUMERICSERV)) != 0) {
+                ERROR("Cannot convert socket address to string: %s",
+                      gai_strerror(err));
+                continue;
+            }
+        } while (false);

-        if ((err = getnameinfo(&sa.sa, salen,
-                               host, sizeof(host),
-                               NULL, 0,
-                               NI_NUMERICHOST | NI_NUMERICSERV)) != 0) {
-            ERROR("Cannot convert socket address to string: %s",
-                  gai_strerror(err));
-            continue;
-        }
+        do {
+            struct addrinfo hints;

-        hints = *pai;
-        hints.ai_flags = AI_NUMERICHOST;
-        hints.ai_family = af;
+            hints = *pai;
+            hints.ai_flags = AI_NUMERICHOST;
+            hints.ai_family = af;

-        if (getaddrinfo(host, NULL, &hints, &res0)) {
-            addrList++;
-            continue;
-        }
+            if (getaddrinfo(host, NULL, &hints, &res0)) {
+                addrList++;
+                continue;
+            }
+        } while (false);

         for (res = res0; res; res = res->ai_next)
             res->ai_flags = pai->ai_flags;
-- 
2.41.0
Re: [PATCH 7/8] nss: aiforaf: Decrease stack size by scoping off large buffers.
Posted by Peter Krempa 2 years, 5 months ago
On Wed, Aug 30, 2023 at 13:59:21 +0200, Peter Krempa wrote:
> The 'buf', 'sa' and 'hints' stack allocated helper variables are never
> used together. Decrease the stack memory usage by scoping them off into
> do-while blocks.
> 
> In this instance we do not want to use dynamic allocation as this is the
> NSS module.
> 
> Signed-off-by: Peter Krempa <pkrempa@redhat.com>
> ---
>  tools/nss/libvirt_nss.c | 97 +++++++++++++++++++++++------------------
>  1 file changed, 54 insertions(+), 43 deletions(-)
> 
> diff --git a/tools/nss/libvirt_nss.c b/tools/nss/libvirt_nss.c
> index 37720bf4ae..dff3c034bf 100644
> --- a/tools/nss/libvirt_nss.c
> +++ b/tools/nss/libvirt_nss.c

[...]

> -        hints = *pai;
> -        hints.ai_flags = AI_NUMERICHOST;
> -        hints.ai_family = af;
> +            hints = *pai;
> +            hints.ai_flags = AI_NUMERICHOST;
> +            hints.ai_family = af;
> 
> -        if (getaddrinfo(host, NULL, &hints, &res0)) {
> -            addrList++;
> -            continue;

Ehh, self-NACK ...

> -        }
> +            if (getaddrinfo(host, NULL, &hints, &res0)) {
> +                addrList++;
> +                continue;
> +            }
> +        } while (false);
> 
>          for (res = res0; res; res = res->ai_next)
>              res->ai_flags = pai->ai_flags;
> -- 
> 2.41.0
>
Re: [PATCH 7/8] nss: aiforaf: Decrease stack size by scoping off large buffers.
Posted by Kristina Hanicova 2 years, 5 months ago
On Wed, Aug 30, 2023 at 2:21 PM Peter Krempa <pkrempa@redhat.com> wrote:

> On Wed, Aug 30, 2023 at 13:59:21 +0200, Peter Krempa wrote:
> > The 'buf', 'sa' and 'hints' stack allocated helper variables are never
> > used together. Decrease the stack memory usage by scoping them off into
> > do-while blocks.
> >
> > In this instance we do not want to use dynamic allocation as this is the
> > NSS module.
> >
> > Signed-off-by: Peter Krempa <pkrempa@redhat.com>
> > ---
> >  tools/nss/libvirt_nss.c | 97 +++++++++++++++++++++++------------------
> >  1 file changed, 54 insertions(+), 43 deletions(-)
> >
> > diff --git a/tools/nss/libvirt_nss.c b/tools/nss/libvirt_nss.c
> > index 37720bf4ae..dff3c034bf 100644
> > --- a/tools/nss/libvirt_nss.c
> > +++ b/tools/nss/libvirt_nss.c
>
> [...]
>
> > -        hints = *pai;
> > -        hints.ai_flags = AI_NUMERICHOST;
> > -        hints.ai_family = af;
> > +            hints = *pai;
> > +            hints.ai_flags = AI_NUMERICHOST;
> > +            hints.ai_family = af;
> >
> > -        if (getaddrinfo(host, NULL, &hints, &res0)) {
> > -            addrList++;
> > -            continue;
>
> Ehh, self-NACK ...


Apart from moving these two continue into loops...

>
>
> > -        }
> > +            if (getaddrinfo(host, NULL, &hints, &res0)) {
> > +                addrList++;
> > +                continue;
> > +            }
> > +        } while (false);
> >
> >          for (res = res0; res; res = res->ai_next)
> >              res->ai_flags = pai->ai_flags;
> > --
> > 2.41.0
> >
>
>
Reviewed-by: Kristina Hanicova <khanicov@redhat.com>

Kristina
[PATCH 7/8 v2] nss: aiforaf: Decrease stack size by scoping off large buffers
Posted by Peter Krempa 2 years, 5 months ago
The 'buf', 'sa' and 'hints' stack allocated helper variables are never
used together. Decrease the stack memory usage by scoping them off into
do-while blocks.

In this instance we do not want to use dynamic allocation as this is the
NSS module.

Signed-off-by: Peter Krempa <pkrempa@redhat.com>
---

v2: Moved two error checks containing a 'continue' out of the 'do-while'
    loop blocks

New pipeline:
https://gitlab.com/pipo.sk/libvirt/-/pipelines/986529301


 tools/nss/libvirt_nss.c | 87 ++++++++++++++++++++++++-----------------
 1 file changed, 51 insertions(+), 36 deletions(-)

diff --git a/tools/nss/libvirt_nss.c b/tools/nss/libvirt_nss.c
index 37720bf4ae..ff6ea1d373 100644
--- a/tools/nss/libvirt_nss.c
+++ b/tools/nss/libvirt_nss.c
@@ -470,58 +470,73 @@ aiforaf(const char *name,
         struct addrinfo **aip)
 {
     struct hostent resolved;
-    char buf[1024] = { 0 };
     int err;
-    int herr;
-    struct addrinfo hints;
-    struct addrinfo *res0;
-    struct addrinfo *res;
     char **addrList;

-    if (NSS_NAME(gethostbyname2)(name, af, &resolved,
-                                 buf, sizeof(buf),
-                                 &err, &herr) != NS_SUCCESS)
-        return;
+    /* 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);

     addrList = resolved.h_addr_list;
     while (*addrList) {
-        union {
-            struct sockaddr sa;
-            struct sockaddr_in sin;
-            struct sockaddr_in6 sin6;
-        } sa = { 0 };
-        socklen_t salen;
         void *address = *addrList;
         char host[NI_MAXHOST];
+        struct addrinfo *res0;
+        struct addrinfo *res;
+
+        do  {
+            union {
+                struct sockaddr sa;
+                struct sockaddr_in sin;
+                struct sockaddr_in6 sin6;
+            } sa = { 0 };
+            socklen_t salen;
+
+            if (resolved.h_addrtype == AF_INET) {
+                sa.sin.sin_family = AF_INET;
+                memcpy(&sa.sin.sin_addr.s_addr,
+                       address,
+                       FAMILY_ADDRESS_SIZE(AF_INET));
+                salen = sizeof(sa.sin);
+            } else {
+                sa.sin6.sin6_family = AF_INET6;
+                memcpy(&sa.sin6.sin6_addr.s6_addr,
+                       address,
+                       FAMILY_ADDRESS_SIZE(AF_INET6));
+                salen = sizeof(sa.sin6);
+            }

-        if (resolved.h_addrtype == AF_INET) {
-            sa.sin.sin_family = AF_INET;
-            memcpy(&sa.sin.sin_addr.s_addr,
-                   address,
-                   FAMILY_ADDRESS_SIZE(AF_INET));
-            salen = sizeof(sa.sin);
-        } else {
-            sa.sin6.sin6_family = AF_INET6;
-            memcpy(&sa.sin6.sin6_addr.s6_addr,
-                   address,
-                   FAMILY_ADDRESS_SIZE(AF_INET6));
-            salen = sizeof(sa.sin6);
-        }
+            err = getnameinfo(&sa.sa, salen,
+                              host, sizeof(host),
+                              NULL, 0,
+                              NI_NUMERICHOST | NI_NUMERICSERV);
+        } while (false);

-        if ((err = getnameinfo(&sa.sa, salen,
-                               host, sizeof(host),
-                               NULL, 0,
-                               NI_NUMERICHOST | NI_NUMERICSERV)) != 0) {
+        if (err != 0) {
             ERROR("Cannot convert socket address to string: %s",
                   gai_strerror(err));
             continue;
         }

-        hints = *pai;
-        hints.ai_flags = AI_NUMERICHOST;
-        hints.ai_family = af;
+        do {
+            struct addrinfo hints;
+
+            hints = *pai;
+            hints.ai_flags = AI_NUMERICHOST;
+            hints.ai_family = af;
+
+            err = getaddrinfo(host, NULL, &hints, &res0);
+        } while (false);

-        if (getaddrinfo(host, NULL, &hints, &res0)) {
+        if (err != 0) {
             addrList++;
             continue;
         }
-- 
2.41.0
Re: [PATCH 7/8 v2] nss: aiforaf: Decrease stack size by scoping off large buffers
Posted by Kristina Hanicova 2 years, 5 months ago
On Wed, Aug 30, 2023 at 3:17 PM Peter Krempa <pkrempa@redhat.com> wrote:

> The 'buf', 'sa' and 'hints' stack allocated helper variables are never
> used together. Decrease the stack memory usage by scoping them off into
> do-while blocks.
>
> In this instance we do not want to use dynamic allocation as this is the
> NSS module.
>
> Signed-off-by: Peter Krempa <pkrempa@redhat.com>
> ---
>
> v2: Moved two error checks containing a 'continue' out of the 'do-while'
>     loop blocks
>
> New pipeline:
> https://gitlab.com/pipo.sk/libvirt/-/pipelines/986529301
>
>
>  tools/nss/libvirt_nss.c | 87 ++++++++++++++++++++++++-----------------
>  1 file changed, 51 insertions(+), 36 deletions(-)
>

Reviewed-by: Kristina Hanicova <khanicov@redhat.com>

Kristina