Browse Source

safer os.chmod for wallet files and config: set perms before write

Set unix file permissions first, before writing data.
master
SomberNight 2 years ago
parent
commit
f495511886
No known key found for this signature in database
GPG Key ID: B33B5F232C6271E9
  1. 2
      electrum/gui/qt/main_window.py
  2. 2
      electrum/simple_config.py
  3. 10
      electrum/storage.py

2
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"])

2
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,

10
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}")

Loading…
Cancel
Save