Compare commits
10 Commits
3bb17c6134
...
056d76b9e4
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
056d76b9e4 | ||
|
|
9e979d281b | ||
|
|
4436901148 | ||
|
|
116659c1e3 | ||
|
|
93a1c370a1 | ||
|
|
85d17fd9a2 | ||
|
|
1c3cc8e3e4 | ||
|
|
ad10043b98 | ||
|
|
7c6cd412b2 | ||
|
|
f42e5b7774 |
@ -0,0 +1,41 @@
|
||||
From 87801a8fd06db1d654eea3e4f7626ff476a9bdaa Mon Sep 17 00:00:00 2001
|
||||
From: Florian Weimer <fweimer@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 <carlos@redhat.com>
|
||||
|
||||
Conflict:NA
|
||||
Reference:https://sourceware.org/git/?p=glibc.git;a=patch;h=87801a8fd06db1d654eea3e4f7626ff476a9bdaa
|
||||
|
||||
---
|
||||
nscd/netgroupcache.c | 5 +++--
|
||||
1 file changed, 3 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/nscd/netgroupcache.c b/nscd/netgroupcache.c
|
||||
index 2f71bf29..f13a11b4 100644
|
||||
--- a/nscd/netgroupcache.c
|
||||
+++ b/nscd/netgroupcache.c
|
||||
@@ -503,12 +503,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.33.0
|
||||
|
||||
@ -0,0 +1,63 @@
|
||||
From b048a482f088e53144d26a61c390bed0210f49f2 Mon Sep 17 00:00:00 2001
|
||||
From: Florian Weimer <fweimer@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 <siddhesh@sourceware.org>
|
||||
|
||||
Conflict:NA
|
||||
Reference:https://sourceware.org/git/?p=glibc.git;a=patch;h=b048a482f088e53144d26a61c390bed0210f49f2
|
||||
|
||||
---
|
||||
nscd/netgroupcache.c | 11 +++++++----
|
||||
1 file changed, 7 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/nscd/netgroupcache.c b/nscd/netgroupcache.c
|
||||
index 08668e96..5ed16f87 100644
|
||||
--- a/nscd/netgroupcache.c
|
||||
+++ b/nscd/netgroupcache.c
|
||||
@@ -512,14 +512,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;
|
||||
|
||||
@@ -567,7 +568,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.33.0
|
||||
|
||||
@ -0,0 +1,62 @@
|
||||
From 7835b00dbce53c3c87bbbb1754a95fb5e58187aa Mon Sep 17 00:00:00 2001
|
||||
From: Florian Weimer <fweimer@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 <siddhesh@sourceware.org>
|
||||
|
||||
Conflict:NA
|
||||
Reference:https://sourceware.org/git/?p=glibc.git;a=patch;h=7835b00dbce53c3c87bbbb1754a95fb5e58187aa
|
||||
|
||||
---
|
||||
nscd/netgroupcache.c | 14 ++++++--------
|
||||
1 file changed, 6 insertions(+), 8 deletions(-)
|
||||
|
||||
diff --git a/nscd/netgroupcache.c b/nscd/netgroupcache.c
|
||||
index f13a11b4..08668e96 100644
|
||||
--- a/nscd/netgroupcache.c
|
||||
+++ b/nscd/netgroupcache.c
|
||||
@@ -148,7 +148,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));
|
||||
@@ -349,7 +349,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;
|
||||
@@ -411,14 +411,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.33.0
|
||||
|
||||
@ -0,0 +1,393 @@
|
||||
From c04a21e050d64a1193a6daab872bca2528bda44b Mon Sep 17 00:00:00 2001
|
||||
From: Florian Weimer <fweimer@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 <siddhesh@sourceware.org>
|
||||
|
||||
Conflict:NA
|
||||
Reference:https://sourceware.org/git/?p=glibc.git;a=patch;h=c04a21e050d64a1193a6daab872bca2528bda44b
|
||||
|
||||
---
|
||||
nscd/netgroupcache.c | 219 ++++++++++++++++++++++++-------------------
|
||||
1 file changed, 121 insertions(+), 98 deletions(-)
|
||||
|
||||
diff --git a/nscd/netgroupcache.c b/nscd/netgroupcache.c
|
||||
index 5ed16f87..92c9cb36 100644
|
||||
--- a/nscd/netgroupcache.c
|
||||
+++ b/nscd/netgroupcache.c
|
||||
@@ -24,6 +24,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/mman.h>
|
||||
+#include <scratch_buffer.h>
|
||||
|
||||
#include "../inet/netgroup.h"
|
||||
#include "nscd.h"
|
||||
@@ -66,6 +67,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, ¬found, 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
|
||||
@@ -84,8 +95,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, ¬found, 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. */
|
||||
@@ -110,11 +120,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))
|
||||
{
|
||||
@@ -133,14 +210,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))
|
||||
@@ -152,8 +225,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;
|
||||
@@ -196,8 +267,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)
|
||||
@@ -205,68 +276,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
|
||||
@@ -318,8 +331,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
|
||||
@@ -352,10 +365,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,
|
||||
@@ -364,11 +384,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. */
|
||||
@@ -399,7 +415,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;
|
||||
@@ -440,7 +456,7 @@ addgetnetgrentX (struct database_dyn *db, int fd, request_header *req,
|
||||
}
|
||||
|
||||
out:
|
||||
- *resultp = dataset;
|
||||
+ scratch->dataset = dataset;
|
||||
|
||||
return timeout;
|
||||
}
|
||||
@@ -461,6 +477,9 @@ addinnetgrX (struct database_dyn *db, int fd, request_header *req,
|
||||
if (user != NULL)
|
||||
key = (char *) rawmemchr (key, '\0') + 1;
|
||||
const char *domain = *key++ ? key : NULL;
|
||||
+ struct addgetnetgrentX_scratch scratch;
|
||||
+
|
||||
+ addgetnetgrentX_scratch_init (&scratch);
|
||||
|
||||
if (__glibc_unlikely (debug_level > 0))
|
||||
{
|
||||
@@ -476,12 +495,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 =
|
||||
@@ -490,7 +505,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
|
||||
@@ -604,7 +622,7 @@ addinnetgrX (struct database_dyn *db, int fd, request_header *req,
|
||||
}
|
||||
|
||||
out:
|
||||
- free (tofree);
|
||||
+ addgetnetgrentX_scratch_free (&scratch);
|
||||
return timeout;
|
||||
}
|
||||
|
||||
@@ -614,11 +632,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;
|
||||
}
|
||||
|
||||
@@ -662,5 +681,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.33.0
|
||||
|
||||
@ -0,0 +1,93 @@
|
||||
From c00b984fcd53f679ca2dafcd1aee2c89836e6e73 Mon Sep 17 00:00:00 2001
|
||||
From: Florian Weimer <fweimer@redhat.com>
|
||||
Date: Tue, 29 Aug 2023 08:28:31 +0200
|
||||
Subject: [PATCH] nscd: Skip unusable entries in first pass in prune_cache (bug
|
||||
30800)
|
||||
|
||||
Previously, if an entry was marked unusable for any reason, but had
|
||||
not timed out yet, the assert would trigger.
|
||||
|
||||
One way to get into such state is if a data change is detected during
|
||||
re-validation of an entry. This causes the entry to be marked as not
|
||||
usable. If exits nscd soon after that, then the clock jumps
|
||||
backwards, and nscd restarted, the cache re-validation run after
|
||||
startup triggers the removed assert.
|
||||
|
||||
The change is more complicated than just the removal of the assert
|
||||
because entries marked as not usable should be garbage-collected in
|
||||
the second pass. To make this happen, it is necessary to update some
|
||||
book-keeping data.
|
||||
|
||||
Reviewed-by: DJ Delorie <dj@redhat.com>
|
||||
|
||||
Conflict:NA
|
||||
Reference:https://sourceware.org/git/?p=glibc.git;a=commitdiff;h=c00b984fcd53f679ca2dafcd1aee2c89836e6e73
|
||||
|
||||
---
|
||||
nscd/cache.c | 25 +++++++++++--------------
|
||||
1 file changed, 11 insertions(+), 14 deletions(-)
|
||||
|
||||
diff --git a/nscd/cache.c b/nscd/cache.c
|
||||
index 78b22697..ac5902ae 100644
|
||||
--- a/nscd/cache.c
|
||||
+++ b/nscd/cache.c
|
||||
@@ -371,8 +371,11 @@ prune_cache (struct database_dyn *table, time_t now, int fd)
|
||||
serv2str[runp->type], str, dh->timeout);
|
||||
}
|
||||
|
||||
- /* Check whether the entry timed out. */
|
||||
- if (dh->timeout < now)
|
||||
+ /* Check whether the entry timed out. Timed out entries
|
||||
+ will be revalidated. For unusable records, it is still
|
||||
+ necessary to record that the bucket needs to be scanned
|
||||
+ again below. */
|
||||
+ if (dh->timeout < now || !dh->usable)
|
||||
{
|
||||
/* This hash bucket could contain entries which need to
|
||||
be looked at. */
|
||||
@@ -384,7 +387,7 @@ prune_cache (struct database_dyn *table, time_t now, int fd)
|
||||
/* We only have to look at the data of the first entries
|
||||
since the count information is kept in the data part
|
||||
which is shared. */
|
||||
- if (runp->first)
|
||||
+ if (runp->first && dh->usable)
|
||||
{
|
||||
|
||||
/* At this point there are two choices: we reload the
|
||||
@@ -400,9 +403,6 @@ prune_cache (struct database_dyn *table, time_t now, int fd)
|
||||
{
|
||||
/* Remove the value. */
|
||||
dh->usable = false;
|
||||
-
|
||||
- /* We definitely have some garbage entries now. */
|
||||
- any = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -414,18 +414,15 @@ prune_cache (struct database_dyn *table, time_t now, int fd)
|
||||
|
||||
time_t timeout = readdfcts[runp->type] (table, runp, dh);
|
||||
next_timeout = MIN (next_timeout, timeout);
|
||||
-
|
||||
- /* If the entry has been replaced, we might need
|
||||
- cleanup. */
|
||||
- any |= !dh->usable;
|
||||
}
|
||||
}
|
||||
+
|
||||
+ /* If the entry has been replaced, we might need cleanup. */
|
||||
+ any |= !dh->usable;
|
||||
}
|
||||
else
|
||||
- {
|
||||
- assert (dh->usable);
|
||||
- next_timeout = MIN (next_timeout, dh->timeout);
|
||||
- }
|
||||
+ /* Entry has not timed out and is usable. */
|
||||
+ next_timeout = MIN (next_timeout, dh->timeout);
|
||||
|
||||
run = runp->next;
|
||||
}
|
||||
--
|
||||
2.33.0
|
||||
|
||||
49
backport-Use-errval-not-errno-to-guide-cache-update.patch
Normal file
49
backport-Use-errval-not-errno-to-guide-cache-update.patch
Normal file
@ -0,0 +1,49 @@
|
||||
From 2d472b48610f6a298d28035b683ab13e9afac4cb Mon Sep 17 00:00:00 2001
|
||||
From: Florian Weimer <fweimer@redhat.com>
|
||||
Date: Mon, 24 Jul 2023 15:12:26 +0200
|
||||
Subject: [PATCH] nscd: Use errval, not errno to guide cache update (bug 30662)
|
||||
|
||||
The errno variable is potentially clobbered by the preceding
|
||||
send call. It is not related to the to-be-cached information.
|
||||
The parallel code in hstcache.c and servicescache.c already uses
|
||||
errval.
|
||||
|
||||
Reviewed-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
|
||||
|
||||
Conflict:NA
|
||||
Reference:https://sourceware.org/git/?p=glibc.git;a=commitdiff;h=2d472b48610f6a298d28035b683ab13e9afac4cb
|
||||
|
||||
---
|
||||
nscd/grpcache.c | 2 +-
|
||||
nscd/pwdcache.c | 2 +-
|
||||
2 files changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/nscd/grpcache.c b/nscd/grpcache.c
|
||||
index 457ca4d8..d18bcabe 100644
|
||||
--- a/nscd/grpcache.c
|
||||
+++ b/nscd/grpcache.c
|
||||
@@ -117,7 +117,7 @@ cache_addgr (struct database_dyn *db, int fd, request_header *req,
|
||||
|
||||
/* If we have a transient error or cannot permanently store
|
||||
the result, so be it. */
|
||||
- if (errno == EAGAIN || __builtin_expect (db->negtimeout == 0, 0))
|
||||
+ if (errval == EAGAIN || __glibc_unlikely (db->negtimeout == 0))
|
||||
{
|
||||
/* Mark the old entry as obsolete. */
|
||||
if (dh != NULL)
|
||||
diff --git a/nscd/pwdcache.c b/nscd/pwdcache.c
|
||||
index dfafb526..409c5acd 100644
|
||||
--- a/nscd/pwdcache.c
|
||||
+++ b/nscd/pwdcache.c
|
||||
@@ -123,7 +123,7 @@ cache_addpw (struct database_dyn *db, int fd, request_header *req,
|
||||
|
||||
/* If we have a transient error or cannot permanently store
|
||||
the result, so be it. */
|
||||
- if (errno == EAGAIN || __builtin_expect (db->negtimeout == 0, 0))
|
||||
+ if (errval == EAGAIN || __glibc_unlikely (db->negtimeout == 0))
|
||||
{
|
||||
/* Mark the old entry as obsolete. */
|
||||
if (dh != NULL)
|
||||
--
|
||||
2.33.0
|
||||
|
||||
209
backport-elf-Add-TLS-modid-reuse-test-for-bug-29039.patch
Normal file
209
backport-elf-Add-TLS-modid-reuse-test-for-bug-29039.patch
Normal file
@ -0,0 +1,209 @@
|
||||
From 980450f12685326729d63ff72e93a996113bf073 Mon Sep 17 00:00:00 2001
|
||||
From: Szabolcs Nagy <szabolcs.nagy@arm.com>
|
||||
Date: Wed, 29 Nov 2023 11:31:37 +0000
|
||||
Subject: [PATCH] elf: Add TLS modid reuse test for bug 29039
|
||||
|
||||
This is a minimal regression test for bug 29039 which only affects
|
||||
targets with TLSDESC and a reproducer requires that
|
||||
|
||||
1) Have modid gaps (closed modules) with old generation.
|
||||
2) Update a DTV to a newer generation (needs a newer dlopen).
|
||||
3) But do not update the closed gap entry in that DTV.
|
||||
4) Reuse the modid gap for a new module (another dlopen).
|
||||
5) Use dynamic TLSDESC in that new module with old generation (bug).
|
||||
6) Access TLS via this TLSDESC and the now outdated DTV.
|
||||
|
||||
However step (3) in practice rarely happens: during DTV update the
|
||||
entries for closed modids are initialized to "unallocated" and then
|
||||
dynamic TLSDESC calls __tls_get_addr independently of its generation.
|
||||
The only exception to this is DTV setup at thread creation (gaps are
|
||||
initialized to NULL instead of unallocated) or DTV resize where the
|
||||
gap entries are outside the previous DTV array (again NULL instead
|
||||
of unallocated, and this requires loading > DTV_SURPLUS modules).
|
||||
|
||||
So the bug can only cause NULL (+ offset) dereference, not use after
|
||||
free. And the easiest way to get (3) is via thread creation.
|
||||
|
||||
Note that step (5) requires that the newly loaded module has larger
|
||||
TLS than the remaining optional static TLS. And for (6) there cannot
|
||||
be other TLS access or dlopen in the thread that updates the DTV.
|
||||
|
||||
Tested on aarch64-linux-gnu.
|
||||
|
||||
Reference:https://sourceware.org/git/?p=glibc.git;a=commit;h=980450f12685326729d63ff72e93a996113bf073
|
||||
|
||||
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||
---
|
||||
elf/Makefile | 15 +++++++
|
||||
elf/tst-tlsgap-mod0.c | 2 +
|
||||
elf/tst-tlsgap-mod1.c | 2 +
|
||||
elf/tst-tlsgap-mod2.c | 2 +
|
||||
elf/tst-tlsgap.c | 92 +++++++++++++++++++++++++++++++++++++++++++
|
||||
5 files changed, 113 insertions(+)
|
||||
create mode 100644 elf/tst-tlsgap-mod0.c
|
||||
create mode 100644 elf/tst-tlsgap-mod1.c
|
||||
create mode 100644 elf/tst-tlsgap-mod2.c
|
||||
create mode 100644 elf/tst-tlsgap.c
|
||||
|
||||
diff --git a/elf/Makefile b/elf/Makefile
|
||||
index ed13f34d..b5de4dd4 100644
|
||||
--- a/elf/Makefile
|
||||
+++ b/elf/Makefile
|
||||
@@ -425,6 +425,7 @@ tests += \
|
||||
tst-tls5 \
|
||||
tst-tlsalign \
|
||||
tst-tlsalign-extern \
|
||||
+ tst-tlsgap \
|
||||
tst-tls-dlinfo \
|
||||
tst-tls-ie \
|
||||
tst-tls-ie-dlmopen \
|
||||
@@ -704,6 +705,9 @@ modules-names = \
|
||||
tst-tls20mod-bad \
|
||||
tst-tls21mod \
|
||||
tst-tlsalign-lib \
|
||||
+ tst-tlsgap-mod0 \
|
||||
+ tst-tlsgap-mod1 \
|
||||
+ tst-tlsgap-mod2 \
|
||||
tst-tls-ie-mod0 \
|
||||
tst-tls-ie-mod1 \
|
||||
tst-tls-ie-mod2 \
|
||||
@@ -2498,3 +2502,14 @@ $(objpfx)tst-non-directory-path.out: tst-non-directory-path.sh \
|
||||
'$(test-wrapper-env)' '$(run_program_env)' \
|
||||
'$(rpath-link)' $(objpfx) > $@; \
|
||||
$(evaluate-test)
|
||||
+
|
||||
+$(objpfx)tst-tlsgap: $(shared-thread-library)
|
||||
+$(objpfx)tst-tlsgap.out: \
|
||||
+ $(objpfx)tst-tlsgap-mod0.so \
|
||||
+ $(objpfx)tst-tlsgap-mod1.so \
|
||||
+ $(objpfx)tst-tlsgap-mod2.so
|
||||
+ifeq (yes,$(have-mtls-dialect-gnu2))
|
||||
+CFLAGS-tst-tlsgap-mod0.c += -mtls-dialect=gnu2
|
||||
+CFLAGS-tst-tlsgap-mod1.c += -mtls-dialect=gnu2
|
||||
+CFLAGS-tst-tlsgap-mod2.c += -mtls-dialect=gnu2
|
||||
+endif
|
||||
diff --git a/elf/tst-tlsgap-mod0.c b/elf/tst-tlsgap-mod0.c
|
||||
new file mode 100644
|
||||
index 00000000..1478b0be
|
||||
--- /dev/null
|
||||
+++ b/elf/tst-tlsgap-mod0.c
|
||||
@@ -0,0 +1,2 @@
|
||||
+int __thread tls0;
|
||||
+int *f0(void) { return &tls0; }
|
||||
diff --git a/elf/tst-tlsgap-mod1.c b/elf/tst-tlsgap-mod1.c
|
||||
new file mode 100644
|
||||
index 00000000..b10fc370
|
||||
--- /dev/null
|
||||
+++ b/elf/tst-tlsgap-mod1.c
|
||||
@@ -0,0 +1,2 @@
|
||||
+int __thread tls1[100]; /* Size > glibc.rtld.optional_static_tls / 2. */
|
||||
+int *f1(void) { return tls1; }
|
||||
diff --git a/elf/tst-tlsgap-mod2.c b/elf/tst-tlsgap-mod2.c
|
||||
new file mode 100644
|
||||
index 00000000..166c27d7
|
||||
--- /dev/null
|
||||
+++ b/elf/tst-tlsgap-mod2.c
|
||||
@@ -0,0 +1,2 @@
|
||||
+int __thread tls2;
|
||||
+int *f2(void) { return &tls2; }
|
||||
diff --git a/elf/tst-tlsgap.c b/elf/tst-tlsgap.c
|
||||
new file mode 100644
|
||||
index 00000000..49328850
|
||||
--- /dev/null
|
||||
+++ b/elf/tst-tlsgap.c
|
||||
@@ -0,0 +1,92 @@
|
||||
+/* TLS modid gap reuse regression test for bug 29039.
|
||||
+ Copyright (C) 2023 Free Software Foundation, Inc.
|
||||
+ This file is part of the GNU C Library.
|
||||
+
|
||||
+ The GNU C Library is free software; you can redistribute it and/or
|
||||
+ modify it under the terms of the GNU Lesser General Public
|
||||
+ License as published by the Free Software Foundation; either
|
||||
+ version 2.1 of the License, or (at your option) any later version.
|
||||
+
|
||||
+ The GNU C Library is distributed in the hope that it will be useful,
|
||||
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
+ Lesser General Public License for more details.
|
||||
+
|
||||
+ You should have received a copy of the GNU Lesser General Public
|
||||
+ License along with the GNU C Library; if not, see
|
||||
+ <http://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include <stdio.h>
|
||||
+#include <dlfcn.h>
|
||||
+#include <pthread.h>
|
||||
+#include <support/xdlfcn.h>
|
||||
+#include <support/xthread.h>
|
||||
+#include <support/check.h>
|
||||
+
|
||||
+static void *mod[3];
|
||||
+#define MOD(i) "tst-tlsgap-mod" #i ".so"
|
||||
+static const char *modname[3] = { MOD(0), MOD(1), MOD(2) };
|
||||
+#undef MOD
|
||||
+
|
||||
+static void
|
||||
+open_mod (int i)
|
||||
+{
|
||||
+ mod[i] = xdlopen (modname[i], RTLD_LAZY);
|
||||
+ printf ("open %s\n", modname[i]);
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+close_mod (int i)
|
||||
+{
|
||||
+ xdlclose (mod[i]);
|
||||
+ mod[i] = NULL;
|
||||
+ printf ("close %s\n", modname[i]);
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+access_mod (int i, const char *sym)
|
||||
+{
|
||||
+ int *(*f) (void) = xdlsym (mod[i], sym);
|
||||
+ int *p = f ();
|
||||
+ printf ("access %s: %s() = %p\n", modname[i], sym, p);
|
||||
+ TEST_VERIFY_EXIT (p != NULL);
|
||||
+ ++*p;
|
||||
+}
|
||||
+
|
||||
+static void *
|
||||
+start (void *arg)
|
||||
+{
|
||||
+ /* The DTV generation is at the last dlopen of mod0 and the
|
||||
+ entry for mod1 is NULL. */
|
||||
+
|
||||
+ open_mod (1); /* Reuse modid of mod1. Uses dynamic TLS. */
|
||||
+
|
||||
+ /* DTV is unchanged: dlopen only updates the DTV to the latest
|
||||
+ generation if static TLS is allocated for a loaded module.
|
||||
+
|
||||
+ With bug 29039, the TLSDESC relocation in mod1 uses the old
|
||||
+ dlclose generation of mod1 instead of the new dlopen one so
|
||||
+ DTV is not updated on TLS access. */
|
||||
+
|
||||
+ access_mod (1, "f1");
|
||||
+
|
||||
+ return arg;
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+do_test (void)
|
||||
+{
|
||||
+ open_mod (0);
|
||||
+ open_mod (1);
|
||||
+ open_mod (2);
|
||||
+ close_mod (0);
|
||||
+ close_mod (1); /* Create modid gap at mod1. */
|
||||
+ open_mod (0); /* Reuse modid of mod0, bump generation count. */
|
||||
+
|
||||
+ /* Create a thread where DTV of mod1 is NULL. */
|
||||
+ pthread_t t = xpthread_create (NULL, start, NULL);
|
||||
+ xpthread_join (t);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+#include <support/test-driver.c>
|
||||
--
|
||||
2.33.0
|
||||
|
||||
35
backport-elf-Check-objname-before-calling-fatal_error.patch
Normal file
35
backport-elf-Check-objname-before-calling-fatal_error.patch
Normal file
@ -0,0 +1,35 @@
|
||||
From 1cce91d8aed5c3eca2b6f47767c82d9ed3e9e33f Mon Sep 17 00:00:00 2001
|
||||
From: "H.J. Lu" <hjl.tools@gmail.com>
|
||||
Date: Mon, 8 Apr 2024 09:06:09 -0700
|
||||
Subject: [PATCH] elf: Check objname before calling fatal_error
|
||||
|
||||
_dl_signal_error may be called with objname == NULL. _dl_exception_create
|
||||
checks objname == NULL. But fatal_error doesn't. Check objname before
|
||||
calling fatal_error. This fixes BZ #31596.
|
||||
|
||||
Reference:https://sourceware.org/git/?p=glibc.git;a=commit;h=1cce91d8aed5c3eca2b6f47767c82d9ed3e9e33f
|
||||
|
||||
Reviewed-by: Sunil K Pandey <skpgkp2@gmail.com>
|
||||
---
|
||||
elf/dl-error-skeleton.c | 4 ++++
|
||||
1 file changed, 4 insertions(+)
|
||||
|
||||
diff --git a/elf/dl-error-skeleton.c b/elf/dl-error-skeleton.c
|
||||
index b699936c..26dfab55 100644
|
||||
--- a/elf/dl-error-skeleton.c
|
||||
+++ b/elf/dl-error-skeleton.c
|
||||
@@ -121,7 +121,11 @@ _dl_signal_error (int errcode, const char *objname, const char *occation,
|
||||
__longjmp (lcatch->env[0].__jmpbuf, 1);
|
||||
}
|
||||
else
|
||||
+ {
|
||||
+ if (objname == NULL)
|
||||
+ objname = "";
|
||||
fatal_error (errcode, objname, occation, errstring);
|
||||
+ }
|
||||
}
|
||||
libc_hidden_def (_dl_signal_error)
|
||||
|
||||
--
|
||||
2.33.0
|
||||
|
||||
@ -0,0 +1,54 @@
|
||||
From 3921c5b40f293c57cb326f58713c924b0662ef59 Mon Sep 17 00:00:00 2001
|
||||
From: Hector Martin <marcan@marcan.st>
|
||||
Date: Tue, 28 Nov 2023 15:23:07 +0900
|
||||
Subject: [PATCH] elf: Fix TLS modid reuse generation assignment (BZ 29039)
|
||||
|
||||
_dl_assign_tls_modid() assigns a slotinfo entry for a new module, but
|
||||
does *not* do anything to the generation counter. The first time this
|
||||
happens, the generation is zero and map_generation() returns the current
|
||||
generation to be used during relocation processing. However, if
|
||||
a slotinfo entry is later reused, it will already have a generation
|
||||
assigned. If this generation has fallen behind the current global max
|
||||
generation, then this causes an obsolete generation to be assigned
|
||||
during relocation processing, as map_generation() returns this
|
||||
generation if nonzero. _dl_add_to_slotinfo() eventually resets the
|
||||
generation, but by then it is too late. This causes DTV updates to be
|
||||
skipped, leading to NULL or broken TLS slot pointers and segfaults.
|
||||
|
||||
Fix this by resetting the generation to zero in _dl_assign_tls_modid(),
|
||||
so it behaves the same as the first time a slot is assigned.
|
||||
_dl_add_to_slotinfo() will still assign the correct static generation
|
||||
later during module load, but relocation processing will no longer use
|
||||
an obsolete generation.
|
||||
|
||||
Note that slotinfo entry (aka modid) reuse typically happens after a
|
||||
dlclose and only TLS access via dynamic tlsdesc is affected. Because
|
||||
tlsdesc is optimized to use the optional part of static TLS, dynamic
|
||||
tlsdesc can be avoided by increasing the glibc.rtld.optional_static_tls
|
||||
tunable to a large enough value, or by LD_PRELOAD-ing the affected
|
||||
modules.
|
||||
|
||||
Fixes bug 29039.
|
||||
|
||||
Reference:https://sourceware.org/git/?p=glibc.git;a=commit;h=3921c5b40f293c57cb326f58713c924b0662ef59
|
||||
|
||||
Reviewed-by: Szabolcs Nagy <szabolcs.nagy@arm.com>
|
||||
---
|
||||
elf/dl-tls.c | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
diff --git a/elf/dl-tls.c b/elf/dl-tls.c
|
||||
index 0070c8bb..42868eef 100644
|
||||
--- a/elf/dl-tls.c
|
||||
+++ b/elf/dl-tls.c
|
||||
@@ -160,6 +160,7 @@ _dl_assign_tls_modid (struct link_map *l)
|
||||
{
|
||||
/* Mark the entry as used, so any dependency see it. */
|
||||
atomic_store_relaxed (&runp->slotinfo[result - disp].map, l);
|
||||
+ atomic_store_relaxed (&runp->slotinfo[result - disp].gen, 0);
|
||||
break;
|
||||
}
|
||||
|
||||
--
|
||||
2.33.0
|
||||
|
||||
@ -0,0 +1,137 @@
|
||||
From 434eca873f14f618d6c2279b54fb809fb56f2c50 Mon Sep 17 00:00:00 2001
|
||||
From: Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||
Date: Mon, 6 Nov 2023 17:25:40 -0300
|
||||
Subject: [PATCH] elf: Fix _dl_debug_vdprintf to work before self-relocation
|
||||
|
||||
The strlen might trigger and invalid GOT entry if it used before
|
||||
the process is self-relocated (for instance on dl-tunables if any
|
||||
error occurs).
|
||||
|
||||
For i386, _dl_writev with PIE requires to use the old 'int $0x80'
|
||||
syscall mode because the calling the TLS register (gs) is not yet
|
||||
initialized.
|
||||
|
||||
Reference:https://sourceware.org/git/?p=glibc.git;a=commit;h=434eca873f14f618d6c2279b54fb809fb56f2c50
|
||||
|
||||
Checked on x86_64-linux-gnu.
|
||||
Reviewed-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
|
||||
---
|
||||
elf/dl-misc.c | 15 +++++++++++++--
|
||||
stdio-common/Makefile | 5 +++++
|
||||
stdio-common/_itoa.c | 5 +++++
|
||||
sysdeps/unix/sysv/linux/i386/dl-writev.h | 24 ++++++++++++++++++++++++
|
||||
4 files changed, 47 insertions(+), 2 deletions(-)
|
||||
create mode 100644 sysdeps/unix/sysv/linux/i386/dl-writev.h
|
||||
|
||||
diff --git a/elf/dl-misc.c b/elf/dl-misc.c
|
||||
index bba2e714..5b637c7e 100644
|
||||
--- a/elf/dl-misc.c
|
||||
+++ b/elf/dl-misc.c
|
||||
@@ -16,6 +16,10 @@
|
||||
License along with the GNU C Library; if not, see
|
||||
<https://www.gnu.org/licenses/>. */
|
||||
|
||||
+#include <string.h>
|
||||
+#if BUILD_PIE_DEFAULT
|
||||
+# pragma GCC visibility push(hidden)
|
||||
+#endif
|
||||
#include <assert.h>
|
||||
#include <fcntl.h>
|
||||
#include <ldsodefs.h>
|
||||
@@ -23,7 +27,6 @@
|
||||
#include <link.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
-#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <stdint.h>
|
||||
#include <sys/mman.h>
|
||||
@@ -71,6 +74,14 @@ _dl_sysdep_read_whole_file (const char *file, size_t *sizep, int prot)
|
||||
return result;
|
||||
}
|
||||
|
||||
+/* The function might be called before the process is self-relocated. */
|
||||
+static size_t
|
||||
+_dl_debug_strlen (const char *s)
|
||||
+{
|
||||
+ const char *p = s;
|
||||
+ for (; *s != '\0'; s++);
|
||||
+ return s - p;
|
||||
+}
|
||||
|
||||
/* Bare-bones printf implementation. This function only knows about
|
||||
the formats and flags needed and can handle only up to 64 stripes in
|
||||
@@ -235,7 +246,7 @@ _dl_debug_vdprintf (int fd, int tag_p, const char *fmt, va_list arg)
|
||||
case 's':
|
||||
/* Get the string argument. */
|
||||
iov[niov].iov_base = va_arg (arg, char *);
|
||||
- iov[niov].iov_len = strlen (iov[niov].iov_base);
|
||||
+ iov[niov].iov_len = _dl_debug_strlen (iov[niov].iov_base);
|
||||
if (prec != -1)
|
||||
iov[niov].iov_len = MIN ((size_t) prec, iov[niov].iov_len);
|
||||
++niov;
|
||||
diff --git a/stdio-common/Makefile b/stdio-common/Makefile
|
||||
index 803f16da..f9763c27 100644
|
||||
--- a/stdio-common/Makefile
|
||||
+++ b/stdio-common/Makefile
|
||||
@@ -181,6 +181,11 @@ CFLAGS-isoc99_scanf.c += -fexceptions
|
||||
CFLAGS-errlist.c += $(fno-unit-at-a-time)
|
||||
CFLAGS-siglist.c += $(fno-unit-at-a-time)
|
||||
|
||||
+# Called during static library initialization, so turn stack-protection
|
||||
+# off for non-shared builds.
|
||||
+CFLAGS-_itoa.o = $(no-stack-protector)
|
||||
+CFLAGS-_itoa.op = $(no-stack-protector)
|
||||
+
|
||||
# scanf14a.c and scanf16a.c test a deprecated extension which is no
|
||||
# longer visible under most conformance levels; see the source files
|
||||
# for more detail.
|
||||
diff --git a/stdio-common/_itoa.c b/stdio-common/_itoa.c
|
||||
index c37d1c35..20c2e384 100644
|
||||
--- a/stdio-common/_itoa.c
|
||||
+++ b/stdio-common/_itoa.c
|
||||
@@ -18,6 +18,11 @@
|
||||
License along with the GNU C Library; if not, see
|
||||
<https://www.gnu.org/licenses/>. */
|
||||
|
||||
+/* Mark symbols hidden in static PIE for early self relocation to work.
|
||||
+ Note: string.h may have ifuncs which cannot be hidden on i686. */
|
||||
+#if BUILD_PIE_DEFAULT
|
||||
+# pragma GCC visibility push(hidden)
|
||||
+#endif
|
||||
#include <gmp-mparam.h>
|
||||
#include <gmp.h>
|
||||
#include <limits.h>
|
||||
diff --git a/sysdeps/unix/sysv/linux/i386/dl-writev.h b/sysdeps/unix/sysv/linux/i386/dl-writev.h
|
||||
new file mode 100644
|
||||
index 00000000..624d0e46
|
||||
--- /dev/null
|
||||
+++ b/sysdeps/unix/sysv/linux/i386/dl-writev.h
|
||||
@@ -0,0 +1,24 @@
|
||||
+/* Message-writing for the dynamic linker. Linux/i386 version.
|
||||
+ Copyright (C) 2013-2023 Free Software Foundation, Inc.
|
||||
+ This file is part of the GNU C Library.
|
||||
+
|
||||
+ The GNU C Library is free software; you can redistribute it and/or
|
||||
+ modify it under the terms of the GNU Lesser General Public
|
||||
+ License as published by the Free Software Foundation; either
|
||||
+ version 2.1 of the License, or (at your option) any later version.
|
||||
+
|
||||
+ The GNU C Library is distributed in the hope that it will be useful,
|
||||
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
+ Lesser General Public License for more details.
|
||||
+
|
||||
+ You should have received a copy of the GNU Lesser General Public
|
||||
+ License along with the GNU C Library; if not, see
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#if BUILD_PIE_DEFAULT
|
||||
+/* Can't use "call *%gs:SYSINFO_OFFSET" during startup in static PIE. */
|
||||
+# define I386_USE_SYSENTER 0
|
||||
+#endif
|
||||
+
|
||||
+#include <sysdeps/unix/sysv/linux/dl-writev.h>
|
||||
--
|
||||
2.33.0
|
||||
|
||||
135
backport-elf-Properly-align-PT_LOAD-segments-BZ-28676.patch
Normal file
135
backport-elf-Properly-align-PT_LOAD-segments-BZ-28676.patch
Normal file
@ -0,0 +1,135 @@
|
||||
From 718fdd87b1b98ef88e883a37d9c18867256fa5a4 Mon Sep 17 00:00:00 2001
|
||||
From: Rongwei Wang <rongwei.wang@linux.alibaba.com>
|
||||
Date: Fri, 10 Dec 2021 20:39:10 +0800
|
||||
Subject: [PATCH] elf: Properly align PT_LOAD segments [BZ #28676]
|
||||
|
||||
When PT_LOAD segment alignment > the page size, allocate enough space to
|
||||
ensure that the segment can be properly aligned. This change helps code
|
||||
segments use huge pages become simple and available.
|
||||
|
||||
This fixes [BZ #28676].
|
||||
|
||||
Signed-off-by: Xu Yu <xuyu@linux.alibaba.com>
|
||||
Signed-off-by: Rongwei Wang <rongwei.wang@linux.alibaba.com>
|
||||
---
|
||||
elf/dl-load.c | 2 ++
|
||||
elf/dl-load.h | 3 ++-
|
||||
elf/dl-map-segments.h | 50 +++++++++++++++++++++++++++++++++++++++----
|
||||
3 files changed, 50 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/elf/dl-load.c b/elf/dl-load.c
|
||||
index bf8957e73c..721593135e 100644
|
||||
--- a/elf/dl-load.c
|
||||
+++ b/elf/dl-load.c
|
||||
@@ -1,5 +1,6 @@
|
||||
/* Map in a shared object's segments from the file.
|
||||
Copyright (C) 1995-2021 Free Software Foundation, Inc.
|
||||
+ Copyright The GNU Toolchain Authors.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
@@ -1150,6 +1151,7 @@ _dl_map_object_from_fd (const char *name, const char *origname, int fd,
|
||||
c->mapend = ALIGN_UP (ph->p_vaddr + ph->p_filesz, GLRO(dl_pagesize));
|
||||
c->dataend = ph->p_vaddr + ph->p_filesz;
|
||||
c->allocend = ph->p_vaddr + ph->p_memsz;
|
||||
+ c->mapalign = ph->p_align;
|
||||
c->mapoff = ALIGN_DOWN (ph->p_offset, GLRO(dl_pagesize));
|
||||
|
||||
/* Determine whether there is a gap between the last segment
|
||||
diff --git a/elf/dl-load.h b/elf/dl-load.h
|
||||
index e329d49a81..e6dabcb336 100644
|
||||
--- a/elf/dl-load.h
|
||||
+++ b/elf/dl-load.h
|
||||
@@ -1,5 +1,6 @@
|
||||
/* Map in a shared object's segments from the file.
|
||||
Copyright (C) 1995-2021 Free Software Foundation, Inc.
|
||||
+ Copyright The GNU Toolchain Authors.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
@@ -74,7 +75,7 @@ ELF_PREFERRED_ADDRESS_DATA;
|
||||
Its details have been expanded out and converted. */
|
||||
struct loadcmd
|
||||
{
|
||||
- ElfW(Addr) mapstart, mapend, dataend, allocend;
|
||||
+ ElfW(Addr) mapstart, mapend, dataend, allocend, mapalign;
|
||||
ElfW(Off) mapoff;
|
||||
int prot; /* PROT_* bits. */
|
||||
};
|
||||
diff --git a/elf/dl-map-segments.h b/elf/dl-map-segments.h
|
||||
index f9fb110ee3..70a4c40695 100644
|
||||
--- a/elf/dl-map-segments.h
|
||||
+++ b/elf/dl-map-segments.h
|
||||
@@ -1,5 +1,6 @@
|
||||
/* Map in a shared object's segments. Generic version.
|
||||
Copyright (C) 1995-2021 Free Software Foundation, Inc.
|
||||
+ Copyright The GNU Toolchain Authors.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
@@ -18,6 +19,50 @@
|
||||
|
||||
#include <dl-load.h>
|
||||
|
||||
+/* Map a segment and align it properly. */
|
||||
+
|
||||
+static __always_inline ElfW(Addr)
|
||||
+_dl_map_segment (const struct loadcmd *c, ElfW(Addr) mappref,
|
||||
+ const size_t maplength, int fd)
|
||||
+{
|
||||
+ if (__glibc_likely (c->mapalign <= GLRO(dl_pagesize)))
|
||||
+ return (ElfW(Addr)) __mmap ((void *) mappref, maplength, c->prot,
|
||||
+ MAP_COPY|MAP_FILE, fd, c->mapoff);
|
||||
+
|
||||
+ /* If the segment alignment > the page size, allocate enough space to
|
||||
+ ensure that the segment can be properly aligned. */
|
||||
+ ElfW(Addr) maplen = (maplength >= c->mapalign
|
||||
+ ? (maplength + c->mapalign)
|
||||
+ : (2 * c->mapalign));
|
||||
+ ElfW(Addr) map_start = (ElfW(Addr)) __mmap ((void *) mappref, maplen,
|
||||
+ PROT_NONE,
|
||||
+ MAP_ANONYMOUS|MAP_PRIVATE,
|
||||
+ -1, 0);
|
||||
+ if (__glibc_unlikely ((void *) map_start == MAP_FAILED))
|
||||
+ return map_start;
|
||||
+
|
||||
+ ElfW(Addr) map_start_aligned = ALIGN_UP (map_start, c->mapalign);
|
||||
+ map_start_aligned = (ElfW(Addr)) __mmap ((void *) map_start_aligned,
|
||||
+ maplength, c->prot,
|
||||
+ MAP_COPY|MAP_FILE|MAP_FIXED,
|
||||
+ fd, c->mapoff);
|
||||
+ if (__glibc_unlikely ((void *) map_start_aligned == MAP_FAILED))
|
||||
+ __munmap ((void *) map_start, maplen);
|
||||
+ else
|
||||
+ {
|
||||
+ /* Unmap the unused regions. */
|
||||
+ ElfW(Addr) delta = map_start_aligned - map_start;
|
||||
+ if (delta)
|
||||
+ __munmap ((void *) map_start, delta);
|
||||
+ ElfW(Addr) map_end = map_start_aligned + maplength;
|
||||
+ delta = map_start + maplen - map_end;
|
||||
+ if (delta)
|
||||
+ __munmap ((void *) map_end, delta);
|
||||
+ }
|
||||
+
|
||||
+ return map_start_aligned;
|
||||
+}
|
||||
+
|
||||
/* This implementation assumes (as does the corresponding implementation
|
||||
of _dl_unmap_segments, in dl-unmap-segments.h) that shared objects
|
||||
are always laid out with all segments contiguous (or with gaps
|
||||
@@ -53,10 +98,7 @@ _dl_map_segments (struct link_map *l, int fd,
|
||||
- MAP_BASE_ADDR (l));
|
||||
|
||||
/* Remember which part of the address space this object uses. */
|
||||
- l->l_map_start = (ElfW(Addr)) __mmap ((void *) mappref, maplength,
|
||||
- c->prot,
|
||||
- MAP_COPY|MAP_FILE,
|
||||
- fd, c->mapoff);
|
||||
+ l->l_map_start = _dl_map_segment (c, mappref, maplength, fd);
|
||||
if (__glibc_unlikely ((void *) l->l_map_start == MAP_FAILED))
|
||||
return DL_MAP_SEGMENTS_ERROR_MAP_SEGMENT;
|
||||
|
||||
--
|
||||
2.43.0
|
||||
|
||||
@ -0,0 +1,76 @@
|
||||
From 2aa0974d2573441bffd596b07bff8698b1f2f18c Mon Sep 17 00:00:00 2001
|
||||
From: Florian Weimer <fweimer@redhat.com>
|
||||
Date: Fri, 20 Oct 2023 14:29:50 +0200
|
||||
Subject: [PATCH 1/1] elf: ldconfig should skip temporary files created by
|
||||
package managers
|
||||
|
||||
This avoids crashes due to partially written files, after a package
|
||||
update is interrupted.
|
||||
|
||||
Reference:https://sourceware.org/git/?p=glibc.git;a=commit;h=2aa0974d2573441bffd596b07bff8698b1f2f18c
|
||||
|
||||
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||
---
|
||||
elf/ldconfig.c | 39 +++++++++++++++++++++++++++------------
|
||||
1 file changed, 27 insertions(+), 12 deletions(-)
|
||||
|
||||
diff --git a/elf/ldconfig.c b/elf/ldconfig.c
|
||||
index 6190e0ea..73b5ef27 100644
|
||||
--- a/elf/ldconfig.c
|
||||
+++ b/elf/ldconfig.c
|
||||
@@ -746,6 +746,31 @@ struct dlib_entry
|
||||
struct dlib_entry *next;
|
||||
};
|
||||
|
||||
+/* Skip some temporary DSO files. These files may be partially written
|
||||
+ and lead to ldconfig crashes when examined. */
|
||||
+static bool
|
||||
+skip_dso_based_on_name (const char *name, size_t len)
|
||||
+{
|
||||
+ /* Skip temporary files created by the prelink program. Files with
|
||||
+ names like these are never really DSOs we want to look at. */
|
||||
+ if (len >= sizeof (".#prelink#") - 1)
|
||||
+ {
|
||||
+ if (strcmp (name + len - sizeof (".#prelink#") + 1,
|
||||
+ ".#prelink#") == 0)
|
||||
+ return true;
|
||||
+ if (len >= sizeof (".#prelink#.XXXXXX") - 1
|
||||
+ && memcmp (name + len - sizeof (".#prelink#.XXXXXX")
|
||||
+ + 1, ".#prelink#.", sizeof (".#prelink#.") - 1) == 0)
|
||||
+ return true;
|
||||
+ }
|
||||
+ /* Skip temporary files created by RPM. */
|
||||
+ if (memchr (name, len, ';') != NULL)
|
||||
+ return true;
|
||||
+ /* Skip temporary files created by dpkg. */
|
||||
+ if (len > 4 && memcmp (name + len - 4, ".tmp", 4) == 0)
|
||||
+ return true;
|
||||
+ return false;
|
||||
+}
|
||||
|
||||
static void
|
||||
search_dir (const struct dir_entry *entry)
|
||||
@@ -822,18 +847,8 @@ search_dir (const struct dir_entry *entry)
|
||||
continue;
|
||||
|
||||
size_t len = strlen (direntry->d_name);
|
||||
- /* Skip temporary files created by the prelink program. Files with
|
||||
- names like these are never really DSOs we want to look at. */
|
||||
- if (len >= sizeof (".#prelink#") - 1)
|
||||
- {
|
||||
- if (strcmp (direntry->d_name + len - sizeof (".#prelink#") + 1,
|
||||
- ".#prelink#") == 0)
|
||||
- continue;
|
||||
- if (len >= sizeof (".#prelink#.XXXXXX") - 1
|
||||
- && memcmp (direntry->d_name + len - sizeof (".#prelink#.XXXXXX")
|
||||
- + 1, ".#prelink#.", sizeof (".#prelink#.") - 1) == 0)
|
||||
- continue;
|
||||
- }
|
||||
+ if (skip_dso_based_on_name (direntry->d_name, len))
|
||||
+ continue;
|
||||
len += strlen (entry->path) + 2;
|
||||
if (len > file_name_len)
|
||||
{
|
||||
--
|
||||
2.33.0
|
||||
|
||||
68
backport-ldconfig-Fixes-for-skipping-temporary-files.patch
Normal file
68
backport-ldconfig-Fixes-for-skipping-temporary-files.patch
Normal file
@ -0,0 +1,68 @@
|
||||
From cfb5a97a93ea656e3b2263e42142a4032986d9ba Mon Sep 17 00:00:00 2001
|
||||
From: Florian Weimer <fweimer@redhat.com>
|
||||
Date: Mon, 23 Oct 2023 12:53:16 +0200
|
||||
Subject: [PATCH] ldconfig: Fixes for skipping temporary files.
|
||||
|
||||
Arguments to a memchr call were swapped, causing incorrect skipping
|
||||
of files.
|
||||
|
||||
Files related to dpkg have different names: they actually end in
|
||||
.dpkg-new and .dpkg-tmp, not .tmp as I mistakenly assumed.
|
||||
|
||||
Fixes commit 2aa0974d2573441bffd59 ("elf: ldconfig should skip
|
||||
temporary files created by package managers").
|
||||
|
||||
Reference:https://sourceware.org/git/?p=glibc.git;a=commit;h=cfb5a97a93ea656e3b2263e42142a4032986d9ba
|
||||
---
|
||||
elf/ldconfig.c | 19 +++++++++++++++----
|
||||
1 file changed, 15 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/elf/ldconfig.c b/elf/ldconfig.c
|
||||
index 73b5ef27..5812a951 100644
|
||||
--- a/elf/ldconfig.c
|
||||
+++ b/elf/ldconfig.c
|
||||
@@ -746,6 +746,17 @@ struct dlib_entry
|
||||
struct dlib_entry *next;
|
||||
};
|
||||
|
||||
+/* Return true if the N bytes at NAME end with with the characters in
|
||||
+ the string SUFFIX. (NAME[N + 1] does not have to be a null byte.)
|
||||
+ Expected to be called with a string literal for SUFFIX. */
|
||||
+static inline bool
|
||||
+endswithn (const char *name, size_t n, const char *suffix)
|
||||
+{
|
||||
+ return (n >= strlen (suffix)
|
||||
+ && memcmp (name + n - strlen (suffix), suffix,
|
||||
+ strlen (suffix)) == 0);
|
||||
+}
|
||||
+
|
||||
/* Skip some temporary DSO files. These files may be partially written
|
||||
and lead to ldconfig crashes when examined. */
|
||||
static bool
|
||||
@@ -755,8 +766,7 @@ skip_dso_based_on_name (const char *name, size_t len)
|
||||
names like these are never really DSOs we want to look at. */
|
||||
if (len >= sizeof (".#prelink#") - 1)
|
||||
{
|
||||
- if (strcmp (name + len - sizeof (".#prelink#") + 1,
|
||||
- ".#prelink#") == 0)
|
||||
+ if (endswithn (name, len, ".#prelink#"))
|
||||
return true;
|
||||
if (len >= sizeof (".#prelink#.XXXXXX") - 1
|
||||
&& memcmp (name + len - sizeof (".#prelink#.XXXXXX")
|
||||
@@ -764,10 +774,11 @@ skip_dso_based_on_name (const char *name, size_t len)
|
||||
return true;
|
||||
}
|
||||
/* Skip temporary files created by RPM. */
|
||||
- if (memchr (name, len, ';') != NULL)
|
||||
+ if (memchr (name, ';', len) != NULL)
|
||||
return true;
|
||||
/* Skip temporary files created by dpkg. */
|
||||
- if (len > 4 && memcmp (name + len - 4, ".tmp", 4) == 0)
|
||||
+ if (endswithn (name, len, ".dpkg-new")
|
||||
+ || endswithn (name, len, ".dpkg-tmp"))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
--
|
||||
2.33.0
|
||||
|
||||
58
glibc.spec
58
glibc.spec
@ -27,10 +27,15 @@
|
||||
# - Run smoke tests with valgrind to verify dynamic loader.
|
||||
# - Default: Always run valgrind tests if there is architecture support.
|
||||
##############################################################################
|
||||
%bcond_without testsuite
|
||||
%bcond_with benchtests
|
||||
%bcond_with bootstrap
|
||||
%ifarch ppc64le
|
||||
%bcond_with testsuite
|
||||
%bcond_with werror
|
||||
%else
|
||||
%bcond_without testsuite
|
||||
%bcond_without werror
|
||||
%endif
|
||||
%bcond_without docs
|
||||
%ifarch x86_64 aarch64
|
||||
%bcond_without compat_2_17
|
||||
@ -66,7 +71,7 @@
|
||||
##############################################################################
|
||||
Name: glibc
|
||||
Version: 2.34
|
||||
Release: 147
|
||||
Release: 152
|
||||
Summary: The GNU libc libraries
|
||||
License: %{all_license}
|
||||
URL: http://www.gnu.org/software/glibc/
|
||||
@ -286,6 +291,19 @@ Patch199: elf-Add-a-way-to-check-if-tunable-is-set-BZ-27069.patch
|
||||
Patch200: malloc-Improve-MAP_HUGETLB-with-glibc.malloc.hugetlb.patch
|
||||
Patch201: iconv-ISO-2022-CN-EXT-fix-out-of-bound-writes-when-w.patch
|
||||
Patch202: backport-resolv_conf-release-lock-on-allocation-failure-bug-30527.patch
|
||||
Patch203: backport-CVE-2024-33599-nscd-Stack-based-buffer-overflow-in-netgroup-cache.patch
|
||||
Patch204: backport-CVE-2024-33600-nscd-Do-not-send-missing-not-found-response.patch
|
||||
Patch205: backport-CVE-2024-33600-nscd-Avoid-null-pointer-crash-after-not-found-response.patch
|
||||
Patch206: backport-CVE-2024-33601-CVE-2024-33602-nscd-Use-two-buffer-in-addgetnetgrentX.patch
|
||||
Patch207: backport-Use-errval-not-errno-to-guide-cache-update.patch
|
||||
Patch208: backport-Skip-unusable-entries-in-first-pass-in-prune_cache.patch
|
||||
Patch209: backport-elf-Add-TLS-modid-reuse-test-for-bug-29039.patch
|
||||
Patch210: backport-elf-Fix-TLS-modid-reuse-generation-assignment-BZ-290.patch
|
||||
Patch211: backport-elf-Check-objname-before-calling-fatal_error.patch
|
||||
Patch212: backport-elf-Fix-_dl_debug_vdprintf-to-work-before-self-reloc.patch
|
||||
Patch213: backport-elf-ldconfig-should-skip-temporary-files-created-by-.patch
|
||||
Patch214: backport-ldconfig-Fixes-for-skipping-temporary-files.patch
|
||||
Patch215: backport-elf-Properly-align-PT_LOAD-segments-BZ-28676.patch
|
||||
|
||||
Patch9000: turn-default-value-of-x86_rep_stosb_threshold_form_2K_to_1M.patch
|
||||
Patch9001: delete-no-hard-link-to-avoid-all_language-package-to.patch
|
||||
@ -1501,6 +1519,42 @@ fi
|
||||
%endif
|
||||
|
||||
%changelog
|
||||
* Tue Jun 25 2024 chenhaixiang <chenhaixiang3@huawei.com> - 2.34-152
|
||||
- Type:bugfix
|
||||
- ID:
|
||||
- SUG:NA
|
||||
- DESC:elf: Properly align PT_LOAD segments
|
||||
|
||||
* Mon Jun 17 2024 hefq343 <fengqing.he@shingroup.cn> - 2.34-151
|
||||
- Type:bugfix
|
||||
- ID:
|
||||
- SUG:NA
|
||||
- DESC:fix compile error for ppc64le
|
||||
|
||||
* Fri May 10 2024 shixuantong <shixuantong1@huawei.com> - 2.34-150
|
||||
- Type:bugfix
|
||||
- ID:
|
||||
- SUG:NA
|
||||
- DESC:elf: Add TLS modid reuse test for bug 29039
|
||||
elf: Fix TLS modid reuse generation assignment
|
||||
elf: Check objname before calling fatal_error
|
||||
elf: Fix _dl_debug_vdprintf to work before self-relocation
|
||||
elf: ldconfig should skip temporary files created by package managers
|
||||
ldconfig: Fixes for skipping temporary files.
|
||||
|
||||
* Mon May 06 2024 chengyechun <chengyechun1@huaiwe.com> - 2.34-149
|
||||
- Type:bugfix
|
||||
- ID:
|
||||
- SUG:NA
|
||||
- DESC:nscd: Use errval, not errno to guide cache update
|
||||
nsce :Skip unusable entries in first pass in prune_cache
|
||||
|
||||
* Mon Apr 29 2024 chengyechun <chengyechun1@huawei.com> - 2.34-148
|
||||
- Type:CVE
|
||||
- ID:CVE-2024-33599 CVE-2024-33600 CVE-2024-33601 CVE-2024-33602
|
||||
- SUG:NA
|
||||
- DESC:fix CVE-2024-33599 CVE-2024-33600 CVE-2024-33601 CVE-2024-33602
|
||||
|
||||
* Wed Apr 24 2024 Lixing <lixing@loongson.cn> - 2.34-147
|
||||
- Add missing LoongArch relocation type in elf.h
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user