Hello community, here is the log from the commit of package libqb for openSUSE:Factory checked in at 2015-10-17 16:38:33 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/libqb (Old) and /work/SRC/openSUSE:Factory/.libqb.new (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "libqb" Changes: -------- --- /work/SRC/openSUSE:Factory/libqb/libqb.changes 2015-08-31 22:57:56.000000000 +0200 +++ /work/SRC/openSUSE:Factory/.libqb.new/libqb.changes 2015-10-17 16:38:34.000000000 +0200 @@ -1,0 +2,13 @@ +Thu Oct 8 13:18:22 UTC 2015 - y...@suse.com + +- ipc: Prevent fd and memory leaks in handle_new_connection() (bsc#947341) + * bug-947341_libqb-ipc-fd-memory-leaks.patch + +------------------------------------------------------------------- +Thu Oct 8 13:15:12 UTC 2015 - y...@suse.com + +- log: don't call dlopen inside dl_iterate_phdr() +- ipc: Don't send the dispatch_del() function a closed fd +- Upstream version cs: 1a7ea3b8d8bf9d5ffbbfdc785ace2b81e9f2356d + +------------------------------------------------------------------- Old: ---- libqb-0.17.2+git20150824.4d817cc.tar.bz2 New: ---- bug-947341_libqb-ipc-fd-memory-leaks.patch libqb-0.17.2+git20151001.1a7ea3b.tar.bz2 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ libqb.spec ++++++ --- /var/tmp/diff_new_pack.8M6YR2/_old 2015-10-17 16:38:35.000000000 +0200 +++ /var/tmp/diff_new_pack.8M6YR2/_new 2015-10-17 16:38:35.000000000 +0200 @@ -17,7 +17,7 @@ Name: libqb -Version: 0.17.2+git20150824.4d817cc +Version: 0.17.2+git20151001.1a7ea3b Release: 0 Summary: An IPC library for high performance servers License: LGPL-2.1+ @@ -26,6 +26,7 @@ Source0: %{name}-%{version}.tar.bz2 Source1: baselibs.conf Patch1: libqb-configure-package-version.patch +Patch2: bug-947341_libqb-ipc-fd-memory-leaks.patch BuildRoot: %{_tmppath}/%{name}-%{version}-build BuildRequires: autoconf @@ -68,6 +69,7 @@ %prep %setup -q -n %{name}-%{version} %patch1 -p1 +%patch2 -p1 %build ./autogen.sh ++++++ _service ++++++ --- /var/tmp/diff_new_pack.8M6YR2/_old 2015-10-17 16:38:35.000000000 +0200 +++ /var/tmp/diff_new_pack.8M6YR2/_new 2015-10-17 16:38:35.000000000 +0200 @@ -11,7 +11,7 @@ <param name="version">0.17.2</param> --> <param name="versionformat">0.17.2+git%cd.%h</param> - <param name="revision">4d817cc7e0b620acda8cc45266dc085c5bf48c59</param> + <param name="revision">1a7ea3b8d8bf9d5ffbbfdc785ace2b81e9f2356d</param> </service> <service name="recompress" mode="disabled"> ++++++ bug-947341_libqb-ipc-fd-memory-leaks.patch ++++++ commit f5fd0c950ce1bf19fd5186fd2b1f2cc67f5de3ec Author: Gao,Yan <y...@suse.com> Date: Tue Oct 6 17:48:05 2015 +0200 Fix: ipc: Prevent fd and memory leaks in handle_new_connection() In handle_new_connection(), connection_accept() could fail, which would leave the state of the connection inactive. Previously, in this case, the socket and the allocated qb_ipcs_connection would be leaked. diff --git a/lib/ipc_setup.c b/lib/ipc_setup.c index 28a0ddc..06257c1 100644 --- a/lib/ipc_setup.c +++ b/lib/ipc_setup.c @@ -556,7 +556,14 @@ send_response: "Error in connection setup (%s)", c->description); } - qb_ipcs_disconnect(c); + + if (c->state == QB_IPCS_CONNECTION_INACTIVE) { + /* This removes the initial alloc ref */ + qb_ipcs_connection_unref(c); + qb_ipcc_us_sock_close(sock); + } else { + qb_ipcs_disconnect(c); + } } return res; } ++++++ libqb-0.17.2+git20150824.4d817cc.tar.bz2 -> libqb-0.17.2+git20151001.1a7ea3b.tar.bz2 ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libqb-0.17.2+git20150824.4d817cc/lib/ipc_shm.c new/libqb-0.17.2+git20151001.1a7ea3b/lib/ipc_shm.c --- old/libqb-0.17.2+git20150824.4d817cc/lib/ipc_shm.c 2015-08-27 17:50:11.000000000 +0200 +++ new/libqb-0.17.2+git20151001.1a7ea3b/lib/ipc_shm.c 2015-10-08 15:05:43.000000000 +0200 @@ -228,8 +228,8 @@ if (c->state == QB_IPCS_CONNECTION_ESTABLISHED || c->state == QB_IPCS_CONNECTION_ACTIVE) { if (c->setup.u.us.sock > 0) { - qb_ipcc_us_sock_close(c->setup.u.us.sock); (void)c->service->poll_fns.dispatch_del(c->setup.u.us.sock); + qb_ipcc_us_sock_close(c->setup.u.us.sock); c->setup.u.us.sock = -1; } } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libqb-0.17.2+git20150824.4d817cc/lib/ipc_socket.c new/libqb-0.17.2+git20151001.1a7ea3b/lib/ipc_socket.c --- old/libqb-0.17.2+git20150824.4d817cc/lib/ipc_socket.c 2015-08-27 17:50:11.000000000 +0200 +++ new/libqb-0.17.2+git20151001.1a7ea3b/lib/ipc_socket.c 2015-10-08 15:05:43.000000000 +0200 @@ -301,7 +301,7 @@ #if !(defined(QB_LINUX) || defined(QB_CYGWIN)) if (getsockname(c->response.u.us.sock, (struct sockaddr *)&un_addr, &un_addr_len) == 0) { length = strlen(un_addr.sun_path); - base_name = strndup(un_addr.sun_path,length-8); + base_name = strndup(un_addr.sun_path,length-9); qb_util_log(LOG_DEBUG, "unlinking socket bound files with base_name=%s length=%d",base_name,length); snprintf(sock_name,PATH_MAX,"%s-%s",base_name,"request"); qb_util_log(LOG_DEBUG, "unlink sock_name=%s",sock_name); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libqb-0.17.2+git20150824.4d817cc/lib/log.c new/libqb-0.17.2+git20151001.1a7ea3b/lib/log.c --- old/libqb-0.17.2+git20150824.4d817cc/lib/log.c 2015-08-27 17:50:11.000000000 +0200 +++ new/libqb-0.17.2+git20151001.1a7ea3b/lib/log.c 2015-10-08 15:05:43.000000000 +0200 @@ -47,9 +47,15 @@ static pthread_rwlock_t _listlock; static qb_log_filter_fn _custom_filter_fn = NULL; +static QB_LIST_DECLARE(dlnames); static QB_LIST_DECLARE(tags_head); static QB_LIST_DECLARE(callsite_sections); +struct dlname { + char *dln_name; + struct qb_list_head list; +}; + struct callsite_section { struct qb_log_callsite *start; struct qb_log_callsite *stop; @@ -739,23 +745,45 @@ } #ifdef QB_HAVE_ATTRIBUTE_SECTION +/* Some platforms (eg. FreeBSD 10+) don't support calling dlopen() from + * within a dl_iterate_phdr() callback; so save all of the dlpi_names to + * a list and iterate over them afterwards. */ static int32_t _log_so_walk_callback(struct dl_phdr_info *info, size_t size, void *data) { + struct dlname *dlname; + if (strlen(info->dlpi_name) > 0) { - void *handle; - void *start; - void *stop; - const char *error; + dlname = calloc(1, sizeof(struct dlname)); + if (!dlname) + return 0; + dlname->dln_name = strdup(info->dlpi_name); + qb_list_add_tail(&dlname->list, &dlnames); + } + + return 0; +} + +static void +_log_so_walk_dlnames(void) +{ + struct dlname *dlname; + struct qb_list_head *iter; + struct qb_list_head *next; + + void *handle; + void *start; + void *stop; + const char *error; - handle = dlopen(info->dlpi_name, RTLD_LAZY); + qb_list_for_each_safe(iter, next, &dlnames) { + dlname = qb_list_entry(iter, struct dlname, list); + + handle = dlopen(dlname->dln_name, RTLD_LAZY); error = dlerror(); if (!handle || error) { qb_log(LOG_ERR, "%s", error); - if (handle) { - dlclose(handle); - } - return 0; + goto done; } start = dlsym(handle, "__start___verbose"); @@ -773,9 +801,13 @@ qb_log_callsites_register(start, stop); } done: - dlclose(handle); + if (handle) + dlclose(handle); + qb_list_del(iter); + if (dlname->dln_name) + free(dlname->dln_name); + free(dlname); } - return 0; } #endif /* QB_HAVE_ATTRIBUTE_SECTION */ @@ -823,6 +855,7 @@ #ifdef QB_HAVE_ATTRIBUTE_SECTION qb_log_callsites_register(__start___verbose, __stop___verbose); dl_iterate_phdr(_log_so_walk_callback, NULL); + _log_so_walk_dlnames(); #endif /* QB_HAVE_ATTRIBUTE_SECTION */ conf[QB_LOG_STDERR].state = QB_LOG_STATE_DISABLED; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libqb-0.17.2+git20150824.4d817cc/tests/check_ipc.c new/libqb-0.17.2+git20151001.1a7ea3b/tests/check_ipc.c --- old/libqb-0.17.2+git20150824.4d817cc/tests/check_ipc.c 2015-08-27 17:50:11.000000000 +0200 +++ new/libqb-0.17.2+git20151001.1a7ea3b/tests/check_ipc.c 2015-10-08 15:05:43.000000000 +0200 @@ -102,7 +102,7 @@ { qb_log(LOG_DEBUG, "caught signal %d", rsignal); qb_ipcs_destroy(s1); - return -1; + exit(0); } static void @@ -424,7 +424,7 @@ if (pid == 0) { run_ipc_server_fn(); - return 0; + exit(0); } return pid; } @@ -1539,7 +1539,7 @@ tc = tcase_create("ipc_stress_connections_shm"); tcase_add_test(tc, test_ipc_stress_connections_shm); - tcase_set_timeout(tc, 200); + tcase_set_timeout(tc, 3600); suite_add_tcase(s, tc); return s; @@ -1618,7 +1618,7 @@ tc = tcase_create("ipc_stress_connections_us"); tcase_add_test(tc, test_ipc_stress_connections_us); - tcase_set_timeout(tc, 200); + tcase_set_timeout(tc, 3600); suite_add_tcase(s, tc); return s;