Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package glibc for openSUSE:Factory checked 
in at 2024-05-23 15:34:07
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/glibc (Old)
 and      /work/SRC/openSUSE:Factory/.glibc.new.24587 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "glibc"

Thu May 23 15:34:07 2024 rev:291 rq:1175454 version:2.39

Changes:
--------
--- /work/SRC/openSUSE:Factory/glibc/glibc.changes      2024-05-08 
11:38:33.766218637 +0200
+++ /work/SRC/openSUSE:Factory/.glibc.new.24587/glibc.changes   2024-05-23 
15:34:11.849301622 +0200
@@ -1,0 +2,33 @@
+Mon May 13 09:45:36 UTC 2024 - Andreas Schwab <sch...@suse.de>
+
+- glibc-CVE-2024-33599-nscd-Stack-based-buffer-overflow-in-n.patch:
+  nscd: Stack-based buffer overflow in netgroup cache
+  (CVE-2024-33599, bsc#1223423, BZ #31677)
+- glibc-CVE-2024-33600-nscd-Avoid-null-pointer-crashes-after.patch:
+  nscd: Avoid null pointer crashes after notfound response
+  (CVE-2024-33600, bsc#1223424, BZ #31678)
+- glibc-CVE-2024-33600-nscd-Do-not-send-missing-not-found-re.patch:
+  nscd: Do not send missing not-found response in addgetnetgrentX
+  (CVE-2024-33600, bsc#1223424, BZ #31678)
+- glibc-CVE-2024-33601-CVE-2024-33602-nscd-netgroup-Use-two.patch:
+  netgroup: Use two buffers in addgetnetgrentX (CVE-2024-33601,
+  CVE-2024-33602, bsc#1223425, BZ #31680)
+- nscd-netgroup-cache-timeout.patch: Use time_t for return type of
+  addgetnetgrentX (CVE-2024-33602, bsc#1223425)
+- glibc-fix-cve-2024-33599.patch: renamed
+
+-------------------------------------------------------------------
+Wed May  8 15:00:21 UTC 2024 - Giuliano Belinassi <giuliano.belina...@suse.com>
+
+- ulp-prologue-into-asm-functions.patch: Avoid creating ULP prologue
+  for _start routine (bsc#1221940)
+
+-------------------------------------------------------------------
+Wed May  8 10:42:39 UTC 2024 - Andreas Schwab <sch...@suse.de>
+
+- utmp-time-bits.patch: login: structs utmp, utmpx, lastlog _TIME_BITS
+  independence (BZ #30701)
+- elf-parse-tunables.patch: elf: Only process multiple tunable once (BZ
+  #31686)
+
+-------------------------------------------------------------------

Old:
----
  glibc-fix-cve-2024-33599.patch

New:
----
  elf-parse-tunables.patch
  glibc-CVE-2024-33599-nscd-Stack-based-buffer-overflow-in-n.patch
  glibc-CVE-2024-33600-nscd-Avoid-null-pointer-crashes-after.patch
  glibc-CVE-2024-33600-nscd-Do-not-send-missing-not-found-re.patch
  glibc-CVE-2024-33601-CVE-2024-33602-nscd-netgroup-Use-two.patch
  nscd-netgroup-cache-timeout.patch
  utmp-time-bits.patch

BETA DEBUG BEGIN:
  Old:  addgetnetgrentX (CVE-2024-33602, bsc#1223425)
- glibc-fix-cve-2024-33599.patch: renamed
BETA DEBUG END:

BETA DEBUG BEGIN:
  New:  independence (BZ #30701)
- elf-parse-tunables.patch: elf: Only process multiple tunable once (BZ
  #31686)
  New:
- glibc-CVE-2024-33599-nscd-Stack-based-buffer-overflow-in-n.patch:
  nscd: Stack-based buffer overflow in netgroup cache
  New:  (CVE-2024-33599, bsc#1223423, BZ #31677)
- glibc-CVE-2024-33600-nscd-Avoid-null-pointer-crashes-after.patch:
  nscd: Avoid null pointer crashes after notfound response
  New:  (CVE-2024-33600, bsc#1223424, BZ #31678)
- glibc-CVE-2024-33600-nscd-Do-not-send-missing-not-found-re.patch:
  nscd: Do not send missing not-found response in addgetnetgrentX
  New:  (CVE-2024-33600, bsc#1223424, BZ #31678)
- glibc-CVE-2024-33601-CVE-2024-33602-nscd-netgroup-Use-two.patch:
  netgroup: Use two buffers in addgetnetgrentX (CVE-2024-33601,
  New:  CVE-2024-33602, bsc#1223425, BZ #31680)
- nscd-netgroup-cache-timeout.patch: Use time_t for return type of
  addgetnetgrentX (CVE-2024-33602, bsc#1223425)
  New:
- utmp-time-bits.patch: login: structs utmp, utmpx, lastlog _TIME_BITS
  independence (BZ #30701)
BETA DEBUG END:

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ glibc.spec ++++++
--- /var/tmp/diff_new_pack.SxmagC/_old  2024-05-23 15:34:15.941450117 +0200
+++ /var/tmp/diff_new_pack.SxmagC/_new  2024-05-23 15:34:15.945450262 +0200
@@ -314,8 +314,20 @@
 Patch1004:      stdbit-builtins.patch
 # PATCH-FIX-UPSTREAM iconv: ISO-2022-CN-EXT: fix out-of-bound writes when 
writing escape sequence (CVE-2024-2961)
 Patch1005:      iconv-iso-2022-cn-ext.patch
-# PATCH-FIX-UPSTREAM: CVE-2024-33599: nscd: Stack-based buffer overflow in 
netgroup cache
-Patch1006:      glibc-fix-cve-2024-33599.patch
+# PATCH-FIX-UPSTREAM login: structs utmp, utmpx, lastlog _TIME_BITS 
independence (BZ #30701)
+Patch1006:      utmp-time-bits.patch
+# PATCH-FIX-UPSTREAM elf: Only process multiple tunable once (BZ #31686)
+Patch1007:      elf-parse-tunables.patch
+# PATCH-FIX-UPSTREAM nscd: Stack-based buffer overflow in netgroup cache 
(CVE-2024-33599, BZ #31677)
+Patch1008:      
glibc-CVE-2024-33599-nscd-Stack-based-buffer-overflow-in-n.patch
+# PATCH-FIX-UPSTREAM nscd: Do not send missing not found response in 
addgetnetgrentX (CVE-2024-33600, BZ #31678)
+Patch1009:      
glibc-CVE-2024-33600-nscd-Do-not-send-missing-not-found-re.patch
+# PATCH-FIX-UPSTREAM nscd: Avoid null pointer crashes after notfound response 
(CVE-2024-33600, BZ #31678)
+Patch1010:      
glibc-CVE-2024-33600-nscd-Avoid-null-pointer-crashes-after.patch
+# PATCH-FIX-UPSTREAM nscd netgroup: Use two buffers in addgetnetgrentX 
(CVE-2024-33601, CVE-2024-33602, BZ #31680)
+Patch1011:      glibc-CVE-2024-33601-CVE-2024-33602-nscd-netgroup-Use-two.patch
+# PATCH-FIX-UPSTREAM nscd: Use time_t for return type of addgetnetgrentX 
(CVE-2024-33602)
+Patch1012:      nscd-netgroup-cache-timeout.patch
 %endif
 
 ###

++++++ elf-parse-tunables.patch ++++++
>From 71149c2a2e85a8233631cc816030d449f021bb2a Mon Sep 17 00:00:00 2001
From: Adhemerval Zanella <adhemerval.zane...@linaro.org>
Date: Mon, 6 May 2024 13:18:45 -0300
Subject: [PATCH] elf: Only process multiple tunable once (BZ 31686)

The 680c597e9c3 commit made loader reject ill-formatted strings by
first tracking all set tunables and then applying them. However, it does
not take into consideration if the same tunable is set multiple times,
where parse_tunables_string appends the found tunable without checking
if it was already in the list. It leads to a stack-based buffer overflow
if the tunable is specified more than the total number of tunables.  For
instance:

  GLIBC_TUNABLES=glibc.malloc.check=2:... (repeat over the number of
  total support for different tunable).

Instead, use the index of the tunable list to get the expected tunable
entry.  Since now the initial list is zero-initialized, the compiler
might emit an extra memset and this requires some minor adjustment
on some ports.

Checked on x86_64-linux-gnu and aarch64-linux-gnu.

Reported-by: Yuto Maeda <ma...@cyberdefense.jp>
Reported-by: Yutaro Shimizu <shim...@cyberdefense.jp>
Reviewed-by: Siddhesh Poyarekar <siddh...@sourceware.org>
(cherry picked from commit bcae44ea8536b30a7119c0986ff5692bddacb672)
---
 elf/dl-tunables.c                          | 28 ++++++----
 elf/tst-tunables.c                         | 61 +++++++++++++++++++++-
 sysdeps/aarch64/multiarch/memset_generic.S |  4 ++
 sysdeps/sparc/sparc64/rtld-memset.c        |  3 ++
 4 files changed, 84 insertions(+), 12 deletions(-)

diff --git a/elf/dl-tunables.c b/elf/dl-tunables.c
index 03e1a68675..614ac9c047 100644
--- a/elf/dl-tunables.c
+++ b/elf/dl-tunables.c
@@ -32,6 +32,7 @@
 #include <ldsodefs.h>
 #include <array_length.h>
 #include <dl-minimal-malloc.h>
+#include <dl-symbol-redir-ifunc.h>
 
 #define TUNABLES_INTERNAL 1
 #include "dl-tunables.h"
@@ -223,6 +224,7 @@ parse_tunables_string (const char *valstring, struct 
tunable_toset_t *tunables)
            {
              tunables[ntunables++] =
                (struct tunable_toset_t) { cur, value, p - value };
+
              break;
            }
        }
@@ -234,23 +236,27 @@ parse_tunables_string (const char *valstring, struct 
tunable_toset_t *tunables)
 static void
 parse_tunables (const char *valstring)
 {
-  struct tunable_toset_t tunables[tunables_list_size];
-  int ntunables = parse_tunables_string (valstring, tunables);
-  if (ntunables == -1)
+  struct tunable_toset_t tunables[tunables_list_size] = { 0 };
+  if (parse_tunables_string (valstring, tunables) == -1)
     {
       _dl_error_printf (
         "WARNING: ld.so: invalid GLIBC_TUNABLES `%s': ignored.\n", valstring);
       return;
     }
 
-  for (int i = 0; i < ntunables; i++)
-    if (!tunable_initialize (tunables[i].t, tunables[i].value,
-                            tunables[i].len))
-      _dl_error_printf ("WARNING: ld.so: invalid GLIBC_TUNABLES value `%.*s' "
-                      "for option `%s': ignored.\n",
-                      (int) tunables[i].len,
-                      tunables[i].value,
-                      tunables[i].t->name);
+  for (int i = 0; i < tunables_list_size; i++)
+    {
+      if (tunables[i].t == NULL)
+       continue;
+
+      if (!tunable_initialize (tunables[i].t, tunables[i].value,
+                              tunables[i].len))
+       _dl_error_printf ("WARNING: ld.so: invalid GLIBC_TUNABLES value `%.*s' "
+                         "for option `%s': ignored.\n",
+                         (int) tunables[i].len,
+                         tunables[i].value,
+                         tunables[i].t->name);
+    }
 }
 
 /* Initialize the tunables list from the environment.  For now we only use the
diff --git a/elf/tst-tunables.c b/elf/tst-tunables.c
index 095b5c81d9..dff34ed748 100644
--- a/elf/tst-tunables.c
+++ b/elf/tst-tunables.c
@@ -17,6 +17,10 @@
    <https://www.gnu.org/licenses/>.  */
 
 #include <array_length.h>
+/* The test uses the tunable_list size, which is only exported for
+   ld.so.  This will result in a copy of tunable_list, which is ununsed by
+   the test itself.  */
+#define TUNABLES_INTERNAL 1
 #include <dl-tunables.h>
 #include <getopt.h>
 #include <intprops.h>
@@ -24,12 +28,13 @@
 #include <stdlib.h>
 #include <support/capture_subprocess.h>
 #include <support/check.h>
+#include <support/support.h>
 
 static int restart;
 #define CMDLINE_OPTIONS \
   { "restart", no_argument, &restart, 1 },
 
-static const struct test_t
+static struct test_t
 {
   const char *name;
   const char *value;
@@ -284,6 +289,29 @@ static const struct test_t
     0,
     0,
   },
+  /* Also check for repeated tunables with a count larger than the total number
+     of tunables.  */
+  {
+    "GLIBC_TUNABLES",
+    NULL,
+    2,
+    0,
+    0,
+  },
+  {
+    "GLIBC_TUNABLES",
+    NULL,
+    1,
+    0,
+    0,
+  },
+  {
+    "GLIBC_TUNABLES",
+    NULL,
+    0,
+    0,
+    0,
+  },
 };
 
 static int
@@ -327,6 +355,37 @@ do_test (int argc, char *argv[])
     spargv[i] = NULL;
   }
 
+  /* Create a tunable line with the duplicate values with a total number
+     larger than the different number of tunables.  */
+  {
+    enum { tunables_list_size = array_length (tunable_list) };
+    const char *value = "";
+    for (int i = 0; i < tunables_list_size; i++)
+      value = xasprintf ("%sglibc.malloc.check=2%c",
+                        value,
+                        i == (tunables_list_size - 1) ? '\0' : ':');
+    tests[33].value = value;
+  }
+  /* Same as before, but the last tunable values is differen than the
+     rest.  */
+  {
+    enum { tunables_list_size = array_length (tunable_list) };
+    const char *value = "";
+    for (int i = 0; i < tunables_list_size - 1; i++)
+      value = xasprintf ("%sglibc.malloc.check=2:", value);
+    value = xasprintf ("%sglibc.malloc.check=1", value);
+    tests[34].value = value;
+  }
+  /* Same as before, but with an invalid last entry.  */
+  {
+    enum { tunables_list_size = array_length (tunable_list) };
+    const char *value = "";
+    for (int i = 0; i < tunables_list_size - 1; i++)
+      value = xasprintf ("%sglibc.malloc.check=2:", value);
+    value = xasprintf ("%sglibc.malloc.check=1=1", value);
+    tests[35].value = value;
+  }
+
   for (int i = 0; i < array_length (tests); i++)
     {
       snprintf (nteststr, sizeof nteststr, "%d", i);
diff --git a/sysdeps/aarch64/multiarch/memset_generic.S 
b/sysdeps/aarch64/multiarch/memset_generic.S
index 81748bdbce..e125a5ed85 100644
--- a/sysdeps/aarch64/multiarch/memset_generic.S
+++ b/sysdeps/aarch64/multiarch/memset_generic.S
@@ -33,3 +33,7 @@
 #endif
 
 #include <../memset.S>
+
+#if IS_IN (rtld)
+strong_alias (memset, __memset_generic)
+#endif
diff --git a/sysdeps/sparc/sparc64/rtld-memset.c 
b/sysdeps/sparc/sparc64/rtld-memset.c
index 55f3835790..a19202a620 100644
--- a/sysdeps/sparc/sparc64/rtld-memset.c
+++ b/sysdeps/sparc/sparc64/rtld-memset.c
@@ -1 +1,4 @@
 #include <string/memset.c>
+#if IS_IN(rtld)
+strong_alias (memset, __memset_ultra1)
+#endif
-- 
2.45.0



++++++ glibc-CVE-2024-33599-nscd-Stack-based-buffer-overflow-in-n.patch ++++++
>From 1263d583d2e28afb8be53f8d6922f0842036f35d Mon Sep 17 00:00:00 2001
From: Florian Weimer <fwei...@redhat.com>
Date: Thu, 25 Apr 2024 15:00:45 +0200
Subject: [PATCH] CVE-2024-33599: nscd: Stack-based buffer overflow in netgroup
 cache (bug 31677)

Using alloca matches what other caches do.  The request length is
bounded by MAXKEYLEN.

Reviewed-by: Carlos O'Donell <car...@redhat.com>
(cherry picked from commit 87801a8fd06db1d654eea3e4f7626ff476a9bdaa)
---
 nscd/netgroupcache.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/nscd/netgroupcache.c b/nscd/netgroupcache.c
index 0c6e46f15c..f227dc7fa2 100644
--- a/nscd/netgroupcache.c
+++ b/nscd/netgroupcache.c
@@ -502,12 +502,13 @@ addinnetgrX (struct database_dyn *db, int fd, 
request_header *req,
       = (struct indataset *) mempool_alloc (db,
                                            sizeof (*dataset) + req->key_len,
                                            1);
-  struct indataset dataset_mem;
   bool cacheable = true;
   if (__glibc_unlikely (dataset == NULL))
     {
       cacheable = false;
-      dataset = &dataset_mem;
+      /* The alloca is safe because nscd_run_worker verfies that
+        key_len is not larger than MAXKEYLEN.  */
+      dataset = alloca (sizeof (*dataset) + req->key_len);
     }
 
   datahead_init_pos (&dataset->head, sizeof (*dataset) + req->key_len,
-- 
2.45.0


++++++ glibc-CVE-2024-33600-nscd-Avoid-null-pointer-crashes-after.patch ++++++
>From c99f886de54446cd4447db6b44be93dabbdc2f8b Mon Sep 17 00:00:00 2001
From: Florian Weimer <fwei...@redhat.com>
Date: Thu, 25 Apr 2024 15:01:07 +0200
Subject: [PATCH] CVE-2024-33600: nscd: Avoid null pointer crashes after
 notfound response (bug 31678)

The addgetnetgrentX call in addinnetgrX may have failed to produce
a result, so the result variable in addinnetgrX can be NULL.
Use db->negtimeout as the fallback value if there is no result data;
the timeout is also overwritten below.

Also avoid sending a second not-found response.  (The client
disconnects after receiving the first response, so the data stream did
not go out of sync even without this fix.)  It is still beneficial to
add the negative response to the mapping, so that the client can get
it from there in the future, instead of going through the socket.

Reviewed-by: Siddhesh Poyarekar <siddh...@sourceware.org>
(cherry picked from commit b048a482f088e53144d26a61c390bed0210f49f2)
---
 nscd/netgroupcache.c | 11 +++++++----
 1 file changed, 7 insertions(+), 4 deletions(-)

diff --git a/nscd/netgroupcache.c b/nscd/netgroupcache.c
index c18fe111f3..e22ffa5884 100644
--- a/nscd/netgroupcache.c
+++ b/nscd/netgroupcache.c
@@ -511,14 +511,15 @@ addinnetgrX (struct database_dyn *db, int fd, 
request_header *req,
 
   datahead_init_pos (&dataset->head, sizeof (*dataset) + req->key_len,
                     sizeof (innetgroup_response_header),
-                    he == NULL ? 0 : dh->nreloads + 1, result->head.ttl);
+                    he == NULL ? 0 : dh->nreloads + 1,
+                    result == NULL ? db->negtimeout : result->head.ttl);
   /* Set the notfound status and timeout based on the result from
      getnetgrent.  */
-  dataset->head.notfound = result->head.notfound;
+  dataset->head.notfound = result == NULL || result->head.notfound;
   dataset->head.timeout = timeout;
 
   dataset->resp.version = NSCD_VERSION;
-  dataset->resp.found = result->resp.found;
+  dataset->resp.found = result != NULL && result->resp.found;
   /* Until we find a matching entry the result is 0.  */
   dataset->resp.result = 0;
 
@@ -566,7 +567,9 @@ addinnetgrX (struct database_dyn *db, int fd, 
request_header *req,
       goto out;
     }
 
-  if (he == NULL)
+  /* addgetnetgrentX may have already sent a notfound response.  Do
+     not send another one.  */
+  if (he == NULL && dataset->resp.found)
     {
       /* We write the dataset before inserting it to the database
         since while inserting this thread might block and so would
-- 
2.45.0


++++++ glibc-CVE-2024-33600-nscd-Do-not-send-missing-not-found-re.patch ++++++
>From 5a508e0b508c8ad53bd0d2fb48fd71b242626341 Mon Sep 17 00:00:00 2001
From: Florian Weimer <fwei...@redhat.com>
Date: Thu, 25 Apr 2024 15:01:07 +0200
Subject: [PATCH] CVE-2024-33600: nscd: Do not send missing not-found response
 in addgetnetgrentX (bug 31678)

If we failed to add a not-found response to the cache, the dataset
point can be null, resulting in a null pointer dereference.

Reviewed-by: Siddhesh Poyarekar <siddh...@sourceware.org>
(cherry picked from commit 7835b00dbce53c3c87bbbb1754a95fb5e58187aa)
---
 nscd/netgroupcache.c | 14 ++++++--------
 1 file changed, 6 insertions(+), 8 deletions(-)

diff --git a/nscd/netgroupcache.c b/nscd/netgroupcache.c
index f227dc7fa2..c18fe111f3 100644
--- a/nscd/netgroupcache.c
+++ b/nscd/netgroupcache.c
@@ -147,7 +147,7 @@ addgetnetgrentX (struct database_dyn *db, int fd, 
request_header *req,
       /* No such service.  */
       cacheable = do_notfound (db, fd, req, key, &dataset, &total, &timeout,
                               &key_copy);
-      goto writeout;
+      goto maybe_cache_add;
     }
 
   memset (&data, '\0', sizeof (data));
@@ -348,7 +348,7 @@ addgetnetgrentX (struct database_dyn *db, int fd, 
request_header *req,
     {
       cacheable = do_notfound (db, fd, req, key, &dataset, &total, &timeout,
                               &key_copy);
-      goto writeout;
+      goto maybe_cache_add;
     }
 
   total = buffilled;
@@ -410,14 +410,12 @@ addgetnetgrentX (struct database_dyn *db, int fd, 
request_header *req,
   }
 
   if (he == NULL && fd != -1)
-    {
-      /* We write the dataset before inserting it to the database
-        since while inserting this thread might block and so would
-        unnecessarily let the receiver wait.  */
-    writeout:
+    /* We write the dataset before inserting it to the database since
+       while inserting this thread might block and so would
+       unnecessarily let the receiver wait.  */
       writeall (fd, &dataset->resp, dataset->head.recsize);
-    }
 
+ maybe_cache_add:
   if (cacheable)
     {
       /* If necessary, we also propagate the data to disk.  */
-- 
2.45.0


++++++ glibc-CVE-2024-33601-CVE-2024-33602-nscd-netgroup-Use-two.patch ++++++
>From a9a8d3eebb145779a18d90e3966009a1daa63cd8 Mon Sep 17 00:00:00 2001
From: Florian Weimer <fwei...@redhat.com>
Date: Thu, 25 Apr 2024 15:01:07 +0200
Subject: [PATCH] CVE-2024-33601, CVE-2024-33602: nscd: netgroup: Use two
 buffers in addgetnetgrentX (bug 31680)

This avoids potential memory corruption when the underlying NSS
callback function does not use the buffer space to store all strings
(e.g., for constant strings).

Instead of custom buffer management, two scratch buffers are used.
This increases stack usage somewhat.

Scratch buffer allocation failure is handled by return -1
(an invalid timeout value) instead of terminating the process.
This fixes bug 31679.

Reviewed-by: Siddhesh Poyarekar <siddh...@sourceware.org>
(cherry picked from commit c04a21e050d64a1193a6daab872bca2528bda44b)
---
 nscd/netgroupcache.c | 219 ++++++++++++++++++++++++-------------------
 1 file changed, 121 insertions(+), 98 deletions(-)

diff --git a/nscd/netgroupcache.c b/nscd/netgroupcache.c
index e22ffa5884..e8fe041846 100644
--- a/nscd/netgroupcache.c
+++ b/nscd/netgroupcache.c
@@ -23,6 +23,7 @@
 #include <stdlib.h>
 #include <unistd.h>
 #include <sys/mman.h>
+#include <scratch_buffer.h>
 
 #include "../nss/netgroup.h"
 #include "nscd.h"
@@ -65,6 +66,16 @@ struct dataset
   char strdata[0];
 };
 
+/* Send a notfound response to FD.  Always returns -1 to indicate an
+   ephemeral error.  */
+static time_t
+send_notfound (int fd)
+{
+  if (fd != -1)
+    TEMP_FAILURE_RETRY (send (fd, &notfound, sizeof (notfound), MSG_NOSIGNAL));
+  return -1;
+}
+
 /* Sends a notfound message and prepares a notfound dataset to write to the
    cache.  Returns true if there was enough memory to allocate the dataset and
    returns the dataset in DATASETP, total bytes to write in TOTALP and the
@@ -83,8 +94,7 @@ do_notfound (struct database_dyn *db, int fd, request_header 
*req,
   total = sizeof (notfound);
   timeout = time (NULL) + db->negtimeout;
 
-  if (fd != -1)
-    TEMP_FAILURE_RETRY (send (fd, &notfound, total, MSG_NOSIGNAL));
+  send_notfound (fd);
 
   dataset = mempool_alloc (db, sizeof (struct dataset) + req->key_len, 1);
   /* If we cannot permanently store the result, so be it.  */
@@ -109,11 +119,78 @@ do_notfound (struct database_dyn *db, int fd, 
request_header *req,
   return cacheable;
 }
 
+struct addgetnetgrentX_scratch
+{
+  /* This is the result that the caller should use.  It can be NULL,
+     point into buffer, or it can be in the cache.  */
+  struct dataset *dataset;
+
+  struct scratch_buffer buffer;
+
+  /* Used internally in addgetnetgrentX as a staging area.  */
+  struct scratch_buffer tmp;
+
+  /* Number of bytes in buffer that are actually used.  */
+  size_t buffer_used;
+};
+
+static void
+addgetnetgrentX_scratch_init (struct addgetnetgrentX_scratch *scratch)
+{
+  scratch->dataset = NULL;
+  scratch_buffer_init (&scratch->buffer);
+  scratch_buffer_init (&scratch->tmp);
+
+  /* Reserve space for the header.  */
+  scratch->buffer_used = sizeof (struct dataset);
+  static_assert (sizeof (struct dataset) < sizeof (scratch->tmp.__space),
+                "initial buffer space");
+  memset (scratch->tmp.data, 0, sizeof (struct dataset));
+}
+
+static void
+addgetnetgrentX_scratch_free (struct addgetnetgrentX_scratch *scratch)
+{
+  scratch_buffer_free (&scratch->buffer);
+  scratch_buffer_free (&scratch->tmp);
+}
+
+/* Copy LENGTH bytes from S into SCRATCH.  Returns NULL if SCRATCH
+   could not be resized, otherwise a pointer to the copy.  */
+static char *
+addgetnetgrentX_append_n (struct addgetnetgrentX_scratch *scratch,
+                         const char *s, size_t length)
+{
+  while (true)
+    {
+      size_t remaining = scratch->buffer.length - scratch->buffer_used;
+      if (remaining >= length)
+       break;
+      if (!scratch_buffer_grow_preserve (&scratch->buffer))
+       return NULL;
+    }
+  char *copy = scratch->buffer.data + scratch->buffer_used;
+  memcpy (copy, s, length);
+  scratch->buffer_used += length;
+  return copy;
+}
+
+/* Copy S into SCRATCH, including its null terminator.  Returns false
+   if SCRATCH could not be resized.  */
+static bool
+addgetnetgrentX_append (struct addgetnetgrentX_scratch *scratch, const char *s)
+{
+  if (s == NULL)
+    s = "";
+  return addgetnetgrentX_append_n (scratch, s, strlen (s) + 1) != NULL;
+}
+
+/* Caller must initialize and free *SCRATCH.  If the return value is
+   negative, this function has sent a notfound response.  */
 static time_t
 addgetnetgrentX (struct database_dyn *db, int fd, request_header *req,
                 const char *key, uid_t uid, struct hashentry *he,
-                struct datahead *dh, struct dataset **resultp,
-                void **tofreep)
+                struct datahead *dh, struct addgetnetgrentX_scratch *scratch)
 {
   if (__glibc_unlikely (debug_level > 0))
     {
@@ -132,14 +209,10 @@ addgetnetgrentX (struct database_dyn *db, int fd, 
request_header *req,
 
   char *key_copy = NULL;
   struct __netgrent data;
-  size_t buflen = MAX (1024, sizeof (*dataset) + req->key_len);
-  size_t buffilled = sizeof (*dataset);
-  char *buffer = NULL;
   size_t nentries = 0;
   size_t group_len = strlen (key) + 1;
   struct name_list *first_needed
     = alloca (sizeof (struct name_list) + group_len);
-  *tofreep = NULL;
 
   if (netgroup_database == NULL
       && !__nss_database_get (nss_database_netgroup, &netgroup_database))
@@ -151,8 +224,6 @@ addgetnetgrentX (struct database_dyn *db, int fd, 
request_header *req,
     }
 
   memset (&data, '\0', sizeof (data));
-  buffer = xmalloc (buflen);
-  *tofreep = buffer;
   first_needed->next = first_needed;
   memcpy (first_needed->name, key, group_len);
   data.needed_groups = first_needed;
@@ -195,8 +266,8 @@ addgetnetgrentX (struct database_dyn *db, int fd, 
request_header *req,
                while (1)
                  {
                    int e;
-                   status = getfct.f (&data, buffer + buffilled,
-                                      buflen - buffilled - req->key_len, &e);
+                   status = getfct.f (&data, scratch->tmp.data,
+                                      scratch->tmp.length, &e);
                    if (status == NSS_STATUS_SUCCESS)
                      {
                        if (data.type == triple_val)
@@ -204,68 +275,10 @@ addgetnetgrentX (struct database_dyn *db, int fd, 
request_header *req,
                            const char *nhost = data.val.triple.host;
                            const char *nuser = data.val.triple.user;
                            const char *ndomain = data.val.triple.domain;
-
-                           size_t hostlen = strlen (nhost ?: "") + 1;
-                           size_t userlen = strlen (nuser ?: "") + 1;
-                           size_t domainlen = strlen (ndomain ?: "") + 1;
-
-                           if (nhost == NULL || nuser == NULL || ndomain == 
NULL
-                               || nhost > nuser || nuser > ndomain)
-                             {
-                               const char *last = nhost;
-                               if (last == NULL
-                                   || (nuser != NULL && nuser > last))
-                                 last = nuser;
-                               if (last == NULL
-                                   || (ndomain != NULL && ndomain > last))
-                                 last = ndomain;
-
-                               size_t bufused
-                                 = (last == NULL
-                                    ? buffilled
-                                    : last + strlen (last) + 1 - buffer);
-
-                               /* We have to make temporary copies.  */
-                               size_t needed = hostlen + userlen + domainlen;
-
-                               if (buflen - req->key_len - bufused < needed)
-                                 {
-                                   buflen += MAX (buflen, 2 * needed);
-                                   /* Save offset in the old buffer.  We don't
-                                      bother with the NULL check here since
-                                      we'll do that later anyway.  */
-                                   size_t nhostdiff = nhost - buffer;
-                                   size_t nuserdiff = nuser - buffer;
-                                   size_t ndomaindiff = ndomain - buffer;
-
-                                   char *newbuf = xrealloc (buffer, buflen);
-                                   /* Fix up the triplet pointers into the new
-                                      buffer.  */
-                                   nhost = (nhost ? newbuf + nhostdiff
-                                            : NULL);
-                                   nuser = (nuser ? newbuf + nuserdiff
-                                            : NULL);
-                                   ndomain = (ndomain ? newbuf + ndomaindiff
-                                              : NULL);
-                                   *tofreep = buffer = newbuf;
-                                 }
-
-                               nhost = memcpy (buffer + bufused,
-                                               nhost ?: "", hostlen);
-                               nuser = memcpy ((char *) nhost + hostlen,
-                                               nuser ?: "", userlen);
-                               ndomain = memcpy ((char *) nuser + userlen,
-                                                 ndomain ?: "", domainlen);
-                             }
-
-                           char *wp = buffer + buffilled;
-                           wp = memmove (wp, nhost ?: "", hostlen);
-                           wp += hostlen;
-                           wp = memmove (wp, nuser ?: "", userlen);
-                           wp += userlen;
-                           wp = memmove (wp, ndomain ?: "", domainlen);
-                           wp += domainlen;
-                           buffilled = wp - buffer;
+                           if (!(addgetnetgrentX_append (scratch, nhost)
+                                 && addgetnetgrentX_append (scratch, nuser)
+                                 && addgetnetgrentX_append (scratch, ndomain)))
+                             return send_notfound (fd);
                            ++nentries;
                          }
                        else
@@ -317,8 +330,8 @@ addgetnetgrentX (struct database_dyn *db, int fd, 
request_header *req,
                      }
                    else if (status == NSS_STATUS_TRYAGAIN && e == ERANGE)
                      {
-                       buflen *= 2;
-                       *tofreep = buffer = xrealloc (buffer, buflen);
+                       if (!scratch_buffer_grow (&scratch->tmp))
+                         return send_notfound (fd);
                      }
                    else if (status == NSS_STATUS_RETURN
                             || status == NSS_STATUS_NOTFOUND
@@ -351,10 +364,17 @@ addgetnetgrentX (struct database_dyn *db, int fd, 
request_header *req,
       goto maybe_cache_add;
     }
 
-  total = buffilled;
+  /* Capture the result size without the key appended.   */
+  total = scratch->buffer_used;
+
+  /* Make a copy of the key.  The scratch buffer must not move after
+     this point.  */
+  key_copy = addgetnetgrentX_append_n (scratch, key, req->key_len);
+  if (key_copy == NULL)
+    return send_notfound (fd);
 
   /* Fill in the dataset.  */
-  dataset = (struct dataset *) buffer;
+  dataset = scratch->buffer.data;
   timeout = datahead_init_pos (&dataset->head, total + req->key_len,
                               total - offsetof (struct dataset, resp),
                               he == NULL ? 0 : dh->nreloads + 1,
@@ -363,11 +383,7 @@ addgetnetgrentX (struct database_dyn *db, int fd, 
request_header *req,
   dataset->resp.version = NSCD_VERSION;
   dataset->resp.found = 1;
   dataset->resp.nresults = nentries;
-  dataset->resp.result_len = buffilled - sizeof (*dataset);
-
-  assert (buflen - buffilled >= req->key_len);
-  key_copy = memcpy (buffer + buffilled, key, req->key_len);
-  buffilled += req->key_len;
+  dataset->resp.result_len = total - sizeof (*dataset);
 
   /* Now we can determine whether on refill we have to create a new
      record or not.  */
@@ -398,7 +414,7 @@ addgetnetgrentX (struct database_dyn *db, int fd, 
request_header *req,
     if (__glibc_likely (newp != NULL))
       {
        /* Adjust pointer into the memory block.  */
-       key_copy = (char *) newp + (key_copy - buffer);
+       key_copy = (char *) newp + (key_copy - (char *) dataset);
 
        dataset = memcpy (newp, dataset, total + req->key_len);
        cacheable = true;
@@ -439,7 +455,7 @@ addgetnetgrentX (struct database_dyn *db, int fd, 
request_header *req,
     }
 
  out:
-  *resultp = dataset;
+  scratch->dataset = dataset;
 
   return timeout;
 }
@@ -460,6 +476,9 @@ addinnetgrX (struct database_dyn *db, int fd, 
request_header *req,
   if (user != NULL)
     key = strchr (key, '\0') + 1;
   const char *domain = *key++ ? key : NULL;
+  struct addgetnetgrentX_scratch scratch;
+
+  addgetnetgrentX_scratch_init (&scratch);
 
   if (__glibc_unlikely (debug_level > 0))
     {
@@ -475,12 +494,8 @@ addinnetgrX (struct database_dyn *db, int fd, 
request_header *req,
                                                            group, group_len,
                                                            db, uid);
   time_t timeout;
-  void *tofree;
   if (result != NULL)
-    {
-      timeout = result->head.timeout;
-      tofree = NULL;
-    }
+    timeout = result->head.timeout;
   else
     {
       request_header req_get =
@@ -489,7 +504,10 @@ addinnetgrX (struct database_dyn *db, int fd, 
request_header *req,
          .key_len = group_len
        };
       timeout = addgetnetgrentX (db, -1, &req_get, group, uid, NULL, NULL,
-                                &result, &tofree);
+                                &scratch);
+      result = scratch.dataset;
+      if (timeout < 0)
+       goto out;
     }
 
   struct indataset
@@ -603,7 +621,7 @@ addinnetgrX (struct database_dyn *db, int fd, 
request_header *req,
     }
 
  out:
-  free (tofree);
+  addgetnetgrentX_scratch_free (&scratch);
   return timeout;
 }
 
@@ -613,11 +631,12 @@ addgetnetgrentX_ignore (struct database_dyn *db, int fd, 
request_header *req,
                        const char *key, uid_t uid, struct hashentry *he,
                        struct datahead *dh)
 {
-  struct dataset *ignore;
-  void *tofree;
-  time_t timeout = addgetnetgrentX (db, fd, req, key, uid, he, dh,
-                                   &ignore, &tofree);
-  free (tofree);
+  struct addgetnetgrentX_scratch scratch;
+  addgetnetgrentX_scratch_init (&scratch);
+  time_t timeout = addgetnetgrentX (db, fd, req, key, uid, he, dh, &scratch);
+  addgetnetgrentX_scratch_free (&scratch);
+  if (timeout < 0)
+    timeout = 0;
   return timeout;
 }
 
@@ -661,5 +680,9 @@ readdinnetgr (struct database_dyn *db, struct hashentry *he,
       .key_len = he->len
     };
 
-  return addinnetgrX (db, -1, &req, db->data + he->key, he->owner, he, dh);
+  int timeout = addinnetgrX (db, -1, &req, db->data + he->key, he->owner,
+                            he, dh);
+  if (timeout < 0)
+    timeout = 0;
+  return timeout;
 }
-- 
2.45.0


++++++ nscd-netgroup-cache-timeout.patch ++++++
>From acc56074b0a5127631a64640aef1b7c5c103ebd8 Mon Sep 17 00:00:00 2001
From: Florian Weimer <fwei...@redhat.com>
Date: Thu, 2 May 2024 17:06:19 +0200
Subject: [PATCH] nscd: Use time_t for return type of addgetnetgrentX

Using int may give false results for future dates (timeouts after the
year 2028).

Fixes commit 04a21e050d64a1193a6daab872bca2528bda44b ("CVE-2024-33601,
CVE-2024-33602: nscd: netgroup: Use two buffers in addgetnetgrentX
(bug 31680)").

Reviewed-by: Carlos O'Donell <car...@redhat.com>
(cherry picked from commit 4bbca1a44691a6e9adcee5c6798a707b626bc331)
---
 nscd/netgroupcache.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/nscd/netgroupcache.c b/nscd/netgroupcache.c
index e8fe041846..01d554af9c 100644
--- a/nscd/netgroupcache.c
+++ b/nscd/netgroupcache.c
@@ -680,8 +680,8 @@ readdinnetgr (struct database_dyn *db, struct hashentry *he,
       .key_len = he->len
     };
 
-  int timeout = addinnetgrX (db, -1, &req, db->data + he->key, he->owner,
-                            he, dh);
+  time_t timeout = addinnetgrX (db, -1, &req, db->data + he->key, he->owner,
+                               he, dh);
   if (timeout < 0)
     timeout = 0;
   return timeout;
-- 
2.45.0


++++++ ulp-prologue-into-asm-functions.patch ++++++
--- /var/tmp/diff_new_pack.SxmagC/_old  2024-05-23 15:34:16.269462020 +0200
+++ /var/tmp/diff_new_pack.SxmagC/_new  2024-05-23 15:34:16.273462165 +0200
@@ -1,6 +1,6 @@
-From 3c0817dcbbc99eb438a33be5336db69cf88ca7cf Mon Sep 17 00:00:00 2001
+From ec4f0a28ed48c51165e3e72c7427efb0ae14a124 Mon Sep 17 00:00:00 2001
 From: Giuliano Belinassi <gbelina...@suse.de>
-Date: Wed, 24 May 2023 18:03:15 -0300
+Date: Mon, 6 May 2024 20:09:55 -0300
 Subject: [PATCH] Add Userspace Livepatch prologue into ASM functions
 
 Userspace Live Patching (ULP) refers to the process of applying
@@ -12,22 +12,22 @@
 
 Signed-off-by: Giuliano Belinassi <gbelina...@suse.de>
 ---
- Makeconfig                               |  5 +++++
- config.h.in                              |  3 +++
+ Makeconfig                               |  5 +++
+ config.h.in                              |  3 ++
  config.make.in                           |  1 +
- configure                                | 21 ++++++++++++++++++
- configure.ac                             | 13 +++++++++++
- sysdeps/x86_64/multiarch/strcmp-avx2.S   |  5 +----
- sysdeps/x86_64/multiarch/strcmp-evex.S   |  5 +----
- sysdeps/x86_64/multiarch/strcmp-sse4_2.S |  5 +----
- sysdeps/x86_64/sysdep.h                  | 28 ++++++++++++++++++++----
- 9 files changed, 70 insertions(+), 16 deletions(-)
+ configure                                | 21 +++++++++
+ configure.ac                             | 13 ++++++
+ sysdeps/x86_64/multiarch/strcmp-avx2.S   |  5 +--
+ sysdeps/x86_64/multiarch/strcmp-evex.S   |  5 +--
+ sysdeps/x86_64/multiarch/strcmp-sse4_2.S |  5 +--
+ sysdeps/x86_64/sysdep.h                  | 54 ++++++++++++++++++++++--
+ 9 files changed, 96 insertions(+), 16 deletions(-)
 
 diff --git a/Makeconfig b/Makeconfig
-index 85e00cef94..502e4e2d89 100644
+index e583765712..b136e10224 100644
 --- a/Makeconfig
 +++ b/Makeconfig
-@@ -979,6 +979,11 @@ else
+@@ -981,6 +981,11 @@ else
  +cflags += $(no-fortify-source)
  endif
  
@@ -40,10 +40,10 @@
  # used to compile and will be installed.  Each can also contain an
  # include/ subdirectory, whose header files will be used to compile
 diff --git a/config.h.in b/config.h.in
-index 44a34072a4..430627dcaf 100644
+index c4cc7d3b9a..dc70ed03d0 100644
 --- a/config.h.in
 +++ b/config.h.in
-@@ -199,6 +199,9 @@
+@@ -205,6 +205,9 @@
  /* Define to 1 if libpthread actually resides in libc.  */
  #define PTHREAD_IN_LIBC 0
  
@@ -66,7 +66,7 @@
  build-profile = @profile@
  build-static-nss = @static_nss@
 diff --git a/configure b/configure
-index 59ff1e415d..69c0795f99 100755
+index 432e40a592..eb6b203925 100755
 --- a/configure
 +++ b/configure
 @@ -622,6 +622,7 @@ LIBOBJS
@@ -94,7 +94,7 @@
  
  Optional Packages:
    --with-PACKAGE[=ARG]    use PACKAGE [ARG=yes]
-@@ -7864,6 +7868,23 @@ libc_cv_multidir=`${CC-cc} $CFLAGS $CPPFLAGS 
-print-multi-directory`
+@@ -7867,6 +7871,23 @@ libc_cv_multidir=`${CC-cc} $CFLAGS $CPPFLAGS 
-print-multi-directory`
  
  
  
@@ -119,10 +119,10 @@
  RELEASE=`sed -n -e 's/^#define RELEASE "\([^"]*\)"/\1/p' < $srcdir/version.h`
  
 diff --git a/configure.ac b/configure.ac
-index 65799e5685..e792f8c866 100644
+index bdc385d03c..cb4d28b3d8 100644
 --- a/configure.ac
 +++ b/configure.ac
-@@ -1753,6 +1753,19 @@ AC_SUBST(DEFINES)
+@@ -1756,6 +1756,19 @@ AC_SUBST(DEFINES)
  dnl See sysdeps/mach/configure.ac for this variable.
  AC_SUBST(mach_interface_list)
  
@@ -191,10 +191,10 @@
  /*
   * This implementation uses SSE to compare up to 16 bytes at a time.
 diff --git a/sysdeps/x86_64/sysdep.h b/sysdeps/x86_64/sysdep.h
-index db6e36b2dd..37136d8ca9 100644
+index db6e36b2dd..86a5d1b2be 100644
 --- a/sysdeps/x86_64/sysdep.h
 +++ b/sysdeps/x86_64/sysdep.h
-@@ -49,6 +49,20 @@ enum cf_protection_level
+@@ -49,6 +49,46 @@ enum cf_protection_level
  
  #ifdef        __ASSEMBLER__
  
@@ -203,29 +203,55 @@
 +   written in ASM, the way we do this is by adding this prologue manually.  */
 +
 +#if ENABLE_USERSPACE_LIVEPATCH
-+# define ULP_PRE_PROLOGUE \
-+  .rept 14; nop; .endr
-+# define ULP_POST_PROLOGUE \
-+  xchg %ax, %ax
++
++/* Instructions to be inserted before the function label.  */
++# define ULP_NOPS_PRE_PROLOGUE     .rept 14; nop; .endr
++
++/* Instruction to be inserted after the function label.  */
++# define ULP_NOPS_POST_PROLOGUE    .rept  2; nop; .endr
++
++
++/* this macro expands according to the following condition:
++ * if name = _start, then the prologue is not inserted.
++ * if name = _dl_relocate_static_pie, then the prologue is not inserted.
++ * if name = anything else, then the prologue is inserted.
++ **/
++# define __ULP_POST_PROLOGUE_dl_relocate_static_pie   ,
++# define __ULP_PRE_PROLOGUE_start                     ,
++# define __ULP_PRE_PROLOGUE(x, y,...)                 y
++# define _ULP_PRE_PROLOGUE(x, ...)                    __ULP_PRE_PROLOGUE(x, 
__VA_ARGS__)
++# define ULP_PRE_PROLOGUE(name)                       
_ULP_PRE_PROLOGUE(__ULP_PRE_PROLOGUE##name, ULP_NOPS_PRE_PROLOGUE,)
++
++/* this macro expands according to the following condition:
++ * if name = _start, then the postlogue is not inserted.
++ * if name = _dl_relocate_static_pie, then the postlogue is not inserted.
++ * if name = anything else, then the postlogue is inserted.
++ **/
++# define __ULP_POST_PROLOGUE_dl_relocate_static_pie   ,
++# define __ULP_POST_PROLOGUE_start                    ,
++# define __ULP_POST_PROLOGUE(x, y,...)                y
++# define _ULP_POST_PROLOGUE(x, ...)                   __ULP_POST_PROLOGUE(x, 
__VA_ARGS__)
++# define ULP_POST_PROLOGUE(name)                      
_ULP_POST_PROLOGUE(__ULP_POST_PROLOGUE##name, ULP_NOPS_POST_PROLOGUE,)
++
 +#else
-+# define ULP_PRE_PROLOGUE
-+# define ULP_POST_PROLOGUE
++# define ULP_PRE_PROLOGUE(name)
++# define ULP_POST_PROLOGUE(name)
 +#endif
 +
  /* Syntactic details of assembler.  */
  
  #ifdef _CET_ENDBR
-@@ -58,15 +72,21 @@ enum cf_protection_level
+@@ -58,15 +98,21 @@ enum cf_protection_level
  # define _CET_NOTRACK
  #endif
  
 +/* Define the first instructions of a function.  */
 +#define FUNCTION_START(name)                                                \
-+  ULP_PRE_PROLOGUE;                                                         \
++  ULP_PRE_PROLOGUE(name);                                                     
      \
 +  C_LABEL(name);                                                            \
 +  cfi_startproc;                                                            \
 +  _CET_ENDBR;                                                               \
-+  ULP_POST_PROLOGUE;                                                        \
++  ULP_POST_PROLOGUE(name);                                                    
      \
 +  CALL_MCOUNT;
 +
  /* Define an entry point visible from C.  */
@@ -242,6 +268,6 @@
  /* This macro is for setting proper CFI with DW_CFA_expression describing
     the register as saved relative to %rsp instead of relative to the CFA.
 -- 
-2.43.0
+2.44.0
 
 

++++++ utmp-time-bits.patch ++++++
++++ 646 lines (skipped)

Reply via email to