From: Neal Norwitz <nnorwitz@gmail.com>
Date: Thu, 5 Sep 2002 21:48:07 +0000 (+0000)
Subject: SF bug # 585792, Invalid mmap crashes Python interpreter
X-Git-Tag: v2.3c1~4204
X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=b567392bbf3c595a47b86ea4d6038af0ec28b383;p=python

SF bug # 585792, Invalid mmap crashes Python interpreter

Raise ValueError if user passes a size to mmap which is larger
than the file.
---

diff --git a/Lib/test/output/test_mmap b/Lib/test/output/test_mmap
index 4adf7027b7..1706ad5868 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 11edbaf797..dd1fb3f359 100644
--- a/Lib/test/test_mmap.py
+++ b/Lib/test/test_mmap.py
@@ -189,6 +189,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 f638e50e92..b877703afb 100644
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -274,6 +274,9 @@ Core and builtins
 
 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]
+
 - The xreadlines module is slated for obsolescence.
 
 - The strptime function in the time module is now always available (a
diff --git a/Modules/mmapmodule.c b/Modules/mmapmodule.c
index 2bb6edc808..cff3c146e6 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;