Re: Perl bug (was Re: [1.7] cygwin allows writing to readonly files)
On Aug 11 04:49, Reini Urban wrote: 2009/8/11 Reini Urban: 2009/8/10 Corinna Vinschen: On Aug 10 20:11, Alexey Borzenkov wrote: Anyway, it means there is a bug in perl, because on Linux: r...@kitsu:~# touch test.txt r...@kitsu:~# chmod 0444 test.txt r...@kitsu:~# perl -e 'print writable\n if -w test.txt' writable On Cygwin 1.7 perl thinks that the file is not writable. Indeed. Checking with strace I found that the test is the same on Linux and Cygwin. In both cases perl uses stat(), and the returned permissions are the same (0444). Further experimenting shows that perl has a hardcoded uid == 0 test which must obviously fail on Cygwin. If I change the user's uid to 0, the string writable is printed by the above command. That's a bug in perl. There are other OSes out there which have root-like permissions for non-0 uids. Perl should use the access() function to check for read/write/execute permissions, which always returns the correct result independent of the uid of the current user. Thanks. I'll carry it along to p5p, but it will definitely not appear in upstream 5.10.1 because this gate is already closed. Even a horrible performance problem with File::Spec::Cygwin::case_tolerant was not fixed. But I work on a fix to be included in blead and in my cygwin package. Bug confirmed too early. It's actually defined and described this way. access() is not used for performance reasons. See perldoc perlfunc -X If you are using ACLs, there is a pragma called Cfiletest that may produce more accurate results than the bare stat() mode bits. When under the Cuse filetest 'access' the above-mentioned filetests will test whether the permission can (not) be granted using the access() family of system calls. Also note that the C-x and C-X may under this pragma return true even if there are no execute permission bits set (nor any extra execute permission ACLs). This strangeness is due to the underlying system calls' definitions. Note also that, due to the implementation of Cuse filetest 'access', the C_ special filehandle won't cache the results of the file tests when this pragma is in effect. Read the documentation for the Cfiletest pragma for more information. As far as I'm concerned this is still a bug. It will result in different behaviour of the same script on different platforms for no apparent reason. $ ./perl -e 'print writable\n if -w test.txt' $ ./perl -e 'use filetest access; print writable\n if -w test.txt' writable I can turn on access checks easily for CYGWIN but cygwin perl is already slow enough, so I will not do that. Changing the uid==0 check to check the Administrators gid is more promising. i.e. --- doio.c.orig 2009-04-18 19:17:04.0 +0200 +++ doio.c 2009-08-11 04:46:09.34375 +0200 @@ -1918,7 +1918,11 @@ return (mode statbufp-st_mode) ? TRUE : FALSE; #else /* ! DOSISH */ +# ifndef __CYGWIN__ if ((effective ? PL_euid : PL_uid) == 0) { /* root is special */ +# else +if ((effective ? PL_egid : PL_gid) == 544) { /* member of Administrators? */ +# endif if (mode == S_IXUSR) { if (statbufp-st_mode 0111 || S_ISDIR(statbufp-st_mode)) return TRUE; but this didn't help me, because Administrators is not my first group. So I call this a known limitation for all ACL aware filesystems. That might be a good workaround nevertheless. You should just test the list of supplementary groups as well, along these lines: # ifndef __CYGWIN__ if ((effective ? PL_euid : PL_uid) == 0) { /* root is special */ # else int is_admin = false; gid_t gid = effective ? PL_egid : PL_gid; int cnt, i; gid_t *glist; cnt = getgroups (0, NULL); if (cnt 0) { glist = (gid_t *) malloc (cnt * sizeof (gid_t)); cnt = getgroups (cnt, glist); for (i = 0; i cnt; ++i) if (gid == glist[i]) { is_admin = true; break; } free (glist); } if (is_admin) # endif Corinna -- Corinna Vinschen Please, send mails regarding Cygwin to Cygwin Project Co-Leader cygwin AT cygwin DOT com Red Hat -- 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: Perl bug (was Re: [1.7] cygwin allows writing to readonly files)
2009/8/11 Corinna Vinschen: On Aug 11 04:49, Reini Urban wrote: 2009/8/11 Reini Urban: 2009/8/10 Corinna Vinschen: On Aug 10 20:11, Alexey Borzenkov wrote: Anyway, it means there is a bug in perl, because on Linux: r...@kitsu:~# touch test.txt r...@kitsu:~# chmod 0444 test.txt r...@kitsu:~# perl -e 'print writable\n if -w test.txt' writable On Cygwin 1.7 perl thinks that the file is not writable. Indeed. Checking with strace I found that the test is the same on Linux and Cygwin. In both cases perl uses stat(), and the returned permissions are the same (0444). Further experimenting shows that perl has a hardcoded uid == 0 test which must obviously fail on Cygwin. If I change the user's uid to 0, the string writable is printed by the above command. That's a bug in perl. There are other OSes out there which have root-like permissions for non-0 uids. Perl should use the access() function to check for read/write/execute permissions, which always returns the correct result independent of the uid of the current user. Thanks. I'll carry it along to p5p, but it will definitely not appear in upstream 5.10.1 because this gate is already closed. Even a horrible performance problem with File::Spec::Cygwin::case_tolerant was not fixed. But I work on a fix to be included in blead and in my cygwin package. Bug confirmed too early. It's actually defined and described this way. access() is not used for performance reasons. See perldoc perlfunc -X If you are using ACLs, there is a pragma called Cfiletest that may produce more accurate results than the bare stat() mode bits. When under the Cuse filetest 'access' the above-mentioned filetests will test whether the permission can (not) be granted using the access() family of system calls. Also note that the C-x and C-X may under this pragma return true even if there are no execute permission bits set (nor any extra execute permission ACLs). This strangeness is due to the underlying system calls' definitions. Note also that, due to the implementation of Cuse filetest 'access', the C_ special filehandle won't cache the results of the file tests when this pragma is in effect. Read the documentation for the Cfiletest pragma for more information. As far as I'm concerned this is still a bug. It will result in different behaviour of the same script on different platforms for no apparent reason. $ ./perl -e 'print writable\n if -w test.txt' $ ./perl -e 'use filetest access; print writable\n if -w test.txt' writable I can turn on access checks easily for CYGWIN but cygwin perl is already slow enough, so I will not do that. Changing the uid==0 check to check the Administrators gid is more promising. i.e. --- doio.c.orig 2009-04-18 19:17:04.0 +0200 +++ doio.c 2009-08-11 04:46:09.34375 +0200 @@ -1918,7 +1918,11 @@ return (mode statbufp-st_mode) ? TRUE : FALSE; #else /* ! DOSISH */ +# ifndef __CYGWIN__ if ((effective ? PL_euid : PL_uid) == 0) { /* root is special */ +# else + if ((effective ? PL_egid : PL_gid) == 544) { /* member of Administrators? */ +# endif if (mode == S_IXUSR) { if (statbufp-st_mode 0111 || S_ISDIR(statbufp-st_mode)) return TRUE; but this didn't help me, because Administrators is not my first group. So I call this a known limitation for all ACL aware filesystems. That might be a good workaround nevertheless. You should just test the list of supplementary groups as well, along these lines: We already have an ingroup() check in this Perl_cando() function, so there is no need to write it again. But it is disabled in perl core for this code path. See http://perl5.git.perl.org/perl.git/blob/HEAD:/doio.c#l1929 It would be: if (ingroup(544,effective)) return TRUE;/* Administrators read and write anything */ but this is simply not true, as under unix. Windows Administrators fall under the same ACL restrictions as normal users. So only using access() is reliable. I rather suggest to add the filetest access hint to the failing ExtUtils::MakeMaker module, and Module::Install and Module::Build also. -- Reini Urban http://phpwiki.org/ http://murbreak.at/ -- 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: Perl bug (was Re: [1.7] cygwin allows writing to readonly files)
On Aug 11 12:44, Reini Urban wrote: 2009/8/11 Corinna Vinschen: That might be a good workaround nevertheless. You should just test the list of supplementary groups as well, along these lines: We already have an ingroup() check in this Perl_cando() function, so there is no need to write it again. But it is disabled in perl core for this code path. See http://perl5.git.perl.org/perl.git/blob/HEAD:/doio.c#l1929 It would be: if (ingroup(544,effective)) return TRUE;/* Administrators read and write anything */ but this is simply not true, as under unix. Windows Administrators fall under the same ACL restrictions as normal users. So only using access() is reliable. I don't understand what you're tryin to say. The members of the Admin group have always write access to files due to the SE_BACKUP_NAME privilege enabled in Cygwin. Corinna -- Corinna Vinschen Please, send mails regarding Cygwin to Cygwin Project Co-Leader cygwin AT cygwin DOT com Red Hat -- 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: Perl bug (was Re: [1.7] cygwin allows writing to readonly files)
2009/8/11 Corinna Vinschen: On Aug 11 12:44, Reini Urban wrote: 2009/8/11 Corinna Vinschen: That might be a good workaround nevertheless. You should just test the list of supplementary groups as well, along these lines: We already have an ingroup() check in this Perl_cando() function, so there is no need to write it again. But it is disabled in perl core for this code path. See http://perl5.git.perl.org/perl.git/blob/HEAD:/doio.c#l1929 It would be: if (ingroup(544,effective)) return TRUE; /* Administrators read and write anything */ but this is simply not true, as under unix. Windows Administrators fall under the same ACL restrictions as normal users. So only using access() is reliable. I don't understand what you're tryin to say. The members of the Admin group have always write access to files due to the SE_BACKUP_NAME privilege enabled in Cygwin. Okay, then the ingroup check should be used. Thanks. -- Reini Urban http://phpwiki.org/ http://murbreak.at/ -- 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
[1.7] cygwin allows writing to readonly files
Hi, $ echo foo test.txt $ chmod 0444 test.txt $ echo bar test.txt This succeeds, even though the file is readonly, and permissions don't allow writing to the file. What's even stranger is that other programs (i.e. Notepad and other editors) can't write to this file, because there are no writing permissions on the file. How does cygwin 1.7 manages to bypass NT permissions in this case? Currently this breaks ExtUtils::MakeMaker, because it expects readonly files not to be writable and test fails. -- 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: [1.7] cygwin allows writing to readonly files
On Aug 10 17:19, Alexey Borzenkov wrote: Hi, $ echo foo test.txt $ chmod 0444 test.txt $ echo bar test.txt This succeeds, even though the file is readonly, and permissions don't allow writing to the file. What's even stranger is that other programs (i.e. Notepad and other editors) can't write to this file, because there are no writing permissions on the file. How does cygwin 1.7 manages to bypass NT permissions in this case? Currently this breaks ExtUtils::MakeMaker, because it expects readonly files not to be writable and test fails. That's a bug in your testsuite. I assume you're running the tests as administrator, right? Administrators have the right to write to all files, even R/O files, according to POSIX rules. Your test would fail on Linux as well, if you're running it as root. Corinna -- Corinna Vinschen Please, send mails regarding Cygwin to Cygwin Project Co-Leader cygwin AT cygwin DOT com Red Hat -- 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: [1.7] cygwin allows writing to readonly files
On Mon, Aug 10, 2009 at 5:25 PM, Corinna Vinschencorinna-cyg...@cygwin.com wrote: That's a bug in your testsuite. I assume you're running the tests as administrator, right? Administrators have the right to write to all files, even R/O files, according to POSIX rules. Your test would fail on Linux as well, if you're running it as root. Well, it's not my testsuite, but yes, I'm running under administrator account. But it makes me wonder, how does it work? Do you change ACLs temporarily? Anyway, it means there is a bug in perl, because on Linux: r...@kitsu:~# touch test.txt r...@kitsu:~# chmod 0444 test.txt r...@kitsu:~# perl -e 'print writable\n if -w test.txt' writable On Cygwin 1.7 perl thinks that the file is not writable. -- 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
Perl bug (was Re: [1.7] cygwin allows writing to readonly files)
On Aug 10 20:11, Alexey Borzenkov wrote: On Mon, Aug 10, 2009 at 5:25 PM, Corinna Vinschencorinna-cyg...@cygwin.com wrote: That's a bug in your testsuite. I assume you're running the tests as administrator, right? Administrators have the right to write to all files, even R/O files, according to POSIX rules. Your test would fail on Linux as well, if you're running it as root. Well, it's not my testsuite, but yes, I'm running under administrator account. But it makes me wonder, how does it work? Do you change ACLs temporarily? No. It's a user privileges thingy. See http://msdn.microsoft.com/en-us/library/aa379306%28VS.85%29.aspx The SE_BACKUP_NAME and SE_RESTORE_NAME privileges are in the administrator's user token, but they are not enabled by default. Cygwin just enables them at startup time, if they are available in the user token. Therefore, a Cygwin process has the usual POSIX-like permissions for admin users. It's no magic which isn't available to any other native Win32 application. Anyway, it means there is a bug in perl, because on Linux: r...@kitsu:~# touch test.txt r...@kitsu:~# chmod 0444 test.txt r...@kitsu:~# perl -e 'print writable\n if -w test.txt' writable On Cygwin 1.7 perl thinks that the file is not writable. Indeed. Checking with strace I found that the test is the same on Linux and Cygwin. In both cases perl uses stat(), and the returned permissions are the same (0444). Further experimenting shows that perl has a hardcoded uid == 0 test which must obviously fail on Cygwin. If I change the user's uid to 0, the string writable is printed by the above command. That's a bug in perl. There are other OSes out there which have root-like permissions for non-0 uids. Perl should use the access() function to check for read/write/execute permissions, which always returns the correct result independent of the uid of the current user. Corinna -- Corinna Vinschen Please, send mails regarding Cygwin to Cygwin Project Co-Leader cygwin AT cygwin DOT com Red Hat -- 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: [1.7] cygwin allows writing to readonly files
On Mon, Aug 10, 2009 at 8:11 PM, Alexey Borzenkovsna...@gmail.com wrote: Anyway, it means there is a bug in perl, because on Linux: On second though, it is actually bug in Cygwin. Programs and libraries expect superuser behavior only when user id is zero, which is clearly not the case in Cygwin 1.7. I think that maybe only local administrator account should be assigned user id 0, and that only local administrator should be allowed reading/writing files that it has no access to. -- 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: Perl bug (was Re: [1.7] cygwin allows writing to readonly files)
On Mon, Aug 10, 2009 at 8:40 PM, Corinna Vinschencorinna-cyg...@cygwin.com wrote: That's a bug in perl. There are other OSes out there which have root-like permissions for non-0 uids. Perl should use the access() function to check for read/write/execute permissions, which always returns the correct result independent of the uid of the current user. Ah, so it is actually possible on other OSes, I didn't know that. Then maybe you're right. Thanks for clarifying. -- 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: [1.7] cygwin allows writing to readonly files
Alexey Borzenkov wrote: On Mon, Aug 10, 2009 at 8:11 PM, Alexey Borzenkovsna...@gmail.com wrote: Anyway, it means there is a bug in perl, because on Linux: On second though, it is actually bug in Cygwin. Programs and libraries expect superuser behavior only when user id is zero, which is clearly not the case in Cygwin 1.7. http://www.opengroup.org/onlinepubs/95399/xrat/xbd_chap03.html Superuser* This concept, with great historical significance to UNIX system users, has been replaced with the notion of appropriate privileges. This would seem to imply that it is permitted for there to be users other than uid 0 with appropriate privileges. Programs should not be trying to second-guess the OS about the privs of a uid, they should ask the access() function and find out. cheers, DaveK -- 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: Perl bug (was Re: [1.7] cygwin allows writing to readonly files)
2009/8/10 Corinna Vinschen: On Aug 10 20:11, Alexey Borzenkov wrote: On Mon, Aug 10, 2009 at 5:25 PM, Corinna Vinschencorinna-cyg...@cygwin.com wrote: That's a bug in your testsuite. I assume you're running the tests as administrator, right? Administrators have the right to write to all files, even R/O files, according to POSIX rules. Your test would fail on Linux as well, if you're running it as root. Well, it's not my testsuite, but yes, I'm running under administrator account. But it makes me wonder, how does it work? Do you change ACLs temporarily? No. It's a user privileges thingy. See http://msdn.microsoft.com/en-us/library/aa379306%28VS.85%29.aspx The SE_BACKUP_NAME and SE_RESTORE_NAME privileges are in the administrator's user token, but they are not enabled by default. Cygwin just enables them at startup time, if they are available in the user token. Therefore, a Cygwin process has the usual POSIX-like permissions for admin users. It's no magic which isn't available to any other native Win32 application. Anyway, it means there is a bug in perl, because on Linux: r...@kitsu:~# touch test.txt r...@kitsu:~# chmod 0444 test.txt r...@kitsu:~# perl -e 'print writable\n if -w test.txt' writable On Cygwin 1.7 perl thinks that the file is not writable. Indeed. Checking with strace I found that the test is the same on Linux and Cygwin. In both cases perl uses stat(), and the returned permissions are the same (0444). Further experimenting shows that perl has a hardcoded uid == 0 test which must obviously fail on Cygwin. If I change the user's uid to 0, the string writable is printed by the above command. That's a bug in perl. There are other OSes out there which have root-like permissions for non-0 uids. Perl should use the access() function to check for read/write/execute permissions, which always returns the correct result independent of the uid of the current user. Thanks. I'll carry it along to p5p, but it will definitely not appear in upstream 5.10.1 because this gate is already closed. Even a horrible performance problem with File::Spec::Cygwin::case_tolerant was not fixed. But I work on a fix to be included in blead and in my cygwin package. -- Reini Urban -- 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: Perl bug (was Re: [1.7] cygwin allows writing to readonly files)
2009/8/11 Reini Urban: 2009/8/10 Corinna Vinschen: On Aug 10 20:11, Alexey Borzenkov wrote: On Mon, Aug 10, 2009 at 5:25 PM, Corinna Vinschencorinna-cyg...@cygwin.com wrote: That's a bug in your testsuite. I assume you're running the tests as administrator, right? Administrators have the right to write to all files, even R/O files, according to POSIX rules. Your test would fail on Linux as well, if you're running it as root. Well, it's not my testsuite, but yes, I'm running under administrator account. But it makes me wonder, how does it work? Do you change ACLs temporarily? No. It's a user privileges thingy. See http://msdn.microsoft.com/en-us/library/aa379306%28VS.85%29.aspx The SE_BACKUP_NAME and SE_RESTORE_NAME privileges are in the administrator's user token, but they are not enabled by default. Cygwin just enables them at startup time, if they are available in the user token. Therefore, a Cygwin process has the usual POSIX-like permissions for admin users. It's no magic which isn't available to any other native Win32 application. Anyway, it means there is a bug in perl, because on Linux: r...@kitsu:~# touch test.txt r...@kitsu:~# chmod 0444 test.txt r...@kitsu:~# perl -e 'print writable\n if -w test.txt' writable On Cygwin 1.7 perl thinks that the file is not writable. Indeed. Checking with strace I found that the test is the same on Linux and Cygwin. In both cases perl uses stat(), and the returned permissions are the same (0444). Further experimenting shows that perl has a hardcoded uid == 0 test which must obviously fail on Cygwin. If I change the user's uid to 0, the string writable is printed by the above command. That's a bug in perl. There are other OSes out there which have root-like permissions for non-0 uids. Perl should use the access() function to check for read/write/execute permissions, which always returns the correct result independent of the uid of the current user. Thanks. I'll carry it along to p5p, but it will definitely not appear in upstream 5.10.1 because this gate is already closed. Even a horrible performance problem with File::Spec::Cygwin::case_tolerant was not fixed. But I work on a fix to be included in blead and in my cygwin package. Bug confirmed too early. It's actually defined and described this way. access() is not used for performance reasons. See perldoc perlfunc -X If you are using ACLs, there is a pragma called Cfiletest that may produce more accurate results than the bare stat() mode bits. When under the Cuse filetest 'access' the above-mentioned filetests will test whether the permission can (not) be granted using the access() family of system calls. Also note that the C-x and C-X may under this pragma return true even if there are no execute permission bits set (nor any extra execute permission ACLs). This strangeness is due to the underlying system calls' definitions. Note also that, due to the implementation of Cuse filetest 'access', the C_ special filehandle won't cache the results of the file tests when this pragma is in effect. Read the documentation for the Cfiletest pragma for more information. $ ./perl -e 'print writable\n if -w test.txt' $ ./perl -e 'use filetest access; print writable\n if -w test.txt' writable I can turn on access checks easily for CYGWIN but cygwin perl is already slow enough, so I will not do that. Changing the uid==0 check to check the Administrators gid is more promising. i.e. --- doio.c.orig 2009-04-18 19:17:04.0 +0200 +++ doio.c 2009-08-11 04:46:09.34375 +0200 @@ -1918,7 +1918,11 @@ return (mode statbufp-st_mode) ? TRUE : FALSE; #else /* ! DOSISH */ +# ifndef __CYGWIN__ if ((effective ? PL_euid : PL_uid) == 0) { /* root is special */ +# else +if ((effective ? PL_egid : PL_gid) == 544) { /* member of Administrators? */ +# endif if (mode == S_IXUSR) { if (statbufp-st_mode 0111 || S_ISDIR(statbufp-st_mode)) return TRUE; but this didn't help me, because Administrators is not my first group. So I call this a known limitation for all ACL aware filesystems. -- Reini Urban http://phpwiki.org/ http://murbreak.at/ -- 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