extb_combi: implement a recursion guard

This commit is contained in:
William Pitcock 2015-12-13 07:49:19 -06:00
parent 2d28539c68
commit d63f3f80f0

View file

@ -44,13 +44,14 @@
// #define DEBUG(s) sendto_realops_snomask(SNO_DEBUG, L_NETWIDE, (s)) // #define DEBUG(s) sendto_realops_snomask(SNO_DEBUG, L_NETWIDE, (s))
#define DEBUG(s) #define DEBUG(s)
#define RETURN_INVALID { recursion_depth--; return EXTBAN_INVALID; }
static int _modinit(void); static int _modinit(void);
static void _moddeinit(void); static void _moddeinit(void);
static int eb_or(const char *data, struct Client *client_p, struct Channel *chptr, long mode_type); static int eb_or(const char *data, struct Client *client_p, struct Channel *chptr, long mode_type);
static int eb_and(const char *data, struct Client *client_p, struct Channel *chptr, long mode_type); static int eb_and(const char *data, struct Client *client_p, struct Channel *chptr, long mode_type);
static int eb_combi(const char *data, struct Client *client_p, struct Channel *chptr, long mode_type, int is_and); static int eb_combi(const char *data, struct Client *client_p, struct Channel *chptr, long mode_type, int is_and);
static int recursion_depth = 0;
DECLARE_MODULE_AV1(extb_extended, _modinit, _moddeinit, NULL, NULL, NULL, "$Revision: 1 $"); DECLARE_MODULE_AV1(extb_extended, _modinit, _moddeinit, NULL, NULL, NULL, "$Revision: 1 $");
@ -89,6 +90,11 @@ static int eb_combi(const char *data, struct Client *client_p,
int have_result = FALSE; int have_result = FALSE;
size_t datalen; size_t datalen;
if (recursion_depth >= 5) {
DEBUG("combo invalid: recursion depth too high");
return EXTBAN_INVALID;
}
if (EmptyString(data)) { if (EmptyString(data)) {
DEBUG("combo invalid: empty data"); DEBUG("combo invalid: empty data");
return EXTBAN_INVALID; return EXTBAN_INVALID;
@ -131,6 +137,8 @@ static int eb_combi(const char *data, struct Client *client_p,
* so we always keep parsing even after we have determined a result. * so we always keep parsing even after we have determined a result.
*/ */
recursion_depth++;
while (TRUE) { while (TRUE) {
int invert = FALSE; int invert = FALSE;
char *child_data, child_data_buf[BANLEN]; char *child_data, child_data_buf[BANLEN];
@ -141,14 +149,14 @@ static int eb_combi(const char *data, struct Client *client_p,
p++; p++;
if (p == banend) { if (p == banend) {
DEBUG("combo invalid: no data after ~"); DEBUG("combo invalid: no data after ~");
return EXTBAN_INVALID; RETURN_INVALID;
} }
} }
f = extban_table[(unsigned char) *p++]; f = extban_table[(unsigned char) *p++];
if (!f) { if (!f) {
DEBUG("combo invalid: non-existant child extban"); DEBUG("combo invalid: non-existant child extban");
return EXTBAN_INVALID; RETURN_INVALID;
} }
if (*p == ':') { if (*p == ':') {
@ -166,7 +174,7 @@ static int eb_combi(const char *data, struct Client *client_p,
if (p == banend) { if (p == banend) {
if (parencount) { if (parencount) {
DEBUG("combo invalid: EOD while in parens"); DEBUG("combo invalid: EOD while in parens");
return EXTBAN_INVALID; RETURN_INVALID;
} }
break; break;
} }
@ -188,7 +196,7 @@ static int eb_combi(const char *data, struct Client *client_p,
case ')': case ')':
if (!parencount) { if (!parencount) {
DEBUG("combo invalid: negative parencount"); DEBUG("combo invalid: negative parencount");
return EXTBAN_INVALID; RETURN_INVALID;
} }
parencount--; parencount--;
*o++ = *p; *o++ = *p;
@ -218,7 +226,7 @@ static int eb_combi(const char *data, struct Client *client_p,
if (child_result == EXTBAN_INVALID) { if (child_result == EXTBAN_INVALID) {
DEBUG("combo invalid: child invalid"); DEBUG("combo invalid: child invalid");
return EXTBAN_INVALID; RETURN_INVALID;
} }
/* Convert child_result to a plain boolean result */ /* Convert child_result to a plain boolean result */
@ -236,15 +244,17 @@ static int eb_combi(const char *data, struct Client *client_p,
if (*p++ != ',') { if (*p++ != ',') {
DEBUG("combo invalid: no ',' after ban"); DEBUG("combo invalid: no ',' after ban");
return EXTBAN_INVALID; RETURN_INVALID;
} }
if (p == banend) { if (p == banend) {
DEBUG("combo invalid: banend after ','"); DEBUG("combo invalid: banend after ','");
return EXTBAN_INVALID; RETURN_INVALID;
} }
} }
recursion_depth--;
if (is_and) if (is_and)
return have_result ? EXTBAN_NOMATCH : EXTBAN_MATCH; return have_result ? EXTBAN_NOMATCH : EXTBAN_MATCH;
else else