Bug#493937: [Patch] Prevent loading of Python modules in working directory
Bram Moolenaar
Bram at moolenaar.net
Thu Nov 13 10:23:07 UTC 2008
James -
> > > Vim's python interface calls PySys_SetArgv with an argv[0] that doesn't
> > > resolve to a filename. This causes Python to prepend sys.path with an
> > > empty string which, due to Python's use of relative imports, allows the
> > > possibility to run arbitrary code on the user's system if a file in
> > > Vim's working directory matches the name of a python module a
> > > Python-using vim script tries to import.
> > >
> > > This should be fixed by Python 2.6 as it uses absolute imports by
> > > default, but I have not been able to test it. The attached patch fixes
> > > the problem in Vim by removing any empty strings from sys.path.
> >
> > I have now applied and tried this patch. It does not really work as
> > expected for me. Apparently the empty string in argv[0] is interpreted
> > as the current directory.
>
> argv[0] is used to seed the value that is prepended to sys.path.
>
> You can take a look at what PySys_SetArgv does at
> http://svn.python.org/view/python/branches/release25-maint/Python/sysmodule.c?rev=54836&view=markup
>
> What it boils down to in the simple case is checking for the existence
> of a path separator in argv0. If that doesn't exist, then a PyString is
> created from argv0 with size 0 and sys.path is prepended with that --
> empty string used for the first element of sys.path.
>
> > My first entry in sys.path is then the directory above the current
> > directory. The filter you added in the patch doesn't change anything.
>
> This is incorrect. In Vim's current code, PySys_SetArgv is called with
> an argv that is simply an empty string (and a terminating NULL
> sentinel). This causes sys.path's first element to be the empty string,
> thus causing any Python import statements to use Vim's current working
> directory as the first location to check for the requested module.
>
> The filter specifically removes any elements in sys.path that evaluate
> to false (i.e., the empty string).
That is not what happens for me. Somehow somewhere the empty entry is
changed to the full path of the directory above the current directory.
I don't know where, but I see it happening. I have tried this with:
:py import sys
:py print sys.path
> Using the attached print_sys.path.diff, the following is printed when I
> start Vim (the sys.path before and after my suggested filter() command):
>
> ['', '/usr/lib/python2.5', '/usr/lib/python2.5/plat-linux2', '/usr/lib/python2.5/lib-tk', '/usr/lib/python2.5/lib-dynload', '/usr/local/lib/python2.5/site-packages', '/usr/lib/python2.5/site-packages']
> ['/usr/lib/python2.5', '/usr/lib/python2.5/plat-linux2', '/usr/lib/python2.5/lib-tk', '/usr/lib/python2.5/lib-dynload', '/usr/local/lib/python2.5/site-packages', '/usr/lib/python2.5/site-packages']
As mentioned, for me the first entry is not '' but a path. The filter
command you suggested doesn't remove it. I don't know where the
difference between our systems comes from.
> You can also test it with the simple pytest.c that I've attached by
> specifying different arguments as the first element of the argv passed
> to PySys_SetArgv.
>
> $ gcc -o pytest $(python-config --cflags) $(python-config --ldflags) pytest.c
> $ ./pytest ''
> ['', '/usr/lib/python2.5', '/usr/lib/python2.5/plat-linux2', '/usr/lib/python2.5/lib-tk', '/usr/lib/python2.5/lib-dynload', '/usr/local/lib/python2.5/site-packages', '/usr/lib/python2.5/site-packages']
> ['/usr/lib/python2.5', '/usr/lib/python2.5/plat-linux2', '/usr/lib/python2.5/lib-tk', '/usr/lib/python2.5/lib-dynload', '/usr/local/lib/python2.5/site-packages', '/usr/lib/python2.5/site-packages']
> $ ./pytest '/must>not&exist/bogusbinary'
> ['/must>not&exist', '/usr/lib/python2.5', '/usr/lib/python2.5/plat-linux2', '/usr/lib/python2.5/lib-tk', '/usr/lib/python2.5/lib-dynload', '/usr/local/lib/python2.5/site-packages', '/usr/lib/python2.5/site-packages']
> ['/must>not&exist', '/usr/lib/python2.5', '/usr/lib/python2.5/plat-linux2', '/usr/lib/python2.5/lib-tk', '/usr/lib/python2.5/lib-dynload', '/usr/local/lib/python2.5/site-packages', '/usr/lib/python2.5/site-packages']
>
> > For me it does work if I use:
> >
> > static char *(argv[2]) = {"/must>not&exist/ls", NULL};
> >
> > The first entry in path is then "/must>not&exist", which we can filter
> > out with:
> >
> > PyRun_SimpleString("import sys; sys.path = filter(lambda x: x != '/must>not&exist', sys.path)");
>
> This is just extra work for no gain.
It does work for me. Does it also work for you?
- Bram
--
hundred-and-one symptoms of being an internet addict:
249. You've forgotten what the outside looks like.
/// Bram Moolenaar -- Bram at Moolenaar.net -- http://www.Moolenaar.net \\\
/// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
\\\ download, build and distribute -- http://www.A-A-P.org ///
\\\ help me help AIDS victims -- http://ICCF-Holland.org ///
More information about the pkg-vim-maintainers
mailing list