Faelix Limited Open Source Software

security, networks & software

Mon, 15 Jan 2007

Patch to Fix Memory Leak in FuseGetContext()

The first difficulty was to upgrade to the latest FusePython to see if the problem had been reported and fixed in a newer version. Unfortunately it had not, and so began the painstaking process of tracking down the bug.

We tracked the problem down to a layer underneath our filesystem, either FusePython, FUSE or Python itself. We began with xmp.py, which didn't exhibit the memory leak, and began comparing the calls it made with our filesystem. Quickly this began to suggest FuseGetContext() (which our filesystem uses, but xmp.py does not) and a one-line patch to readdir() made it easy to replicate the memory leak:

  946 maz       18   0 42032 3308  884 S  0.0  0.3   0:00.05 python

...30 seconds later...

  946 maz       18   0 43344 4588  884 S  3.7  0.4   0:00.73 python

...and another 30 seconds...

  946 maz       18   0 45712 6968  884 S  2.0  0.7   0:01.94 python

It appears that there ar three Py_XDECREF() calls missing from FuseGetContext(), and our fixed version is now available from http://hg.faelix.net/maz/fuse-python (patch) or add the three lines below by hand to FuseGetContext():

         num = PyInt_FromLong(fc->uid);
         PyDict_SetItemString(ret, "uid", num);
+        Py_XDECREF( num );

         num = PyInt_FromLong(fc->gid);
         PyDict_SetItemString(ret, "gid", num);
+        Py_XDECREF( num );

         num = PyInt_FromLong(fc->pid);
         PyDict_SetItemString(ret, "pid", num);
+        Py_XDECREF( num );