diff --git a/main/fontconfig/APKBUILD b/main/fontconfig/APKBUILD index f6793d45fdf8207a738ecbf6ef58a74efe2f62f8..523546fade3c7938afc9f6129f99499c8ee07e08 100644 --- a/main/fontconfig/APKBUILD +++ b/main/fontconfig/APKBUILD @@ -2,7 +2,7 @@ # Maintainer: Natanael Copa <ncopa@alpinelinux.org> pkgname=fontconfig pkgver=2.11.1 -pkgrel=1 +pkgrel=2 pkgdesc="The Fontconfig package is a library for configuring and customizing font access." url="http://fontconfig.org" arch="all" @@ -13,9 +13,16 @@ makedepends="$depends_dev zlib-dev" install= triggers="$pkgname.trigger=/usr/share/fonts/*" subpackages="$pkgname-doc $pkgname-dev" -source="http://fontconfig.org/release/${pkgname}-${pkgver}.tar.gz" +source="http://fontconfig.org/release/${pkgname}-${pkgver}.tar.gz + CVE-2016-5384.patch + " _builddir="$srcdir/$pkgname-$pkgver" + +# security fixes: +# 2.11.1-r2: +# - CVE-2016-5384 + prepare() { local i cd "$_builddir" @@ -48,6 +55,9 @@ package() { install -m644 -D COPYING "$pkgdir"/usr/share/licenses/"${pkgname}"/COPYING } -md5sums="e75e303b4f7756c2b16203a57ac87eba fontconfig-2.11.1.tar.gz" -sha256sums="b6b066c7dce3f436fdc0dfbae9d36122b38094f4f53bd8dffd45e195b0540d8d fontconfig-2.11.1.tar.gz" -sha512sums="a3eecb35a59c2f83e7fec1238ff288978643a1b2a2a7bff7b07bb62b2ccd48aa7a6b5b164472f019efd390e9eea5391313c070dcbd680a2e1227ea8ec125e28b fontconfig-2.11.1.tar.gz" +md5sums="e75e303b4f7756c2b16203a57ac87eba fontconfig-2.11.1.tar.gz +2a8da386a078ae02b0e28b9dbe83872a CVE-2016-5384.patch" +sha256sums="b6b066c7dce3f436fdc0dfbae9d36122b38094f4f53bd8dffd45e195b0540d8d fontconfig-2.11.1.tar.gz +291c2a0d7f007f4148eefcafe7f1e5ccabf1a56c2359bd09cddfd9ca3b564888 CVE-2016-5384.patch" +sha512sums="a3eecb35a59c2f83e7fec1238ff288978643a1b2a2a7bff7b07bb62b2ccd48aa7a6b5b164472f019efd390e9eea5391313c070dcbd680a2e1227ea8ec125e28b fontconfig-2.11.1.tar.gz +d3daba3bf74aa200d34a473f2703c40ca175868a3a3c689002afc4d58c129f69b36176fb9a3e082a57b6eb82d641d070a6bc1fb905ce569200a5886dff6143a4 CVE-2016-5384.patch" diff --git a/main/fontconfig/CVE-2016-5384.patch b/main/fontconfig/CVE-2016-5384.patch new file mode 100644 index 0000000000000000000000000000000000000000..75aa6c387b3f72009ee3520feba0986def22f659 --- /dev/null +++ b/main/fontconfig/CVE-2016-5384.patch @@ -0,0 +1,160 @@ +From 7a4a5bd7897d216f0794ca9dbce0a4a5c9d14940 Mon Sep 17 00:00:00 2001 +From: Tobias Stoeckmann <tobias@stoeckmann.org> +Date: Sat, 25 Jun 2016 19:18:53 +0200 +Subject: [PATCH] Properly validate offsets in cache files. + +The cache files are insufficiently validated. Even though the magic +number at the beginning of the file as well as time stamps are checked, +it is not verified if contained offsets are in legal ranges or are +even pointers. + +The lack of validation allows an attacker to trigger arbitrary free() +calls, which in turn allows double free attacks and therefore arbitrary +code execution. Due to the conversion from offsets into pointers through +macros, this even allows to circumvent ASLR protections. + +This attack vector allows privilege escalation when used with setuid +binaries like fbterm. A user can create ~/.fonts or any other +system-defined user-private font directory, run fc-cache and adjust +cache files in ~/.cache/fontconfig. The execution of setuid binaries will +scan these files and therefore are prone to attacks. + +If it's not about code execution, an endless loop can be created by +letting linked lists become circular linked lists. + +This patch verifies that: + +- The file is not larger than the maximum addressable space, which + basically only affects 32 bit systems. This allows out of boundary + access into unallocated memory. +- Offsets are always positive or zero +- Offsets do not point outside file boundaries +- No pointers are allowed in cache files, every "pointer or offset" + field must be an offset or NULL +- Iterating linked lists must not take longer than the amount of elements + specified. A violation of this rule can break a possible endless loop. + +If one or more of these points are violated, the cache is recreated. +This is current behaviour. + +Even though this patch fixes many issues, the use of mmap() shall be +forbidden in setuid binaries. It is impossible to guarantee with these +checks that a malicious user does not change cache files after +verification. This should be handled in a different patch. + +Signed-off-by: Tobias Stoeckmann <tobias@stoeckmann.org> +--- + src/fccache.c | 81 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- + 1 file changed, 80 insertions(+), 1 deletion(-) + +--- a/src/fccache.c ++++ b/src/fccache.c +@@ -27,6 +27,7 @@ + #include <fcntl.h> + #include <dirent.h> + #include <string.h> ++#include <limits.h> + #include <sys/types.h> + #include <assert.h> + #if defined(HAVE_MMAP) || defined(__CYGWIN__) +@@ -544,6 +545,82 @@ FcCacheTimeValid (FcCache *cache, struct + return cache->checksum == (int) dir_stat->st_mtime; + } + ++static FcBool ++FcCacheOffsetsValid (FcCache *cache) ++{ ++ char *base = (char *)cache; ++ char *end = base + cache->size; ++ intptr_t *dirs; ++ FcFontSet *fs; ++ int i, j; ++ ++ if (cache->dir < 0 || cache->dir > cache->size - sizeof (intptr_t) || ++ memchr (base + cache->dir, '\0', cache->size - cache->dir) == NULL) ++ return FcFalse; ++ ++ if (cache->dirs < 0 || cache->dirs >= cache->size || ++ cache->dirs_count < 0 || ++ cache->dirs_count > (cache->size - cache->dirs) / sizeof (intptr_t)) ++ return FcFalse; ++ ++ dirs = FcCacheDirs (cache); ++ if (dirs) ++ { ++ for (i = 0; i < cache->dirs_count; i++) ++ { ++ FcChar8 *dir; ++ ++ if (dirs[i] < 0 || ++ dirs[i] > end - (char *) dirs - sizeof (intptr_t)) ++ return FcFalse; ++ ++ dir = FcOffsetToPtr (dirs, dirs[i], FcChar8); ++ if (memchr (dir, '\0', end - (char *) dir) == NULL) ++ return FcFalse; ++ } ++ } ++ ++ if (cache->set < 0 || cache->set > cache->size - sizeof (FcFontSet)) ++ return FcFalse; ++ ++ fs = FcCacheSet (cache); ++ if (fs) ++ { ++ if (fs->nfont > (end - (char *) fs) / sizeof (FcPattern)) ++ return FcFalse; ++ ++ if (fs->fonts != 0 && !FcIsEncodedOffset(fs->fonts)) ++ return FcFalse; ++ ++ for (i = 0; i < fs->nfont; i++) ++ { ++ FcPattern *font = FcFontSetFont (fs, i); ++ FcPatternElt *e; ++ FcValueListPtr l; ++ ++ if ((char *) font < base || ++ (char *) font > end - sizeof (FcFontSet) || ++ font->elts_offset < 0 || ++ font->elts_offset > end - (char *) font || ++ font->num > (end - (char *) font - font->elts_offset) / sizeof (FcPatternElt)) ++ return FcFalse; ++ ++ ++ e = FcPatternElts(font); ++ if (e->values != 0 && !FcIsEncodedOffset(e->values)) ++ return FcFalse; ++ ++ for (j = font->num, l = FcPatternEltValues(e); j >= 0 && l; j--, l = FcValueListNext(l)) ++ if (l->next != NULL && !FcIsEncodedOffset(l->next)) ++ break; ++ if (j < 0) ++ return FcFalse; ++ } ++ } ++ ++ return FcTrue; ++} ++ + /* + * Map a cache file into memory + */ +@@ -553,7 +630,8 @@ FcDirCacheMapFd (int fd, struct stat *fd + FcCache *cache; + FcBool allocated = FcFalse; + +- if (fd_stat->st_size < (int) sizeof (FcCache)) ++ if (fd_stat->st_size > INTPTR_MAX || ++ fd_stat->st_size < (int) sizeof (FcCache)) + return NULL; + cache = FcCacheFindByStat (fd_stat); + if (cache) +@@ -609,6 +687,7 @@ FcDirCacheMapFd (int fd, struct stat *fd + if (cache->magic != FC_CACHE_MAGIC_MMAP || + cache->version < FC_CACHE_CONTENT_VERSION || + cache->size != (intptr_t) fd_stat->st_size || ++ !FcCacheOffsetsValid (cache) || + !FcCacheTimeValid (cache, dir_stat) || + !FcCacheInsert (cache, fd_stat)) + {