Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
home:varkoly:branches:server:mail
cyrus-imapd
cyrus-imapd-2.5.17-fix-cve-2021-33582.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File cyrus-imapd-2.5.17-fix-cve-2021-33582.patch of Package cyrus-imapd
From ae5262cb335be9c2790a6e97e01ebce0fdf633f0 Mon Sep 17 00:00:00 2001 From: Robert Stepanek <rsto@fastmailteam.com> Date: Mon, 14 Oct 2019 17:43:18 +0200 Subject: [PATCH 1/5] hash: gracefully handle lookup on zero-sized tables --- lib/hash.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/lib/hash.c b/lib/hash.c index 5aef64c8c5..ff64653016 100644 --- a/lib/hash.c +++ b/lib/hash.c @@ -153,9 +153,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(key) % table->size; + if (!(table->table)[val]) return NULL; From 63c711047c281f25e1dfb98abe488e80475f85ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=94=D0=B8=D0=BB=D1=8F=D0=BD=20=D0=9F=D0=B0=D0=BB=D0=B0?= =?UTF-8?q?=D1=83=D0=B7=D0=BE=D0=B2?= <git-dpa@aegee.org> Date: Tue, 29 Sep 2020 22:15:18 +0300 Subject: [PATCH 2/5] hash.c:hash_del: deduplicate code --- lib/hash.c | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/lib/hash.c b/lib/hash.c index ff64653016..1c77e80f98 100644 --- a/lib/hash.c +++ b/lib/hash.c @@ -184,7 +184,6 @@ EXPORTED void *hash_lookup(const char *key, hash_table *table) EXPORTED void *hash_del(const char *key, hash_table *table) { unsigned val = strhash(key) % table->size; - void *data; bucket *ptr, *last = NULL; if (!(table->table)[val]) @@ -205,15 +204,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; } /* @@ -226,15 +220,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 (cmpresult < 0) { /* its not here! */ return NULL; } From 1ebd8ae4d537c7397a81797c9f050cfa9d1066b8 Mon Sep 17 00:00:00 2001 From: ellie timoney <ellie@fastmail.com> Date: Wed, 19 May 2021 13:39:34 +1000 Subject: [PATCH 3/5] strhash: replace ad-hoc algorithm with seeded djb2 Part of CVE-2021-33582 --- lib/strhash.c | 37 ++++++++++++++++++++++++++----------- lib/strhash.h | 6 +++++- 2 files changed, 31 insertions(+), 12 deletions(-) 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; + + 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; - while (*string) - { - i = (int) *string; - ret_val ^= i; - ret_val <<= 1; - string ++; - } - return ret_val; + 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 <stdint.h> -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_ */ From b4510ba7eb8d2c7a78a5be36f1c6feed76c61101 Mon Sep 17 00:00:00 2001 From: ellie timoney <ellie@fastmail.com> Date: Wed, 19 May 2021 14:01:41 +1000 Subject: [PATCH 4/5] hash: use a seed when hashing Part of CVE-2021-33582 --- lib/hash.c | 9 ++++++--- lib/hash.h | 4 +++- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/lib/hash.c b/lib/hash.c index 1c77e80f98..7e5fe8aaac 100644 --- a/lib/hash.c +++ b/lib/hash.c @@ -44,6 +44,9 @@ EXPORTED hash_table *construct_hash_table(hash_table *table, size_t size, int us assert(size); table->size = size; + do { + table->seed = rand(); + } while (table->seed == 0); /* Allocate the table -- different for using memory pools and not */ if(use_mpool) { @@ -72,7 +75,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; @@ -159,7 +162,7 @@ EXPORTED void *hash_lookup(const char *key, hash_table *table) if (!table->size) return NULL; - val = strhash(key) % table->size; + val = strhash_seeded(table->seed, key) % table->size; if (!(table->table)[val]) return NULL; @@ -183,7 +186,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; + unsigned val = strhash_seeded(table->seed, key) % table->size; bucket *ptr, *last = NULL; if (!(table->table)[val]) diff --git a/lib/hash.h b/lib/hash.h index 2631f959ee..400aeb296b 100644 --- a/lib/hash.h +++ b/lib/hash.h @@ -3,9 +3,10 @@ #define HASH__H #include <stddef.h> /* For size_t */ +#include <stdint.h> #include "mpool.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 @@ -31,6 +32,7 @@ typedef struct bucket { typedef struct hash_table { size_t size; + uint32_t seed; bucket **table; struct mpool *pool; } hash_table; From 79273ca94248eb7696ab71bac4ec46d91359bb09 Mon Sep 17 00:00:00 2001 From: ellie timoney <ellie@fastmail.com> Date: Fri, 2 Jul 2021 10:34:20 +1000 Subject: [PATCH 5/5] hash: it's okay for seed to be zero sometimes randomly not seeding is not any more predictable than any individual random seed, and allowing it to be zero saves us having to deal with preventing zeroes. --- lib/hash.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/lib/hash.c b/lib/hash.c index 7e5fe8aaac..c6186d4c2a 100644 --- a/lib/hash.c +++ b/lib/hash.c @@ -44,9 +44,7 @@ EXPORTED hash_table *construct_hash_table(hash_table *table, size_t size, int us assert(size); table->size = size; - do { - table->seed = rand(); - } while (table->seed == 0); + table->seed = rand(); /* might be zero, that's okay */ /* Allocate the table -- different for using memory pools and not */ if(use_mpool) {
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor