Fix various improper memory handling bugs 37/246437/3 accepted/tizen/unified/20201102.124206 submit/tizen/20201102.025704
authorSeungbae Shin <seungbae.shin@samsung.com>
Thu, 29 Oct 2020 08:51:05 +0000 (17:51 +0900)
committerSeungbae Shin <seungbae.shin@samsung.com>
Fri, 30 Oct 2020 07:30:12 +0000 (16:30 +0900)
- memory leaks due to missing message unref
- memory leaks due to missing dbus string array free.
- potential memory corruption due to passing different size of data type.
- use-after-free of string retrieved by dbus_message_iter_get_basic()
- use duplicated string for strtok_r()

[Version] 13.0.37
[Issue Type] Bug

Change-Id: I6dea62168cef2fd1387f1e1a3ffc37eb2fe47fa5

packaging/pulseaudio-modules-tizen.spec
src/device-manager-dbus.c
src/stream-manager-dbus.c
src/subscribe-observer.c
src/tizen-device.c

index 9f5b1f7..7c7715c 100644 (file)
@@ -1,6 +1,6 @@
 Name:             pulseaudio-modules-tizen
 Summary:          Pulseaudio modules for Tizen
-Version:          13.0.36
+Version:          13.0.37
 Release:          0
 Group:            Multimedia/Audio
 License:          LGPL-2.1+
index 52e87e1..2bc5dbd 100644 (file)
@@ -481,7 +481,7 @@ static int handle_bluez_headset_property_changed(DBusConnection *c, DBusMessage
             return -1;
         }
         handle_device_status_changed(dm, DEVICE_TYPE_BT_SCO, name, dbus_message_get_path(s),  detected);
-
+        pa_xfree(name);
     } else if (pa_safe_streq(property_name, "Playing")) {
         pa_tz_device *device;
         pa_log_info("SCO Playing : %d", value);
@@ -639,6 +639,7 @@ static int method_call_bt_get_name(DBusConnection *conn, const char *device_path
     DBusMessage *msg, *reply;
     DBusMessageIter reply_iter, variant_iter;
     DBusError err;
+    const char *_name;
 
     pa_assert(conn);
     pa_assert(device_path);
@@ -654,23 +655,27 @@ static int method_call_bt_get_name(DBusConnection *conn, const char *device_path
                                                DBUS_TYPE_INVALID));
 
     dbus_error_init(&err);
-    if (!(reply = dbus_connection_send_with_reply_and_block(conn, msg, -1, &err))) {
+
+    reply = dbus_connection_send_with_reply_and_block(conn, msg, DBUS_TIMEOUT_USE_DEFAULT, &err);
+    dbus_message_unref(msg);
+    if (!reply) {
         pa_log_error("Failed to method call %s.%s, %s", DBUS_INTERFACE_BLUEZ_DEVICE, "Get", err.message);
         dbus_error_free(&err);
         return -1;
     }
 
-    dbus_message_iter_init(reply,  &reply_iter);
+    dbus_message_iter_init(reply, &reply_iter);
 
     if (dbus_message_iter_get_arg_type(&reply_iter) != DBUS_TYPE_VARIANT) {
         pa_log_error("Cannot get reply argument");
         return -1;
     }
 
-    dbus_message_iter_recurse(&reply_iter,  &variant_iter);
+    dbus_message_iter_recurse(&reply_iter, &variant_iter);
 
     if (dbus_message_iter_get_arg_type(&variant_iter) == DBUS_TYPE_STRING) {
-        dbus_message_iter_get_basic(&variant_iter, name);
+        dbus_message_iter_get_basic(&variant_iter, &_name);
+        *name = pa_xstrdup(_name);
     }
 
     dbus_message_unref(reply);
@@ -1666,7 +1671,7 @@ static void fill_signal_msg_with_device(const char *description, DBusMessageIter
 void send_device_connection_changed_signal(uint32_t event_id, pa_tz_device *device, bool connected, pa_device_manager *dm) {
     DBusMessage *signal_msg;
     DBusMessageIter msg_iter;
-    dbus_bool_t _connected = connected;
+    dbus_bool_t _connected = (dbus_bool_t)connected;
 
     pa_assert(device);
     pa_assert(dm);
index d5c87b3..d81d157 100644 (file)
@@ -1717,6 +1717,7 @@ static int32_t parse_call_parameters(const char *parameters, char *call_type, ch
     const char delimiter[] = ";";
     char *token, *ptr = NULL;
     char key[32] = "";
+    char *_parameters = NULL;
 
     pa_assert(parameters);
     pa_assert(call_type);
@@ -1725,39 +1726,44 @@ static int32_t parse_call_parameters(const char *parameters, char *call_type, ch
 
     pa_log_info("parameters[%s]", parameters);
 
-    /*Reset the call parameters*/
+    _parameters = pa_xstrdup(parameters);
+    if (!_parameters) {
+        pa_log_error("string duplication error!");
+        return -1;
+    }
+
+    /* Reset the call parameters */
     memset(call_type, 0, MAX_CALL_PARAM_SIZE);
     memset(call_domain, 0, MAX_CALL_PARAM_SIZE);
     memset(network_band, 0, MAX_CALL_PARAM_SIZE);
 
-    if (parameters) {
-        token = strtok_r((char *)parameters, delimiter, &ptr);
-        while (token) {
-            char *delimiter_ptr = NULL;
-            char *value = NULL;
-
-            delimiter_ptr = strstr(token, "=");
-            if (!delimiter_ptr) {
-                token = strtok_r(NULL, delimiter, &ptr);
-                continue;
-            }
-            strncpy(key, token, delimiter_ptr - token);
-            value = delimiter_ptr + 1;
-            pa_log_debug("key(%s), value(%s)", key, value);
-            if (!strncmp(key, "call-type", strlen("call-type")))
-                pa_strlcpy(call_type, value, MAX_CALL_PARAM_SIZE);
-            else if (!strncmp(key, "call-domain", strlen("call-domain")))
-                pa_strlcpy(call_domain, value, MAX_CALL_PARAM_SIZE);
-            else if (!strncmp(key, "network-band", strlen("network-band")))
-                pa_strlcpy(network_band, value, MAX_CALL_PARAM_SIZE);
-            else
-                pa_log_warn("not supported key(%s)", key);
+    token = strtok_r(_parameters, delimiter, &ptr);
+    while (token) {
+        char *delimiter_ptr = NULL;
+        char *value = NULL;
 
+        delimiter_ptr = strstr(token, "=");
+        if (!delimiter_ptr) {
             token = strtok_r(NULL, delimiter, &ptr);
-            memset(key, 0, sizeof(key));
+            continue;
         }
-        pa_log_info("call-type[%s], call-domain[%s], network-band[%s]", call_type, call_domain, network_band);
+        strncpy(key, token, delimiter_ptr - token);
+        value = delimiter_ptr + 1;
+        pa_log_debug("key(%s), value(%s)", key, value);
+        if (!strncmp(key, "call-type", strlen("call-type")))
+            pa_strlcpy(call_type, value, MAX_CALL_PARAM_SIZE);
+        else if (!strncmp(key, "call-domain", strlen("call-domain")))
+            pa_strlcpy(call_domain, value, MAX_CALL_PARAM_SIZE);
+        else if (!strncmp(key, "network-band", strlen("network-band")))
+            pa_strlcpy(network_band, value, MAX_CALL_PARAM_SIZE);
+        else
+            pa_log_warn("not supported key(%s)", key);
+
+        token = strtok_r(NULL, delimiter, &ptr);
+        memset(key, 0, sizeof(key));
     }
+    pa_log_info("call-type[%s], call-domain[%s], network-band[%s]", call_type, call_domain, network_band);
+    pa_xfree(_parameters);
 
     return 0;
 }
@@ -1991,7 +1997,7 @@ static bool find_the_lastest_stream(pa_stream_manager *m, stream_type_t type, co
 static void handle_get_pid_of_latest_stream(DBusConnection *conn, DBusMessage *msg, void *userdata) {
     pa_stream_manager *m = (pa_stream_manager *)userdata;
     const char *direction;
-    const char **types;
+    char **types;
     int length;
     stream_type_t stream_type = STREAM_SINK_INPUT;
     uint32_t pid = 0;
@@ -2022,7 +2028,7 @@ static void handle_get_pid_of_latest_stream(DBusConnection *conn, DBusMessage *m
         goto finish;
     }
 
-    if (!find_the_lastest_stream(m, stream_type, types, length, &pid))
+    if (!find_the_lastest_stream(m, stream_type, (const char **)types, length, &pid))
         ret = RET_MSG_ERROR_NO_STREAM;
 
 finish:
@@ -2031,6 +2037,8 @@ finish:
                                                  DBUS_TYPE_INVALID));
     pa_assert_se(dbus_connection_send(conn, reply, NULL));
     dbus_message_unref(reply);
+
+    dbus_free_string_array(types);
 }
 
 static void handle_activate_ducking(DBusConnection *conn, DBusMessage *msg, void *userdata) {
@@ -2220,14 +2228,16 @@ static int dbus_launch_mdnsd(pa_stream_manager *m, DBusConnection *conn) {
     pa_assert_se(dbus_message_append_args(msg, DBUS_TYPE_STRING, &name, DBUS_TYPE_INVALID));
 
     dbus_error_init(&err);
-    if (!(reply = dbus_connection_send_with_reply_and_block(conn, msg, -1, &err))) {
+
+    reply = dbus_connection_send_with_reply_and_block(conn, msg, DBUS_TIMEOUT_USE_DEFAULT, &err);
+    dbus_message_unref(msg);
+    if (!reply) {
         pa_log_error("Failed to method call :  %s", err.message);
         dbus_error_free(&err);
         return -1;
     }
 
     dbus_message_unref(reply);
-
     pa_log_info("success");
 
     return 0;
@@ -2523,7 +2533,7 @@ void send_remote_found_signal(DBusConnection *conn, int type, bool connected, un
                                                       const char *name, const char *description) {
     DBusMessage *signal_msg;
     DBusMessageIter msg_iter;
-    dbus_bool_t c = (dbus_bool_t)connected;
+    dbus_bool_t _connected = (dbus_bool_t)connected;
 
     pa_assert(conn);
 
@@ -2539,7 +2549,7 @@ void send_remote_found_signal(DBusConnection *conn, int type, bool connected, un
 
     dbus_message_iter_append_basic(&msg_iter, DBUS_TYPE_INT32, &type);
     dbus_message_iter_append_basic(&msg_iter, DBUS_TYPE_UINT32, &index);
-    dbus_message_iter_append_basic(&msg_iter, DBUS_TYPE_BOOLEAN, &c);
+    dbus_message_iter_append_basic(&msg_iter, DBUS_TYPE_BOOLEAN, &_connected);
     dbus_message_iter_append_basic(&msg_iter, DBUS_TYPE_STRING, &name);
     dbus_message_iter_append_basic(&msg_iter, DBUS_TYPE_STRING, &description);
 
index a8ec66a..b6e7d70 100644 (file)
@@ -193,7 +193,7 @@ static int get_sender_pid(DBusConnection *c, DBusMessage *got_msg, uint32_t *_se
                 DBUS_TYPE_INVALID));
 
     dbus_error_init(&err);
-    if (!(reply = dbus_connection_send_with_reply_and_block(c, msg, -1, &err))) {
+    if (!(reply = dbus_connection_send_with_reply_and_block(c, msg, DBUS_TIMEOUT_USE_DEFAULT, &err))) {
         pa_log_error("Failed to method call %s.%s, %s", intf, method, err.message);
         dbus_error_free(&err);
         goto fail;
index 4f90d45..996098a 100644 (file)
@@ -836,6 +836,7 @@ static int method_call_bt_sco_enable_pcm(pa_dbus_connection *conn, bool enable)
     DBusMessage *msg, *reply;
     DBusError err;
     const char *method = "SetVoiceDial";
+    dbus_bool_t _enable = (dbus_bool_t)enable;
 
     pa_assert(conn);
 
@@ -844,9 +845,12 @@ static int method_call_bt_sco_enable_pcm(pa_dbus_connection *conn, bool enable)
         return -1;
     }
 
+    pa_assert_se(dbus_message_append_args(msg, DBUS_TYPE_BOOLEAN, &_enable, DBUS_TYPE_INVALID));
+
     dbus_error_init(&err);
-    pa_assert_se(dbus_message_append_args(msg, DBUS_TYPE_BOOLEAN, &enable, DBUS_TYPE_INVALID));
-    if (!(reply = dbus_connection_send_with_reply_and_block(pa_dbus_connection_get(conn), msg, -1, &err))) {
+    reply = dbus_connection_send_with_reply_and_block(pa_dbus_connection_get(conn), msg, DBUS_TIMEOUT_USE_DEFAULT, &err);
+    dbus_message_unref(msg);
+    if (!reply) {
         pa_log_error("Failed to method call %s.%s, %s", DBUS_INTERFACE_HFP_AGENT, method, err.message);
         dbus_error_free(&err);
         return -1;
@@ -870,7 +874,9 @@ static int method_call_bt_sco(pa_dbus_connection *conn, bool onoff) {
     }
 
     dbus_error_init(&err);
-    if (!(reply = dbus_connection_send_with_reply_and_block(pa_dbus_connection_get(conn), msg, -1, &err))) {
+    reply = dbus_connection_send_with_reply_and_block(pa_dbus_connection_get(conn), msg, DBUS_TIMEOUT_USE_DEFAULT, &err);
+    dbus_message_unref(msg);
+    if (!reply) {
         pa_log_error("Failed to method call %s.%s, %s", DBUS_INTERFACE_HFP_AGENT, method, err.message);
         dbus_error_free(&err);
         return -1;
@@ -900,7 +906,9 @@ static int method_call_bt_sco_get_property(pa_dbus_connection *conn, bool *is_wi
     }
 
     dbus_error_init(&err);
-    if (!(reply = dbus_connection_send_with_reply_and_block(pa_dbus_connection_get(conn), msg, -1, &err))) {
+    reply = dbus_connection_send_with_reply_and_block(pa_dbus_connection_get(conn), msg, DBUS_TIMEOUT_USE_DEFAULT, &err);
+    dbus_message_unref(msg);
+    if (!reply) {
         pa_log_error("Failed to method call %s.%s, %s", DBUS_INTERFACE_HFP_AGENT, "GetProperties", err.message);
         dbus_error_free(&err);
         return -1;
@@ -936,7 +944,7 @@ static int method_call_bt_sco_get_property(pa_dbus_connection *conn, bool *is_wi
             if (dbus_message_iter_get_arg_type(&dict_entry_val) != DBUS_TYPE_BOOLEAN)
                 continue;
             dbus_message_iter_get_basic(&dict_entry_val, &nrec);
-            pa_log_debug("nrec= [%d]", nrec);
+            pa_log_debug("nrec = [%d]", nrec);
             *is_nrec = nrec;
         }