From f495511886aee470a1132dc945dfe449b4b07ccf Mon Sep 17 00:00:00 2001 From: SomberNight Date: Mon, 8 Apr 2024 13:55:52 +0000 Subject: [PATCH] safer os.chmod for wallet files and config: set perms before write Set unix file permissions first, before writing data. --- electrum/gui/qt/main_window.py | 2 +- electrum/simple_config.py | 2 +- electrum/storage.py | 10 +++++----- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/electrum/gui/qt/main_window.py b/electrum/gui/qt/main_window.py index 57c8ec0e6..bad544f5f 100644 --- a/electrum/gui/qt/main_window.py +++ b/electrum/gui/qt/main_window.py @@ -2332,7 +2332,7 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, Logger, QtEventListener): def do_export_privkeys(self, fileName, pklist, is_csv): with open(fileName, "w+") as f: - os_chmod(fileName, 0o600) + os_chmod(fileName, 0o600) # set restrictive perms *before* we write data if is_csv: transaction = csv.writer(f) transaction.writerow(["address", "private_key"]) diff --git a/electrum/simple_config.py b/electrum/simple_config.py index 36b472f77..a8edefc7f 100644 --- a/electrum/simple_config.py +++ b/electrum/simple_config.py @@ -421,8 +421,8 @@ class SimpleConfig(Logger): s = json.dumps(self.user_config, indent=4, sort_keys=True) try: with open(path, "w", encoding='utf-8') as f: + os_chmod(path, stat.S_IREAD | stat.S_IWRITE) # set restrictive perms *before* we write data f.write(s) - os_chmod(path, stat.S_IREAD | stat.S_IWRITE) except OSError: # datadir probably deleted while running... e.g. portable exe running on ejected USB drive # (in which case it is typically either FileNotFoundError or PermissionError, diff --git a/electrum/storage.py b/electrum/storage.py index eaf63b32a..d5770424a 100644 --- a/electrum/storage.py +++ b/electrum/storage.py @@ -87,22 +87,22 @@ class WalletStorage(Logger): return self.decrypted if self.is_encrypted() else self.raw def write(self, data: str) -> None: + try: + mode = os.stat(self.path).st_mode + except FileNotFoundError: + mode = stat.S_IREAD | stat.S_IWRITE s = self.encrypt_before_writing(data) temp_path = "%s.tmp.%s" % (self.path, os.getpid()) with open(temp_path, "wb") as f: + os_chmod(temp_path, mode) # set restrictive perms *before* we write data f.write(s.encode("utf-8")) self.pos = f.seek(0, os.SEEK_END) f.flush() os.fsync(f.fileno()) - try: - mode = os.stat(self.path).st_mode - except FileNotFoundError: - mode = stat.S_IREAD | stat.S_IWRITE # assert that wallet file does not exist, to prevent wallet corruption (see issue #5082) if not self.file_exists(): assert not os.path.exists(self.path) os.replace(temp_path, self.path) - os_chmod(self.path, mode) self._file_exists = True self.logger.info(f"saved {self.path}")