Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
SUSE:SLE-15-SP2:Update
python-paramiko
CVE-2022-24302-race-condition.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File CVE-2022-24302-race-condition.patch of Package python-paramiko
Index: paramiko-2.4.2/paramiko/pkey.py =================================================================== --- paramiko-2.4.2.orig/paramiko/pkey.py +++ paramiko-2.4.2/paramiko/pkey.py @@ -519,7 +519,18 @@ class PKey(object): :raises: ``IOError`` -- if there was an error writing the file. """ - with open(filename, "w") as f: + # Ensure that we create new key files directly with a user-only mode, + # instead of opening, writing, then chmodding, which leaves us open to + # CVE-2022-24302. + # NOTE: O_TRUNC is a noop on new files, and O_CREAT is a noop on + # existing files, so using all 3 in both cases is fine. Ditto the use + # of the 'mode' argument; it should be safe to give even for existing + # files (though it will not act like a chmod in that case). + # TODO 3.0: turn into kwargs again + args = [os.O_WRONLY | os.O_TRUNC | os.O_CREAT, o600] + # NOTE: yea, you still gotta inform the FLO that it is in "write" mode + with os.fdopen(os.open(filename, *args), "w") as f: + # TODO 3.0: remove the now redundant chmod os.chmod(filename, o600) self._write_private_key(f, key, format, password=password) Index: paramiko-2.4.2/tests/test_pkey.py =================================================================== --- paramiko-2.4.2.orig/tests/test_pkey.py +++ paramiko-2.4.2/tests/test_pkey.py @@ -23,11 +23,15 @@ Some unit tests for public/private key o import unittest import os +import stat from binascii import hexlify from hashlib import md5 from paramiko import RSAKey, DSSKey, ECDSAKey, Ed25519Key, Message, util from paramiko.py3compat import StringIO, byte_chr, b, bytes, PY2 +from paramiko.common import o600 + +from mock import patch, Mock from .util import _support @@ -567,3 +571,57 @@ class KeyTest(unittest.TestCase): key1.load_certificate, _support("test_rsa.key-cert.pub"), ) + + @patch("paramiko.pkey.os") + def _test_keyfile_race(self, os_, exists): + # Re: CVE-2022-24302 + password = "television" + newpassword = "radio" + source = _support("test_ecdsa_384.key") + new = source + ".new" + # Mock setup + os_.path.exists.return_value = exists + # Attach os flag values to mock + for attr, value in vars(os).items(): + if attr.startswith("O_"): + setattr(os_, attr, value) + # Load fixture key + key = ECDSAKey(filename=source, password=password) + key._write_private_key = Mock() + # Write out in new location + key.write_private_key_file(new, password=newpassword) + # Expected open via os module + os_.open.assert_called_once_with(new, os.O_WRONLY | os.O_CREAT | os.O_TRUNC, o600) + os_.fdopen.assert_called_once_with(os_.open.return_value, "w") + # Old chmod still around for backwards compat + os_.chmod.assert_called_once_with(new, o600) + assert ( + key._write_private_key.call_args[0][0] + == os_.fdopen.return_value.__enter__.return_value + ) + + def test_new_keyfiles_avoid_file_descriptor_race_on_chmod(self): + self._test_keyfile_race(exists=False) + + def test_existing_keyfiles_still_work_ok(self): + self._test_keyfile_race(exists=True) + + def test_new_keyfiles_avoid_descriptor_race_integration(self): + # Integration-style version of above + password = "television" + newpassword = "radio" + source = _support("test_ecdsa_384.key") + new = source + ".new" + # Load fixture key + key = ECDSAKey(filename=source, password=password) + try: + # Write out in new location + key.write_private_key_file(new, password=newpassword) + # Test mode + assert stat.S_IMODE(os.stat(new).st_mode) == o600 + # Prove can open with new password + reloaded = ECDSAKey(filename=new, password=newpassword) + assert reloaded == key + finally: + if os.path.exists(new): + os.unlink(new)
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor