]> git.ipfire.org Git - thirdparty/asterisk.git/commitdiff
pbx.c: Allow dangerous functions when adding a hint to dialplan. 68/3368/1
authorRichard Mudgett <rmudgett@digium.com>
Wed, 27 Jul 2016 22:17:53 +0000 (17:17 -0500)
committerRichard Mudgett <rmudgett@digium.com>
Thu, 28 Jul 2016 18:56:23 +0000 (13:56 -0500)
We can allow dangerous functions when adding a hint since altering
dialplan is itself a privileged activity.  Otherwise, we could never
execute dangerous functions.

ASTERISK-25996 #close
Reported by: Andrew Nagy

Change-Id: I4929ff100ad1200a0198262d069a34f2296e77ba

include/asterisk/pbx.h
main/pbx.c

index 40bd6d32ad512ddc39f616e8805d427231f3ad65..4b2d62fe4f670a1779429e828429b447100743a6 100644 (file)
@@ -1500,6 +1500,18 @@ void pbx_live_dangerously(int new_live_dangerously);
  */
 int ast_thread_inhibit_escalations(void);
 
+/*!
+ * \brief Swap the current thread escalation inhibit setting.
+ * \since 11.24.0
+ *
+ * \param inhibit New setting.  Non-zero to inhibit.
+ *
+ * \retval 1 if dangerous function execution was inhibited.
+ * \retval 0 if dangerous function execution was allowed.
+ * \retval -1 on error.
+ */
+int ast_thread_inhibit_escalations_swap(int inhibit);
+
 #if defined(__cplusplus) || defined(c_plusplus)
 }
 #endif
index 80e153784cd41ac5327449f8c9745b7866bf1337..f5e49e0da0ade793609b8524e058db38c43f6500 100644 (file)
@@ -4249,7 +4249,6 @@ int ast_thread_inhibit_escalations(void)
 
        thread_inhibit_escalations = ast_threadstorage_get(
                &thread_inhibit_escalations_tl, sizeof(*thread_inhibit_escalations));
-
        if (thread_inhibit_escalations == NULL) {
                ast_log(LOG_ERROR, "Error inhibiting privilege escalations for current thread\n");
                return -1;
@@ -4259,6 +4258,23 @@ int ast_thread_inhibit_escalations(void)
        return 0;
 }
 
+int ast_thread_inhibit_escalations_swap(int inhibit)
+{
+       int *thread_inhibit_escalations;
+       int orig;
+
+       thread_inhibit_escalations = ast_threadstorage_get(
+               &thread_inhibit_escalations_tl, sizeof(*thread_inhibit_escalations));
+       if (thread_inhibit_escalations == NULL) {
+               ast_log(LOG_ERROR, "Error swapping privilege escalations inhibit for current thread\n");
+               return -1;
+       }
+
+       orig = *thread_inhibit_escalations;
+       *thread_inhibit_escalations = !!inhibit;
+       return orig;
+}
+
 /*!
  * \brief Indicates whether the current thread inhibits the execution of
  * dangerous functions.
@@ -4272,7 +4288,6 @@ static int thread_inhibits_escalations(void)
 
        thread_inhibit_escalations = ast_threadstorage_get(
                &thread_inhibit_escalations_tl, sizeof(*thread_inhibit_escalations));
-
        if (thread_inhibit_escalations == NULL) {
                ast_log(LOG_ERROR, "Error checking thread's ability to run dangerous functions\n");
                /* On error, assume that we are inhibiting */
@@ -10248,13 +10263,25 @@ static int ast_add_extension2_lockopt(struct ast_context *con,
 
        /* If we are adding a hint evalulate in variables and global variables */
        if (priority == PRIORITY_HINT && strstr(application, "${") && extension[0] != '_') {
+               int inhibited;
                struct ast_channel *c = ast_dummy_channel_alloc();
 
                if (c) {
                        ast_channel_exten_set(c, extension);
                        ast_channel_context_set(c, con->name);
                }
+
+               /*
+                * We can allow dangerous functions when adding a hint since
+                * altering dialplan is itself a privileged activity.  Otherwise,
+                * we could never execute dangerous functions.
+                */
+               inhibited = ast_thread_inhibit_escalations_swap(0);
                pbx_substitute_variables_helper(c, application, expand_buf, sizeof(expand_buf));
+               if (0 < inhibited) {
+                       ast_thread_inhibit_escalations();
+               }
+
                application = expand_buf;
                if (c) {
                        ast_channel_unref(c);