diff --git a/libical-3.0.3-load-builtin-timezone.patch b/libical-3.0.3-load-builtin-timezone.patch new file mode 100644 index 0000000..c7b654d --- /dev/null +++ b/libical-3.0.3-load-builtin-timezone.patch @@ -0,0 +1,110 @@ +From e5f3df8ab02574d7edcce9ceef4622569edb6f92 Mon Sep 17 00:00:00 2001 +From: Milan Crha +Date: Thu, 3 Jan 2019 12:53:04 +0100 +Subject: [PATCH] Improve thread safety of icaltimezone_load_builtin_timezone() + +Even the function does test whether the passed-in zone has set +the component, it doesn't retest it when it acquires the lock, but +other thread could already assign the component, which can cause +use-after-free in certain thread interleaving. +--- + src/libical/icaltimezone.c | 6 ++++ + src/test/builtin_timezones.c | 54 ++++++++++++++++++++++++++++++++++++ + 2 files changed, 60 insertions(+) + +diff --git a/src/libical/icaltimezone.c b/src/libical/icaltimezone.c +index 12f6c291..3c4bf14d 100644 +--- a/src/libical/icaltimezone.c ++++ b/src/libical/icaltimezone.c +@@ -1806,6 +1806,12 @@ static void icaltimezone_load_builtin_timezone(icaltimezone *zone) + + icaltimezone_builtin_lock(); + ++ /* Try again, maybe it had been set by other thread while waiting for the lock */ ++ if (zone->component) { ++ icaltimezone_builtin_unlock(); ++ return; ++ } ++ + /* If the location isn't set, it isn't a builtin timezone. */ + if (!zone->location || !zone->location[0]) { + icaltimezone_builtin_unlock(); +diff --git a/src/test/builtin_timezones.c b/src/test/builtin_timezones.c +index c2d36845..b0e472cb 100644 +--- a/src/test/builtin_timezones.c ++++ b/src/test/builtin_timezones.c +@@ -20,10 +20,60 @@ + #include + #endif + ++#ifdef HAVE_PTHREAD_H ++#include ++#include ++#endif ++ + #include "libical/ical.h" + + #include + ++#if defined(HAVE_PTHREAD_H) && defined(HAVE_PTHREAD) && defined(HAVE_PTHREAD_CREATE) ++ ++#define N_THREADS 20 ++ ++static const void *thread_comp = NULL; ++ ++static void * ++thread_func(void *user_data) ++{ ++ icaltimezone *zone = user_data; ++ icalcomponent *icalcomp; ++ ++ if(!zone) ++ return NULL; ++ ++ icalcomp = icaltimezone_get_component(zone); ++ if(!thread_comp) ++ thread_comp = icalcomp; ++ else ++ assert(thread_comp == icalcomp); ++ icalcomp = icalcomponent_new_clone(icalcomp); ++ icalcomponent_free(icalcomp); ++ ++ return NULL; ++} ++ ++static void ++test_get_component_threadsafety(void) ++{ ++ pthread_t thread[N_THREADS]; ++ icaltimezone *zone; ++ int ii; ++ ++ zone = icaltimezone_get_builtin_timezone("Europe/London"); ++ ++ for(ii = 0; ii < N_THREADS; ii++) { ++ pthread_create(&thread[ii], NULL, thread_func, zone); ++ } ++ ++ for(ii = 0; ii < N_THREADS; ii++) { ++ pthread_join(thread[ii], NULL); ++ } ++} ++#endif ++ + int main() + { + icalarray *builtin_timezones; +@@ -34,6 +84,10 @@ int main() + set_zone_directory("../../zoneinfo"); + icaltimezone_set_tzid_prefix("/softwarestudio.org/"); + ++ #if defined(HAVE_PTHREAD_H) && defined(HAVE_PTHREAD) && defined(HAVE_PTHREAD_CREATE) ++ test_get_component_threadsafety(); ++ #endif ++ + tt = icaltime_current_time_with_zone(icaltimezone_get_builtin_timezone("America/New_York")); + + tt.year = 2038; +-- +2.17.0 + diff --git a/libical.spec b/libical.spec index bd37210..fe5d05a 100644 --- a/libical.spec +++ b/libical.spec @@ -1,12 +1,13 @@ Summary: Reference implementation of the iCalendar data type and serialization format Name: libical Version: 3.0.3 -Release: 7%{?dist} +Release: 8%{?dist} License: LGPLv2 or MPLv2.0 URL: https://libical.github.io/libical/ Source: https://github.com/%{name}/%{name}/archive/v%{version}/%{name}-%{version}.tar.gz Patch01: libical-3.0.3-covscan.patch +Patch02: libical-3.0.3-load-builtin-timezone.patch BuildRequires: gcc BuildRequires: gcc-c++ @@ -64,6 +65,7 @@ Development files needed for building things which link against %{name}-glib. %setup -q %patch01 -p1 -b .covscan +%patch02 -p1 -b .load-builtin-timezone %build mkdir -p %{_target_platform} @@ -127,6 +129,9 @@ make test ARGS="-V" -C %{_target_platform} %{_datadir}/gtk-doc/html/%{name}-glib %changelog +* Thu Jan 03 2019 Milan Crha - 3.0.3-8 +- Add patch for Red Hat bug #1661501 (Improve thread safety of icaltimezone_load_builtin_timezone()) + * Thu Jul 19 2018 Milan Crha - 3.0.3-7 - Address a warning found by Coverity Scan