summaryrefslogtreecommitdiff
path: root/main
diff options
context:
space:
mode:
authorCorey Farrell <git@cfware.com>2015-06-08 11:09:22 -0400
committerCorey Farrell <git@cfware.com>2015-06-08 11:09:22 -0400
commit55c8daf88b94f74e334ab246c51bdb7b469eedc4 (patch)
tree8c79fa393e6f2427929d2f89bf0bd4ee03b25a09 /main
parent720251f2b80639324a37b2041997292d97858d39 (diff)
Fix unsafe uses of ast_context pointers.
Although ast_context_find, ast_context_find_or_create and ast_context_destroy perform locking of the contexts table, any context pointer can become invalid at any time that the contexts table is unlocked. This change adds locking around all complete operations involving these functions. Places where ast_context_find was followed by ast_context_destroy have been replaced with calls ast_context_destroy_by_name. ASTERISK-25094 #close Reported by: Corey Farrell Change-Id: I1866b6787730c9c4f3f836b6133ffe9c820734fa
Diffstat (limited to 'main')
-rw-r--r--main/pbx.c36
1 files changed, 30 insertions, 6 deletions
diff --git a/main/pbx.c b/main/pbx.c
index 2be01b28e..7686b4b5d 100644
--- a/main/pbx.c
+++ b/main/pbx.c
@@ -8742,9 +8742,9 @@ struct ast_context *ast_context_find_or_create(struct ast_context **extcontexts,
ast_rdlock_contexts();
local_contexts = &contexts;
tmp = ast_hashtab_lookup(contexts_table, &search);
- ast_unlock_contexts();
if (tmp) {
tmp->refcount++;
+ ast_unlock_contexts();
return tmp;
}
} else { /* local contexts just in a linked list; search there for the new context; slow, linear search, but not frequent */
@@ -8768,11 +8768,13 @@ struct ast_context *ast_context_find_or_create(struct ast_context **extcontexts,
tmp->refcount = 1;
} else {
ast_log(LOG_ERROR, "Danger! We failed to allocate a context for %s!\n", name);
+ if (!extcontexts) {
+ ast_unlock_contexts();
+ }
return NULL;
}
if (!extcontexts) {
- ast_wrlock_contexts();
tmp->next = *local_contexts;
*local_contexts = tmp;
ast_hashtab_insert_safe(contexts_table, tmp); /*put this context into the tree */
@@ -9671,18 +9673,24 @@ int ast_context_add_ignorepat2(struct ast_context *con, const char *value, const
int ast_ignore_pattern(const char *context, const char *pattern)
{
- struct ast_context *con = ast_context_find(context);
+ int ret = 0;
+ struct ast_context *con;
+ ast_rdlock_contexts();
+ con = ast_context_find(context);
if (con) {
struct ast_ignorepat *pat;
for (pat = con->ignorepats; pat; pat = pat->next) {
- if (ast_extension_match(pat->pattern, pattern))
- return 1;
+ if (ast_extension_match(pat->pattern, pattern)) {
+ ret = 1;
+ break;
+ }
}
}
+ ast_unlock_contexts();
- return 0;
+ return ret;
}
/*
@@ -10890,6 +10898,22 @@ void __ast_context_destroy(struct ast_context *list, struct ast_hashtab *context
}
}
+int ast_context_destroy_by_name(const char *context, const char *registrar)
+{
+ struct ast_context *con;
+ int ret = -1;
+
+ ast_wrlock_contexts();
+ con = ast_context_find(context);
+ if (con) {
+ ast_context_destroy(con, registrar);
+ ret = 0;
+ }
+ ast_unlock_contexts();
+
+ return ret;
+}
+
void ast_context_destroy(struct ast_context *con, const char *registrar)
{
ast_wrlock_contexts();