This is the mail archive of the
cygwin
mailing list for the Cygwin project.
Re: Cannot exec() program outside of /bin if PATH is unset
- From: Christian Franke <Christian dot Franke at t-online dot de>
- To: cygwin at cygwin dot com
- Date: Mon, 15 Sep 2014 16:35:50 +0200
- Subject: Re: Cannot exec() program outside of /bin if PATH is unset
- Authentication-results: sourceware.org; auth=none
- References: <5413271B dot 1010109 at t-online dot de> <54134A83 dot 80107 at redhat dot com> <54135451 dot 3060902 at t-online dot de> <601154762 dot 20140913012935 at yandex dot ru> <541378C4 dot 6030705 at t-online dot de> <54137BDE dot 6040907 at redhat dot com> <54137C7F dot 1040507 at redhat dot com> <541415B1 dot 8090500 at t-online dot de> <541698CC dot 7090802 at lysator dot liu dot se>
Peter Rosin wrote:
On 2014-09-13 12:00, Christian Franke wrote:
Note that setting PATH=/bin on Cygwin does not fix the security problem in the DLL search order. Even with "SafeDllSearchMode" enabled, the current directory is always checked before PATH. Running some Cygwin program from /usr/sbin, /usr/local/bin, /usr/libexec, ... would load a possible malicious cyg*.dll from current directory regardless of PATH setting. Only programs in /bin are safe.
Using SetDllDirectory("c:\\cygwin\\bin") somewhere in cygwin1.dll would fix this also.
How could a call inside a DLL fix the library search order used
to find that same DLL? Yes, it is possible (or likely) that
SetDllDirectory fixes the immediate problem for processes that
are started *by* cygwin1.dll, but it is not effective for Cygwin
processes that are started by some direct use of the Win32 API.
Of course, and the same is true for any non-Cygwin program. The security
fix is effective only for any CreateProcess()/LoadLibrary() call within
the process which called SetDllDirectory(DIR_OF_SUBSYSTEM_DLLs).
Also, SetDllDirectory will kill all attempts to run 32-bit
Cygwin programs from 64-bit Cygwin (and vice versa).
For programs in /bin directory, there is no problem because the EXE's
directory is always searched first for required DLLs. SetDllDirectory()
then has no effect for cyg*.dll search order.
For other programs it also works because Windows (at least 7) apparently
skips 32-bit DLLs when searching for 64-bit ones (and vice versa). It is
then required that PATH contains the other Cygwin's /bin directory.
Testcase for calling 64-bit from 32-bit:
exe in /bin:
SetDllDirectory("c:\\cygwin\\bin");
unsetenv("PATH");
execl("/cygdrive/c/cygwin64/bin/uname", "uname", "-a", (const char*)0);
exe not in /bin:
SetDllDirectory("c:\\cygwin\\bin");
setenv("PATH", "/cygdrive/c/cygwin64/bin", 1);
execl("/cygdrive/c/cygwin64/usr/sbin/alternatives", "alternatives",
(const char*)0);
In both cases, the SetDllDirectory() call does not break anything.
Cheers,
Christian
--
Problem reports: http://cygwin.com/problems.html
FAQ: http://cygwin.com/faq/
Documentation: http://cygwin.com/docs.html
Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple