Title: Race condition in shutil.copyfile()
Type: security Stage:
Components: Library (Lib) Versions: Python 3.7, Python 2.7
Status: open Resolution:
Dependencies: Superseder:
Assigned To: Nosy List: Preston Moore, giampaolo.rodola
Priority: normal Keywords:

Created on 2017-05-18 20:22 by Preston Moore, last changed 2018-06-12 10:10 by giampaolo.rodola.

Pull Requests
URL Status Linked Edit
PR 1659 open python-dev, 2017-05-18 20:42
Messages (3)
msg293938 - (view) Author: Preston Moore (Preston Moore) * Date: 2017-05-18 20:21
A race condition exists in shutil.copyfile() that allows the file being copied to be replaced between the time it was initially checked with stat() in this function and when it is actually open()'d and copied.  This issue can be triggered from shutil.move() (and likely other places) when attempting to move a file from one location to another where the source and destination are on different devices.  This behavior can be replicated by setting a catchpoint in gdb on calls to stat() and, after the initial call to stat in shutil.copyfile(), replacing the source file.

The attached pull request addresses this issue by storing the inode number of the source file when it is initially stat()'d and comparing this value to an inode value taken from a call to fstat() after the file is open. If these two values differ, the file has been replaced.  This is the pattern employed by coreutil's mv utility in an effort to address this issue.

This bug was found as part of an ongoing research effort into detecting and addressing bugs caused by differences in the environments in which an application may be run (the environmental issue in this place being the difficulties around correctly copying a file from one disk to another).
msg293940 - (view) Author: Preston Moore (Preston Moore) * Date: 2017-05-18 20:49
It looks like the PR is not passing 3 tests.  I think this might be a result of the mock file objects not having inode numbers? Any feedback on this front?
msg296037 - (view) Author: Preston Moore (Preston Moore) * Date: 2017-06-14 20:44
Pull request is now passing with no conflicts.
Date User Action Args
2018-06-12 10:10:13giampaolo.rodolasetnosy: + giampaolo.rodola
2017-06-14 20:44:22Preston Mooresetmessages: + msg296037
2017-05-18 20:49:01Preston Mooresetmessages: + msg293940
2017-05-18 20:42:07python-devsetpull_requests: + pull_request1753
2017-05-18 20:22:00Preston Moorecreate