From 7e5ec859c8d6b972c4fafa873b22c30b927ec15f Mon Sep 17 00:00:00 2001 From: Tomas Heinrich Date: Fri, 12 Apr 2013 10:09:33 +0200 Subject: [PATCH] bugfix: prevent a segfault if ratelimit condition is not met Move the severity-check logic inside the ratelimiter and add a new function ratelimitSetSeverity() to manipulate the treshold. Currently only utilized by the imuxsock module. --- plugins/imuxsock/imuxsock.c | 9 +++++---- runtime/ratelimit.c | 14 +++++++++++++- runtime/ratelimit.h | 2 ++ 3 files changed, 20 insertions(+), 5 deletions(-) diff --git a/plugins/imuxsock/imuxsock.c b/plugins/imuxsock/imuxsock.c index 0f4ded1..9553747 100644 --- a/plugins/imuxsock/imuxsock.c +++ b/plugins/imuxsock/imuxsock.c @@ -412,6 +412,8 @@ addListner(instanceConf_t *inst) ratelimitSetLinuxLike(listeners[nfd].dflt_ratelimiter, listeners[nfd].ratelimitInterval, listeners[nfd].ratelimitBurst); + ratelimitSetSeverity(listeners[nfd].dflt_ratelimiter, + listeners[nfd].ratelimitSev); nfd++; } else { errmsg.LogError(0, NO_ERRCODE, "Out of unix socket name descriptors, ignoring %s\n", @@ -586,6 +588,7 @@ findRatelimiter(lstn_t *pLstn, struct ucred *cred, ratelimit_t **prl) pidbuf[sizeof(pidbuf)-1] = '\0'; /* to be on safe side */ CHKiRet(ratelimitNew(&rl, "imuxsock", pidbuf)); ratelimitSetLinuxLike(rl, pLstn->ratelimitInterval, pLstn->ratelimitBurst); + ratelimitSetSeverity(rl, pLstn->ratelimitSev); CHKmalloc(keybuf = malloc(sizeof(pid_t))); *keybuf = cred->pid; r = hashtable_insert(pLstn->ht, keybuf, rl); @@ -775,10 +778,7 @@ SubmitMsg(uchar *pRcv, int lenRcv, lstn_t *pLstn, struct ucred *cred, struct tim facil = LOG_FAC(pri); sever = LOG_PRI(pri); - if(sever >= pLstn->ratelimitSev) { - /* note: if cred == NULL, then ratelimiter == NULL as well! */ - findRatelimiter(pLstn, cred, &ratelimiter); /* ignore error, better so than others... */ - } + findRatelimiter(pLstn, cred, &ratelimiter); /* ignore error, better so than others... */ if(ts == NULL) { datetime.getCurrTime(&st, &tt); @@ -1075,6 +1075,7 @@ activateListeners() ratelimitSetLinuxLike(listeners[0].dflt_ratelimiter, listeners[0].ratelimitInterval, listeners[0].ratelimitBurst); + ratelimitSetSeverity(listeners[0].dflt_ratelimiter,listeners[0].ratelimitSev); sd_fds = sd_listen_fds(0); if(sd_fds < 0) { diff --git a/runtime/ratelimit.c b/runtime/ratelimit.c index 4b618fb..d83da2d 100644 --- a/runtime/ratelimit.c +++ b/runtime/ratelimit.c @@ -202,7 +202,9 @@ ratelimitMsg(ratelimit_t *ratelimit, msg_t *pMsg, msg_t **ppRepMsg) DEFiRet; *ppRepMsg = NULL; - if(ratelimit->interval) { + /* Only the messages having severity level at or below the + * treshold (the value is >=) are subject to ratelimiting. */ + if(ratelimit->interval && (pMsg->iSeverity >= ratelimit->severity)) { if(withinRatelimit(ratelimit, pMsg->ttGenTime) == 0) { msgDestruct(&pMsg); ABORT_FINALIZE(RS_RET_DISCARDMSG); @@ -284,6 +286,7 @@ ratelimitNew(ratelimit_t **ppThis, char *modname, char *dynname) namebuf[sizeof(namebuf)-1] = '\0'; /* to be on safe side */ pThis->name = strdup(namebuf); } + /* pThis->severity == 0 - all messages are ratelimited */ pThis->bReduceRepeatMsgs = loadConf->globals.bReduceRepeatMsgs; *ppThis = pThis; finalize_it: @@ -316,6 +319,15 @@ ratelimitSetThreadSafe(ratelimit_t *ratelimit) pthread_mutex_init(&ratelimit->mut, NULL); } +/* Severity level determines which messages are subject to + * ratelimiting. Default (no value set) is all messages. + */ +void +ratelimitSetSeverity(ratelimit_t *ratelimit, intTiny severity) +{ + ratelimit->severity = severity; +} + void ratelimitDestruct(ratelimit_t *ratelimit) { diff --git a/runtime/ratelimit.h b/runtime/ratelimit.h index 820817b..a058b06 100644 --- a/runtime/ratelimit.h +++ b/runtime/ratelimit.h @@ -26,6 +26,7 @@ struct ratelimit_s { /* support for Linux kernel-type ratelimiting */ unsigned short interval; unsigned short burst; + intTiny severity; /**< ratelimit only equal or lower severity levels (eq or higher values) */ unsigned done; unsigned missed; time_t begin; @@ -41,6 +42,7 @@ struct ratelimit_s { rsRetVal ratelimitNew(ratelimit_t **ppThis, char *modname, char *dynname); void ratelimitSetThreadSafe(ratelimit_t *ratelimit); void ratelimitSetLinuxLike(ratelimit_t *ratelimit, unsigned short interval, unsigned short burst); +void ratelimitSetSeverity(ratelimit_t *ratelimit, intTiny severity); rsRetVal ratelimitMsg(ratelimit_t *ratelimit, msg_t *pMsg, msg_t **ppRep); rsRetVal ratelimitAddMsg(ratelimit_t *ratelimit, multi_submit_t *pMultiSub, msg_t *pMsg); void ratelimitDestruct(ratelimit_t *pThis); -- 1.7.10.4