From 0e043244684bccfc35a1649630bccd162cf0720e Mon Sep 17 00:00:00 2001 From: CentOS Sources Date: Sep 03 2021 04:19:13 +0000 Subject: import cyrus-imapd-3.0.7-23.el8 --- diff --git a/SOURCES/cyrus-imapd-3.0-CVE-2021-33582.patch b/SOURCES/cyrus-imapd-3.0-CVE-2021-33582.patch new file mode 100644 index 0000000..aa5c3ba --- /dev/null +++ b/SOURCES/cyrus-imapd-3.0-CVE-2021-33582.patch @@ -0,0 +1,205 @@ +diff --git a/imap/http_dav.c b/imap/http_dav.c +index 91bbc28b6b..a6fa5c8345 100644 +--- a/imap/http_dav.c ++++ b/imap/http_dav.c +@@ -5494,7 +5494,7 @@ EXPORTED int meth_propfind(struct transaction_t *txn, void *params) + xmlDocPtr indoc = NULL, outdoc = NULL; + xmlNodePtr root, cur = NULL, props = NULL; + xmlNsPtr ns[NUM_NAMESPACE]; +- struct hash_table ns_table = { 0, NULL, NULL }; ++ struct hash_table ns_table = HASH_TABLE_INITIALIZER; + struct propfind_ctx fctx; + struct propfind_entry_list *elist = NULL; + +@@ -7900,7 +7900,7 @@ int meth_report(struct transaction_t *txn, void *params) + xmlNodePtr inroot = NULL, outroot = NULL, cur, prop = NULL, props = NULL; + const struct report_type_t *report = NULL; + xmlNsPtr ns[NUM_NAMESPACE]; +- struct hash_table ns_table = { 0, NULL, NULL }; ++ struct hash_table ns_table = HASH_TABLE_INITIALIZER; + struct propfind_ctx fctx; + struct propfind_entry_list *elist = NULL; + +diff --git a/lib/hash.c b/lib/hash.c +index 9703142c3b..84f2e80d28 100644 +--- a/lib/hash.c ++++ b/lib/hash.c +@@ -43,10 +43,11 @@ EXPORTED hash_table *construct_hash_table(hash_table *table, size_t size, int us + assert(table); + assert(size); + +- table->size = size; ++ table->size = size; ++ table->seed = rand(); /* might be zero, that's okay */ + + /* Allocate the table -- different for using memory pools and not */ +- if(use_mpool) { ++ if (use_mpool) { + /* Allocate an initial memory pool for 32 byte keys + the hash table + * + the buckets themselves */ + table->pool = +@@ -72,7 +73,7 @@ EXPORTED hash_table *construct_hash_table(hash_table *table, size_t size, int us + + EXPORTED void *hash_insert(const char *key, void *data, hash_table *table) + { +- unsigned val = strhash(key) % table->size; ++ unsigned val = strhash_seeded(table->seed, key) % table->size; + bucket *ptr, *newptr; + bucket **prev; + +@@ -153,9 +154,14 @@ EXPORTED void *hash_insert(const char *key, void *data, hash_table *table) + + EXPORTED void *hash_lookup(const char *key, hash_table *table) + { +- unsigned val = strhash(key) % table->size; ++ unsigned val; + bucket *ptr; + ++ if (!table->size) ++ return NULL; ++ ++ val = strhash_seeded(table->seed, key) % table->size; ++ + if (!(table->table)[val]) + return NULL; + +@@ -178,8 +184,7 @@ EXPORTED void *hash_lookup(const char *key, hash_table *table) + * since it will leak memory until you get rid of the entire hash table */ + EXPORTED void *hash_del(const char *key, hash_table *table) + { +- unsigned val = strhash(key) % table->size; +- void *data; ++ unsigned val = strhash_seeded(table->seed, key) % table->size; + bucket *ptr, *last = NULL; + + if (!(table->table)[val]) +@@ -200,15 +205,10 @@ EXPORTED void *hash_del(const char *key, hash_table *table) + int cmpresult = strcmp(key, ptr->key); + if (!cmpresult) + { ++ void *data = ptr->data; + if (last != NULL ) + { +- data = ptr -> data; + last -> next = ptr -> next; +- if(!table->pool) { +- free(ptr->key); +- free(ptr); +- } +- return data; + } + + /* +@@ -221,15 +221,15 @@ EXPORTED void *hash_del(const char *key, hash_table *table) + + else + { +- data = ptr->data; + (table->table)[val] = ptr->next; +- if(!table->pool) { +- free(ptr->key); +- free(ptr); +- } +- return data; + } +- } else if (cmpresult < 0) { ++ if(!table->pool) { ++ free(ptr->key); ++ free(ptr); ++ } ++ return data; ++ } ++ if (cmpresult < 0) { + /* its not here! */ + return NULL; + } +diff --git a/lib/hash.h b/lib/hash.h +index 8051ac1760..cfa7da1ffa 100644 +--- a/lib/hash.h ++++ b/lib/hash.h +@@ -3,10 +3,11 @@ + #define HASH__H + + #include /* For size_t */ ++#include + #include "mpool.h" + #include "strarray.h" + +-#define HASH_TABLE_INITIALIZER {0, NULL, NULL} ++#define HASH_TABLE_INITIALIZER {0, 0, NULL, NULL} + + /* + ** A hash table consists of an array of these buckets. Each bucket +@@ -32,6 +33,7 @@ typedef struct bucket { + + typedef struct hash_table { + size_t size; ++ uint32_t seed; + bucket **table; + struct mpool *pool; + } hash_table; +diff --git a/lib/strhash.c b/lib/strhash.c +index d7c1741d2a..1b3251db73 100644 +--- a/lib/strhash.c ++++ b/lib/strhash.c +@@ -42,17 +42,32 @@ + + #include "config.h" + +-EXPORTED unsigned strhash(const char *string) ++#include "lib/strhash.h" ++ ++/* The well-known djb2 algorithm (e.g. http://www.cse.yorku.ca/~oz/hash.html), ++ * with the addition of an optional seed to limit predictability. ++ * ++ * XXX return type 'unsigned' for back-compat to previous version, but ++ * XXX ought to be 'uint32_t' ++ */ ++EXPORTED unsigned strhash_seeded_djb2(uint32_t seed, const char *string) + { +- unsigned ret_val = 0; +- int i; ++ const unsigned char *ustr = (const unsigned char *) string; ++ unsigned hash = 5381; ++ int c; + +- while (*string) +- { +- i = (int) *string; +- ret_val ^= i; +- ret_val <<= 1; +- string ++; +- } +- return ret_val; ++ if (seed) { ++ /* treat the bytes of the seed as a prefix to the string */ ++ unsigned i; ++ for (i = 0; i < sizeof seed; i++) { ++ c = seed & 0xff; ++ hash = ((hash << 5) + hash) ^ c; ++ seed >>= 8; ++ } ++ } ++ ++ while ((c = *ustr++)) ++ hash = ((hash << 5) + hash) ^ c; ++ ++ return hash; + } +diff --git a/lib/strhash.h b/lib/strhash.h +index 34533fdffa..27339bb288 100644 +--- a/lib/strhash.h ++++ b/lib/strhash.h +@@ -41,7 +41,11 @@ + */ + + #ifndef _STRHASH_H_ ++#include + +-unsigned strhash(const char *string); ++unsigned strhash_seeded_djb2(uint32_t seed, const char *string); ++ ++#define strhash(in) strhash_seeded_djb2((0), (in)) ++#define strhash_seeded(sd, in) strhash_seeded_djb2((sd), (in)) + + #endif /* _STRHASH_H_ */ diff --git a/SPECS/cyrus-imapd.spec b/SPECS/cyrus-imapd.spec index 1d62bae..40a3718 100644 --- a/SPECS/cyrus-imapd.spec +++ b/SPECS/cyrus-imapd.spec @@ -9,7 +9,7 @@ Name: cyrus-imapd Version: 3.0.7 -Release: 22%{?dist} +Release: 23%{?dist} %define ssl_pem_file_prefix /etc/pki/%name/%name @@ -47,6 +47,7 @@ Patch8: cyrus-imapd-cve_2019_11356.patch Patch9: cyrus-imapd-CVE-2019-19783.patch Patch10: cyrus-imapd-CVE-2019-18928.patch Patch11: cyrus-imapd-use_system_ciphers.patch +Patch12: cyrus-imapd-3.0-CVE-2021-33582.patch Source10: cyrus-imapd.logrotate Source11: cyrus-imapd.pam-config @@ -90,16 +91,12 @@ Source92: patch-cassandane-fix-annotator Source93: cyrus-imapd-master_rename.patch - BuildRequires: autoconf automake bison flex gcc gcc-c++ git groff libtool BuildRequires: pkgconfig systemd transfig BuildRequires: perl-devel perl-generators perl(ExtUtils::MakeMaker) BuildRequires: perl(Pod::Html) -%if 0%{?fedora} && 0%{?fedora} >= 0 -BuildRequires: clamav-devel shapelib-devel -%endif BuildRequires: CUnit-devel cyrus-sasl-devel glib2-devel BuildRequires: jansson-devel krb5-devel libical-devel libicu-devel BuildRequires: libnghttp2-devel libxml2-devel mariadb-devel net-snmp-devel @@ -475,6 +472,10 @@ find %buildroot -name ".packlist" -exec rm {} \; imaptest -h 2>&1 > /dev/null || (echo "Imaptest is not functional" && exit 1) make %{?_smp_mflags} check || exit 1 +%ifarch ppc64le %ix86 +exit 0 +%endif + %if %{without cassandane} exit 0 %endif @@ -530,6 +531,9 @@ tests=( # This one needs a patch to xapian. # https://github.com/cyrusimap/cyrus-imapd/issues/2348 SearchFuzzy.search_subjectsnippet + + # this one is not working on builder machines + Conversations.xconvfetch ) for i in ${tests[@]}; do exclude+=("!$i"); done @@ -681,6 +685,11 @@ getent passwd cyrus >/dev/null || /usr/sbin/useradd -c "Cyrus IMAP Server" -d /v %changelog +* Wed Sep 01 2021 Tomas Korbar - 3.0.7-23 +- Fix CVE-2021-33582 +- Also disable unstable test +- Resolves: CVE-2021-33582 + * Thu May 27 2021 Pavel Zhukov - 3.0.7-22 - rebuild with xapian support