From: Hyunho Kang Date: Thu, 12 May 2016 09:17:17 +0000 (+0900) Subject: Fix socket fd leak X-Git-Tag: accepted/tizen/ivi/20160513.082347^0 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=05321f75d44ffceacf8d1e13962223c4295348cb;p=platform%2Fcore%2Fappfw%2Fmessage-port.git Fix socket fd leak Uneccessary socket dup and send uneccessary fd using gdbus cause fd leak It also cause sender didn't clear invalid opponent info which already die. Change-Id: Ifa79b3340ab5358ecfb1deb5791dc1d5df35ac5f Signed-off-by: Hyunho Kang --- diff --git a/src/message-port.c b/src/message-port.c index a337d29..fb1163a 100755 --- a/src/message-port.c +++ b/src/message-port.c @@ -51,6 +51,9 @@ #define DBUS_RELEASE_NAME_REPLY_NOT_OWNER 3 /* *< Service is not an owner of the given name */ #define HEADER_LEN 8 #define MAX_RETRY_CNT 2 +#define SOCK_PAIR_SENDER 0 +#define SOCK_PAIR_RECEIVER 1 + #define retvm_if(expr, val, fmt, arg...) do { \ if (expr) { \ @@ -124,7 +127,7 @@ typedef struct port_list_info { char *port_name; char *encoded_bus_name; bool is_trusted; - int sock_pair[2]; + int send_sock_fd; int watcher_id; bool exist; } port_list_info_s; @@ -297,6 +300,11 @@ static void on_name_vanished(GDBusConnection *connection, port_list_info_s *pli = (port_list_info_s *)user_data; g_bus_unwatch_name(pli->watcher_id); pli->exist = false; + _LOGI("name vanished socket : %d", pli->send_sock_fd); + if (pli->send_sock_fd > 0) { + close(pli->send_sock_fd); + pli->send_sock_fd = 0; + } } static int __get_local_port_info(int id, message_port_local_port_info_s **info) @@ -325,16 +333,12 @@ static port_list_info_s *__set_remote_port_info(const char *remote_app_id, const goto out; } port_info->is_trusted = is_trusted; - port_info->encoded_bus_name = __get_encoded_name(remote_app_id, remote_port, is_trusted); if (port_info->encoded_bus_name == NULL) { ret_val = MESSAGEPORT_ERROR_OUT_OF_MEMORY; goto out; } - - port_info->sock_pair[0] = 0; - port_info->sock_pair[1] = 0; - + port_info->send_sock_fd = 0; out: if (ret_val != MESSAGEPORT_ERROR_NONE) { if (port_info) { @@ -715,6 +719,11 @@ static bool send_message(GVariant *parameters, GDBusMethodInvocation *invocation message_port_callback_info_s *callback_info; int local_reg_id = 0; char buf[1024]; + GDBusMessage *msg; + GUnixFDList *fd_list; + int fd_len; + int *returned_fds; + int fd; g_variant_get(parameters, "(ssbbssbus)", &local_appid, &local_port, &local_trusted, &bi_dir, &remote_appid, &remote_port, &remote_trusted, &len, &raw); @@ -775,18 +784,12 @@ static bool send_message(GVariant *parameters, GDBusMethodInvocation *invocation callback_info->remote_app_id = strdup(local_appid); callback_info->callback = mi->callback; - GError *error = NULL; - GDBusMessage *msg = g_dbus_method_invocation_get_message(invocation); - - GUnixFDList *fd_list = g_dbus_message_get_unix_fd_list(msg); - int fd = g_unix_fd_list_get(fd_list, 0, &error); - if (error) { - LOGE("g_unix_fd_list_get fail : %s", error->message); - g_error_free(error); - } - - LOGI("g_unix_fd_list_get fd: [%d]", fd); + msg = g_dbus_method_invocation_get_message(invocation); + fd_list = g_dbus_message_get_unix_fd_list(msg); + returned_fds = g_unix_fd_list_steal_fds(fd_list, &fd_len); + fd = returned_fds[0]; + LOGI("g_unix_fd_list_get %d fd: [%d]", fd_len, fd); if (fd > 0) { callback_info->gio_read = g_io_channel_unix_new(fd); @@ -1296,6 +1299,7 @@ static int __message_port_send_message(const char *remote_appid, const char *rem GDBusMessage *msg = NULL; GError *err = NULL; GVariant *body = NULL; + int sock_pair[2] = {0,}; ret = __get_remote_port_info(remote_appid, remote_port, trusted_message, &remote_app_info, &port_info); if (ret != MESSAGEPORT_ERROR_NONE) @@ -1313,8 +1317,8 @@ static int __message_port_send_message(const char *remote_appid, const char *rem } } - if (port_info->sock_pair[0] > 0) { - ret = __message_port_send_async(port_info->sock_pair[0], message, + if (port_info->send_sock_fd > 0) { + ret = __message_port_send_async(port_info->send_sock_fd, message, (local_port) ? local_port : "", local_trusted, bi_dir); } else { @@ -1333,29 +1337,26 @@ static int __message_port_send_message(const char *remote_appid, const char *rem body = g_variant_new("(ssbbssbus)", __app_id, (local_port) ? local_port : "", local_trusted, bi_dir, remote_appid, remote_port, trusted_message, len, raw); - - if (strcmp(remote_appid, __app_id) != 0) { /* self send */ /* if message-port fail to get socket pair, communicate using GDBus */ - if (aul_request_message_port_socket_pair(port_info->sock_pair) != AUL_R_OK) { + if (aul_request_message_port_socket_pair(sock_pair) != AUL_R_OK) { _LOGE("error create socket pair"); } else { - _LOGI("sock pair : %d, %d", port_info->sock_pair[0], port_info->sock_pair[1]); - + _LOGI("sock pair : %d, %d", + sock_pair[SOCK_PAIR_SENDER], sock_pair[SOCK_PAIR_RECEIVER]); fd_list = g_unix_fd_list_new(); - g_unix_fd_list_append(fd_list, port_info->sock_pair[1], &err); - g_unix_fd_list_append(fd_list, port_info->sock_pair[0], &err); - + g_unix_fd_list_append(fd_list, sock_pair[SOCK_PAIR_RECEIVER], &err); if (err != NULL) { _LOGE("g_unix_fd_list_append [%s]", error->message); ret = MESSAGEPORT_ERROR_IO_ERROR; g_error_free(err); goto out; } + port_info->send_sock_fd = sock_pair[SOCK_PAIR_SENDER]; + close(sock_pair[SOCK_PAIR_RECEIVER]); } - } msg = g_dbus_message_new_method_call(bus_name, MESSAGEPORT_OBJECT_PATH, interface_name, "send_message");