diff --git a/.dleyna-core.metadata b/.dleyna-core.metadata index fbeb579..e40cba0 100644 --- a/.dleyna-core.metadata +++ b/.dleyna-core.metadata @@ -1 +1 @@ -99f24c9ea5935154d02f5eb67d37afa23e407dd5 SOURCES/dleyna-core-0.4.0.tar.gz +a2faa21d03eb6fa78bbfc863ba18513051723abc SOURCES/dleyna-core-0.5.0.tar.gz diff --git a/.gitignore b/.gitignore index 612c595..816fb75 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1 @@ -SOURCES/dleyna-core-0.4.0.tar.gz +SOURCES/dleyna-core-0.5.0.tar.gz diff --git a/SOURCES/0001-Don-t-schedule-dleyna_task_processor_t-on_quit_cb-mo.patch b/SOURCES/0001-Don-t-schedule-dleyna_task_processor_t-on_quit_cb-mo.patch new file mode 100644 index 0000000..de88dba --- /dev/null +++ b/SOURCES/0001-Don-t-schedule-dleyna_task_processor_t-on_quit_cb-mo.patch @@ -0,0 +1,82 @@ +From dc8858944f523961edcaea5b2e5f73dfb7d14907 Mon Sep 17 00:00:00 2001 +From: Debarshi Ray +Date: Thu, 15 Sep 2016 17:06:56 +0200 +Subject: [PATCH] Don't schedule dleyna_task_processor_t->on_quit_cb more than + once + +Even if there are some running tasks, cancelling all the queues will +set processor->running_tasks to zero. It will call +dleyna_task_queue_task_completed for each running task, which will +keep decrementing processor->running_tasks and schedule the on_quit_cb +handler once it is zero. Therefore, it is meaningless to check the +value of processor->running_tasks after prv_cancel_all_queues. +Instead, we should do it before. + +Otherwise, it can confuse client code which doesn't expect to have the +on_quit_cb handler invoked multiple times. For example, it causes +dleyna-render-service to crash with this backtrace: + +%0 __GI_raise (sig=sig@entry=6) + at ../sysdeps/unix/sysv/linux/raise.c:55 +%1 __GI_abort () at abort.c:89 +%2 __libc_message (do_abort=do_abort@entry=2, + fmt=fmt@entry=0x7f89f83f0e20 "*** Error in `%s': + %s: 0x%s ***\n") + at ../sysdeps/posix/libc_fatal.c:175 +%3 malloc_printerr (ar_ptr=, + ptr=, + str=0x7f89f83f0ee8 "double free or corruption + (fasttop)", + action=3) + at malloc.c:5000 +%4 _int_free (av=, + p=, + have_lock=0) + at malloc.c:3861 +%5 __GI___libc_free (mem=) at malloc.c:2962 +%6 g_free (mem=0x558aa23b0000) at gmem.c:192 +%7 dlr_upnp_delete (upnp=) at upnp.c:423 +%8 prv_control_point_stop_service () at server.c:725 +%9 prv_context_quit_cb (user_data=) + at libdleyna/core/main-loop.c:61 +%10 g_main_dispatch (context=0x558aa237a140) at gmain.c:3122 +%11 g_main_context_dispatch (context=context@entry=0x558aa237a140) + at gmain.c:3737 +%12 g_main_context_iterate (context=0x558aa237a140, + block=block@entry=1, + dispatch=dispatch@entry=1, + self=) + at gmain.c:3808 +%13 g_main_loop_run (loop=0x558aa23aecc0) at gmain.c:4002 +%14 dleyna_main_loop_start (server=, + control_point=, + user_data=0x0) + at libdleyna/core/main-loop.c:155 +%16 _start () + +https://bugzilla.redhat.com/show_bug.cgi?id=1251366 +--- + libdleyna/core/task-processor.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/libdleyna/core/task-processor.c b/libdleyna/core/task-processor.c +index 62778971d7a6..6d7f5b87de3d 100644 +--- a/libdleyna/core/task-processor.c ++++ b/libdleyna/core/task-processor.c +@@ -253,11 +253,11 @@ void dleyna_task_processor_set_quitting(dleyna_task_processor_t *processor) + + processor->quitting = TRUE; + +- prv_cancel_all_queues(processor); +- + if (processor->running_tasks == 0) + g_idle_add(processor->on_quit_cb, NULL); + ++ prv_cancel_all_queues(processor); ++ + DLEYNA_LOG_DEBUG("Exit"); + } + +-- +2.7.4 + diff --git a/SOURCES/0002-Remove-all-queues-before-dleyna_task_processor_t-on_.patch b/SOURCES/0002-Remove-all-queues-before-dleyna_task_processor_t-on_.patch new file mode 100644 index 0000000..e60e5d0 --- /dev/null +++ b/SOURCES/0002-Remove-all-queues-before-dleyna_task_processor_t-on_.patch @@ -0,0 +1,113 @@ +From 1de3325c201dc0e1132bd34ea6f952ff8acbcf80 Mon Sep 17 00:00:00 2001 +From: Debarshi Ray +Date: Fri, 16 Sep 2016 08:41:48 +0200 +Subject: [PATCH 2/2] Remove all queues before + dleyna_task_processor_t->on_quit_cb is run + +If dleyna_task_processor_t->on_quit_cb is run while there are still +queues present in the processor, it can lead to a crash if one of the +queue's task_queue_finally_cb handler didn't expect to be run after +the control point has been stopped. For example, +dleyna-renderer-service crashes with this backtrace: + +%0 __GI_raise (sig=sig@entry=6) + at ../sysdeps/unix/sysv/linux/raise.c:54 +%1 __GI_abort () at abort.c:89 +%2 g_assertion_message (domain="GLib", + file="ghash.c", + line=373, + func="g_hash_table_lookup_node", + message="assertion failed: + (hash_table->ref_count > 0)") + at gtestutils.c:2429 +%3 g_assertion_message_expr (domain="GLib", + file="ghash.c", + line=373, + func="g_hash_table_lookup_node", + expr="hash_table->ref_count > 0") + at gtestutils.c:2452 +%4 g_hash_table_lookup_node (hash_return=, + key=0x561e98ca21c0, + hash_table=0x561e985899e0) + at ghash.c:373 +%5 g_hash_table_insert_internal (hash_table=0x561e985899e0, + key=0x561e98ca21c0, + value=0x561e98a581f0, + keep_new_key=0) + at ghash.c:1227 +%6 prv_device_chain_end (cancelled=, + data=0x561e98e3acb0) + at upnp.c:85 +%7 prv_free_cb (data=0x561e98b97280) + at libdleyna/core/task-processor.c:103 +%8 g_hash_table_remove_all_nodes (hash_table=0x561e98549240, + notify=, + destruction=) + at ghash.c:548 +%9 g_hash_table_remove_all_nodes (destruction=1, + notify=1, + hash_table=0x561e98549240) + at ghash.c:1093 +%10 g_hash_table_unref (hash_table=0x561e98549240) at ghash.c:1097 +%11 dleyna_task_processor_free (processor=0x561e985543a0) + at libdleyna/core/task-processor.c:136 +%12 prv_context_free () at libdleyna/core/main-loop.c:108 +%13 dleyna_main_loop_start (server=, + control_point=, + user_data=0x0) + at libdleyna/core/main-loop.c:167 +%14 __libc_start_main (main=0x561e97db5990
, + argc=1, + argv=0x7fff905cb0a8, + init=, + fini=, + rtld_fini=, + stack_end=0x7fff905cb098) + at ../csu/libc-start.c:289 +%15 _start () + +The processor's on_quit_cb handler is set to prv_context_quit_cb, +which calls control_point->stop_service and quits the GMainLoop. Then +the processor is destroyed, which in turn destroys any queues that +might have been left inside it. Unfortunately, a queue's +task_queue_finally_cb handler might be set to something that assumes +that the control_point has not been stopped. For example, +dleyna-renderer-service sets task_queue_finally_cb to +prv_device_chain_end, which will crash due to accessing invalid memory +(specifically the dlr_upnp_t) if prv_control_point_stop_service has +already been invoked. We see the same problem in dleyna-server-service +too. + +Therefore, let's remove any leftover queues from the processor just +before dleyna_task_processor_t->on_quit_cb is scheduled to run. We are +about to terminate the process anyway, so it shouldn't hurt to do it +slightly earlier in the sequence. + +https://bugzilla.redhat.com/show_bug.cgi?id=1360209 +--- + libdleyna/core/task-processor.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/libdleyna/core/task-processor.c b/libdleyna/core/task-processor.c +index 6d7f5b87de3d..89f0386c3f98 100644 +--- a/libdleyna/core/task-processor.c ++++ b/libdleyna/core/task-processor.c +@@ -257,6 +257,7 @@ void dleyna_task_processor_set_quitting(dleyna_task_processor_t *processor) + g_idle_add(processor->on_quit_cb, NULL); + + prv_cancel_all_queues(processor); ++ g_hash_table_remove_all(processor->task_queues); + + DLEYNA_LOG_DEBUG("Exit"); + } +@@ -460,6 +461,7 @@ void dleyna_task_queue_task_completed(const dleyna_task_queue_key_t *queue_id) + + if (processor->quitting && !processor->running_tasks) { + g_idle_add(processor->on_quit_cb, NULL); ++ g_hash_table_remove_all(processor->task_queues); + } else if (queue->defer_remove) { + DLEYNA_LOG_DEBUG("Removing queue <%s,%s>", + queue_id->source, queue_id->sink); +-- +2.7.4 + diff --git a/SPECS/dleyna-core.spec b/SPECS/dleyna-core.spec index fbf65c2..cb488b0 100644 --- a/SPECS/dleyna-core.spec +++ b/SPECS/dleyna-core.spec @@ -1,7 +1,7 @@ %define api 1.0 Name: dleyna-core -Version: 0.4.0 +Version: 0.5.0 Release: 1%{?dist} Summary: Utilities for higher level dLeyna libraries @@ -9,9 +9,19 @@ License: LGPLv2 URL: https://01.org/dleyna/ Source0: https://01.org/dleyna/sites/default/files/downloads/%{name}-%{version}.tar.gz -BuildRequires: glib2-devel >= 2.28 -BuildRequires: gupnp-devel >= 0.19.1 -BuildRequires: pkgconfig autoconf automake libtool +# https://github.com/01org/dleyna-core/pull/48 +Patch0: 0001-Don-t-schedule-dleyna_task_processor_t-on_quit_cb-mo.patch +# https://github.com/01org/dleyna-core/pull/49 +Patch1: 0002-Remove-all-queues-before-dleyna_task_processor_t-on_.patch + +BuildRequires: autoconf +BuildRequires: automake +BuildRequires: libtool +BuildRequires: pkgconfig +BuildRequires: pkgconfig(gio-2.0) +BuildRequires: pkgconfig(glib-2.0) +BuildRequires: pkgconfig(gmodule-2.0) +BuildRequires: pkgconfig(gupnp-1.0) %description A set of utility functions that are used by the higher level dLeyna libraries @@ -29,6 +39,8 @@ developing applications that use %{name}. %prep %setup -q +%patch0 -p1 +%patch1 -p1 %build @@ -66,6 +78,10 @@ find $RPM_BUILD_ROOT -name '*.la' -delete %changelog +* Fri Mar 03 2017 Debarshi Ray - 0.5.0-1 +- Update to 0.5.0 +Resolves: #1386846 + * Wed May 27 2015 Debarshi Ray - 0.4.0-1 - Initial RHEL import Resolves: #1221264