diff --git a/glibc-CVE-2024-33599-nscd-Stack-based-buffer-overflow-in-n.patch b/glibc-CVE-2024-33599-nscd-Stack-based-buffer-overflow-in-n.patch new file mode 100644 index 0000000..a370334 --- /dev/null +++ b/glibc-CVE-2024-33599-nscd-Stack-based-buffer-overflow-in-n.patch @@ -0,0 +1,37 @@ +From 87801a8fd06db1d654eea3e4f7626ff476a9bdaa Mon Sep 17 00:00:00 2001 +From: Florian Weimer +Date: Thu, 25 Apr 2024 15:00:45 +0200 +Subject: [PATCH 1/4] 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 +--- + 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.35.3 + diff --git a/glibc-CVE-2024-33600-nscd-Avoid-null-pointer-crashes-after.patch b/glibc-CVE-2024-33600-nscd-Avoid-null-pointer-crashes-after.patch new file mode 100644 index 0000000..e3f3ab4 --- /dev/null +++ b/glibc-CVE-2024-33600-nscd-Avoid-null-pointer-crashes-after.patch @@ -0,0 +1,59 @@ +From b048a482f088e53144d26a61c390bed0210f49f2 Mon Sep 17 00:00:00 2001 +From: Florian Weimer +Date: Thu, 25 Apr 2024 15:01:07 +0200 +Subject: [PATCH 3/4] 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 +--- + 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.35.3 + diff --git a/glibc-CVE-2024-33600-nscd-Do-not-send-missing-not-found-re.patch b/glibc-CVE-2024-33600-nscd-Do-not-send-missing-not-found-re.patch new file mode 100644 index 0000000..0727ac7 --- /dev/null +++ b/glibc-CVE-2024-33600-nscd-Do-not-send-missing-not-found-re.patch @@ -0,0 +1,58 @@ +From 7835b00dbce53c3c87bbbb1754a95fb5e58187aa Mon Sep 17 00:00:00 2001 +From: Florian Weimer +Date: Thu, 25 Apr 2024 15:01:07 +0200 +Subject: [PATCH 2/4] 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 +--- + 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.35.3 + diff --git a/glibc-CVE-2024-33601-CVE-2024-33602-nscd-netgroup-Use-two.patch b/glibc-CVE-2024-33601-CVE-2024-33602-nscd-netgroup-Use-two.patch new file mode 100644 index 0000000..9a9ffe1 --- /dev/null +++ b/glibc-CVE-2024-33601-CVE-2024-33602-nscd-netgroup-Use-two.patch @@ -0,0 +1,389 @@ +From c04a21e050d64a1193a6daab872bca2528bda44b Mon Sep 17 00:00:00 2001 +From: Florian Weimer +Date: Thu, 25 Apr 2024 15:01:07 +0200 +Subject: [PATCH 4/4] 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 +--- + 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 + #include + #include ++#include + + #include "../inet/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, ¬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 +@@ -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, ¬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. */ +@@ -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.35.3 + diff --git a/glibc.changes b/glibc.changes index ba01efb..0e4282b 100644 --- a/glibc.changes +++ b/glibc.changes @@ -1,3 +1,70 @@ +------------------------------------------------------------------- +Thu Jul 18 08:31:37 UTC 2024 - Andreas Schwab + +- s390x-wcsncmp.patch: s390x: Fix segfault in wcsncmp (bsc#1228041, BZ + #31934) + +------------------------------------------------------------------- +Wed May 29 10:41:20 UTC 2024 - Andreas Schwab + +- Fix typo in last change + +------------------------------------------------------------------- +Thu May 23 11:31:34 UTC 2024 - Andreas Schwab + +- Also include stat64 in the 32-bit libc_nonshared.a workaround + (bsc#1221482) + +------------------------------------------------------------------- +Wed May 8 14:06:39 UTC 2024 - Giuliano Belinassi + +- ulp-prologue-into-asm-functions.patch: Avoid creating ULP prologue + for _start routine (bsc#1221940) + +------------------------------------------------------------------- +Tue May 7 10:32:54 UTC 2024 - Andreas Schwab + +- nscd-netgroup-cache-timeout.patch: Use time_t for return type of + addgetnetgrentX (CVE-2024-33602, bsc#1223425) +- Also add libc_nonshared.a workaround to 32-bit x86 compat package + (bsc#1221482) + +------------------------------------------------------------------- +Wed May 1 23:50:51 UTC 2024 - Giuliano Belinassi + +- 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) + +------------------------------------------------------------------- +Thu Apr 18 08:22:48 UTC 2024 - Andreas Schwab + +- iconv-iso-2022-cn-ext.patch: iconv: ISO-2022-CN-EXT: fix out-of-bound + writes when writing escape sequence (CVE-2024-2961, bsc#1222992) + +------------------------------------------------------------------- +Wed Apr 3 15:54:02 UTC 2024 - Andreas Schwab + +- Add workaround for invalid use of libc_nonshared.a with non-SUSE libc + (bsc#1221482) + +------------------------------------------------------------------- +Thu Mar 21 13:22:51 UTC 2024 - Andreas Schwab + +- malloc-arena-get2.patch: malloc: Use __get_nprocs on arena_get2 (BZ + #30945) +- sched-getcpu-rseq-area.patch: linux: Use rseq area unconditionally in + sched_getcpu (BZ #31479) + ------------------------------------------------------------------- Mon Mar 11 10:06:42 UTC 2024 - Andreas Schwab diff --git a/glibc.spec b/glibc.spec index d65bf94..aec11f5 100644 --- a/glibc.spec +++ b/glibc.spec @@ -343,6 +343,24 @@ Patch1022: qsort-invalid-cmp.patch Patch1023: s390-clone-error-clobber-r7.patch # PATCH-FIX-UPSTREAM duplocale: protect use of global locale (BZ #23970) Patch1024: duplocale-global-locale.patch +# PATCH-FIX-UPSTREAM malloc: Use __get_nprocs on arena_get2 (BZ #30945) +Patch1025: malloc-arena-get2.patch +# PATCH-FIX-UPSTREAM linux: Use rseq area unconditionally in sched_getcpu (BZ #31479) +Patch1026: sched-getcpu-rseq-area.patch +# PATCH-FIX-UPSTREAM iconv: ISO-2022-CN-EXT: fix out-of-bound writes when writing escape sequence (CVE-2024-2961) +Patch1027: iconv-iso-2022-cn-ext.patch +# PATCH-FIX-UPSTREAM nscd: Stack-based buffer overflow in netgroup cache (CVE-2024-33599, BZ #31677) +Patch1028: 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) +Patch1029: 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) +Patch1030: 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) +Patch1031: 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) +Patch1032: nscd-netgroup-cache-timeout.patch +# PATCH-FIX-UPSTREAM s390x: Fix segfault in wcsncmp (BZ #31934) +Patch1033: s390x-wcsncmp.patch ### # Patches awaiting upstream approval @@ -750,6 +768,35 @@ echo 'CFLAGS-.os += -fdump-ipa-clones' \ %endif make %{?_smp_mflags} %{?make_output_sync} + +%if %{build_main} && 0%{?sle_version} +%ifarch x86_64 i686 +# Horrible workaround for bsc#1221482 +xstatbuild () +{ + gcc -O2 -I ../sysdeps/unix/sysv/linux/x86 -xc - -c -o $1stat$2.oS < +int __$1xstat$2 (int, $3, void *); + +int +$1stat$2 ($3 file, void *buf) +{ + return __$1xstat$2 (_STAT_VER, file, buf); +} +EOF + ar r libc_nonshared.a $1stat$2.oS +} +xstatbuild "" "" "const char *" +xstatbuild f "" int +xstatbuild l "" "const char *" +%ifarch i686 +xstatbuild "" 64 "const char *" +xstatbuild f 64 int +xstatbuild l 64 "const char *" +%endif +%endif +%endif + cd .. # diff --git a/iconv-iso-2022-cn-ext.patch b/iconv-iso-2022-cn-ext.patch new file mode 100644 index 0000000..bfc742e --- /dev/null +++ b/iconv-iso-2022-cn-ext.patch @@ -0,0 +1,216 @@ +From e1135387deded5d73924f6ca20c72a35dc8e1bda Mon Sep 17 00:00:00 2001 +From: Charles Fol +Date: Thu, 28 Mar 2024 12:25:38 -0300 +Subject: [PATCH] iconv: ISO-2022-CN-EXT: fix out-of-bound writes when writing + escape sequence (CVE-2024-2961) + +ISO-2022-CN-EXT uses escape sequences to indicate character set changes +(as specified by RFC 1922). While the SOdesignation has the expected +bounds checks, neither SS2designation nor SS3designation have its; +allowing a write overflow of 1, 2, or 3 bytes with fixed values: +'$+I', '$+J', '$+K', '$+L', '$+M', or '$*H'. + +Checked on aarch64-linux-gnu. + +Co-authored-by: Adhemerval Zanella +Reviewed-by: Carlos O'Donell +Tested-by: Carlos O'Donell + +(cherry picked from commit f9dc609e06b1136bb0408be9605ce7973a767ada) +--- + iconvdata/Makefile | 5 +- + iconvdata/iso-2022-cn-ext.c | 12 +++ + iconvdata/tst-iconv-iso-2022-cn-ext.c | 128 ++++++++++++++++++++++++++ + 3 files changed, 144 insertions(+), 1 deletion(-) + create mode 100644 iconvdata/tst-iconv-iso-2022-cn-ext.c + +diff --git a/iconvdata/Makefile b/iconvdata/Makefile +index dd5cafab21..075098dce8 100644 +--- a/iconvdata/Makefile ++++ b/iconvdata/Makefile +@@ -75,7 +75,8 @@ ifeq (yes,$(build-shared)) + tests = bug-iconv1 bug-iconv2 tst-loading tst-e2big tst-iconv4 bug-iconv4 \ + tst-iconv6 bug-iconv5 bug-iconv6 tst-iconv7 bug-iconv8 bug-iconv9 \ + bug-iconv10 bug-iconv11 bug-iconv12 tst-iconv-big5-hkscs-to-2ucs4 \ +- bug-iconv13 bug-iconv14 bug-iconv15 ++ bug-iconv13 bug-iconv14 bug-iconv15 \ ++ tst-iconv-iso-2022-cn-ext + ifeq ($(have-thread-library),yes) + tests += bug-iconv3 + endif +@@ -330,6 +331,8 @@ $(objpfx)bug-iconv14.out: $(addprefix $(objpfx), $(gconv-modules)) \ + $(addprefix $(objpfx),$(modules.so)) + $(objpfx)bug-iconv15.out: $(addprefix $(objpfx), $(gconv-modules)) \ + $(addprefix $(objpfx),$(modules.so)) ++$(objpfx)tst-iconv-iso-2022-cn-ext.out: $(addprefix $(objpfx), $(gconv-modules)) \ ++ $(addprefix $(objpfx),$(modules.so)) + + $(objpfx)iconv-test.out: run-iconv-test.sh \ + $(addprefix $(objpfx), $(gconv-modules)) \ +diff --git a/iconvdata/iso-2022-cn-ext.c b/iconvdata/iso-2022-cn-ext.c +index 36727f0865..9bb02238a3 100644 +--- a/iconvdata/iso-2022-cn-ext.c ++++ b/iconvdata/iso-2022-cn-ext.c +@@ -574,6 +574,12 @@ DIAG_IGNORE_Os_NEEDS_COMMENT (5, "-Wmaybe-uninitialized"); + { \ + const char *escseq; \ + \ ++ if (outptr + 4 > outend) \ ++ { \ ++ result = __GCONV_FULL_OUTPUT; \ ++ break; \ ++ } \ ++ \ + assert (used == CNS11643_2_set); /* XXX */ \ + escseq = "*H"; \ + *outptr++ = ESC; \ +@@ -587,6 +593,12 @@ DIAG_IGNORE_Os_NEEDS_COMMENT (5, "-Wmaybe-uninitialized"); + { \ + const char *escseq; \ + \ ++ if (outptr + 4 > outend) \ ++ { \ ++ result = __GCONV_FULL_OUTPUT; \ ++ break; \ ++ } \ ++ \ + assert ((used >> 5) >= 3 && (used >> 5) <= 7); \ + escseq = "+I+J+K+L+M" + ((used >> 5) - 3) * 2; \ + *outptr++ = ESC; \ +diff --git a/iconvdata/tst-iconv-iso-2022-cn-ext.c b/iconvdata/tst-iconv-iso-2022-cn-ext.c +new file mode 100644 +index 0000000000..96a8765fd5 +--- /dev/null ++++ b/iconvdata/tst-iconv-iso-2022-cn-ext.c +@@ -0,0 +1,128 @@ ++/* Verify ISO-2022-CN-EXT does not write out of the bounds. ++ Copyright (C) 2024 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 ++ . */ ++ ++#include ++#include ++ ++#include ++#include ++#include ++ ++#include ++#include ++#include ++ ++/* The test sets up a two memory page buffer with the second page marked ++ PROT_NONE to trigger a fault if the conversion writes beyond the exact ++ expected amount. Then we carry out various conversions and precisely ++ place the start of the output buffer in order to trigger a SIGSEGV if the ++ process writes anywhere between 1 and page sized bytes more (only one ++ PROT_NONE page is setup as a canary) than expected. These tests exercise ++ all three of the cases in ISO-2022-CN-EXT where the converter must switch ++ character sets and may run out of buffer space while doing the ++ operation. */ ++ ++static int ++do_test (void) ++{ ++ iconv_t cd = iconv_open ("ISO-2022-CN-EXT", "UTF-8"); ++ TEST_VERIFY_EXIT (cd != (iconv_t) -1); ++ ++ char *ntf; ++ size_t ntfsize; ++ char *outbufbase; ++ { ++ int pgz = getpagesize (); ++ TEST_VERIFY_EXIT (pgz > 0); ++ ntfsize = 2 * pgz; ++ ++ ntf = xmmap (NULL, ntfsize, PROT_READ | PROT_WRITE, MAP_PRIVATE ++ | MAP_ANONYMOUS, -1); ++ xmprotect (ntf + pgz, pgz, PROT_NONE); ++ ++ outbufbase = ntf + pgz; ++ } ++ ++ /* Check if SOdesignation escape sequence does not trigger an OOB write. */ ++ { ++ char inbuf[] = "\xe4\xba\xa4\xe6\x8d\xa2"; ++ ++ for (int i = 0; i < 9; i++) ++ { ++ char *inp = inbuf; ++ size_t inleft = sizeof (inbuf) - 1; ++ ++ char *outp = outbufbase - i; ++ size_t outleft = i; ++ ++ TEST_VERIFY_EXIT (iconv (cd, &inp, &inleft, &outp, &outleft) ++ == (size_t) -1); ++ TEST_COMPARE (errno, E2BIG); ++ ++ TEST_VERIFY_EXIT (iconv (cd, NULL, NULL, NULL, NULL) == 0); ++ } ++ } ++ ++ /* Same as before for SS2designation. */ ++ { ++ char inbuf[] = "㴽 \xe3\xb4\xbd"; ++ ++ for (int i = 0; i < 14; i++) ++ { ++ char *inp = inbuf; ++ size_t inleft = sizeof (inbuf) - 1; ++ ++ char *outp = outbufbase - i; ++ size_t outleft = i; ++ ++ TEST_VERIFY_EXIT (iconv (cd, &inp, &inleft, &outp, &outleft) ++ == (size_t) -1); ++ TEST_COMPARE (errno, E2BIG); ++ ++ TEST_VERIFY_EXIT (iconv (cd, NULL, NULL, NULL, NULL) == 0); ++ } ++ } ++ ++ /* Same as before for SS3designation. */ ++ { ++ char inbuf[] = "劄 \xe5\x8a\x84"; ++ ++ for (int i = 0; i < 14; i++) ++ { ++ char *inp = inbuf; ++ size_t inleft = sizeof (inbuf) - 1; ++ ++ char *outp = outbufbase - i; ++ size_t outleft = i; ++ ++ TEST_VERIFY_EXIT (iconv (cd, &inp, &inleft, &outp, &outleft) ++ == (size_t) -1); ++ TEST_COMPARE (errno, E2BIG); ++ ++ TEST_VERIFY_EXIT (iconv (cd, NULL, NULL, NULL, NULL) == 0); ++ } ++ } ++ ++ TEST_VERIFY_EXIT (iconv_close (cd) != -1); ++ ++ xmunmap (ntf, ntfsize); ++ ++ return 0; ++} ++ ++#include +-- +2.44.0 + diff --git a/malloc-arena-get2.patch b/malloc-arena-get2.patch new file mode 100644 index 0000000..e846830 --- /dev/null +++ b/malloc-arena-get2.patch @@ -0,0 +1,106 @@ +From 506e47da1d66b33e24440a495eeef85daf7f2a78 Mon Sep 17 00:00:00 2001 +From: Adhemerval Zanella +Date: Wed, 11 Oct 2023 13:43:56 -0300 +Subject: [PATCH] malloc: Use __get_nprocs on arena_get2 (BZ 30945) + +This restore the 2.33 semantic for arena_get2. It was changed by +11a02b035b46 to avoid arena_get2 call malloc (back when __get_nproc +was refactored to use an scratch_buffer - 903bc7dcc2acafc). The +__get_nproc was refactored over then and now it also avoid to call +malloc. + +The 11a02b035b46 did not take in consideration any performance +implication, which should have been discussed properly. The +__get_nprocs_sched is still used as a fallback mechanism if procfs +and sysfs is not acessible. + +Checked on x86_64-linux-gnu. +Reviewed-by: DJ Delorie + +(cherry picked from commit 472894d2cfee5751b44c0aaa71ed87df81c8e62e) +--- + include/sys/sysinfo.h | 4 ---- + malloc/arena.c | 2 +- + misc/getsysstats.c | 6 ------ + sysdeps/mach/getsysstats.c | 6 ------ + sysdeps/unix/sysv/linux/getsysstats.c | 2 +- + 5 files changed, 2 insertions(+), 18 deletions(-) + +diff --git a/include/sys/sysinfo.h b/include/sys/sysinfo.h +index c490561581..65742b1036 100644 +--- a/include/sys/sysinfo.h ++++ b/include/sys/sysinfo.h +@@ -14,10 +14,6 @@ libc_hidden_proto (__get_nprocs_conf) + extern int __get_nprocs (void); + libc_hidden_proto (__get_nprocs) + +-/* Return the number of available processors which the process can +- be scheduled. */ +-extern int __get_nprocs_sched (void) attribute_hidden; +- + /* Return number of physical pages of memory in the system. */ + extern long int __get_phys_pages (void); + libc_hidden_proto (__get_phys_pages) +diff --git a/malloc/arena.c b/malloc/arena.c +index 6f03955ff2..82b09adb47 100644 +--- a/malloc/arena.c ++++ b/malloc/arena.c +@@ -820,7 +820,7 @@ arena_get2 (size_t size, mstate avoid_arena) + narenas_limit = mp_.arena_max; + else if (narenas > mp_.arena_test) + { +- int n = __get_nprocs_sched (); ++ int n = __get_nprocs (); + + if (n >= 1) + narenas_limit = NARENAS_FROM_NCORES (n); +diff --git a/misc/getsysstats.c b/misc/getsysstats.c +index 5f36adc0e8..23cc112074 100644 +--- a/misc/getsysstats.c ++++ b/misc/getsysstats.c +@@ -44,12 +44,6 @@ weak_alias (__get_nprocs, get_nprocs) + link_warning (get_nprocs, "warning: get_nprocs will always return 1") + + +-int +-__get_nprocs_sched (void) +-{ +- return 1; +-} +- + long int + __get_phys_pages (void) + { +diff --git a/sysdeps/mach/getsysstats.c b/sysdeps/mach/getsysstats.c +index 5184e5eee1..d3834f3b69 100644 +--- a/sysdeps/mach/getsysstats.c ++++ b/sysdeps/mach/getsysstats.c +@@ -62,12 +62,6 @@ __get_nprocs (void) + libc_hidden_def (__get_nprocs) + weak_alias (__get_nprocs, get_nprocs) + +-int +-__get_nprocs_sched (void) +-{ +- return __get_nprocs (); +-} +- + /* Return the number of physical pages on the system. */ + long int + __get_phys_pages (void) +diff --git a/sysdeps/unix/sysv/linux/getsysstats.c b/sysdeps/unix/sysv/linux/getsysstats.c +index b0b6c154ac..1ea7f1f01f 100644 +--- a/sysdeps/unix/sysv/linux/getsysstats.c ++++ b/sysdeps/unix/sysv/linux/getsysstats.c +@@ -29,7 +29,7 @@ + #include + #include + +-int ++static int + __get_nprocs_sched (void) + { + enum +-- +2.44.0 + diff --git a/nscd-netgroup-cache-timeout.patch b/nscd-netgroup-cache-timeout.patch new file mode 100644 index 0000000..2fffdae --- /dev/null +++ b/nscd-netgroup-cache-timeout.patch @@ -0,0 +1,36 @@ +From f510d75ff7f7405328853bd67b75f6847dfe9d31 Mon Sep 17 00:00:00 2001 +From: Florian Weimer +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 +(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 cc4e270c1f..a63b260fdb 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 + diff --git a/s390x-wcsncmp.patch b/s390x-wcsncmp.patch new file mode 100644 index 0000000..58a8b70 --- /dev/null +++ b/s390x-wcsncmp.patch @@ -0,0 +1,58 @@ +From 712453634c8efd71a9b3ff0122145a9e90e9955c Mon Sep 17 00:00:00 2001 +From: Stefan Liebler +Date: Thu, 11 Jul 2024 11:28:53 +0200 +Subject: [PATCH] s390x: Fix segfault in wcsncmp [BZ #31934] + +The z13/vector-optimized wcsncmp implementation segfaults if n=1 +and there is only one character (equal on both strings) before +the page end. Then it loads and compares one character and misses +to check n again. The following load fails. + +This patch removes the extra load and compare of the first character +and just start with the loop which uses vector-load-to-block-boundary. +This code-path also checks n. + +With this patch both tests are passing: +- the simplified one mentioned in the bugzilla 31934 +- the full one in Florian Weimer's patch: +"manual: Document a GNU extension for strncmp/wcsncmp" +(https://patchwork.sourceware.org/project/glibc/patch/874j9eml6y.fsf@oldenburg.str.redhat.com/): +On s390x-linux-gnu (z16), the new wcsncmp test fails due to bug 31934. +Reviewed-by: Carlos O'Donell + +(cherry picked from commit 9b7651410375ec8848a1944992d663d514db4ba7) +--- + sysdeps/s390/wcsncmp-vx.S | 10 +--------- + 1 file changed, 1 insertion(+), 9 deletions(-) + +diff --git a/sysdeps/s390/wcsncmp-vx.S b/sysdeps/s390/wcsncmp-vx.S +index 1bf769b870..4028d1e624 100644 +--- a/sysdeps/s390/wcsncmp-vx.S ++++ b/sysdeps/s390/wcsncmp-vx.S +@@ -59,14 +59,7 @@ ENTRY(WCSNCMP_Z13) + sllg %r4,%r4,2 /* Convert character-count to byte-count. */ + locgrne %r4,%r1 /* Use max byte-count, if bit 0/1 was one. */ + +- /* Check first character without vector load. */ +- lghi %r5,4 /* current_len = 4 bytes. */ +- /* Check s1/2[0]. */ +- lt %r0,0(%r2) +- l %r1,0(%r3) +- je .Lend_cmp_one_char +- crjne %r0,%r1,.Lend_cmp_one_char +- ++ lghi %r5,0 /* current_len = 0 bytes. */ + .Lloop: + vlbb %v17,0(%r5,%r3),6 /* Load s2 to block boundary. */ + vlbb %v16,0(%r5,%r2),6 /* Load s1 to block boundary. */ +@@ -167,7 +160,6 @@ ENTRY(WCSNCMP_Z13) + srl %r4,2 /* And convert it to character-index. */ + vlgvf %r0,%v16,0(%r4) /* Load character-values. */ + vlgvf %r1,%v17,0(%r4) +-.Lend_cmp_one_char: + cr %r0,%r1 + je .Lend_equal + lghi %r2,1 +-- +2.45.2 + diff --git a/sched-getcpu-rseq-area.patch b/sched-getcpu-rseq-area.patch new file mode 100644 index 0000000..b377442 --- /dev/null +++ b/sched-getcpu-rseq-area.patch @@ -0,0 +1,52 @@ +From 5753cda1ca0749002c4718122a9b6d5177087b7b Mon Sep 17 00:00:00 2001 +From: Florian Weimer +Date: Fri, 15 Mar 2024 19:08:24 +0100 +Subject: [PATCH] linux: Use rseq area unconditionally in sched_getcpu (bug + 31479) + +Originally, nptl/descr.h included , but we removed that +in commit 2c6b4b272e6b4d07303af25709051c3e96288f2d ("nptl: +Unconditionally use a 32-byte rseq area"). After that, it was +not ensured that the RSEQ_SIG macro was defined during sched_getcpu.c +compilation that provided a definition. This commit always checks +the rseq area for CPU number information before using the other +approaches. + +This adds an unnecessary (but well-predictable) branch on +architectures which do not define RSEQ_SIG, but its cost is small +compared to the system call. Most architectures that have vDSO +acceleration for getcpu also have rseq support. + +Fixes: 2c6b4b272e6b4d07303af25709051c3e96288f2d +Fixes: 1d350aa06091211863e41169729cee1bca39f72f +Reviewed-by: Arjun Shankar +(cherry picked from commit 7a76f218677d149d8b7875b336722108239f7ee9) +--- + sysdeps/unix/sysv/linux/sched_getcpu.c | 8 -------- + 1 file changed, 8 deletions(-) + +diff --git a/sysdeps/unix/sysv/linux/sched_getcpu.c b/sysdeps/unix/sysv/linux/sched_getcpu.c +index 4457d714bc..22700ef846 100644 +--- a/sysdeps/unix/sysv/linux/sched_getcpu.c ++++ b/sysdeps/unix/sysv/linux/sched_getcpu.c +@@ -33,17 +33,9 @@ vsyscall_sched_getcpu (void) + return r == -1 ? r : cpu; + } + +-#ifdef RSEQ_SIG + int + sched_getcpu (void) + { + int cpu_id = THREAD_GETMEM_VOLATILE (THREAD_SELF, rseq_area.cpu_id); + return __glibc_likely (cpu_id >= 0) ? cpu_id : vsyscall_sched_getcpu (); + } +-#else /* RSEQ_SIG */ +-int +-sched_getcpu (void) +-{ +- return vsyscall_sched_getcpu (); +-} +-#endif /* RSEQ_SIG */ +-- +2.44.0 + diff --git a/ulp-prologue-into-asm-functions.patch b/ulp-prologue-into-asm-functions.patch index 9e9f2e6..59e9da3 100644 --- a/ulp-prologue-into-asm-functions.patch +++ b/ulp-prologue-into-asm-functions.patch @@ -153,19 +153,19 @@ index 0b3483a77a..329c16306e 100644 +/* For 32-bit glibc then define those macros as empty. */ +#ifndef ULP_PRE_PROLOGUE -+# define ULP_PRE_PROLOGUE ++# define ULP_PRE_PROLOGUE(name) +#endif +#ifndef ULP_POST_PROLOGUE -+# define ULP_POST_PROLOGUE ++# define ULP_POST_PROLOGUE(name) +#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. */ @@ -230,10 +230,10 @@ index cbb22884eb..327377daa6 100644 /* * 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 6ca169573d..c18f0ef914 100644 +index c8ad778fee..59c278eb58 100644 --- a/sysdeps/x86_64/sysdep.h +++ b/sysdeps/x86_64/sysdep.h -@@ -24,6 +24,19 @@ +@@ -23,6 +23,46 @@ #ifdef __ASSEMBLER__ @@ -242,12 +242,39 @@ index 6ca169573d..c18f0ef914 100644 + written in ASM, the way we do this is by adding this prologue manually. */ + +#if ENABLE_USERSPACE_LIVEPATCH -+# undef ULP_PRE_PROLOGUE -+# undef ULP_POST_PROLOGUE -+# 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(name) ++# define ULP_POST_PROLOGUE(name) +#endif + /* Syntactic details of assembler. */