diff options
author | Yuri Konotopov <ykonotopov@gnome.org> | 2022-09-14 16:24:43 +0400 |
---|---|---|
committer | Mariusz Felisiak <felisiak.mariusz@gmail.com> | 2022-10-24 13:54:51 +0200 |
commit | 64e5ef1f17cd18cb8ca24f4e7107dfd28c18b378 (patch) | |
tree | 892cdb18df92907297cbe20f254060e219243b04 /tests/files | |
parent | 08c5a787262c1ae57f6517d4574b54a5fcaad124 (diff) | |
download | django-64e5ef1f17cd18cb8ca24f4e7107dfd28c18b378.tar.gz |
Fixed #29027 -- Fixed file_move_safe() crash when moving files with SELinux.
Thanks Florian Apolloner for the review.
Diffstat (limited to 'tests/files')
-rw-r--r-- | tests/files/tests.py | 46 |
1 files changed, 36 insertions, 10 deletions
diff --git a/tests/files/tests.py b/tests/files/tests.py index 9777d09e1c..b3478d2732 100644 --- a/tests/files/tests.py +++ b/tests/files/tests.py @@ -419,35 +419,61 @@ class FileMoveSafeTests(unittest.TestCase): os.close(handle_a) os.close(handle_b) - def test_file_move_copystat_cifs(self): + def test_file_move_permissionerror(self): """ - file_move_safe() ignores a copystat() EPERM PermissionError. This - happens when the destination filesystem is CIFS, for example. + file_move_safe() ignores PermissionError thrown by copystat() and + copymode(). + For example, PermissionError can be raised when the destination + filesystem is CIFS, or when relabel is disabled by SELinux across + filesystems. """ - copystat_EACCES_error = PermissionError(errno.EACCES, "msg") - copystat_EPERM_error = PermissionError(errno.EPERM, "msg") + permission_error = PermissionError(errno.EPERM, "msg") + os_error = OSError("msg") handle_a, self.file_a = tempfile.mkstemp() handle_b, self.file_b = tempfile.mkstemp() + handle_c, self.file_c = tempfile.mkstemp() try: # This exception is required to reach the copystat() call in # file_safe_move(). with mock.patch("django.core.files.move.os.rename", side_effect=OSError()): - # An error besides EPERM isn't ignored. + # An error besides PermissionError isn't ignored. with mock.patch( - "django.core.files.move.copystat", side_effect=copystat_EACCES_error + "django.core.files.move.copystat", side_effect=os_error ): - with self.assertRaises(PermissionError): + with self.assertRaises(OSError): file_move_safe(self.file_a, self.file_b, allow_overwrite=True) - # EPERM is ignored. + # When copystat() throws PermissionError, copymode() error besides + # PermissionError isn't ignored. with mock.patch( - "django.core.files.move.copystat", side_effect=copystat_EPERM_error + "django.core.files.move.copystat", side_effect=permission_error + ): + with mock.patch( + "django.core.files.move.copymode", side_effect=os_error + ): + with self.assertRaises(OSError): + file_move_safe( + self.file_a, self.file_b, allow_overwrite=True + ) + # PermissionError raised by copystat() is ignored. + with mock.patch( + "django.core.files.move.copystat", side_effect=permission_error ): self.assertIsNone( file_move_safe(self.file_a, self.file_b, allow_overwrite=True) ) + # PermissionError raised by copymode() is ignored too. + with mock.patch( + "django.core.files.move.copymode", side_effect=permission_error + ): + self.assertIsNone( + file_move_safe( + self.file_c, self.file_b, allow_overwrite=True + ) + ) finally: os.close(handle_a) os.close(handle_b) + os.close(handle_c) class SpooledTempTests(unittest.TestCase): |