Re: Cannot exec() program outside of /bin if PATH is unset

2014-10-17 Thread Corinna Vinschen
On Oct 16 23:51, Christian Franke wrote:
 Corinna Vinschen wrote:
 ...
 I implemented this in the latest snapshot.  It calls SetDllDirectory
 on Cygwin's /bin, and dlopen addiotnally tries to load the DLL with
 LoadLibraryEx(LOAD_WITH_ALTERED_SEARCH_PATH) if all else failed.
 
 For some reason, the SetDllDirectory() call has no effect for exec():
 
 Testcase:
 
 $ unset PATH
 
 $ uname -srvm
 -bash: uname: No such file or directory
 
 $ /bin/uname -srvm
 CYGWIN_NT-6.1-WOW64 1.7.33s(0.277/5/3) 20141014 19:44:03 i686
 
 $ /usr/sbin/alternatives
 /usr/sbin/alternatives: error while loading shared libraries: ?: cannot open
 shared object file: No such file or directory

Weird.  The same sequence of commands works fine for me on W8,
W8.1 and W10 64 bit, under i686 as well as x86_64 Cygwin.  

[...]

but it doesn't on Vista and W7, wow.

The question now is, is it because the path given to SetDllDirectory
is not propagated to child processes on older systems, or is it
because the directory is only used in calls to LoadLibrary{Ex} on
older systems.

Stay tuned, I have to investigate this.


Thanks,
Corinna

-- 
Corinna Vinschen  Please, send mails regarding Cygwin to
Cygwin Maintainer cygwin AT cygwin DOT com
Red Hat


pgpHp9ibyscfH.pgp
Description: PGP signature


Re: Cannot exec() program outside of /bin if PATH is unset

2014-10-17 Thread Corinna Vinschen
On Oct 17 11:10, Corinna Vinschen wrote:
 On Oct 16 23:51, Christian Franke wrote:
  Corinna Vinschen wrote:
  ...
  I implemented this in the latest snapshot.  It calls SetDllDirectory
  on Cygwin's /bin, and dlopen addiotnally tries to load the DLL with
  LoadLibraryEx(LOAD_WITH_ALTERED_SEARCH_PATH) if all else failed.
  
  For some reason, the SetDllDirectory() call has no effect for exec():
  
  Testcase:
  
  $ unset PATH
  
  $ uname -srvm
  -bash: uname: No such file or directory
  
  $ /bin/uname -srvm
  CYGWIN_NT-6.1-WOW64 1.7.33s(0.277/5/3) 20141014 19:44:03 i686
  
  $ /usr/sbin/alternatives
  /usr/sbin/alternatives: error while loading shared libraries: ?: cannot open
  shared object file: No such file or directory
 
 Weird.  The same sequence of commands works fine for me on W8,
 W8.1 and W10 64 bit, under i686 as well as x86_64 Cygwin.  
 
 [...]
 
 but it doesn't on Vista and W7, wow.
 
 The question now is, is it because the path given to SetDllDirectory
 is not propagated to child processes on older systems, or is it
 because the directory is only used in calls to LoadLibrary{Ex} on
 older systems.
 
 Stay tuned, I have to investigate this.

Ok, so prior to W8, the SetDllDirectory path is not propagated to child
processes :-|

I created a patch and a new snapshot on https://cygwin.com/snapshots/
which calls SetDllDirectory during initialization of every process.
Please give it a try.


Thanks,
Corinna

-- 
Corinna Vinschen  Please, send mails regarding Cygwin to
Cygwin Maintainer cygwin AT cygwin DOT com
Red Hat


pgp7hW4w5b98s.pgp
Description: PGP signature


Re: Cannot exec() program outside of /bin if PATH is unset

2014-10-17 Thread Christian Franke

Corinna Vinschen wrote:

On Oct 17 11:10, Corinna Vinschen wrote:

On Oct 16 23:51, Christian Franke wrote:

Corinna Vinschen wrote:

...
I implemented this in the latest snapshot.  It calls SetDllDirectory
on Cygwin's /bin, and dlopen addiotnally tries to load the DLL with
LoadLibraryEx(LOAD_WITH_ALTERED_SEARCH_PATH) if all else failed.

For some reason, the SetDllDirectory() call has no effect for exec():

Testcase:

$ unset PATH

$ uname -srvm
-bash: uname: No such file or directory

$ /bin/uname -srvm
CYGWIN_NT-6.1-WOW64 1.7.33s(0.277/5/3) 20141014 19:44:03 i686

$ /usr/sbin/alternatives
/usr/sbin/alternatives: error while loading shared libraries: ?: cannot open
shared object file: No such file or directory

Weird.  The same sequence of commands works fine for me on W8,
W8.1 and W10 64 bit, under i686 as well as x86_64 Cygwin.

[...]

but it doesn't on Vista and W7, wow.

The question now is, is it because the path given to SetDllDirectory
is not propagated to child processes on older systems, or is it
because the directory is only used in calls to LoadLibrary{Ex} on
older systems.

Stay tuned, I have to investigate this.

Ok, so prior to W8, the SetDllDirectory path is not propagated to child
processes :-|

I created a patch and a new snapshot on https://cygwin.com/snapshots/
which calls SetDllDirectory during initialization of every process.
Please give it a try.


Now works.

cygwin_patches_for_postfix_count++; postfix_patches_for_cygwin_count--; :-)

Thanks,
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



Re: Cannot exec() program outside of /bin if PATH is unset

2014-10-17 Thread Corinna Vinschen
On Oct 17 19:56, Christian Franke wrote:
 Corinna Vinschen wrote:
 On Oct 17 11:10, Corinna Vinschen wrote:
 On Oct 16 23:51, Christian Franke wrote:
 Corinna Vinschen wrote:
 ...
 I implemented this in the latest snapshot.  It calls SetDllDirectory
 on Cygwin's /bin, and dlopen addiotnally tries to load the DLL with
 LoadLibraryEx(LOAD_WITH_ALTERED_SEARCH_PATH) if all else failed.
 For some reason, the SetDllDirectory() call has no effect for exec():
 
 Testcase:
 
 $ unset PATH
 
 $ uname -srvm
 -bash: uname: No such file or directory
 
 $ /bin/uname -srvm
 CYGWIN_NT-6.1-WOW64 1.7.33s(0.277/5/3) 20141014 19:44:03 i686
 
 $ /usr/sbin/alternatives
 /usr/sbin/alternatives: error while loading shared libraries: ?: cannot 
 open
 shared object file: No such file or directory
 Weird.  The same sequence of commands works fine for me on W8,
 W8.1 and W10 64 bit, under i686 as well as x86_64 Cygwin.
 
 [...]
 
 but it doesn't on Vista and W7, wow.
 
 The question now is, is it because the path given to SetDllDirectory
 is not propagated to child processes on older systems, or is it
 because the directory is only used in calls to LoadLibrary{Ex} on
 older systems.
 
 Stay tuned, I have to investigate this.
 Ok, so prior to W8, the SetDllDirectory path is not propagated to child
 processes :-|
 
 I created a patch and a new snapshot on https://cygwin.com/snapshots/
 which calls SetDllDirectory during initialization of every process.
 Please give it a try.
 
 Now works.
 
 cygwin_patches_for_postfix_count++; postfix_patches_for_cygwin_count--; :-)

You seem to like the idea... ;)


Thanks for testing,
Corinna

-- 
Corinna Vinschen  Please, send mails regarding Cygwin to
Cygwin Maintainer cygwin AT cygwin DOT com
Red Hat


pgpnQKN483ANh.pgp
Description: PGP signature


Re: Cannot exec() program outside of /bin if PATH is unset

2014-10-17 Thread Csaba Raduly
On Fri, Oct 17, 2014 at 8:20 PM, Corinna Vinschen  wrote:
 On Oct 17 19:56, Christian Franke wrote:
 Now works.

 cygwin_patches_for_postfix_count++; postfix_patches_for_cygwin_count--; :-)

 You seem to like the idea... ;)

Of course. He has to deal with postfix, _you_ have to deal with Cygwin.

(: Csaba :)
-- 
GCS a+ e++ d- C++ ULS$ L+$ !E- W++ P+++$ w++$ tv+ b++ DI D++ 5++
The Tao of math: The numbers you can count are not the real numbers.
Life is complex, with real and imaginary parts.
Ok, it boots. Which means it must be bug-free and perfect.  -- Linus Torvalds
People disagree with me. I just ignore them. -- Linus Torvalds

--
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



Re: Cannot exec() program outside of /bin if PATH is unset

2014-10-16 Thread Christian Franke

Corinna Vinschen wrote:

...
I implemented this in the latest snapshot.  It calls SetDllDirectory
on Cygwin's /bin, and dlopen addiotnally tries to load the DLL with
LoadLibraryEx(LOAD_WITH_ALTERED_SEARCH_PATH) if all else failed.


For some reason, the SetDllDirectory() call has no effect for exec():

Testcase:

$ unset PATH

$ uname -srvm
-bash: uname: No such file or directory

$ /bin/uname -srvm
CYGWIN_NT-6.1-WOW64 1.7.33s(0.277/5/3) 20141014 19:44:03 i686

$ /usr/sbin/alternatives
/usr/sbin/alternatives: error while loading shared libraries: ?: cannot 
open shared object file: No such file or directory


$ PATH=/bin /usr/sbin/alternatives
alternatives version 1.3.30c - ...

$ cd /bin

$ /usr/sbin/alternatives
alternatives version 1.3.30c - ...




Please give the latest snapshot from https://cygwin.com/snapshots/
a try.


No regressions found yet :-)

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



Re: Cannot exec() program outside of /bin if PATH is unset

2014-10-14 Thread Corinna Vinschen
On Oct 10 17:39, Corinna Vinschen wrote:
 On Oct 10 14:13, Arjen Markus wrote:
  2014-10-10 13:22 GMT+02:00  tednolan:
  2014-10-10 13:24 GMT+02:00 Jan Nijtmans ...:
   2014-10-10 12:34 GMT+02:00 Corinna Vinschen ...:
   On Oct  9 11:46, tednolan.net wrote:
   I'm pretty sure I've got some programs loading Tcl extensions that
   cd into the directory with the extension dlls, load the extension and 
   then
   change back to where ever they were.
  
   Hmm.  If so, it's quite a weird way to handle this, rather than
   loading the modules with full path.
  
   Is that a Tcl feature, or is it how certain Tcl apps are implemented?
   I can't really believe the former...
  
   This is certainly not a Tcl feature!  The standard Tcl extension
   mechanism always uses the full path simply because Tcl
   cannot depend on platform-specific ways to search for
   such libraries elsewhere.
  
   I'm willing to test this;I don't believe such a change
   will break anything in my Tcl environment.
  
   Regards,
  Jan Nijtmans
  
   Hmm,
  
   It's been a while, but I think it is something like the extension is
   a DLL, but it depends on another DLL.  Consider for instance, mysqltcl.
   If you want to deploy that, you need the mysqltcl.dll and the mysql dll,
   so you either have to be in the same dir when you load the extension,
   or put that dir in PATH.
  
   Unfortunately, I can't run a test release on my work machine, or take
   my work progs home.
  
  Right, that makes sense. There is indeed no way for the package
  manager to handle that scenario without external help, such as a PATH
  variable that includes the various directories these extra DLLs reside
  in.
 
 There might be a potential workaround.  Given that Cygwin Tcl calls
 dlopen to load DLLs, we have this somewhat under control.
 
 The default DLL search algorithm searches the application dir for
 dependent DLLs.  But there's a LoadLibraryEx flag called
 LOAD_WITH_ALTERED_SEARCH_PATH.  When using this flag, and the DLL is
 given with full path, the application dir in the DLL search path is
 replaced by the directory of the DLL.  Thus, dependent DLLs will be
 searched in the same dir the original DLL has been loaded from.
 
 This could be utilized in dlopen.  If the DLL is given with no path, and
 if LoadLibrary failes, create the full path to the DLL and call
 LoadLibraryEx (full_path, LOAD_WITH_ALTERED_SEARCH_PATH).  DLLs in /bin
 are taken care of by the SetDllDirectory call we're talking about here.

I implemented this in the latest snapshot.  It calls SetDllDirectory
on Cygwin's /bin, and dlopen addiotnally tries to load the DLL with
LoadLibraryEx(LOAD_WITH_ALTERED_SEARCH_PATH) if all else failed.

Please give the latest snapshot from https://cygwin.com/snapshots/
a try.


Thanks,
Corinna

-- 
Corinna Vinschen  Please, send mails regarding Cygwin to
Cygwin Maintainer cygwin AT cygwin DOT com
Red Hat


pgp2M5GRUkdW0.pgp
Description: PGP signature


Re: Cannot exec() program outside of /bin if PATH is unset

2014-10-10 Thread Corinna Vinschen
On Oct  9 11:46, tedno...@bellsouth.net wrote:
 In message 20141009162906.ga25...@calimero.vinschen.deyou write:
 
 Any other idea what *might* be broken if we remove CWD from the
 DLL search path?
 
 
 Corinna
 
 
 I'm pretty sure I've got some programs loading Tcl extensions that
 cd into the directory with the extension dlls, load the extension and then
 change back to where ever they were.

Hmm.  If so, it's quite a weird way to handle this, rather than
loading the modules with full path.

Is that a Tcl feature, or is it how certain Tcl apps are implemented?
I can't really believe the former...

Assuming I create a Cygwin snapshot adding a call to SetDllDirectory in
the next couple of days, would you be willing to test if your Tcl stuff
still works?


Thanks,
Corinna

-- 
Corinna Vinschen  Please, send mails regarding Cygwin to
Cygwin Maintainer cygwin AT cygwin DOT com
Red Hat


pgpwp55oFyeJ5.pgp
Description: PGP signature


Re: Cannot exec() program outside of /bin if PATH is unset

2014-10-10 Thread Jan Nijtmans
2014-10-10 12:34 GMT+02:00 Corinna Vinschen corinna-cyg...@cygwin.com:
 On Oct  9 11:46, tedno...@bellsouth.net wrote:
 I'm pretty sure I've got some programs loading Tcl extensions that
 cd into the directory with the extension dlls, load the extension and then
 change back to where ever they were.

 Hmm.  If so, it's quite a weird way to handle this, rather than
 loading the modules with full path.

 Is that a Tcl feature, or is it how certain Tcl apps are implemented?
 I can't really believe the former...

This is certainly not a Tcl feature!  The standard Tcl extension
mechanism always uses the full path simply because Tcl
cannot depend on platform-specific ways to search for
such libraries elsewhere.

I'm willing to test this;I don't believe such a change
will break anything in my Tcl environment.

Regards,
   Jan Nijtmans

--
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



Re: Cannot exec() program outside of /bin if PATH is unset

2014-10-10 Thread Arjen Markus
This might the way the pkgIndex.tcl file for this particular extension
has been implemented, but like Jan says, that is not the Tcl way.

Here is a sample that illustrates the more acceptable procedure:

# Tcl package index file, version 1.0

if {![package vsatisfies [package provide Tcl] 8.6]} {return}

package ifneeded itcl 4.0b7 [list load [file join $dir itcl40b7.dll] itcl]
package ifneeded Itcl 4.0b7 [list load [file join $dir itcl40b7.dll] itcl]

The variable dir is set by the package management subsystem and the
effect is that the _full_ path is constructed before the DLL is
actually loaded.

Regards,

Arjen

2014-10-10 13:24 GMT+02:00 Jan Nijtmans jan.nijtm...@gmail.com:
 2014-10-10 12:34 GMT+02:00 Corinna Vinschen corinna-cyg...@cygwin.com:
 On Oct  9 11:46, tedno...@bellsouth.net wrote:
 I'm pretty sure I've got some programs loading Tcl extensions that
 cd into the directory with the extension dlls, load the extension and then
 change back to where ever they were.

 Hmm.  If so, it's quite a weird way to handle this, rather than
 loading the modules with full path.

 Is that a Tcl feature, or is it how certain Tcl apps are implemented?
 I can't really believe the former...

 This is certainly not a Tcl feature!  The standard Tcl extension
 mechanism always uses the full path simply because Tcl
 cannot depend on platform-specific ways to search for
 such libraries elsewhere.

 I'm willing to test this;I don't believe such a change
 will break anything in my Tcl environment.

 Regards,
Jan Nijtmans

 --
 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


--
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



Re: Cannot exec() program outside of /bin if PATH is unset

2014-10-10 Thread tednolan
In message CAMCbSMrar1Zu4p6gN=gc8-xqe-8rutmp3er0ujen--chkzc...@mail.gmail.com
you write:
This might the way the pkgIndex.tcl file for this particular extension
has been implemented, but like Jan says, that is not the Tcl way.

Here is a sample that illustrates the more acceptable procedure:

# Tcl package index file, version 1.0

if {![package vsatisfies [package provide Tcl] 8.6]} {return}

package ifneeded itcl 4.0b7 [list load [file join $dir itcl40b7.dll] itcl]
package ifneeded Itcl 4.0b7 [list load [file join $dir itcl40b7.dll] itcl]

The variable dir is set by the package management subsystem and the
effect is that the _full_ path is constructed before the DLL is
actually loaded.

Regards,

Arjen

2014-10-10 13:24 GMT+02:00 Jan Nijtmans jan.nijtm...@gmail.com:
 2014-10-10 12:34 GMT+02:00 Corinna Vinschen corinna-cyg...@cygwin.com:
 On Oct  9 11:46, tedno...@bellsouth.net wrote:
 I'm pretty sure I've got some programs loading Tcl extensions that
 cd into the directory with the extension dlls, load the extension and then
 change back to where ever they were.

 Hmm.  If so, it's quite a weird way to handle this, rather than
 loading the modules with full path.

 Is that a Tcl feature, or is it how certain Tcl apps are implemented?
 I can't really believe the former...

 This is certainly not a Tcl feature!  The standard Tcl extension
 mechanism always uses the full path simply because Tcl
 cannot depend on platform-specific ways to search for
 such libraries elsewhere.

 I'm willing to test this;I don't believe such a change
 will break anything in my Tcl environment.

 Regards,
Jan Nijtmans

Hmm,

It's been a while, but I think it is something like the extension is
a DLL, but it depends on another DLL.  Consider for instance, mysqltcl.
If you want to deploy that, you need the mysqltcl.dll and the mysql dll,
so you either have to be in the same dir when you load the extension,
or put that dir in PATH.

Unfortunately, I can't run a test release on my work machine, or take
my work progs home.

--
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



Re: Cannot exec() program outside of /bin if PATH is unset

2014-10-10 Thread Arjen Markus
Right, that makes sense. There is indeed no way for the package
manager to handle that scenario without external help, such as a PATH
variable that includes the various directories these extra DLLs reside
in.

Regards,

Arjen



2014-10-10 13:22 GMT+02:00  tedno...@bellsouth.net:
 In message 
 CAMCbSMrar1Zu4p6gN=gc8-xqe-8rutmp3er0ujen--chkzc...@mail.gmail.com
 you write:
This might the way the pkgIndex.tcl file for this particular extension
has been implemented, but like Jan says, that is not the Tcl way.

Here is a sample that illustrates the more acceptable procedure:

# Tcl package index file, version 1.0

if {![package vsatisfies [package provide Tcl] 8.6]} {return}

package ifneeded itcl 4.0b7 [list load [file join $dir itcl40b7.dll] itcl]
package ifneeded Itcl 4.0b7 [list load [file join $dir itcl40b7.dll] itcl]

The variable dir is set by the package management subsystem and the
effect is that the _full_ path is constructed before the DLL is
actually loaded.

Regards,

Arjen

2014-10-10 13:24 GMT+02:00 Jan Nijtmans jan.nijtm...@gmail.com:
 2014-10-10 12:34 GMT+02:00 Corinna Vinschen corinna-cyg...@cygwin.com:
 On Oct  9 11:46, tedno...@bellsouth.net wrote:
 I'm pretty sure I've got some programs loading Tcl extensions that
 cd into the directory with the extension dlls, load the extension and then
 change back to where ever they were.

 Hmm.  If so, it's quite a weird way to handle this, rather than
 loading the modules with full path.

 Is that a Tcl feature, or is it how certain Tcl apps are implemented?
 I can't really believe the former...

 This is certainly not a Tcl feature!  The standard Tcl extension
 mechanism always uses the full path simply because Tcl
 cannot depend on platform-specific ways to search for
 such libraries elsewhere.

 I'm willing to test this;I don't believe such a change
 will break anything in my Tcl environment.

 Regards,
Jan Nijtmans

 Hmm,

 It's been a while, but I think it is something like the extension is
 a DLL, but it depends on another DLL.  Consider for instance, mysqltcl.
 If you want to deploy that, you need the mysqltcl.dll and the mysql dll,
 so you either have to be in the same dir when you load the extension,
 or put that dir in PATH.

 Unfortunately, I can't run a test release on my work machine, or take
 my work progs home.

 --
 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


--
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



Re: Cannot exec() program outside of /bin if PATH is unset

2014-10-10 Thread Corinna Vinschen
On Oct 10 14:13, Arjen Markus wrote:
 2014-10-10 13:22 GMT+02:00  tednolan:
 2014-10-10 13:24 GMT+02:00 Jan Nijtmans ...:
  2014-10-10 12:34 GMT+02:00 Corinna Vinschen ...:
  On Oct  9 11:46, tednolan.net wrote:
  I'm pretty sure I've got some programs loading Tcl extensions that
  cd into the directory with the extension dlls, load the extension and 
  then
  change back to where ever they were.
 
  Hmm.  If so, it's quite a weird way to handle this, rather than
  loading the modules with full path.
 
  Is that a Tcl feature, or is it how certain Tcl apps are implemented?
  I can't really believe the former...
 
  This is certainly not a Tcl feature!  The standard Tcl extension
  mechanism always uses the full path simply because Tcl
  cannot depend on platform-specific ways to search for
  such libraries elsewhere.
 
  I'm willing to test this;I don't believe such a change
  will break anything in my Tcl environment.
 
  Regards,
 Jan Nijtmans
 
  Hmm,
 
  It's been a while, but I think it is something like the extension is
  a DLL, but it depends on another DLL.  Consider for instance, mysqltcl.
  If you want to deploy that, you need the mysqltcl.dll and the mysql dll,
  so you either have to be in the same dir when you load the extension,
  or put that dir in PATH.
 
  Unfortunately, I can't run a test release on my work machine, or take
  my work progs home.
 
 Right, that makes sense. There is indeed no way for the package
 manager to handle that scenario without external help, such as a PATH
 variable that includes the various directories these extra DLLs reside
 in.

There might be a potential workaround.  Given that Cygwin Tcl calls
dlopen to load DLLs, we have this somewhat under control.

The default DLL search algorithm searches the application dir for
dependent DLLs.  But there's a LoadLibraryEx flag called
LOAD_WITH_ALTERED_SEARCH_PATH.  When using this flag, and the DLL is
given with full path, the application dir in the DLL search path is
replaced by the directory of the DLL.  Thus, dependent DLLs will be
searched in the same dir the original DLL has been loaded from.

This could be utilized in dlopen.  If the DLL is given with no path, and
if LoadLibrary failes, create the full path to the DLL and call
LoadLibraryEx (full_path, LOAD_WITH_ALTERED_SEARCH_PATH).  DLLs in /bin
are taken care of by the SetDllDirectory call we're talking about here.

This is no 100% safe bet, I guess.  It would fail to load DLLs in
scenarios where DLLs depend on other DLLs from the current dir as well
as from the application dir, and the application dir is not /bin.  Just
how realistic is this scenario in a Cygwin environment?


Corinna

-- 
Corinna Vinschen  Please, send mails regarding Cygwin to
Cygwin Maintainer cygwin AT cygwin DOT com
Red Hat


pgp65qTmyzRW5.pgp
Description: PGP signature


Re: Cannot exec() program outside of /bin if PATH is unset

2014-10-09 Thread Corinna Vinschen
On Oct  8 19:15, Christian Franke wrote:
 Corinna Vinschen wrote:
 On Sep 15 16:35, Christian Franke wrote:
 ...
 I'm somewhat reluctant to add a call to SetDllDirectory to the Cygwin
 DLL for two reasons.
 
 - Calling SetDllDirectory with an explicit dir doesn't just add this dir
to the search path, it also removes the CWD from the search path.
While I agree that this is a good thing from a security POV, can we be
sure that this behaviour isn't needed somewhere, by somebody?
 
 - The fact that SetDllDirectory affects searching linked DLLs in calls
to CreateProcess is undocumented.  Per the original MSDN pages,
SetDllDirectory affects calls to LoadLibrary and LoadLibraryEx, but
not linked DLLs when starting a child process.  The latter is only
mentioned in a Community Addition:
 

  http://msdn.microsoft.com/en-us/library/windows/desktop/ms686203%28v=vs.85%29.aspx
 
 Having said that, we can certainly test this, but I'm wondering
 if an upstream Cygwin patch might be ok.  Something similar has been
 applied to the portable OpenSSH repository years ago, so there's
 precedent.
 
 We could leave this open for now. I already added an easy workaround to
 postfix
 (add PATH=/usr/bin to import/export_environment default settings).

Ok.  Or... hmm.  The fact that using SetDllDirectory disallows searching
the CWD got me thinking twice.  Security-wise it would really be the
right thing to do.  Usually DLLs are in defined search paths:

- Application dir
- Application defined dirs
- System dirs

So, what scenario would actually break by removing CWD from the search
path?  Running tests in an libtoolized project dir, perhaps?  Is that a
valid concern or did libtool already take care of this?


Corinna

-- 
Corinna Vinschen  Please, send mails regarding Cygwin to
Cygwin Maintainer cygwin AT cygwin DOT com
Red Hat


pgpKVQVCVm2PU.pgp
Description: PGP signature


Re: Cannot exec() program outside of /bin if PATH is unset

2014-10-09 Thread Eric Blake
On 10/09/2014 04:03 AM, Corinna Vinschen wrote:

 Ok.  Or... hmm.  The fact that using SetDllDirectory disallows searching
 the CWD got me thinking twice.  Security-wise it would really be the
 right thing to do.  Usually DLLs are in defined search paths:
 
 - Application dir
 - Application defined dirs
 - System dirs
 
 So, what scenario would actually break by removing CWD from the search
 path?  Running tests in an libtoolized project dir, perhaps?  Is that a
 valid concern or did libtool already take care of this?

Running a libtool project is probably unimpacted - libtool builds
in-tree dlls into a subdirectory, which is not usually the CWD.

-- 
Eric Blake   eblake redhat com+1-919-301-3266
Libvirt virtualization library http://libvirt.org



signature.asc
Description: OpenPGP digital signature


Re: Cannot exec() program outside of /bin if PATH is unset

2014-10-09 Thread Corinna Vinschen
On Oct  9 08:25, Eric Blake wrote:
 On 10/09/2014 04:03 AM, Corinna Vinschen wrote:
 
  Ok.  Or... hmm.  The fact that using SetDllDirectory disallows searching
  the CWD got me thinking twice.  Security-wise it would really be the
  right thing to do.  Usually DLLs are in defined search paths:
  
  - Application dir
  - Application defined dirs
  - System dirs
  
  So, what scenario would actually break by removing CWD from the search
  path?  Running tests in an libtoolized project dir, perhaps?  Is that a
  valid concern or did libtool already take care of this?
 
 Running a libtool project is probably unimpacted - libtool builds
 in-tree dlls into a subdirectory, which is not usually the CWD.

Right, and AFAICS a wrapper is created which adds the path to the
DLLs to $PATH before starting the actual executable.  So this is no
problem at all.

Any other idea what *might* be broken if we remove CWD from the 
DLL search path?


Corinna

-- 
Corinna Vinschen  Please, send mails regarding Cygwin to
Cygwin Maintainer cygwin AT cygwin DOT com
Red Hat


pgpV98BadIRPT.pgp
Description: PGP signature


Re: Cannot exec() program outside of /bin if PATH is unset

2014-10-09 Thread tednolan
In message 20141009162906.ga25...@calimero.vinschen.deyou write:

Any other idea what *might* be broken if we remove CWD from the
DLL search path?


Corinna


I'm pretty sure I've got some programs loading Tcl extensions that
cd into the directory with the extension dlls, load the extension and then
change back to where ever they were.

--
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



Re: Cannot exec() program outside of /bin if PATH is unset

2014-10-08 Thread Corinna Vinschen
On Sep 15 16:35, Christian Franke wrote:
 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.

I'm somewhat reluctant to add a call to SetDllDirectory to the Cygwin
DLL for two reasons.

- Calling SetDllDirectory with an explicit dir doesn't just add this dir
  to the search path, it also removes the CWD from the search path.
  While I agree that this is a good thing from a security POV, can we be
  sure that this behaviour isn't needed somewhere, by somebody?

- The fact that SetDllDirectory affects searching linked DLLs in calls
  to CreateProcess is undocumented.  Per the original MSDN pages,
  SetDllDirectory affects calls to LoadLibrary and LoadLibraryEx, but
  not linked DLLs when starting a child process.  The latter is only
  mentioned in a Community Addition:

  
http://msdn.microsoft.com/en-us/library/windows/desktop/ms686203%28v=vs.85%29.aspx

Having said that, we can certainly test this, but I'm wondering
if an upstream Cygwin patch might be ok.  Something similar has been
applied to the portable OpenSSH repository years ago, so there's
precedent.


Corinna

-- 
Corinna Vinschen  Please, send mails regarding Cygwin to
Cygwin Maintainer cygwin AT cygwin DOT com
Red Hat


pgpp4VeU4cpn3.pgp
Description: PGP signature


Re: Cannot exec() program outside of /bin if PATH is unset

2014-10-08 Thread Christian Franke

Corinna Vinschen wrote:

On Sep 15 16:35, Christian Franke wrote:

...

I'm somewhat reluctant to add a call to SetDllDirectory to the Cygwin
DLL for two reasons.

- Calling SetDllDirectory with an explicit dir doesn't just add this dir
   to the search path, it also removes the CWD from the search path.
   While I agree that this is a good thing from a security POV, can we be
   sure that this behaviour isn't needed somewhere, by somebody?

- The fact that SetDllDirectory affects searching linked DLLs in calls
   to CreateProcess is undocumented.  Per the original MSDN pages,
   SetDllDirectory affects calls to LoadLibrary and LoadLibraryEx, but
   not linked DLLs when starting a child process.  The latter is only
   mentioned in a Community Addition:

   
http://msdn.microsoft.com/en-us/library/windows/desktop/ms686203%28v=vs.85%29.aspx

Having said that, we can certainly test this, but I'm wondering
if an upstream Cygwin patch might be ok.  Something similar has been
applied to the portable OpenSSH repository years ago, so there's
precedent.


We could leave this open for now. I already added an easy workaround to 
postfix

(add PATH=/usr/bin to import/export_environment default settings).

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



Re: Cannot exec() program outside of /bin if PATH is unset

2014-09-15 Thread Peter Rosin
On 2014-09-13 12:00, Christian Franke wrote:
 Eric Blake wrote:
 (by passing an actual safe path, and NOT by completely unsetting PATH).

 
 Disagree. The postfix master(8) spawns all of its daemons with PATH unset. 
 This IMO does not violate POSIX.
 
 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.

Also, SetDllDirectory will kill all attempts to run 32-bit
Cygwin programs from 64-bit Cygwin (and vice versa).

Cheers,
Peter


--
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



Re: Cannot exec() program outside of /bin if PATH is unset

2014-09-15 Thread Peter Rosin
(sorry for replying to self)

On 2014-09-15 09:44, Peter Rosin wrote:
 Also, SetDllDirectory will kill all attempts to run 32-bit
 Cygwin programs from 64-bit Cygwin (and vice versa).

At least I think so.

Cheers,
Peter


--
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



Re: Cannot exec() program outside of /bin if PATH is unset

2014-09-15 Thread Christian Franke

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



Re: Cannot exec() program outside of /bin if PATH is unset

2014-09-14 Thread Csaba Raduly
On Fri, Sep 12, 2014 at 9:33 PM, Eric Blake  wrote:
 On 09/12/2014 11:02 AM, Christian Franke wrote:
(snip)

 int main()
 {
   unsetenv(PATH);

 This is undefined behavior, per POSIX.  POSIX recommends that you always
 leave PATH defined to at least a bare minimum of the results of
 confstr(_CS_PATH, ...); it also states that implementations are free to
 do what they want (in this case, crash) if you don't follow the
 recommendation:

 http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap08.html
 If PATH is unset or is set to null, the path search is
 implementation-defined.

Nitpick: undefined != implementation-defined

Csaba
-- 
GCS a+ e++ d- C++ ULS$ L+$ !E- W++ P+++$ w++$ tv+ b++ DI D++ 5++
The Tao of math: The numbers you can count are not the real numbers.
Life is complex, with real and imaginary parts.
Ok, it boots. Which means it must be bug-free and perfect.  -- Linus Torvalds
People disagree with me. I just ignore them. -- Linus Torvalds

--
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



Re: Cannot exec() program outside of /bin if PATH is unset

2014-09-13 Thread Christian Franke

Eric Blake wrote:

On 09/12/2014 05:03 PM, Eric Blake wrote:

On 09/12/2014 04:50 PM, Christian Franke wrote:

Andrey Repin wrote:

Hmm... is postfix actually broken?
Unsetting PATH is IMO sane (from the POSIX POV) if all exec() calls use
absolute path names.

If all exec() calls are made with full paths, unsetting $PATH does not
improve
security in any way,

Of course. But postfix could be configured to run unknown external
programs through its various daemons. In this case, a fixed (here:
empty) PATH improves security. If not convinced, please discuss with the
author of postfix :-)

An empty PATH leaves it up to the implementation what helpers get run
(if it doesn't fall over first), which is LESS secure than a guaranteed
safe PATH of confstr(_CS_PATH).

By the way, passing a _safe_ PATH to your child process IS a good idea
for security-conscious programs, but you have to do it correctly


Agree. The postfix spawn(8) and pipe(8) daemons actually spawn external 
programs with PATH set to _PATH_DEFPATH.




(by passing an actual safe path, and NOT by completely unsetting PATH).



Disagree. The postfix master(8) spawns all of its daemons with PATH 
unset. This IMO does not violate POSIX.


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.



--
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



Cannot exec() program outside of /bin if PATH is unset

2014-09-12 Thread Christian Franke
If PATH variable is unset or does not contain /bin or /usr/bin, 
exec(/not_bin/program, ...) fails because cygwin DLLs could not be loaded.


This affects postfix which cleans the environment to the bare minimum 
for security reasons.
(fortunately there is an easy workaround, so this does not block postfix 
ITP)


Testcase:

$ cat nopath.cc
#include stdio.h
#include stdlib.h
#include unistd.h
// #include windows.h

int main()
{
  unsetenv(PATH);
  // SetDllDirectory(c:\\cygwin\\bin);
  execl(/usr/sbin/alternatives, alternatives, (const char*)0);
  perror(execl);
  return 1;
}

$ make nopath
...

$ ./nopath
/usr/sbin/alternatives.exe: error while loading shared libraries: ?: 
cannot open shared object file: No such file or directory


Enabling the SetDllDirectory() Win32 call fixes the problem.
Would possibly make sense to add this call to cygwin1.dll.


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



Re: Cannot exec() program outside of /bin if PATH is unset

2014-09-12 Thread Eric Blake
On 09/12/2014 11:02 AM, Christian Franke wrote:
 If PATH variable is unset or does not contain /bin or /usr/bin,
 exec(/not_bin/program, ...) fails because cygwin DLLs could not be
 loaded.
 
 This affects postfix which cleans the environment to the bare minimum
 for security reasons.
 (fortunately there is an easy workaround, so this does not block postfix
 ITP)
 
 Testcase:
 
 $ cat nopath.cc
 #include stdio.h
 #include stdlib.h
 #include unistd.h
 // #include windows.h
 
 int main()
 {
   unsetenv(PATH);

This is undefined behavior, per POSIX.  POSIX recommends that you always
leave PATH defined to at least a bare minimum of the results of
confstr(_CS_PATH, ...); it also states that implementations are free to
do what they want (in this case, crash) if you don't follow the
recommendation:

http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap08.html
If PATH is unset or is set to null, the path search is
implementation-defined.

 Enabling the SetDllDirectory() Win32 call fixes the problem.
 Would possibly make sense to add this call to cygwin1.dll.

That said, just because POSIX has already given us the
get-out-of-jail-free card doesn't mean that we can't be nice and improve
cygwin1.dll to try and help broken programs that unset PATH.

-- 
Eric Blake   eblake redhat com+1-919-301-3266
Libvirt virtualization library http://libvirt.org



signature.asc
Description: OpenPGP digital signature


Re: Cannot exec() program outside of /bin if PATH is unset

2014-09-12 Thread Christian Franke

Eric Blake wrote:

On 09/12/2014 11:02 AM, Christian Franke wrote:

If PATH variable is unset or does not contain /bin or /usr/bin,
exec(/not_bin/program, ...) fails because cygwin DLLs could not be
loaded.

This affects postfix which cleans the environment to the bare minimum
for security reasons.
(fortunately there is an easy workaround, so this does not block postfix
ITP)

Testcase:

$ cat nopath.cc
#include stdio.h
#include stdlib.h
#include unistd.h
// #include windows.h

int main()
{
   unsetenv(PATH);

This is undefined behavior, per POSIX.  POSIX recommends that you always
leave PATH defined to at least a bare minimum of the results of
confstr(_CS_PATH, ...); it also states that implementations are free to
do what they want (in this case, crash) if you don't follow the
recommendation:

http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap08.html
If PATH is unset or is set to null, the path search is
implementation-defined.


There is no POSIX PATH search needed in my testcase:
  execl(/usr/sbin/alternatives, ...)

The alternatives.exe could be found. The required DLLs could not be loaded.
POSIX does not specify anything about the load path of shared libraries.
On Linux, LD_LIBRARY_PATH is completely separate from PATH.
On Windows, the DLL load path is connected to PATH.


Enabling the SetDllDirectory() Win32 call fixes the problem.
Would possibly make sense to add this call to cygwin1.dll.

That said, just because POSIX has already given us the
get-out-of-jail-free card doesn't mean that we can't be nice and improve
cygwin1.dll to try and help broken programs that unset PATH.


Hmm... is postfix actually broken?
Unsetting PATH is IMO sane (from the POSIX POV) if all exec() calls use 
absolute path names.


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



Re: Cannot exec() program outside of /bin if PATH is unset

2014-09-12 Thread Andrey Repin
Greetings, Christian Franke!

 Enabling the SetDllDirectory() Win32 call fixes the problem.
 Would possibly make sense to add this call to cygwin1.dll.
 That said, just because POSIX has already given us the
 get-out-of-jail-free card doesn't mean that we can't be nice and improve
 cygwin1.dll to try and help broken programs that unset PATH.

 Hmm... is postfix actually broken?
 Unsetting PATH is IMO sane (from the POSIX POV) if all exec() calls use 
 absolute path names.

If all exec() calls are made with full paths, unsetting $PATH does not improve
security in any way, but leave underlying system in an inconsistent state. As
you've witnessed yourself.
This is not limited to Cygwin1.dll, but to all other system DLL's that you
might need to load.


--
WBR,
Andrey Repin (anrdae...@yandex.ru) 13.09.2014, 1:27

Sorry for my terrible english...


--
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



Re: Cannot exec() program outside of /bin if PATH is unset

2014-09-12 Thread Eric Blake
On 09/12/2014 02:15 PM, Christian Franke wrote:
unsetenv(PATH);
 This is undefined behavior, per POSIX.  POSIX recommends that you always
 leave PATH defined to at least a bare minimum of the results of
 confstr(_CS_PATH, ...); it also states that implementations are free to
 do what they want (in this case, crash) if you don't follow the
 recommendation:

 http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap08.html
 If PATH is unset or is set to null, the path search is
 implementation-defined.
 
 There is no POSIX PATH search needed in my testcase:
   execl(/usr/sbin/alternatives, ...)

PATH may not be needed for execl() to find the binary it will be
executing, but it IS required to be set in the environment to the bare
minimum of confstr(_CS_PATH) for that binary to have a chance of
executing in a well-defined setup.

 
 The alternatives.exe could be found. The required DLLs could not be loaded.
 POSIX does not specify anything about the load path of shared libraries.
 On Linux, LD_LIBRARY_PATH is completely separate from PATH.
 On Windows, the DLL load path is connected to PATH.
 
 Enabling the SetDllDirectory() Win32 call fixes the problem.
 Would possibly make sense to add this call to cygwin1.dll.
 That said, just because POSIX has already given us the
 get-out-of-jail-free card doesn't mean that we can't be nice and improve
 cygwin1.dll to try and help broken programs that unset PATH.
 
 Hmm... is postfix actually broken?

Yes, from the POSIX point of view.  It is doing something that is
documented to have unspecified behavior, namely, removing PATH from the
environment.

 Unsetting PATH is IMO sane (from the POSIX POV) if all exec() calls use
 absolute path names.

It is unspecified, whether or not it has sane behavior on some
platforms.  Just because something is unspecified by POSIX doesn't mean
that you can't do it, it just means that if you do it, and things break,
you get to keep both pieces.

So I would file a bug to upstream postfix that they are broken for
unsetting PATH.

-- 
Eric Blake   eblake redhat com+1-919-301-3266
Libvirt virtualization library http://libvirt.org



signature.asc
Description: OpenPGP digital signature


Re: Cannot exec() program outside of /bin if PATH is unset

2014-09-12 Thread Christian Franke

Andrey Repin wrote:

Hmm... is postfix actually broken?
Unsetting PATH is IMO sane (from the POSIX POV) if all exec() calls use
absolute path names.

If all exec() calls are made with full paths, unsetting $PATH does not improve
security in any way,


Of course. But postfix could be configured to run unknown external 
programs through its various daemons. In this case, a fixed (here: 
empty) PATH improves security. If not convinced, please discuss with the 
author of postfix :-)




but leave underlying system in an inconsistent state.


I don't see any added inconsistencies, please explain.



This is not limited to Cygwin1.dll, but to all other system DLL's that you
might need to load.


No. The system (aka Windows) DDLs are always found due to the 
built-in defaults which *precede* PATH:

http://msdn.microsoft.com/en-us/library/windows/desktop/ms682586.aspx

The Cygwin system DLLs may be not found if PATH is modified/unset, 
therefore I suggested to fix this by a SetDllDirectory() call.



--
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



Re: Cannot exec() program outside of /bin if PATH is unset

2014-09-12 Thread Eric Blake
On 09/12/2014 04:50 PM, Christian Franke wrote:
 Andrey Repin wrote:
 Hmm... is postfix actually broken?
 Unsetting PATH is IMO sane (from the POSIX POV) if all exec() calls use
 absolute path names.
 If all exec() calls are made with full paths, unsetting $PATH does not
 improve
 security in any way,
 
 Of course. But postfix could be configured to run unknown external
 programs through its various daemons. In this case, a fixed (here:
 empty) PATH improves security. If not convinced, please discuss with the
 author of postfix :-)

An empty PATH leaves it up to the implementation what helpers get run
(if it doesn't fall over first), which is LESS secure than a guaranteed
safe PATH of confstr(_CS_PATH).

 
 
 but leave underlying system in an inconsistent state.
 
 I don't see any added inconsistencies, please explain.

The moment you throw away the bare minimum POSIX-required PATH, you have
introduced inconsistency into the environment you are handing to your
child process.

-- 
Eric Blake   eblake redhat com+1-919-301-3266
Libvirt virtualization library http://libvirt.org



signature.asc
Description: OpenPGP digital signature


Re: Cannot exec() program outside of /bin if PATH is unset

2014-09-12 Thread Eric Blake
On 09/12/2014 05:03 PM, Eric Blake wrote:
 On 09/12/2014 04:50 PM, Christian Franke wrote:
 Andrey Repin wrote:
 Hmm... is postfix actually broken?
 Unsetting PATH is IMO sane (from the POSIX POV) if all exec() calls use
 absolute path names.
 If all exec() calls are made with full paths, unsetting $PATH does not
 improve
 security in any way,

 Of course. But postfix could be configured to run unknown external
 programs through its various daemons. In this case, a fixed (here:
 empty) PATH improves security. If not convinced, please discuss with the
 author of postfix :-)
 
 An empty PATH leaves it up to the implementation what helpers get run
 (if it doesn't fall over first), which is LESS secure than a guaranteed
 safe PATH of confstr(_CS_PATH).

By the way, passing a _safe_ PATH to your child process IS a good idea
for security-conscious programs, but you have to do it correctly (by
passing an actual safe path, and NOT by completely unsetting PATH).

-- 
Eric Blake   eblake redhat com+1-919-301-3266
Libvirt virtualization library http://libvirt.org



signature.asc
Description: OpenPGP digital signature


Re: Cannot exec() program outside of /bin if PATH is unset

2014-09-12 Thread David Boyce
On Fri, Sep 12, 2014 at 6:24 PM, Eric Blake ebl...@redhat.com wrote:
 On 09/12/2014 02:15 PM, Christian Franke wrote:
unsetenv(PATH);
 This is undefined behavior, per POSIX.  POSIX recommends that you always
 leave PATH defined to at least a bare minimum of the results of
 confstr(_CS_PATH, ...); it also states that implementations are free to
 do what they want (in this case, crash) if you don't follow the
 recommendation:

 http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap08.html
 If PATH is unset or is set to null, the path search is
 implementation-defined.

 There is no POSIX PATH search needed in my testcase:
   execl(/usr/sbin/alternatives, ...)

 PATH may not be needed for execl() to find the binary it will be
 executing, but it IS required to be set in the environment to the bare
 minimum of confstr(_CS_PATH) for that binary to have a chance of
 executing in a well-defined setup.

Eric,

I think your interpretation is wrong. The line you quote from POSIX
refers to a path search but there is no path search happening here.
The concept of path search is implicitly defined by the first line in
your citation:

PATH: This variable shall represent the sequence of path prefixes
that certain functions and utilities apply in searching for an
executable file known only by a filename.

Notice the way this sentence ends. The argument to execl() is a full
path, not only a filename, thus no PATH search is involved. I agree
that unsetting PATH is not ideal practice but I think it's perfectly
well defined by POSIX.

David

--
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