From f62c129198cc5e5c83dba2e09867f78eedd011af Mon Sep 17 00:00:00 2001 From: Andrew Gunnerson Date: Wed, 15 Feb 2023 18:43:46 -0500 Subject: [PATCH] avbroot/ota.py: Fix EPIPE when interrupted by controlling TTY This fixes an issue where BrokenPipeError was being raised while handling a KeyboardInterrupt on Linux. This was happening because ^C and ^\ cause SIGINT/SIGQUIT to be sent to the entire process group, including `openssl cms`. openssl would die and ZipFile's __exit__ would try to finalize the zip during stack unwinding, causing a write to a dead pipe. Signed-off-by: Andrew Gunnerson --- avbroot/ota.py | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/avbroot/ota.py b/avbroot/ota.py index e86081f..ed6b775 100644 --- a/avbroot/ota.py +++ b/avbroot/ota.py @@ -664,6 +664,16 @@ def open_signing_wrapper(f, privkey, passphrase, cert): ''' with openssl.inject_passphrase(passphrase): + session_kwargs = {} + if os.name != 'nt': + # We don't want the controlling terminal to interrupt openssl on + # ^C or ^\. That'll cause _TeeFileDescriptor's writes to the stdin + # pipe to fail, and certain classes, like ZipFile, will write to + # the fd in their __exit__ methods. This causes a BrokenPipeError + # to be raised while the existing KeyboardInterrupt is being + # propagated up. We'll handling killing openssl ourselves. + session_kwargs['start_new_session'] = True + process = subprocess.Popen( [ 'openssl', @@ -679,6 +689,7 @@ def open_signing_wrapper(f, privkey, passphrase, cert): ], stdin=subprocess.PIPE, stdout=subprocess.PIPE, + **session_kwargs, ) try: