From: Neal Norwitz Date: Thu, 5 Sep 2002 22:30:03 +0000 (+0000) Subject: Backport of SF bug # 585792, Invalid mmap crashes Python interpreter X-Git-Tag: v2.2.2b1~183 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=df4626fb8a003fdce8996fcdbefe1bba1f2a63cf;p=thirdparty%2FPython%2Fcpython.git Backport of SF bug # 585792, Invalid mmap crashes Python interpreter Raise ValueError if user passes a size to mmap which is larger than the file. Also need Tim's fix in test_mmap.py, 1.22 which flushes the file before mmap'ing it. --- diff --git a/Lib/test/output/test_mmap b/Lib/test/output/test_mmap index 4adf7027b78f..1706ad586805 100644 --- a/Lib/test/output/test_mmap +++ b/Lib/test/output/test_mmap @@ -24,6 +24,7 @@ test_mmap Ensuring that readonly mmap can't be write() to. Ensuring that readonly mmap can't be write_byte() to. Ensuring that readonly mmap can't be resized. + Opening mmap with size too big Opening mmap with access=ACCESS_WRITE Modifying write-through memory map. Opening mmap with access=ACCESS_COPY diff --git a/Lib/test/test_mmap.py b/Lib/test/test_mmap.py index fcf3c92ca752..7333d5f4dbc2 100644 --- a/Lib/test/test_mmap.py +++ b/Lib/test/test_mmap.py @@ -17,6 +17,7 @@ def test_both(): f.write('\0'* PAGESIZE) f.write('foo') f.write('\0'* (PAGESIZE-3) ) + f.flush() m = mmap.mmap(f.fileno(), 2 * PAGESIZE) f.close() @@ -189,6 +190,21 @@ def test_both(): verify(open(TESTFN, "rb").read() == 'a'*mapsize, "Readonly memory map data file was modified") + print " Opening mmap with size too big" + import sys + f = open(TESTFN, "r+b") + try: + m = mmap.mmap(f.fileno(), mapsize+1) + except ValueError: + # we do not expect a ValueError on Windows + if sys.platform.startswith('win'): + verify(0, "Opening mmap with size+1 should work on Windows.") + pass + else: + # we expect a ValueError on Unix, but not on Windows + if not sys.platform.startswith('win'): + verify(0, "Opening mmap with size+1 should raise ValueError.") + print " Opening mmap with access=ACCESS_WRITE" f = open(TESTFN, "r+b") m = mmap.mmap(f.fileno(), mapsize, access=mmap.ACCESS_WRITE) diff --git a/Misc/NEWS b/Misc/NEWS index a823bce79bc9..99704c8b54d1 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -45,6 +45,11 @@ Core and builtins will return "200". This is useful for replacing code that assumed longs will always be printed with a trailing "L". +Extension modules + +- If the size passed to mmap.mmap() is larger than the length of the + file on non-Windows platforms, a ValueError is raised. [SF bug 585792] + Library - Some fixes in the copy module: when an object is copied through its diff --git a/Modules/mmapmodule.c b/Modules/mmapmodule.c index 5bad8e45afe8..cabb8600869e 100644 --- a/Modules/mmapmodule.c +++ b/Modules/mmapmodule.c @@ -850,6 +850,9 @@ _GetMapSize(PyObject *o) static PyObject * new_mmap_object(PyObject *self, PyObject *args, PyObject *kwdict) { +#ifdef HAVE_FSTAT + struct stat st; +#endif mmap_object *m_obj; PyObject *map_size_obj = NULL; int map_size; @@ -890,7 +893,14 @@ new_mmap_object(PyObject *self, PyObject *args, PyObject *kwdict) return PyErr_Format(PyExc_ValueError, "mmap invalid access parameter."); } - + +#ifdef HAVE_FSTAT + if (fstat(fd, &st) == 0 && (size_t)map_size > st.st_size) { + PyErr_SetString(PyExc_ValueError, + "mmap length is greater than file size"); + return NULL; + } +#endif m_obj = PyObject_New (mmap_object, &mmap_object_type); if (m_obj == NULL) {return NULL;} m_obj->size = (size_t) map_size;