host: check reply_fds before sending them

If there are fds to send back to the client, do a check that none
of them are invalid, so that we do not raise an exception in send
later. This allows us to send a proper RemoteError instead of no
reply at all.
This commit is contained in:
Christian Kellner 2021-09-24 11:17:45 +02:00 committed by Tom Gundersen
parent 6a39067772
commit 28dcd0ee9a

View file

@ -38,6 +38,7 @@ their clean up, independent of any control of osbuild.
import abc
import argparse
import asyncio
import fcntl
import importlib
import io
import os
@ -252,11 +253,17 @@ class Service(abc.ABC):
if not msg:
break
reply_fds = None
try:
reply, reply_fds = self._handle_message(msg, fds)
# Catch invalid file descriptors early so that
# we send an error reply instead of throwing
# an exception in `sock.send` later.
self._check_fds(reply_fds)
except: # pylint: disable=bare-except
reply_fds = None
reply_fds = self._close_all(reply_fds)
_, val, tb = sys.exc_info()
reply = self.protocol.encode_exception(val, tb)
@ -289,13 +296,22 @@ class Service(abc.ABC):
@staticmethod
def _close_all(fds: Optional[List[int]]):
if not fds:
return
return []
for fd in fds:
try:
os.close(fd)
except OSError as e:
print(f"error closing fd '{fd}': {e!s}")
return []
@staticmethod
def _check_fds(fds: Optional[List[int]]):
if not fds:
return
for fd in fds:
fcntl.fcntl(fd, fcntl.F_GETFD)
class ServiceClient: