This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: Crash in imputil.imp.find_module when a *directory* exists with the given name due to double-close of FILE*
Type: crash Stage:
Components: Library (Lib) Versions: Python 2.7
process
Status: closed Resolution: duplicate
Dependencies: Superseder: imp.find_module crashes Python if there exists a directory named "__init__.py"
View: 7732
Assigned To: Nosy List: dmalcolm
Priority: normal Keywords:

Created on 2012-02-20 19:01 by dmalcolm, last changed 2022-04-11 14:57 by admin. This issue is now closed.

Messages (2)
msg153799 - (view) Author: Dave Malcolm (dmalcolm) (Python committer) Date: 2012-02-20 19:01
$ mkdir some_directory_ending_with_a.py
$ python -c "import imputil; imputil.imp.find_module('some_directory_ending_with_a')"
*** glibc detected *** python: double free or corruption (!prev): 0x0000000001589bf0 ***
Aborted

What's happening is that call_find_module opens fp, and tries to create a PyFileObject from it:

  2844     if (fp != NULL) {
>>2845         fob = PyFile_FromFile(fp, pathname, fdp->mode, fclose);
  2846         if (fob == NULL) {
  2847             fclose(fp);
  2848             return NULL;
  2849         }
  2850     }

The call fails at the very end of fill_file_fields() inside the call to dircheck() here:
   180      f->f_fp = fp;
   181      f = dircheck(f);
   182      return (PyObject *) f;
   183  }
   184  

but f->fp == fp

Hence when fill_file_fields returns NULL, and f is cleaned up here:
   484      if (fill_file_fields(f, fp, o_name, mode, close) == NULL) {
>> 485          Py_DECREF(f);
   486          Py_DECREF(o_name);
   487          return NULL;
   488      }

then f->fp is closed within file_dealloc()

Then, when PyFile_FromFile returns NULL, call_find_module calls fclose(fp):
  2844     if (fp != NULL) {
  2845         fob = PyFile_FromFile(fp, pathname, fdp->mode, fclose);
  2846         if (fob == NULL) {
>>2847             fclose(fp);
  2848             return NULL;
  2849         }
  2850     }

and it attempts to close fp for the second time.

The documentation for PyFile_FromFile:
  http://docs.python.org/c-api/file.html#PyFile_FromFile
says:
"Return NULL and close the file using close on failure".

It therefore looks like call_find_module's fclose(fp) is incorrect here, and is what leads to the double-free.
msg153801 - (view) Author: Dave Malcolm (dmalcolm) (Python committer) Date: 2012-02-20 20:36
Duplicate of issue 7732
History
Date User Action Args
2022-04-11 14:57:26adminsetgithub: 58274
2012-02-20 20:36:46dmalcolmsetstatus: open -> closed
resolution: duplicate
superseder: imp.find_module crashes Python if there exists a directory named "__init__.py"
messages: + msg153801
2012-02-20 19:01:40dmalcolmcreate