From 48a72bba86c923a6802637036594f4e9acf5f9f3 Mon Sep 17 00:00:00 2001 From: Russell Bryant Date: Tue, 15 Jan 2008 23:50:10 +0000 Subject: [PATCH] Change a buffer in check_auth() to be a thread local dynamically allocated buffer, instead of a massive buffer on the stack. This fixes a crash reported by Qwell due to running out of stack space when building with LOW_MEMORY defined. On a very related note, the usage of BUFSIZ in various places in chan_sip is arbitrary and careless. BUFSIZ is a system specific define. On my machine, it is 8192, but by definition (according to google) could be as small as 256. So, this buffer in check_auth was 16 kB. We don't even support SIP messages larger than 4 kB! Further usage of this define should be avoided, unless it is used in the proper context. git-svn-id: https://origsvn.digium.com/svn/asterisk/branches/1.4@98946 65c4cc65-6c06-0410-ace0-fbb531ad65f3 --- channels/chan_sip.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/channels/chan_sip.c b/channels/chan_sip.c index f04dd544e2..0d92418438 100644 --- a/channels/chan_sip.c +++ b/channels/chan_sip.c @@ -8281,6 +8281,8 @@ static void build_route(struct sip_pvt *p, struct sip_request *req, int backward list_route(p->route); } +AST_THREADSTORAGE(check_auth_buf, check_auth_buf_init); +#define CHECK_AUTH_BUF_INITLEN 256 /*! \brief Check user authorization from peer definition Some actions, like REGISTER and INVITEs from peers require @@ -8297,11 +8299,12 @@ static enum check_auth_result check_auth(struct sip_pvt *p, struct sip_request * const char *authtoken; char a1_hash[256]; char resp_hash[256]=""; - char tmp[BUFSIZ * 2]; /* Make a large enough buffer */ char *c; int wrongnonce = FALSE; int good_response; const char *usednonce = p->randdata; + struct ast_dynamic_str *buf; + int res; /* table of recognised keywords, and their value in the digest */ enum keys { K_RESP, K_URI, K_USER, K_NONCE, K_LAST }; @@ -8353,10 +8356,16 @@ static enum check_auth_result check_auth(struct sip_pvt *p, struct sip_request * /* Whoever came up with the authentication section of SIP can suck my %&#$&* for not putting an example in the spec of just what it is you're doing a hash on. */ + if (!(buf = ast_dynamic_str_thread_get(&check_auth_buf, CHECK_AUTH_BUF_INITLEN))) + return AUTH_SECRET_FAILED; /*! XXX \todo need a better return code here */ /* Make a copy of the response and parse it */ - ast_copy_string(tmp, authtoken, sizeof(tmp)); - c = tmp; + res = ast_dynamic_str_thread_set(&buf, 0, &check_auth_buf, "%s", authtoken); + + if (res == AST_DYNSTR_BUILD_FAILED) + return AUTH_SECRET_FAILED; /*! XXX \todo need a better return code here */ + + c = buf->str; while(c && *(c = ast_skip_blanks(c)) ) { /* lookup for keys */ for (i = keys; i->key != NULL; i++) {