diff options
author | Kristján Valur Jónsson <kristjan@ccpgames.com> | 2009-03-24 15:27:42 (GMT) |
---|---|---|
committer | Kristján Valur Jónsson <kristjan@ccpgames.com> | 2009-03-24 15:27:42 (GMT) |
commit | a8abe863316b8f0bc92c9a490573dde67c7c81e6 (patch) | |
tree | bc85db382070c19b73c12a900278567ddbc0b279 /Modules | |
parent | 649170bd66e0084f227b55a6941c41e0c4d79df7 (diff) | |
download | cpython-a8abe863316b8f0bc92c9a490573dde67c7c81e6.zip cpython-a8abe863316b8f0bc92c9a490573dde67c7c81e6.tar.gz cpython-a8abe863316b8f0bc92c9a490573dde67c7c81e6.tar.bz2 |
http://bugs.python.org/issue5544
Guard _fileio.c against other malicious os.close(f.fileno()) attempts.
Add tests to test_fileio.py to verify behaviour.
Diffstat (limited to 'Modules')
-rw-r--r-- | Modules/_fileio.c | 51 |
1 files changed, 34 insertions, 17 deletions
diff --git a/Modules/_fileio.c b/Modules/_fileio.c index cc1cbef..27823b3 100644 --- a/Modules/_fileio.c +++ b/Modules/_fileio.c @@ -475,10 +475,13 @@ fileio_readinto(PyFileIOObject *self, PyObject *args) if (!PyArg_ParseTuple(args, "w*", &pbuf)) return NULL; - Py_BEGIN_ALLOW_THREADS - errno = 0; - n = read(self->fd, pbuf.buf, pbuf.len); - Py_END_ALLOW_THREADS + if (_PyVerify_fd(self->fd)) { + Py_BEGIN_ALLOW_THREADS + errno = 0; + n = read(self->fd, pbuf.buf, pbuf.len); + Py_END_ALLOW_THREADS + } else + n = -1; PyBuffer_Release(&pbuf); if (n < 0) { if (errno == EAGAIN) @@ -522,6 +525,9 @@ fileio_readall(PyFileIOObject *self) Py_ssize_t total = 0; int n; + if (!_PyVerify_fd(self->fd)) + return PyErr_SetFromErrno(PyExc_IOError); + result = PyBytes_FromStringAndSize(NULL, SMALLCHUNK); if (result == NULL) return NULL; @@ -596,10 +602,13 @@ fileio_read(PyFileIOObject *self, PyObject *args) return NULL; ptr = PyBytes_AS_STRING(bytes); - Py_BEGIN_ALLOW_THREADS - errno = 0; - n = read(self->fd, ptr, size); - Py_END_ALLOW_THREADS + if (_PyVerify_fd(self->fd)) { + Py_BEGIN_ALLOW_THREADS + errno = 0; + n = read(self->fd, ptr, size); + Py_END_ALLOW_THREADS + } else + n = -1; if (n < 0) { if (errno == EAGAIN) @@ -632,10 +641,13 @@ fileio_write(PyFileIOObject *self, PyObject *args) if (!PyArg_ParseTuple(args, "s*", &pbuf)) return NULL; - Py_BEGIN_ALLOW_THREADS - errno = 0; - n = write(self->fd, pbuf.buf, pbuf.len); - Py_END_ALLOW_THREADS + if (_PyVerify_fd(self->fd)) { + Py_BEGIN_ALLOW_THREADS + errno = 0; + n = write(self->fd, pbuf.buf, pbuf.len); + Py_END_ALLOW_THREADS + } else + n = -1; PyBuffer_Release(&pbuf); @@ -688,13 +700,16 @@ portable_lseek(int fd, PyObject *posobj, int whence) return NULL; } - Py_BEGIN_ALLOW_THREADS + if (_PyVerify_fd(fd)) { + Py_BEGIN_ALLOW_THREADS #if defined(MS_WIN64) || defined(MS_WINDOWS) - res = _lseeki64(fd, pos, whence); + res = _lseeki64(fd, pos, whence); #else - res = lseek(fd, pos, whence); + res = lseek(fd, pos, whence); #endif - Py_END_ALLOW_THREADS + Py_END_ALLOW_THREADS + } else + res = -1; if (res < 0) return PyErr_SetFromErrno(PyExc_IOError); @@ -757,13 +772,15 @@ fileio_truncate(PyFileIOObject *self, PyObject *args) /* Move to the position to be truncated. */ posobj = portable_lseek(fd, posobj, 0); } + if (posobj == NULL) + return NULL; #if defined(HAVE_LARGEFILE_SUPPORT) pos = PyLong_AsLongLong(posobj); #else pos = PyLong_AsLong(posobj); #endif - if (PyErr_Occurred()) + if (pos == -1 && PyErr_Occurred()) return NULL; #ifdef MS_WINDOWS |