mirror of
https://github.com/django/django.git
synced 2025-08-03 18:38:50 +00:00
Fixed #29027 -- Fixed file_move_safe() crash when moving files with SELinux.
Thanks Florian Apolloner for the review.
This commit is contained in:
parent
08c5a78726
commit
64e5ef1f17
2 changed files with 44 additions and 16 deletions
|
@ -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):
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue