Package: osc Version: 0.162.1-1 Severity: normal Tags: patch pending Control: tags 895035 + patch pending Control: tags 898775 + patch pending
Hi, I needed to build a working osc for $work, so I've prepared an NMU for osc (versioned as 0.162.1-1.1) and uploaded it to DELAYED/7. Please feel free to tell me if I should change the delay or cancel it. The build tool I use is pedantic about Policy §7.7, so I had to fix #898775 as well as #895035 to be able to NMU. Regards, smcv
diffstat for osc-0.162.1 osc-0.162.1 changelog | 15 +++ control | 12 +-- patches/Disable-ssl-session-resumption.patch | 105 +++++++++++++++++++++++++++ patches/series | 1 4 files changed, 127 insertions(+), 6 deletions(-) diff -Nru osc-0.162.1/debian/changelog osc-0.162.1/debian/changelog --- osc-0.162.1/debian/changelog 2018-01-23 08:47:02.000000000 +0000 +++ osc-0.162.1/debian/changelog 2018-05-17 21:48:13.000000000 +0100 @@ -1,3 +1,18 @@ +osc (0.162.1-1.1) unstable; urgency=medium + + * Non-maintainer upload. + * Merge Build-Depends-Indep into Build-Depends. The python2 and + bash-completion debhelper sequences are needed for the clean target + when building a source package, but that target is only guaranteed to + have the Build-Depends available; and python-urlgrabber turns out to + also be needed during clean, because it's indirectly imported + by setup.py. (Closes: #898775) + * d/p/Disable-ssl-session-resumption.patch: + Add patch from upstream fixing a segfault when used with + libssl1.1 (>= 1.1.0h) (Closes: #895035) + + -- Simon McVittie <s...@debian.org> Thu, 17 May 2018 21:48:13 +0100 + osc (0.162.1-1) unstable; urgency=medium * New upstream release. diff -Nru osc-0.162.1/debian/control osc-0.162.1/debian/control --- osc-0.162.1/debian/control 2018-01-23 08:46:42.000000000 +0000 +++ osc-0.162.1/debian/control 2018-05-17 21:48:13.000000000 +0100 @@ -3,12 +3,12 @@ Uploaders: Michal Čihař <ni...@debian.org> Section: devel Priority: optional -Build-Depends: debhelper (>= 9), - dh-exec -Build-Depends-Indep: python, - python-urlgrabber, - dh-python, - bash-completion +Build-Depends: bash-completion, + debhelper (>= 9), + dh-exec, + dh-python, + python, + python-urlgrabber Standards-Version: 4.1.3 Vcs-Browser: https://anonscm.debian.org/git/pkg-rpm/osc.git Vcs-Git: https://anonscm.debian.org/git/pkg-rpm/osc.git diff -Nru osc-0.162.1/debian/patches/Disable-ssl-session-resumption.patch osc-0.162.1/debian/patches/Disable-ssl-session-resumption.patch --- osc-0.162.1/debian/patches/Disable-ssl-session-resumption.patch 1970-01-01 01:00:00.000000000 +0100 +++ osc-0.162.1/debian/patches/Disable-ssl-session-resumption.patch 2018-05-17 21:48:13.000000000 +0100 @@ -0,0 +1,105 @@ +From: Marcus Huewe <suse-...@gmx.de> +Date: Tue, 8 May 2018 14:23:08 +0200 +Subject: Disable ssl session resumption + +The old code could potentially yield to a use-after-free situation, +which results in UB. For this, consider the following scenario, where +osc performs several HTTPS requests (assumption: the server supports +ssl session resumption): + +- HTTPS Request 1: + * a new SSL *s connection is established, which also creates a new + SSL_SESSION *ss => ss->references == 1 + * once the handshake is done, the ss is put into the session cache + (see ssl_update_cache) => ss->references == 2 + - osc saves the session ss in a class variable + - s is SSL_free()d, which calls SSL_SESSION_free => ss->references == 1 + +- HTTPS Request 2: + * setup a new SSL *s connection that reuses the saved session ss + => ss->references == 2 + * once the handshake is done, ssl_update_cache is called, which is a + NOP, because s->hit == 1 (that is, the session was resumed) + * osc saves the session ss in a class variable + * s is SSL_free()d, which calls SSL_SESSION_free => ss->references == 1 + +... + +> 2 hours later (see tls1_default_timeout) + +... + +- HTTPS Request 256: + * setup a new SSL *s connection that reuses the saved session ss + => ss->references == 2 + * once the handshake is done, ssl_update_cache is called, but is + _no_ NOP anymore + * ssl_update_cache flushes the session cache (this is done every + 255/256 (depending on the way we count) connections) => ss is + SSL_SESSION_free()d => ss->references == 1 + * osc saves the session ss in a class variable + * s is SSL_free()d, which calls SSL_SESSION_free: + since ss->references == 1, ss is eventually free()d + +- HTTPS Request 257: + * setup a new SSL *s connection that reuses the saved session ss + +Since ss does not exist anymore, the remaining program execution is UB. + +(Note: SSL_free(...) is _NOT_ called, if M2Crypto 0.29 is used. +M2Crypto 0.30 calls SSL_free(...) again.) + +Due to a bug in OpenSSL_1_1_0h (see openssl commit 8e405776858) the +scenario from above can be triggered with exactly 2 HTTPS requests (the +SSL_SESSION is not cached, because we configured SSL_VERIFY_PEER, but +no sid_ctx was set). This is fixed in openssl commit c4fa1f7fc01. + +In order to reliably reuse a session, we probably need to listen to the +session cache changes. Such callbacks could be registered via +SSL_CTX_sess_set_new_cb and/or SSL_CTX_sess_set_remove_cb, but both +functions are not provided by M2Crypto. Another idea is to directly utilize +the session cache, but this also has to be implemented in M2Crypto first. +Yet another approach is to retrieve the session via SSL_get1_session, which +increases the session's refcnt, but this also needs to be implemented in +M2Crypto first (if we choose to use this approach, we also have to make +sure that we eventually free the session manually...). + +Fixes: #398 ("SIGSEGV on \"osc commit\"") +Origin: upstream, 0.162.2, commit:https://github.com/openSUSE/osc/commit/b730f880cfe85a8547f569355a21706f27ebfa78 +Bug: https://github.com/openSUSE/osc/issues/398 +Bug-Debian: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=895035 +--- + osc/oscssl.py | 6 ------ + 1 file changed, 6 deletions(-) + +diff --git a/osc/oscssl.py b/osc/oscssl.py +index 7aa5a0d..186c98d 100644 +--- a/osc/oscssl.py ++++ b/osc/oscssl.py +@@ -174,7 +174,6 @@ class mySSLContext(SSL.Context): + + class myHTTPSHandler(M2Crypto.m2urllib2.HTTPSHandler): + handler_order = 499 +- saved_session = None + + def __init__(self, *args, **kwargs): + self.appname = kwargs.pop('appname', 'generic') +@@ -204,8 +203,6 @@ class myHTTPSHandler(M2Crypto.m2urllib2.HTTPSHandler): + selector = req.get_selector() + # End our change + h.set_debuglevel(self._debuglevel) +- if self.saved_session: +- h.set_session(self.saved_session) + + headers = dict(req.headers) + headers.update(req.unredirected_hdrs) +@@ -218,9 +215,6 @@ class myHTTPSHandler(M2Crypto.m2urllib2.HTTPSHandler): + headers["Connection"] = "close" + try: + h.request(req.get_method(), selector, req.data, headers) +- s = h.get_session() +- if s: +- self.saved_session = s + r = h.getresponse() + except socket.error as err: # XXX what error? + err.filename = full_url diff -Nru osc-0.162.1/debian/patches/series osc-0.162.1/debian/patches/series --- osc-0.162.1/debian/patches/series 1970-01-01 01:00:00.000000000 +0100 +++ osc-0.162.1/debian/patches/series 2018-05-17 21:48:13.000000000 +0100 @@ -0,0 +1 @@ +Disable-ssl-session-resumption.patch