fix CVE-2023-28320

(cherry picked from commit 0fb95c607c50e71d8a422697e370854be749e471)
This commit is contained in:
xingwei 2023-06-08 05:56:06 +00:00 committed by openeuler-sync-bot
parent c7a0ae24a8
commit 069153a396
4 changed files with 498 additions and 1 deletions

View File

@ -0,0 +1,327 @@
From 23af112f5556d6a785c17e09f2422ac931405f61 Mon Sep 17 00:00:00 2001
From: Thomas Guillem <thomas@gllm.fr>
Date: Tue, 5 Apr 2022 15:46:03 +0200
Subject: [PATCH 1/1] lib: make curl_global_init() threadsafe when possible
Use a posix pthread or a Windows SRWLOCK to lock curl_global_init*() and
curl_global_cleanup().
Closes #8680
Conflict:update easy_lock.h to latest
Reference:https://github.com/curl/curl/commit/23af112f5556d6a785c17e09f2422ac931405f61
---
configure.ac | 2 ++
lib/Makefile.inc | 1 +
lib/easy.c | 52 +++++++++++++++++++++++++++++----
lib/easy_lock.h | 105 ++++++++++++++++++++++++++++++++++++++++++++
m4/curl-functions.m4 | 23 +++++++++++++++
5 files changed, 178 insertions(+), 5 deletions(-)
create mode 100644 lib/easy_lock.h
diff --git a/configure.ac b/configure.ac
index 3910ec631..009f32c32 100644
--- a/configure.ac
+++ b/configure.ac
@@ -118,6 +118,7 @@ AC_SUBST(libext)
dnl figure out the libcurl version
CURLVERSION=`$SED -ne 's/^#define LIBCURL_VERSION "\(.*\)".*/\1/p' ${srcdir}/include/curl/curlver.h`
XC_CHECK_PROG_CC
+CURL_ATOMIC
dnl for --enable-code-coverage
CURL_COVERAGE
@@ -3444,6 +3445,7 @@ AC_CHECK_FUNCS([fnmatch \
if_nametoindex \
mach_absolute_time \
pipe \
+ sched_yield \
setlocale \
setmode \
setrlimit \
diff --git a/lib/Makefile.inc b/lib/Makefile.inc
index 1ab007896..f756515d6 100644
--- a/lib/Makefile.inc
+++ b/lib/Makefile.inc
@@ -262,6 +262,7 @@ LIB_HFILES = \
doh.h \
dotdot.h \
dynbuf.h \
+ easy_lock.h \
easyif.h \
easyoptions.h \
escape.h \
diff --git a/lib/easy.c b/lib/easy.c
index 336cada87..7781c8e16 100644
--- a/lib/easy.c
+++ b/lib/easy.c
@@ -84,11 +84,25 @@
#include "curl_printf.h"
#include "curl_memory.h"
#include "memdebug.h"
+#include "easy_lock.h"
/* true globals -- for curl_global_init() and curl_global_cleanup() */
static unsigned int initialized;
static long init_flags;
+#ifdef GLOBAL_INIT_IS_THREADSAFE
+
+static curl_simple_lock s_lock = CURL_SIMPLE_LOCK_INIT;
+#define global_init_lock() curl_simple_lock_lock(&s_lock)
+#define global_init_unlock() curl_simple_lock_unlock(&s_lock)
+
+#else
+
+#define global_init_lock()
+#define global_init_unlock()
+
+#endif
+
/*
* strdup (and other memory functions) is redefined in complicated
* ways, but at this point it must be defined as the system-supplied strdup
@@ -207,7 +221,14 @@ static CURLcode global_init(long flags, bool memoryfuncs)
*/
CURLcode curl_global_init(long flags)
{
- return global_init(flags, TRUE);
+ CURLcode result;
+ global_init_lock();
+
+ result = global_init(flags, TRUE);
+
+ global_init_unlock();
+
+ return result;
}
/*
@@ -218,15 +239,20 @@ CURLcode curl_global_init_mem(long flags, curl_malloc_callback m,
curl_free_callback f, curl_realloc_callback r,
curl_strdup_callback s, curl_calloc_callback c)
{
+ CURLcode result;
+
/* Invalid input, return immediately */
if(!m || !f || !r || !s || !c)
return CURLE_FAILED_INIT;
+ global_init_lock();
+
if(initialized) {
/* Already initialized, don't do it again, but bump the variable anyway to
work like curl_global_init() and require the same amount of cleanup
calls. */
initialized++;
+ global_init_unlock();
return CURLE_OK;
}
@@ -239,7 +265,11 @@ CURLcode curl_global_init_mem(long flags, curl_malloc_callback m,
Curl_ccalloc = c;
/* Call the actual init function, but without setting */
- return global_init(flags, FALSE);
+ result = global_init(flags, FALSE);
+
+ global_init_unlock();
+
+ return result;
}
/**
@@ -248,11 +278,17 @@ CURLcode curl_global_init_mem(long flags, curl_malloc_callback m,
*/
void curl_global_cleanup(void)
{
- if(!initialized)
+ global_init_lock();
+
+ if(!initialized) {
+ global_init_unlock();
return;
+ }
- if(--initialized)
+ if(--initialized) {
+ global_init_unlock();
return;
+ }
Curl_ssl_cleanup();
Curl_resolver_global_cleanup();
@@ -273,6 +309,8 @@ void curl_global_cleanup(void)
#endif
init_flags = 0;
+
+ global_init_unlock();
}
/*
@@ -285,14 +323,18 @@ struct Curl_easy *curl_easy_init(void)
struct Curl_easy *data;
/* Make sure we inited the global SSL stuff */
+ global_init_lock();
+
if(!initialized) {
- result = curl_global_init(CURL_GLOBAL_DEFAULT);
+ result = global_init(CURL_GLOBAL_DEFAULT, TRUE);
if(result) {
/* something in the global init failed, return nothing */
DEBUGF(fprintf(stderr, "Error: curl_global_init failed\n"));
+ global_init_unlock();
return NULL;
}
}
+ global_init_unlock();
/* We use curl_open() with undefined URL so far */
result = Curl_open(&data);
diff --git a/lib/easy_lock.h b/lib/easy_lock.h
new file mode 100644
index 000000000..41627c4d4
--- /dev/null
+++ b/lib/easy_lock.h
@@ -0,0 +1,105 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ * SPDX-License-Identifier: curl
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#define GLOBAL_INIT_IS_THREADSAFE
+
+#if defined(_WIN32_WINNT) && _WIN32_WINNT >= 0x600
+
+#ifdef __MINGW32__
+#ifndef __MINGW64_VERSION_MAJOR
+#if (__MINGW32_MAJOR_VERSION < 5) || \
+ (__MINGW32_MAJOR_VERSION == 5 && __MINGW32_MINOR_VERSION == 0)
+/* mingw >= 5.0.1 defines SRWLOCK, and slightly different from MS define */
+typedef PVOID SRWLOCK, *PSRWLOCK;
+#endif
+#endif
+#ifndef SRWLOCK_INIT
+#define SRWLOCK_INIT NULL
+#endif
+#endif /* __MINGW32__ */
+
+#define curl_simple_lock SRWLOCK
+#define CURL_SIMPLE_LOCK_INIT SRWLOCK_INIT
+
+#define curl_simple_lock_lock(m) AcquireSRWLockExclusive(m)
+#define curl_simple_lock_unlock(m) ReleaseSRWLockExclusive(m)
+
+#elif defined(HAVE_ATOMIC) && defined(HAVE_STDATOMIC_H)
+#include <stdatomic.h>
+#if defined(HAVE_SCHED_YIELD)
+#include <sched.h>
+#endif
+
+#define curl_simple_lock atomic_int
+#define CURL_SIMPLE_LOCK_INIT 0
+
+/* a clang-thing */
+#ifndef __has_builtin
+#define __has_builtin(x) 0
+#endif
+
+#ifndef __INTEL_COMPILER
+/* The Intel compiler tries to look like GCC *and* clang *and* lies in its
+ __has_builtin() function, so override it. */
+
+/* if GCC on i386/x86_64 or if the built-in is present */
+#if ( (defined(__GNUC__) && !defined(__clang__)) && \
+ (defined(__i386__) || defined(__x86_64__))) || \
+ __has_builtin(__builtin_ia32_pause)
+#define HAVE_BUILTIN_IA32_PAUSE
+#endif
+
+#endif
+
+static inline void curl_simple_lock_lock(curl_simple_lock *lock)
+{
+ for(;;) {
+ if(!atomic_exchange_explicit(lock, true, memory_order_acquire))
+ break;
+ /* Reduce cache coherency traffic */
+ while(atomic_load_explicit(lock, memory_order_relaxed)) {
+ /* Reduce load (not mandatory) */
+#ifdef HAVE_BUILTIN_IA32_PAUSE
+ __builtin_ia32_pause();
+#elif defined(__aarch64__)
+ __asm__ volatile("yield" ::: "memory");
+#elif defined(HAVE_SCHED_YIELD)
+ sched_yield();
+#endif
+ }
+ }
+}
+
+static inline void curl_simple_lock_unlock(curl_simple_lock *lock)
+{
+ atomic_store_explicit(lock, false, memory_order_release);
+}
+
+#else
+
+#undef GLOBAL_INIT_IS_THREADSAFE
+
+#endif
diff --git a/m4/curl-functions.m4 b/m4/curl-functions.m4
index b40d42798..eb85dce4a 100644
--- a/m4/curl-functions.m4
+++ b/m4/curl-functions.m4
@@ -6566,3 +6566,26 @@ AC_DEFUN([CURL_COVERAGE],[
LIBS="$LIBS -lgcov"
fi
])
+
+dnl CURL_ATOMIC
+dnl --------------------------------------------------
+dnl Check if _Atomic works
+dnl
+AC_DEFUN([CURL_ATOMIC],[
+ AC_MSG_CHECKING([if _Atomic is available])
+ AC_COMPILE_IFELSE([
+ AC_LANG_PROGRAM([[
+ $curl_includes_unistd
+ ]],[[
+ _Atomic int i = 0;
+ ]])
+ ],[
+ AC_MSG_RESULT([yes])
+ AC_DEFINE_UNQUOTED(HAVE_ATOMIC, 1,
+ [Define to 1 if you have _Atomic support.])
+ tst_atomic="yes"
+ ],[
+ AC_MSG_RESULT([no])
+ tst_atomic="no"
+ ])
+])
--
2.33.0

View File

@ -0,0 +1,82 @@
From 13718030ad4b3209a7583b4f27f683cd3a6fa5f2 Mon Sep 17 00:00:00 2001
From: Harry Sintonen <sintonen@iki.fi>
Date: Tue, 25 Apr 2023 09:22:26 +0200
Subject: [PATCH] hostip: add locks around use of global buffer for alarm()
When building with the sync name resolver and timeout ability we now
require thread-safety to be present to enable it.
Closes #11030
Conflict:NA
Reference:https://github.com/curl/curl/commit/13718030ad4b3209a7583b
---
lib/hostip.c | 19 +++++++++++++++----
1 file changed, 15 insertions(+), 4 deletions(-)
diff --git a/lib/hostip.c b/lib/hostip.c
index 2381290fdd43e..e410cda69ae6e 100644
--- a/lib/hostip.c
+++ b/lib/hostip.c
@@ -70,12 +70,19 @@
#include <SystemConfiguration/SCDynamicStoreCopySpecific.h>
#endif
-#if defined(CURLRES_SYNCH) && \
- defined(HAVE_ALARM) && defined(SIGALRM) && defined(HAVE_SIGSETJMP)
+#if defined(CURLRES_SYNCH) && \
+ defined(HAVE_ALARM) && \
+ defined(SIGALRM) && \
+ defined(HAVE_SIGSETJMP) && \
+ defined(GLOBAL_INIT_IS_THREADSAFE)
/* alarm-based timeouts can only be used with all the dependencies satisfied */
#define USE_ALARM_TIMEOUT
#endif
+#ifdef USE_ALARM_TIMEOUT
+#include "easy_lock.h"
+#endif
+
#define MAX_HOSTCACHE_LEN (255 + 7) /* max FQDN + colon + port number + zero */
/*
@@ -254,11 +261,12 @@ void Curl_hostcache_prune(struct Curl_easy *data)
Curl_share_unlock(data, CURL_LOCK_DATA_DNS);
}
-#ifdef HAVE_SIGSETJMP
+#ifdef USE_ALARM_TIMEOUT
/* Beware this is a global and unique instance. This is used to store the
return address that we can jump back to from inside a signal handler. This
is not thread-safe stuff. */
sigjmp_buf curl_jmpenv;
+curl_simple_lock curl_jmpenv_lock;
#endif
/* lookup address, returns entry if found and not stale */
@@ -832,7 +840,6 @@ enum resolve_t Curl_resolv(struct Curl_easy *data,
static
void alarmfunc(int sig)
{
- /* this is for "-ansi -Wall -pedantic" to stop complaining! (rabe) */
(void)sig;
siglongjmp(curl_jmpenv, 1);
}
@@ -912,6 +919,8 @@ enum resolve_t Curl_resolv_timeout(struct Curl_easy *data,
This should be the last thing we do before calling Curl_resolv(),
as otherwise we'd have to worry about variables that get modified
before we invoke Curl_resolv() (and thus use "volatile"). */
+ curl_simple_lock_lock(&curl_jmpenv_lock);
+
if(sigsetjmp(curl_jmpenv, 1)) {
/* this is coming from a siglongjmp() after an alarm signal */
failf(data, "name lookup timed out");
@@ -980,6 +989,8 @@ enum resolve_t Curl_resolv_timeout(struct Curl_easy *data,
#endif
#endif /* HAVE_SIGACTION */
+ curl_simple_lock_unlock(&curl_jmpenv_lock);
+
/* switch back the alarm() to either zero or to what it was before minus
the time we spent until now! */
if(prev_alarm) {

View File

@ -0,0 +1,79 @@
From f446258f0269a62289cca0210157cb8558d0edc3 Mon Sep 17 00:00:00 2001
From: Daniel Stenberg <daniel@haxx.se>
Date: Tue, 16 May 2023 23:40:42 +0200
Subject: [PATCH 1/1] hostip: include easy_lock.h before using
GLOBAL_INIT_IS_THREADSAFE
Since that header file is the only place that define can be defined.
Reported-by: Marc Deslauriers
Follow-up to 13718030ad4b3209
Closes #11121
Conflict:context adapt
Reference:https://github.com/curl/curl/commit/f446258f0269a62289cca0210157cb8558d0edc3
---
lib/hostip.c | 10 ++++------
lib/hostip.h | 9 ---------
2 files changed, 4 insertions(+), 15 deletions(-)
diff --git a/lib/hostip.c b/lib/hostip.c
index 615f36c16..4ff348436 100644
--- a/lib/hostip.c
+++ b/lib/hostip.c
@@ -70,6 +70,8 @@
#include <SystemConfiguration/SCDynamicStoreCopySpecific.h>
#endif
+#include "easy_lock.h"
+
#if defined(CURLRES_SYNCH) && \
defined(HAVE_ALARM) && \
defined(SIGALRM) && \
@@ -79,10 +81,6 @@
#define USE_ALARM_TIMEOUT
#endif
-#ifdef USE_ALARM_TIMEOUT
-#include "easy_lock.h"
-#endif
-
#define MAX_HOSTCACHE_LEN (255 + 7) /* max FQDN + colon + port number + zero */
/*
@@ -289,8 +287,8 @@ void Curl_hostcache_prune(struct Curl_easy *data)
/* Beware this is a global and unique instance. This is used to store the
return address that we can jump back to from inside a signal handler. This
is not thread-safe stuff. */
-sigjmp_buf curl_jmpenv;
-curl_simple_lock curl_jmpenv_lock;
+static sigjmp_buf curl_jmpenv;
+static curl_simple_lock curl_jmpenv_lock;
#endif
/* lookup address, returns entry if found and not stale */
diff --git a/lib/hostip.h b/lib/hostip.h
index 4b5481f65..0dd19e87c 100644
--- a/lib/hostip.h
+++ b/lib/hostip.h
@@ -186,15 +186,6 @@ Curl_cache_addr(struct Curl_easy *data, struct Curl_addrinfo *addr,
#define CURL_INADDR_NONE INADDR_NONE
#endif
-#ifdef HAVE_SIGSETJMP
-/* Forward-declaration of variable defined in hostip.c. Beware this
- * is a global and unique instance. This is used to store the return
- * address that we can jump back to from inside a signal handler.
- * This is not thread-safe stuff.
- */
-extern sigjmp_buf curl_jmpenv;
-#endif
-
/*
* Function provided by the resolver backend to set DNS servers to use.
*/
--
2.33.0

View File

@ -6,7 +6,7 @@
Name: curl
Version: 7.79.1
Release: 17
Release: 18
Summary: Curl is used in command lines or scripts to transfer data
License: MIT
URL: https://curl.haxx.se/
@ -50,6 +50,9 @@ Patch35: backport-CVE-2023-27535.patch
Patch36: backport-after-CVE-2022-32207-to-fix-build-error-when-user-don-t-use-glibc.patch
Patch37: backport-CVE-2023-28321.patch
Patch38: backport-CVE-2023-28322.patch
Patch39: backport-0001-CVE-2023-28320.patch
Patch40: backport-0002-CVE-2023-28320.patch
Patch41: backport-0003-CVE-2023-28320.patch
BuildRequires: automake brotli-devel coreutils gcc groff krb5-devel
BuildRequires: libidn2-devel libnghttp2-devel libpsl-devel
@ -224,6 +227,12 @@ rm -rf ${RPM_BUILD_ROOT}%{_libdir}/libcurl.la
%{_mandir}/man3/*
%changelog
* Thu Jun 08 2023 xingwei <xingwei14@h-partners.com> - 7.79.1-18
- Type:CVE
- CVE:CVE-2023-28320
- SUG:NA
- DESC:fix CVE-2023-28320
* Wed May 24 2023 xingwei <xingwei14@h-partners.com> - 7.79.1-17
- Type:CVE
- CVE:CVE-2023-28321,CVE-2023-28322