From dc2937e1cf812b4ade99d377ae5ef41c00dd0292 Mon Sep 17 00:00:00 2001 From: Zdenek Dohnal Date: Thu, 13 Aug 2020 12:17:31 +0200 Subject: [PATCH] 1867692 - airscan driver crashes in mock during wsdd_cleanup() --- sane-airscan-exit.patch | 172 ++++++++++++++++++++++++++++++++++++++++ sane-airscan.spec | 9 ++- 2 files changed, 180 insertions(+), 1 deletion(-) create mode 100644 sane-airscan-exit.patch diff --git a/sane-airscan-exit.patch b/sane-airscan-exit.patch new file mode 100644 index 0000000..2a3e37b --- /dev/null +++ b/sane-airscan-exit.patch @@ -0,0 +1,172 @@ +diff --git a/airscan-conf.c b/airscan-conf.c +index 401272c..e252551 100644 +--- a/airscan-conf.c ++++ b/airscan-conf.c +@@ -604,6 +604,8 @@ conf_device_list_free (void) + { + conf_device *list = conf.devices, *next; + ++ conf.devices = NULL; ++ + while (list != NULL) { + next = list->next; + mem_free((char*) list->name); +diff --git a/airscan-mdns.c b/airscan-mdns.c +index 7611fef..55cae5b 100644 +--- a/airscan-mdns.c ++++ b/airscan-mdns.c +@@ -891,6 +891,10 @@ mdns_init (void) + void + mdns_cleanup (void) + { ++ if (mdns_log == NULL) { ++ return; /* MDNS not initialized */ ++ } ++ + if (mdns_avahi_poll != NULL) { + mdns_avahi_browser_stop(); + mdns_avahi_client_stop(); +diff --git a/airscan-rand.c b/airscan-rand.c +index 036a16b..7d22d4a 100644 +--- a/airscan-rand.c ++++ b/airscan-rand.c +@@ -46,8 +46,10 @@ rand_init (void) + void + rand_cleanup (void) + { +- fclose(rand_fp); +- rand_fp = NULL; ++ if (rand_fp != NULL) { ++ fclose(rand_fp); ++ rand_fp = NULL; ++ } + } + + /* vim:ts=8:sw=4:et +diff --git a/airscan-trace.c b/airscan-trace.c +index a0f08a3..de0fd1f 100644 +--- a/airscan-trace.c ++++ b/airscan-trace.c +@@ -315,10 +315,10 @@ trace_http_query_hook (trace *t, http_query *q) + trace_message_headers_foreach_callback, t); + fprintf(t->log, "\n"); + ++ trace_dump_body(t, http_query_get_response_data(q)); ++ + mp_count = http_query_get_mp_response_count(q); +- if (mp_count == 0) { +- trace_dump_body(t, http_query_get_response_data(q)); +- } else { ++ if (mp_count != 0) { + int i; + + for (i = 0; i < mp_count; i ++) { +diff --git a/airscan-wsdd.c b/airscan-wsdd.c +index 549f46d..695f704 100644 +--- a/airscan-wsdd.c ++++ b/airscan-wsdd.c +@@ -1671,6 +1671,10 @@ wsdd_cleanup (void) + { + netif_addr *addr; + ++ if (wsdd_log == NULL) { ++ return; /* WSDD not initialized */ ++ } ++ + if (wsdd_netif_notifier != NULL) { + netif_notifier_free(wsdd_netif_notifier); + wsdd_netif_notifier = NULL; +@@ -1695,10 +1699,8 @@ wsdd_cleanup (void) + + log_assert(wsdd_log, ll_empty(&wsdd_finding_list)); + +- if (wsdd_log != NULL) { +- log_ctx_free(wsdd_log); +- wsdd_log = NULL; +- } ++ log_ctx_free(wsdd_log); ++ wsdd_log = NULL; + } + + /* vim:ts=8:sw=4:et +diff --git a/airscan-zeroconf.c b/airscan-zeroconf.c +index 2c14196..3b8c667 100644 +--- a/airscan-zeroconf.c ++++ b/airscan-zeroconf.c +@@ -1441,9 +1441,11 @@ zeroconf_init (void) + void + zeroconf_cleanup (void) + { +- log_ctx_free(zeroconf_log); +- zeroconf_log = NULL; +- pthread_cond_destroy(&zeroconf_initscan_cond); ++ if (zeroconf_log != NULL) { ++ log_ctx_free(zeroconf_log); ++ zeroconf_log = NULL; ++ pthread_cond_destroy(&zeroconf_initscan_cond); ++ } + } + + /* vim:ts=8:sw=4:et +diff --git a/airscan.c b/airscan.c +index 198a09e..c422048 100644 +--- a/airscan.c ++++ b/airscan.c +@@ -8,6 +8,11 @@ + + #include "airscan.h" + ++/* Forward declarations ++ */ ++static void ++sane_exit_internal (void); ++ + /* Static variables + */ + static const SANE_Device **sane_device_list; +@@ -60,7 +65,7 @@ sane_init (SANE_Int *version_code, SANE_Auth_Callback authorize) + } + + if (status != SANE_STATUS_GOOD) { +- sane_exit(); ++ sane_exit_internal(); + } + + /* Start airscan thread */ +@@ -75,10 +80,10 @@ sane_init (SANE_Int *version_code, SANE_Auth_Callback authorize) + return status; + } + +-/* Exit the backend ++/* Exit the backend -- internal version + */ +-void +-sane_exit (void) ++static void ++sane_exit_internal (void) + { + log_debug(NULL, "sane_exit() called"); + +@@ -102,6 +107,22 @@ sane_exit (void) + log_cleanup(); /* Must be the last thing to do */ + } + ++/* Exit the backend ++ * ++ * It wraps sane_exit_internal(), which does the actual work. ++ * Without this wrapping, if sane_exit() is overridden by ++ * dynamic linking and sane_init() calls sane_exit() to ++ * cleanup after failed initialization, it leads to unpredictable ++ * results ++ * ++ * See #61 for details ++ */ ++void ++sane_exit (void) ++{ ++ sane_exit_internal(); ++} ++ + /* Get list of devices + */ + SANE_Status diff --git a/sane-airscan.spec b/sane-airscan.spec index 8ee22cf..a5a742b 100644 --- a/sane-airscan.spec +++ b/sane-airscan.spec @@ -5,13 +5,17 @@ Name: sane-airscan Version: 0.99.13 -Release: 1%{?dist} +Release: 2%{?dist} Summary: SANE backend for AirScan (eSCL) and WSD document scanners # the exception is defined in LICENSE, meant for SANE project in most cases License: GPLv2+ with exceptions URL: https://github.com/alexpevzner/sane-airscan Source: %{URL}/archive/%{version}/%{name}-%{version}.tar.gz +# crash wsdd_cleanup in mock - sane_exit from SANE libs was +# called instead of airscan internal one +Patch01: sane-airscan-exit.patch + # needed for querying and getting mDNS messages from local network BuildRequires: avahi-devel # project is written in C @@ -80,6 +84,9 @@ mkdir -p %{buildroot}/ %changelog +* Thu Aug 13 2020 Zdenek Dohnal - 0.99.13-2 +- 1867692 - airscan driver crashes in mock during wsdd_cleanup() + * Mon Aug 10 2020 Zdenek Dohnal - 0.99.13-1 - 0.99.13