mirror of
https://abf.rosa.ru/djam/glibc40.git
synced 2025-02-24 00:02:53 +00:00
Fix CVE-2023-4806
This commit is contained in:
parent
c785123c5e
commit
894fcbf028
2 changed files with 112 additions and 1 deletions
107
CVE-2023-4806.patch
Normal file
107
CVE-2023-4806.patch
Normal file
|
@ -0,0 +1,107 @@
|
||||||
|
From 74d98fb3d9e489666195d69efff04b5760632312 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Mikhail Novosyolov <m.novosyolov@rosalinux.ru>
|
||||||
|
Date: Mon, 11 Dec 2023 20:09:59 +0300
|
||||||
|
Subject: [PATCH] getaddrinfo: Fix use after free in getcanonname (CVE-2023-4806)
|
||||||
|
|
||||||
|
When an NSS plugin only implements the _gethostbyname2_r and
|
||||||
|
_getcanonname_r callbacks, getaddrinfo could use memory that was freed
|
||||||
|
during tmpbuf resizing, through h_name in a previous query response.
|
||||||
|
|
||||||
|
The backing store for res->at->name when doing a query with
|
||||||
|
gethostbyname3_r or gethostbyname2_r is tmpbuf, which is reallocated in
|
||||||
|
gethosts during the query. For AF_INET6 lookup with AI_ALL |
|
||||||
|
AI_V4MAPPED, gethosts gets called twice, once for a v6 lookup and second
|
||||||
|
for a v4 lookup. In this case, if the first call reallocates tmpbuf
|
||||||
|
enough number of times, resulting in a malloc, th->h_name (that
|
||||||
|
res->at->name refers to) ends up on a heap allocated storage in tmpbuf.
|
||||||
|
Now if the second call to gethosts also causes the plugin callback to
|
||||||
|
return NSS_STATUS_TRYAGAIN, tmpbuf will get freed, resulting in a UAF
|
||||||
|
reference in res->at->name. This then gets dereferenced in the
|
||||||
|
getcanonname_r plugin call, resulting in the use after free.
|
||||||
|
|
||||||
|
Fix this by copying h_name over and freeing it at the end. This
|
||||||
|
resolves BZ #30843, which is assigned CVE-2023-4806.
|
||||||
|
|
||||||
|
Minimal port of https://git.almalinux.org/rpms/glibc/src/branch/c8/SOURCES/glibc-RHEL-2423.patch
|
||||||
|
into glibc-2.33 by mikhailnov
|
||||||
|
Original author: Siddhesh Poyarekar <siddhesh@sourceware.org>
|
||||||
|
---
|
||||||
|
sysdeps/posix/getaddrinfo.c | 21 +++++++++++++++++----
|
||||||
|
1 file changed, 17 insertions(+), 4 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/sysdeps/posix/getaddrinfo.c b/sysdeps/posix/getaddrinfo.c
|
||||||
|
index 92d2a1c284..2e26a98050 100644
|
||||||
|
--- a/sysdeps/posix/getaddrinfo.c
|
||||||
|
+++ b/sysdeps/posix/getaddrinfo.c
|
||||||
|
@@ -232,7 +232,6 @@ convert_hostent_to_gaih_addrtuple (const struct addrinfo *req,
|
||||||
|
}
|
||||||
|
array[i].next = array + i + 1;
|
||||||
|
}
|
||||||
|
- array[0].name = h->h_name;
|
||||||
|
array[count - 1].next = NULL;
|
||||||
|
|
||||||
|
*result = array;
|
||||||
|
@@ -283,6 +282,18 @@ convert_hostent_to_gaih_addrtuple (const struct addrinfo *req,
|
||||||
|
} \
|
||||||
|
*pat = addrmem; \
|
||||||
|
\
|
||||||
|
+ /* Store h_name so that it survives accidental deallocation when \
|
||||||
|
+ gethosts is called again and tmpbuf gets reallocated. */ \
|
||||||
|
+ if (h_name == NULL && th.h_name != NULL) \
|
||||||
|
+ { \
|
||||||
|
+ h_name = __strdup (th.h_name); \
|
||||||
|
+ if (h_name == NULL) \
|
||||||
|
+ { \
|
||||||
|
+ __resolv_context_put (res_ctx); \
|
||||||
|
+ result = -EAI_SYSTEM; \
|
||||||
|
+ goto free_and_return; \
|
||||||
|
+ } \
|
||||||
|
+ } \
|
||||||
|
if (localcanon != NULL && canon == NULL) \
|
||||||
|
{ \
|
||||||
|
canonbuf = __strdup (localcanon); \
|
||||||
|
@@ -307,14 +318,14 @@ convert_hostent_to_gaih_addrtuple (const struct addrinfo *req,
|
||||||
|
memory allocation failure. The returned string is allocated on the
|
||||||
|
heap; the caller has to free it. */
|
||||||
|
static char *
|
||||||
|
-getcanonname (nss_action_list nip, struct gaih_addrtuple *at, const char *name)
|
||||||
|
+getcanonname (nss_action_list nip, const char *hname, const char *name)
|
||||||
|
{
|
||||||
|
nss_getcanonname_r *cfct = __nss_lookup_function (nip, "getcanonname_r");
|
||||||
|
char *s = (char *) name;
|
||||||
|
if (cfct != NULL)
|
||||||
|
{
|
||||||
|
char buf[256];
|
||||||
|
- if (DL_CALL_FCT (cfct, (at->name ?: name, buf, sizeof (buf),
|
||||||
|
+ if (DL_CALL_FCT (cfct, (hname ?: name, buf, sizeof (buf),
|
||||||
|
&s, &errno, &h_errno)) != NSS_STATUS_SUCCESS)
|
||||||
|
/* If the canonical name cannot be determined, use the passed
|
||||||
|
string. */
|
||||||
|
@@ -333,6 +344,7 @@ gaih_inet (const char *name, const struct gaih_service *service,
|
||||||
|
struct gaih_addrtuple *at = NULL;
|
||||||
|
bool got_ipv6 = false;
|
||||||
|
const char *canon = NULL;
|
||||||
|
+ char *h_name = NULL;
|
||||||
|
const char *orig_name = name;
|
||||||
|
|
||||||
|
/* Reserve stack memory for the scratch buffer in the getaddrinfo
|
||||||
|
@@ -860,7 +872,7 @@ gaih_inet (const char *name, const struct gaih_service *service,
|
||||||
|
if ((req->ai_flags & AI_CANONNAME) != 0
|
||||||
|
&& canon == NULL)
|
||||||
|
{
|
||||||
|
- canonbuf = getcanonname (nip, at, name);
|
||||||
|
+ canonbuf = getcanonname (nip, h_name, name);
|
||||||
|
if (canonbuf == NULL)
|
||||||
|
{
|
||||||
|
__resolv_context_put (res_ctx);
|
||||||
|
@@ -1102,6 +1114,7 @@ gaih_inet (const char *name, const struct gaih_service *service,
|
||||||
|
free ((char *) name);
|
||||||
|
free (addrmem);
|
||||||
|
free (canonbuf);
|
||||||
|
+ free (h_name);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
--
|
||||||
|
2.40.1
|
||||||
|
|
|
@ -102,7 +102,7 @@ Version: 2.33
|
||||||
#Source0: http://ftp.gnu.org/gnu/glibc/%{oname}-%{version}.tar.xz
|
#Source0: http://ftp.gnu.org/gnu/glibc/%{oname}-%{version}.tar.xz
|
||||||
# use ./upd.sh to make a tarball and automatically update Release
|
# use ./upd.sh to make a tarball and automatically update Release
|
||||||
Source0: glibc-%{commit}.tar.xz
|
Source0: glibc-%{commit}.tar.xz
|
||||||
Release: 10.git%{commit_short}.2
|
Release: 10.git%{commit_short}.3
|
||||||
License: LGPLv2+ and LGPLv2+ with exceptions and GPLv2+
|
License: LGPLv2+ and LGPLv2+ with exceptions and GPLv2+
|
||||||
Group: System/Libraries
|
Group: System/Libraries
|
||||||
Url: http://www.gnu.org/software/libc/
|
Url: http://www.gnu.org/software/libc/
|
||||||
|
@ -190,6 +190,10 @@ Patch1040: https://github.com/FireBurn/glibc/commit/2efa9591e5e8a129e7b73ad0dad3
|
||||||
|
|
||||||
Patch1051: glibc-2.34-select-i686.patch
|
Patch1051: glibc-2.34-select-i686.patch
|
||||||
|
|
||||||
|
# https://sourceware.org/bugzilla/show_bug.cgi?id=30843#c19
|
||||||
|
# This fix does not introduce CVE-2023-5156
|
||||||
|
Patch2001: CVE-2023-4806.patch
|
||||||
|
|
||||||
# do not remove this BR - it helps to bootstrap the generator
|
# do not remove this BR - it helps to bootstrap the generator
|
||||||
BuildRequires: devel-rpm-generators
|
BuildRequires: devel-rpm-generators
|
||||||
BuildRequires: autoconf2.5
|
BuildRequires: autoconf2.5
|
||||||
|
|
Loading…
Add table
Reference in a new issue