Commit cc08cd6a authored by Jesus Cea's avatar Jesus Cea

Closes #15897: zipimport.c doesn't check return value of fseek()

parent d4fc2553
...@@ -227,6 +227,7 @@ Christopher A. Craig ...@@ -227,6 +227,7 @@ Christopher A. Craig
Jeremy Craven Jeremy Craven
Laura Creighton Laura Creighton
Simon Cross Simon Cross
Felipe Cruz
Drew Csillag Drew Csillag
Joaquin Cuenca Abela Joaquin Cuenca Abela
John Cugini John Cugini
......
...@@ -49,6 +49,9 @@ Core and Builtins ...@@ -49,6 +49,9 @@ Core and Builtins
- Issue #15020: The program name used to search for Python's path is now - Issue #15020: The program name used to search for Python's path is now
"python3" under Unix, not "python". "python3" under Unix, not "python".
- Issue #15897: zipimport.c doesn't check return value of fseek().
Patch by Felipe Cruz.
- Issue #15033: Fix the exit status bug when modules invoked using -m swith, - Issue #15033: Fix the exit status bug when modules invoked using -m swith,
return the proper failure return value (1). Patch contributed by Jeff Knupp. return the proper failure return value (1). Patch contributed by Jeff Knupp.
......
...@@ -741,7 +741,12 @@ read_directory(PyObject *archive_obj) ...@@ -741,7 +741,12 @@ read_directory(PyObject *archive_obj)
PyErr_Format(ZipImportError, "can't open Zip file: '%U'", archive_obj); PyErr_Format(ZipImportError, "can't open Zip file: '%U'", archive_obj);
return NULL; return NULL;
} }
fseek(fp, -22, SEEK_END);
if (fseek(fp, -22, SEEK_END) == -1) {
fclose(fp);
PyErr_Format(ZipImportError, "can't read Zip file: %R", archive);
return NULL;
}
header_position = ftell(fp); header_position = ftell(fp);
if (fread(endof_central_dir, 1, 22, fp) != 22) { if (fread(endof_central_dir, 1, 22, fp) != 22) {
fclose(fp); fclose(fp);
...@@ -773,11 +778,13 @@ read_directory(PyObject *archive_obj) ...@@ -773,11 +778,13 @@ read_directory(PyObject *archive_obj)
PyObject *t; PyObject *t;
int err; int err;
fseek(fp, header_offset, 0); /* Start of file header */ if (fseek(fp, header_offset, 0) == -1) /* Start of file header */
goto fseek_error;
l = PyMarshal_ReadLongFromFile(fp); l = PyMarshal_ReadLongFromFile(fp);
if (l != 0x02014B50) if (l != 0x02014B50)
break; /* Bad: Central Dir File Header */ break; /* Bad: Central Dir File Header */
fseek(fp, header_offset + 8, 0); if (fseek(fp, header_offset + 8, 0) == -1)
goto fseek_error;
flags = (unsigned short)PyMarshal_ReadShortFromFile(fp); flags = (unsigned short)PyMarshal_ReadShortFromFile(fp);
compress = PyMarshal_ReadShortFromFile(fp); compress = PyMarshal_ReadShortFromFile(fp);
time = PyMarshal_ReadShortFromFile(fp); time = PyMarshal_ReadShortFromFile(fp);
...@@ -789,7 +796,8 @@ read_directory(PyObject *archive_obj) ...@@ -789,7 +796,8 @@ read_directory(PyObject *archive_obj)
header_size = 46 + name_size + header_size = 46 + name_size +
PyMarshal_ReadShortFromFile(fp) + PyMarshal_ReadShortFromFile(fp) +
PyMarshal_ReadShortFromFile(fp); PyMarshal_ReadShortFromFile(fp);
fseek(fp, header_offset + 42, 0); if (fseek(fp, header_offset + 42, 0) == -1)
goto fseek_error;
file_offset = PyMarshal_ReadLongFromFile(fp) + arc_offset; file_offset = PyMarshal_ReadLongFromFile(fp) + arc_offset;
if (name_size > MAXPATHLEN) if (name_size > MAXPATHLEN)
name_size = MAXPATHLEN; name_size = MAXPATHLEN;
...@@ -849,6 +857,12 @@ read_directory(PyObject *archive_obj) ...@@ -849,6 +857,12 @@ read_directory(PyObject *archive_obj)
PySys_FormatStderr("# zipimport: found %ld names in %U\n", PySys_FormatStderr("# zipimport: found %ld names in %U\n",
count, archive_obj); count, archive_obj);
return files; return files;
fseek_error:
fclose(fp);
Py_XDECREF(files);
Py_XDECREF(nameobj);
PyErr_Format(ZipImportError, "can't read Zip file: %R", archive);
return NULL;
error: error:
fclose(fp); fclose(fp);
Py_XDECREF(files); Py_XDECREF(files);
...@@ -918,7 +932,12 @@ get_data(PyObject *archive, PyObject *toc_entry) ...@@ -918,7 +932,12 @@ get_data(PyObject *archive, PyObject *toc_entry)
} }
/* Check to make sure the local file header is correct */ /* Check to make sure the local file header is correct */
fseek(fp, file_offset, 0); if (fseek(fp, file_offset, 0) == -1) {
fclose(fp);
PyErr_Format(ZipImportError, "can't read Zip file: %R", archive);
return NULL;
}
l = PyMarshal_ReadLongFromFile(fp); l = PyMarshal_ReadLongFromFile(fp);
if (l != 0x04034B50) { if (l != 0x04034B50) {
/* Bad: Local File Header */ /* Bad: Local File Header */
...@@ -928,7 +947,12 @@ get_data(PyObject *archive, PyObject *toc_entry) ...@@ -928,7 +947,12 @@ get_data(PyObject *archive, PyObject *toc_entry)
fclose(fp); fclose(fp);
return NULL; return NULL;
} }
fseek(fp, file_offset + 26, 0); if (fseek(fp, file_offset + 26, 0) == -1) {
fclose(fp);
PyErr_Format(ZipImportError, "can't read Zip file: %R", archive);
return NULL;
}
l = 30 + PyMarshal_ReadShortFromFile(fp) + l = 30 + PyMarshal_ReadShortFromFile(fp) +
PyMarshal_ReadShortFromFile(fp); /* local header size */ PyMarshal_ReadShortFromFile(fp); /* local header size */
file_offset += l; /* Start of file data */ file_offset += l; /* Start of file data */
...@@ -945,8 +969,13 @@ get_data(PyObject *archive, PyObject *toc_entry) ...@@ -945,8 +969,13 @@ get_data(PyObject *archive, PyObject *toc_entry)
buf = PyBytes_AsString(raw_data); buf = PyBytes_AsString(raw_data);
err = fseek(fp, file_offset, 0); err = fseek(fp, file_offset, 0);
if (err == 0) if (err == 0) {
bytes_read = fread(buf, 1, data_size, fp); bytes_read = fread(buf, 1, data_size, fp);
} else {
fclose(fp);
PyErr_Format(ZipImportError, "can't read Zip file: %R", archive);
return NULL;
}
fclose(fp); fclose(fp);
if (err || bytes_read != data_size) { if (err || bytes_read != data_size) {
PyErr_SetString(PyExc_IOError, PyErr_SetString(PyExc_IOError,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment