From 47ec109fcece3cf605dc3ee557b9be8f8fc81641 Mon Sep 17 00:00:00 2001 From: k4be Date: Fri, 16 Jul 2021 22:58:23 +0200 Subject: [PATCH] Fix crash on /REHASH with exceptionally large number of client capabilities loaded. --- src/api-clicap.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/api-clicap.c b/src/api-clicap.c index e004fb9b7..69fff7437 100644 --- a/src/api-clicap.c +++ b/src/api-clicap.c @@ -263,7 +263,12 @@ void unload_all_unused_caps(void) } } -#define MAXCLICAPS 64 +#define ADVERTISEONLYCAPS 16 +/* Advertise only caps are not counted anywhere, this only provides space in rehash temporary storage arrays. + * If exceeded, the caps just won't be stored and will be re-added safely. --k4be + */ + +#define MAXCLICAPS ((int)(sizeof(long)*8 - 1 + ADVERTISEONLYCAPS)) /* how many cap bits will fit in `long`? */ static char *old_caps[MAXCLICAPS]; /**< List of old CAP names - used for /rehash */ int old_caps_proto[MAXCLICAPS]; /**< List of old CAP protocol values - used for /rehash */ @@ -324,7 +329,7 @@ void clicap_post_rehash(void) /* Let's deal with CAP DEL first: * Go through the old caps and see what's missing now. */ - for (i = 0; old_caps[i]; i++) + for (i = 0; i < MAXCLICAPS && old_caps[i]; i++) { name = old_caps[i]; found = 0; @@ -351,7 +356,7 @@ void clicap_post_rehash(void) { name = clicap->name; found = 0; - for (i = 0; old_caps[i]; i++) + for (i = 0; i < MAXCLICAPS && old_caps[i]; i++) { if (!strcmp(old_caps[i], name)) { @@ -368,6 +373,6 @@ void clicap_post_rehash(void) } /* Now free the old caps. */ - for (i = 0; old_caps[i]; i++) + for (i = 0; i < MAXCLICAPS && old_caps[i]; i++) safe_free(old_caps[i]); }