8000 gh-73069 c2: fix race conditions with os.scandir direntry stat · python/cpython@2aa5de3 · GitHub
[go: up one dir, main page]

Skip to content

Commit 2aa5de3

Browse files
committed
gh-73069 c2: fix race conditions with os.scandir direntry stat
1 parent 7f1fa36 commit 2aa5de3

File tree

1 file changed

+13
-1
lines changed

1 file changed

+13
-1
lines changed

Modules/posixmodule.c

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15582,6 +15582,7 @@ typedef struct {
1558215582
ino_t d_ino;
1558315583
int dir_fd;
1558415584
#endif
15585+
PyMutex mutex;
1558515586
} DirEntry;
1558615587

1558715588
#define DirEntry_CAST(op) ((DirEntry *)(op))
@@ -15591,10 +15592,12 @@ DirEntry_dealloc(PyObject *op)
1559115592
{
1559215593
DirEntry *entry = DirEntry_CAST(op);
1559315594
PyTypeObject *tp = Py_TYPE(entry);
15595+
PyMutex_Lock(&entry->mutex);
1559415596
Py_XDECREF(entry->name);
1559515597
Py_XDECREF(entry->path);
1559615598
Py_XDECREF(entry->stat);
1559715599
Py_XDECREF(entry->lstat);
15600+
PyMutex_Unlock(&entry->mutex);
1559815601
freefunc free_func = PyType_GetSlot(tp, Py_tp_free);
1559915602
free_func(entry);
1560015603
Py_DECREF(tp);
@@ -15712,6 +15715,7 @@ DirEntry_fetch_stat(PyObject *module, DirEntry *self, int follow_symlinks)
1571215715
static PyObject *
1571315716
DirEntry_get_lstat(PyTypeObject *defining_class, DirEntry *self)
1571415717
{
15718+
/* Must be called with self->mutex held */
1571515719
if (!self->lstat) {
1571615720
PyObject *module = PyType_GetModule(defining_class);
1571715721
#ifdef MS_WINDOWS
@@ -15739,12 +15743,17 @@ os_DirEntry_stat_impl(DirEntry *self, PyTypeObject *defining_class,
1573915743
/*[clinic end generated code: output=23f803e19c3e780e input=e816273c4e67ee98]*/
1574015744
{
1574115745
if (!follow_symlinks) {
15742-
return DirEntry_get_lstat(defining_class, self);
15746+
PyMutex_Lock(&self->mutex);
15747+
PyObject *stat = DirEntry_get_lstat(defining_class, self);
15748+
PyMutex_Unlock(&self->mutex);
15749+
return stat;
1574315750
}
1574415751

15752+
PyMutex_Lock(&self->mutex);
1574515753
if (!self->stat) {
1574615754
int result = os_DirEntry_is_symlink_impl(self, defining_class);
1574715755
if (result == -1) {
15756+
PyMutex_Unlock(&self->mutex);
1574815757
return NULL;
1574915758
}
1575015759
if (result) {
@@ -15755,6 +15764,7 @@ os_DirEntry_stat_impl(DirEntry *self, PyTypeObject *defining_class,
1575515764
self->stat = DirEntry_get_lstat(defining_class, self);
1575615765
}
1575715766
}
15767+
PyMutex_Unlock(&self->mutex);
1575815768

1575915769
return Py_XNewRef(self->stat);
1576015770
}
@@ -16029,6 +16039,7 @@ DirEntry_from_find_data(PyObject *module, path_t *path, WIN32_FIND_DATAW *dataW)
1602916039
entry->stat = NULL;
1603016040
entry->lstat = NULL;
1603116041
entry->got_file_index = 0;
16042+
entry->mutex = (PyMutex){0};
1603216043

1603316044
entry->name = PyUnicode_FromWideChar(dataW->cFileName, -1);
1603416045
if (!entry->name)
@@ -16121,6 +16132,7 @@ DirEntry_from_posix_info(PyObject *module, path_t *path, const char *name,
1612116132
entry->path = NULL;
1612216133
entry->stat = NULL;
1612316134
entry->lstat = NULL;
16135+
entry->mutex = (PyMutex){0};
1612416136

1612516137
if (path->fd != -1) {
1612616138
entry->dir_fd = path->fd;

0 commit comments

Comments
 (0)
0