[asterisk-commits] mmichelson: branch 1.8 r375025 - in /branches/1.8: apps/ channels/ include/as...
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Mon Oct 15 16:00:11 CDT 2012
Author: mmichelson
Date: Mon Oct 15 16:00:03 2012
New Revision: 375025
URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=375025
Log:
Fix some potential misuses of ast_str in the code.
Passing an ast_str pointer by value that then calls
ast_str_set(), ast_str_set_va(), ast_str_append(), or
ast_str_append_va() can result in the pointer originally
passed by value being invalidated if the ast_str had
to be reallocated.
This fixes places in the code that do this. Only the
example in ccss.c could result in pointer invalidation
though since the other cases use a stack-allocated ast_str
and cannot be reallocated.
I've also updated the doxygen in strings.h to include
notes about potential misuse of the functions mentioned
previously.
Review: https://reviewboard.asterisk.org/r/2161
Modified:
branches/1.8/apps/app_dial.c
branches/1.8/channels/chan_iax2.c
branches/1.8/include/asterisk/strings.h
branches/1.8/main/ccss.c
Modified: branches/1.8/apps/app_dial.c
URL: http://svnview.digium.com/svn/asterisk/branches/1.8/apps/app_dial.c?view=diff&rev=375025&r1=375024&r2=375025
==============================================================================
--- branches/1.8/apps/app_dial.c (original)
+++ branches/1.8/apps/app_dial.c Mon Oct 15 16:00:03 2012
@@ -672,7 +672,7 @@
struct ast_aoc_decoded *aoc_s_rate_list;
};
-static int detect_disconnect(struct ast_channel *chan, char code, struct ast_str *featurecode);
+static int detect_disconnect(struct ast_channel *chan, char code, struct ast_str **featurecode);
static void chanlist_free(struct chanlist *outgoing)
{
@@ -1532,7 +1532,7 @@
}
if (ast_test_flag64(peerflags, OPT_CALLER_HANGUP) &&
- detect_disconnect(in, f->subclass.integer, featurecode)) {
+ detect_disconnect(in, f->subclass.integer, &featurecode)) {
ast_verb(3, "User requested call disconnect.\n");
*to = 0;
strcpy(pa->status, "CANCEL");
@@ -1645,18 +1645,18 @@
return peer;
}
-static int detect_disconnect(struct ast_channel *chan, char code, struct ast_str *featurecode)
+static int detect_disconnect(struct ast_channel *chan, char code, struct ast_str **featurecode)
{
struct ast_flags features = { AST_FEATURE_DISCONNECT }; /* only concerned with disconnect feature */
struct ast_call_feature feature = { 0, };
int res;
- ast_str_append(&featurecode, 1, "%c", code);
-
- res = ast_feature_detect(chan, &features, ast_str_buffer(featurecode), &feature);
+ ast_str_append(featurecode, 1, "%c", code);
+
+ res = ast_feature_detect(chan, &features, ast_str_buffer(*featurecode), &feature);
if (res != AST_FEATURE_RETURN_STOREDIGITS) {
- ast_str_reset(featurecode);
+ ast_str_reset(*featurecode);
}
if (feature.feature_mask & AST_FEATURE_DISCONNECT) {
return 1;
Modified: branches/1.8/channels/chan_iax2.c
URL: http://svnview.digium.com/svn/asterisk/branches/1.8/channels/chan_iax2.c?view=diff&rev=375025&r1=375024&r2=375025
==============================================================================
--- branches/1.8/channels/chan_iax2.c (original)
+++ branches/1.8/channels/chan_iax2.c Mon Oct 15 16:00:03 2012
@@ -1539,19 +1539,19 @@
return 0;
}
-static void encmethods_to_str(int e, struct ast_str *buf)
-{
- ast_str_set(&buf, 0, "(");
+static void encmethods_to_str(int e, struct ast_str **buf)
+{
+ ast_str_set(buf, 0, "(");
if (e & IAX_ENCRYPT_AES128) {
- ast_str_append(&buf, 0, "aes128");
+ ast_str_append(buf, 0, "aes128");
}
if (e & IAX_ENCRYPT_KEYROTATE) {
- ast_str_append(&buf, 0, ",keyrotate");
- }
- if (ast_str_strlen(buf) > 1) {
- ast_str_append(&buf, 0, ")");
+ ast_str_append(buf, 0, ",keyrotate");
+ }
+ if (ast_str_strlen(*buf) > 1) {
+ ast_str_append(buf, 0, ")");
} else {
- ast_str_set(&buf, 0, "No");
+ ast_str_set(buf, 0, "No");
}
}
@@ -3775,7 +3775,7 @@
ast_sockaddr_to_sin(&peer->addr, &peer_addr);
- encmethods_to_str(peer->encmethods, encmethods);
+ encmethods_to_str(peer->encmethods, &encmethods);
ast_cli(a->fd, "\n\n");
ast_cli(a->fd, " * Name : %s\n", peer->name);
ast_cli(a->fd, " Secret : %s\n", ast_strlen_zero(peer->secret) ? "<Not set>" : "<Set>");
@@ -6718,7 +6718,7 @@
else
ast_copy_string(name, peer->name, sizeof(name));
- encmethods_to_str(peer->encmethods, encmethods);
+ encmethods_to_str(peer->encmethods, &encmethods);
retstatus = peer_status(peer, status, sizeof(status));
if (retstatus > 0)
online_peers++;
@@ -7023,7 +7023,7 @@
i = ao2_iterator_init(peers, 0);
for (; (peer = ao2_iterator_next(&i)); peer_unref(peer)) {
- encmethods_to_str(peer->encmethods, encmethods);
+ encmethods_to_str(peer->encmethods, &encmethods);
astman_append(s, "Event: PeerEntry\r\n%sChanneltype: IAX\r\n", idtext);
if (!ast_strlen_zero(peer->username)) {
astman_append(s, "ObjectName: %s\r\nObjectUsername: %s\r\n", peer->name, peer->username);
@@ -14591,7 +14591,7 @@
ast_data_add_bool(data_peer, "dynamic", ast_test_flag64(peer, IAX_DYNAMIC));
- encmethods_to_str(peer->encmethods, encmethods);
+ encmethods_to_str(peer->encmethods, &encmethods);
ast_data_add_str(data_peer, "encryption", peer->encmethods ? ast_str_buffer(encmethods) : "no");
peer_unref(peer);
Modified: branches/1.8/include/asterisk/strings.h
URL: http://svnview.digium.com/svn/asterisk/branches/1.8/include/asterisk/strings.h?view=diff&rev=375025&r1=375024&r2=375025
==============================================================================
--- branches/1.8/include/asterisk/strings.h (original)
+++ branches/1.8/include/asterisk/strings.h Mon Oct 15 16:00:03 2012
@@ -778,6 +778,12 @@
* ...
* }
* \endcode
+ *
+ * \note Care should be taken when using this function. The function can
+ * result in reallocating the ast_str. If a pointer to the ast_str is passed
+ * by value to a function that calls ast_str_set_va(), then the original ast_str
+ * pointer may be invalidated due to a reallocation.
+ *
*/
AST_INLINE_API(int __attribute__((format(printf, 3, 0))) ast_str_set_va(struct ast_str **buf, ssize_t max_len, const char *fmt, va_list ap),
{
@@ -789,6 +795,12 @@
* \brief Append to a dynamic string using a va_list
*
* Same as ast_str_set_va(), but append to the current content.
+ *
+ * \note Care should be taken when using this function. The function can
+ * result in reallocating the ast_str. If a pointer to the ast_str is passed
+ * by value to a function that calls ast_str_append_va(), then the original ast_str
+ * pointer may be invalidated due to a reallocation.
+ *
*/
AST_INLINE_API(int __attribute__((format(printf, 3, 0))) ast_str_append_va(struct ast_str **buf, ssize_t max_len, const char *fmt, va_list ap),
{
@@ -826,6 +838,11 @@
/*!
* \brief Set a dynamic string using variable arguments
+ *
+ * \note Care should be taken when using this function. The function can
+ * result in reallocating the ast_str. If a pointer to the ast_str is passed
+ * by value to a function that calls ast_str_set(), then the original ast_str
+ * pointer may be invalidated due to a reallocation.
*
* \param buf This is the address of a pointer to a struct ast_str which should
* have been retrieved using ast_str_thread_get. It will need to
@@ -859,6 +876,11 @@
/*!
* \brief Append to a thread local dynamic string
*
+ * \note Care should be taken when using this function. The function can
+ * result in reallocating the ast_str. If a pointer to the ast_str is passed
+ * by value to a function that calls ast_str_append(), then the original ast_str
+ * pointer may be invalidated due to a reallocation.
+ *
* The arguments, return values, and usage of this function are the same as
* ast_str_set(), but the new data is appended to the current value.
*/
Modified: branches/1.8/main/ccss.c
URL: http://svnview.digium.com/svn/asterisk/branches/1.8/main/ccss.c?view=diff&rev=375025&r1=375024&r2=375025
==============================================================================
--- branches/1.8/main/ccss.c (original)
+++ branches/1.8/main/ccss.c Mon Oct 15 16:00:03 2012
@@ -3289,7 +3289,7 @@
* \param dialstring A new dialstring to add
* \retval void
*/
-static void cc_unique_append(struct ast_str *str, const char *dialstring)
+static void cc_unique_append(struct ast_str **str, const char *dialstring)
{
char dialstring_search[AST_CHANNEL_NAME];
@@ -3298,10 +3298,10 @@
return;
}
snprintf(dialstring_search, sizeof(dialstring_search), "%s%c", dialstring, '&');
- if (strstr(ast_str_buffer(str), dialstring_search)) {
+ if (strstr(ast_str_buffer(*str), dialstring_search)) {
return;
}
- ast_str_append(&str, 0, "%s", dialstring_search);
+ ast_str_append(str, 0, "%s", dialstring_search);
}
/*!
@@ -3319,7 +3319,7 @@
* \param str Where we will store CC_INTERFACES
* \retval void
*/
-static void build_cc_interfaces_chanvar(struct ast_cc_monitor *starting_point, struct ast_str *str)
+static void build_cc_interfaces_chanvar(struct ast_cc_monitor *starting_point, struct ast_str **str)
{
struct extension_monitor_pvt *extension_pvt;
struct extension_child_dialstring *child_dialstring;
@@ -3328,7 +3328,7 @@
size_t length;
/* Init to an empty string. */
- ast_str_truncate(str, 0);
+ ast_str_truncate(*str, 0);
/* First we need to take all of the is_valid child_dialstrings from
* the extension monitor we found and add them to the CC_INTERFACES
@@ -3351,9 +3351,9 @@
/* str will have an extra '&' tacked onto the end of it, so we need
* to get rid of that.
*/
- length = ast_str_strlen(str);
+ length = ast_str_strlen(*str);
if (length) {
- ast_str_truncate(str, length - 1);
+ ast_str_truncate(*str, length - 1);
}
if (length <= 1) {
/* Nothing to recall? This should not happen. */
@@ -3388,7 +3388,7 @@
AST_LIST_LOCK(interface_tree);
monitor = AST_LIST_FIRST(interface_tree);
- build_cc_interfaces_chanvar(monitor, str);
+ build_cc_interfaces_chanvar(monitor, &str);
AST_LIST_UNLOCK(interface_tree);
pbx_builtin_setvar_helper(chan, "CC_INTERFACES", ast_str_buffer(str));
@@ -3440,7 +3440,7 @@
return -1;
}
- build_cc_interfaces_chanvar(monitor_iter, str);
+ build_cc_interfaces_chanvar(monitor_iter, &str);
AST_LIST_UNLOCK(interface_tree);
pbx_builtin_setvar_helper(chan, "CC_INTERFACES", ast_str_buffer(str));
More information about the asterisk-commits
mailing list