Re: RFC: [PATCH] trans/fakeroot.c
On Mon, 2015-10-12 at 15:21 +0200, Samuel Thibault wrote: > I believe they will. But perhaps in your tests they didn't (but did > your tests really try that?), in which case it'd mean there is a bug. > But for now nothing said there was a bug there. FYI: gcc-snapshot (20150817, not 20150913) and frama-c (20150201+sodium +dfsg-2) with downgraded dependencies (probably an FTBFS issue if rebuilt on other arches) build fine with the latest fakeroot :)
Re: RFC: [PATCH] trans/fakeroot.c
Svante Signell, le Tue 13 Oct 2015 13:42:22 +0200, a écrit : > On Mon, 2015-10-12 at 15:21 +0200, Samuel Thibault wrote: > > > I believe they will. But perhaps in your tests they didn't (but did > > your tests really try that?), in which case it'd mean there is a bug. > > But for now nothing said there was a bug there. > > FYI: gcc-snapshot (20150817, not 20150913) and frama-c (20150201+sodium > +dfsg-2) with downgraded dependencies (probably an FTBFS issue if > rebuilt on other arches) build fine with the latest fakeroot :) I've seen that on buildds, yes, but snd & such still have an issue with temporary files in /tmp Samuel
Re: RFC: [PATCH] trans/fakeroot.c
On Tue, 2015-10-13 at 13:49 +0200, Samuel Thibault wrote: > Svante Signell, le Tue 13 Oct 2015 13:42:22 +0200, a écrit : > > On Mon, 2015-10-12 at 15:21 +0200, Samuel Thibault wrote: > > FYI: gcc-snapshot (20150817, not 20150913) and frama-c (20150201+sodium > > +dfsg-2) with downgraded dependencies (probably an FTBFS issue if > > rebuilt on other arches) build fine with the latest fakeroot :) > > I've seen that on buildds, yes, but snd & such still have an issue with > temporary files in /tmp Well, with the updated 06-hurd.diff patch in #801604 I don't see any fakeroot problems (old or new version)
Re: RFC: [PATCH] trans/fakeroot.c
Svante Signell, le Mon 12 Oct 2015 15:16:19 +0200, a écrit : > On Mon, 2015-10-12 at 15:12 +0200, Samuel Thibault wrote: > > Svante Signell, le Mon 12 Oct 2015 15:04:40 +0200, a écrit : > > > OK I buy your explanation; though there seems to be remaining bugs. > > > > Which bugs? > > You wrote it not me: > > Subsequent writes to the file will then fail (and if they don't, > that's another bug to be fixed). "If they don't" I believe they will. But perhaps in your tests they didn't (but did your tests really try that?), in which case it'd mean there is a bug. But for now nothing said there was a bug there. Samuel
Re: RFC: [PATCH] trans/fakeroot.c
On Mon, 2015-10-12 at 14:49 +0200, Samuel Thibault wrote: > Svante Signell, le Mon 12 Oct 2015 14:45:09 +0200, a écrit : > > On Mon, 2015-10-12 at 02:08 +0200, Samuel Thibault wrote: > > > The commit I have just pushed, which does make sense, does fix gpsd at > > > least. > Please erase your build tree and restart the build from scratch. You > probably have a remaining non-writable gpsd.udev file. Yes, I had forgotten to remove it. Thanks! > > Since the packages I've built builds fine using the condition below: > > if (file != MACH_PORT_NULL && (nn->openmodes & newmodes)) > > please explain what is wrong with it and why it works while your does > > not? > > I have explained at length how the function is supposed to behave in > my previous mail. Your proposed change does not meet what I said. > Notably, in the nn->openmodes = O_READ and newmodes = O_WRITE case, > it'll be wrong: nn->openmodes & newmodes will be zero, and thus the > 'file' port will be used as such, but it will not have O_WRITE mode! > Subsequent writes to the file will then fail (and if they don't, that's > another bug to be fixed). OK I buy your explanation; though there seems to be remaining bugs.
Re: RFC: [PATCH] trans/fakeroot.c
On Mon, 2015-10-12 at 02:08 +0200, Samuel Thibault wrote: > The commit I have just pushed, which does make sense, does fix gpsd at > least. Building gpsd (3.15-1) with your patch applied: cp /home/srs/DEBs/gpsd/gpsd-3.15/gpsd.rules /home/srs/DEBs/gpsd/gpsd-3.15/debian/gpsd.udev cp: cannot create regular file ‘/home/srs/DEBs/gpsd/gpsd-3.15/debian/gpsd.udev’: Permission denied Since the packages I've built builds fine using the condition below: if (file != MACH_PORT_NULL && (nn->openmodes & newmodes)) please explain what is wrong with it and why it works while your does not?
Re: RFC: [PATCH] trans/fakeroot.c
On Mon, 2015-10-12 at 15:12 +0200, Samuel Thibault wrote: > Svante Signell, le Mon 12 Oct 2015 15:04:40 +0200, a écrit : > > OK I buy your explanation; though there seems to be remaining bugs. > > Which bugs? You wrote it not me: > Subsequent writes to the file will then fail (and if they don't, that's another bug to be fixed).
Re: RFC: [PATCH] trans/fakeroot.c
Svante Signell, le Mon 12 Oct 2015 15:04:40 +0200, a écrit : > OK I buy your explanation; though there seems to be remaining bugs. Which bugs? Samuel
Re: RFC: [PATCH] trans/fakeroot.c
Svante Signell, le Mon 12 Oct 2015 14:45:09 +0200, a écrit : > On Mon, 2015-10-12 at 02:08 +0200, Samuel Thibault wrote: > > The commit I have just pushed, which does make sense, does fix gpsd at > > least. > > Building gpsd (3.15-1) with your patch applied: > cp /home/srs/DEBs/gpsd/gpsd-3.15/gpsd.rules > /home/srs/DEBs/gpsd/gpsd-3.15/debian/gpsd.udev > cp: cannot create regular file > ‘/home/srs/DEBs/gpsd/gpsd-3.15/debian/gpsd.udev’: Permission denied Please erase your build tree and restart the build from scratch. You probably have a remaining non-writable gpsd.udev file. > Since the packages I've built builds fine using the condition below: > if (file != MACH_PORT_NULL && (nn->openmodes & newmodes)) > please explain what is wrong with it and why it works while your does > not? I have explained at length how the function is supposed to behave in my previous mail. Your proposed change does not meet what I said. Notably, in the nn->openmodes = O_READ and newmodes = O_WRITE case, it'll be wrong: nn->openmodes & newmodes will be zero, and thus the 'file' port will be used as such, but it will not have O_WRITE mode! Subsequent writes to the file will then fail (and if they don't, that's another bug to be fixed). Samuel
Re: RFC: [PATCH] trans/fakeroot.c
Samuel Thibault, le Mon 12 Oct 2015 14:49:43 +0200, a écrit : > Your proposed change does not meet what I said. > Notably, in the nn->openmodes = O_READ and newmodes = O_WRITE case, > it'll be wrong: nn->openmodes & newmodes will be zero, and thus the > 'file' port will be used as such, but it will not have O_WRITE mode! > Subsequent writes to the file will then fail (and if they don't, that's > another bug to be fixed). Grmbl, I actually meant: in the nn->openmodes = O_WRITE and newmodes = O_READ case. Samuel
Re: RFC: [PATCH] trans/fakeroot.c
Svante Signell, le Sun 11 Oct 2015 23:02:16 +0200, a écrit : > > We also see from the printout that > > nn->openmodes = 2 = O_WRITE and > > newmodes = 1 = O_READ i.e. no intersecting sets. > > > > The above condition is really happening when building (patched to > build, not related to fakeroot) gpsd. Ok. It makes complete sense: we've been writing to a file, and now we are reading from it. > --- a/trans/fakeroot.c.orig 2015-10-08 22:32:09.0 +0200 > +++ b/trans/fakeroot.c2015-10-08 22:34:47.0 +0200 > @@ -216,9 +216,9 @@ > { >/* The user wants openmodes we haven't tried before. */ > > - if (file != MACH_PORT_NULL && (nn->openmodes & ~newmodes)) > + if (file != MACH_PORT_NULL && (nn->openmodes & newmodes)) > { > - /* Intersecting sets with no inclusion. `file' doesn't fit > either, > + /* Intersecting sets. `file' doesn't fit either, But this doesn't make sense! Let me explain in detail what check_openmodes does: - we have an existing node, nn, which contains an opened file nn->file, opened with modes nn->openmodes. - we want to have it opened with nn->openmodes | newmodes. - the 'file' port parameter happens to be that file opened with newmodes. so: - either nn->openmodes already contains the newmodes bits, nn->file is thus already the file opened with modes nn->openmodes | newmodes - or it doesn't, and so we have to do something: - if newmodes actually contains all the nn->openmodes bit, then the 'file' port is just what we need, and there is no need to reopen the file. - otherwise the 'file' port is useless, so we should just close it, and really reopen the file with nn->openmodes | newmodes. So the condition for closing the file and making it null is "nn->openmodes has bits that newmodes doesn't have". That happens to translate to "nn->openmodes & ~newmodes". If I'm wrong somewhere in my reasoning (which can probably be very true), please tell me where. Just saying "that testcase works with my patch" is not enough to convince me to apply it, because there are so many other cases. In the testcase you mention above: > > nn->openmodes = 2 = O_WRITE and > > newmodes = 1 = O_READ i.e. no intersecting sets. (nn->openmodes & ~newmodes) will be O_WRITE, which shows that we have an existing file opened with O_WRITE, but the provided 'file' port doesn't have it (as announced by newmodes). And thus we *have* to destroy the 'file' port and not use it, and instead reopen the file to really get O_WRITE|O_READ: otherwise we wouldn't have O_WRITE any more, which will pose problem whenever we want to write to it again. In the other testcase you mentioned in your previous mail: > nn->openmodes = 1 = O_READ and > newmodes = 3 = O_READ | O_WRITE, We have an existing file opened in O_READ, and now we want O_READ|O_WRITE. The existing file is not enough, it's missing O_WRITE (newmodes &~ nn->openmodes returns O_WRITE), but the provided 'file' port has both O_READ|O_WRITE, so we can just use it, there is no need to reopen the file, it'll cover both the original need (O_READ) as tested by nn->openmodes & ~newmodes being 0, and the new need (O_READ|O_WRITE). > I told you, the test should be inclusive, not exclusive :) You didn't prove why. Testcases are good when they cover all cases. Otherwise they are just an indication of something is going wrong, not that the proposed fix is always right. Either what I said above is wrong at some point, or the bug is somewhere else (see the previous changes we had to make in netfs_attempt_chmod for instance). What call *actually* produces the permission denied error, BTW? In our previous exchange it was actually the reopen operation. Samuel
Re: RFC: [PATCH] trans/fakeroot.c
On Thu, 2015-05-21 at 10:56 +0200, Svante Signell wrote: > On Fri, 2015-05-15 at 20:31 +0200, Samuel Thibault wrote: > > Svante Signell, le Tue 12 May 2015 09:15:46 +0200, a écrit : > > > > - if (file != MACH_PORT_NULL && (nn->openmodes & ~newmodes)) > > > + if (file != MACH_PORT_NULL && (nn->openmodes & newmodes )) > > > /* works */ > > > > This change needs to be motivated and explained. ... > A few notes: > - the condition (nn->openmodes & ~newmodes) is wrong since this > triggers > on newmodes being complementary to nn->openmodes but the comment in > the > code says: > /* Intersecting sets. >We need yet another new peropen on this node. */ > The correct condition for intersection is the and operation, i.e. > (nn->openmodes & newmodes ), one example being > nn->openmodes = 1 = O_READ and > newmodes = 3 = O_READ | O_WRITE,; the intersection being O_READ. > > For the test case given before and the wrong condition triggers the > following: > ./my_fakeroot-hurd rpctrace make 2>&1 | tee rpctrace_nOK.out > ... > 9<--154(pid16637)->dir_lookup ("dev/null" 1 0) > Intersecting sets > newmodes=1, (nn->openmodes=2 & ~newmodes=376) = 2 > (nn->openmodes & newmodes) = 0 > > file == MACH_PORT_NULL > nn->file=62 > (nn->openmodes=2 | newmodes=1) = 3 > bad_retryname=NULL, file=60 > = 0 1 ""175<--183(pid16637) > > with no bad effects but > > 146<--178(pid16637)->dir_lookup ("gnatvsn_from/alloc.ali" 1 0) > Intersecting sets > newmodes=1, (nn->openmodes=2 & ~newmodes=376) = 2 > (nn->openmodes & newmodes) = 0 > > file == MACH_PORT_NULL > nn->file=84 > (nn->openmodes=2 | newmodes=1) = 3 > bad_retryname=NULL, file=0 > = 0x400d (Permission denied) > > has, since the file returned is zero. > > According to dir_lookup in fs.defs a file name of null is equivalent > to > a reopen of that file. > err = dir_lookup (nn->file, "", nn->openmodes | newmodes, > 0, > _retry, bad_retryname, ); > We also see from the printout that > nn->openmodes = 2 = O_WRITE and > newmodes = 1 = O_READ i.e. no intersecting sets. > The above condition is really happening when building (patched to build, not related to fakeroot) gpsd. I have now built the failing packages with the patch inlined below: - gpsd 3.15-1 (patched to build, bug #) - frama-c 20150201+sodium+dfsg-2 - snd 11.7-4 (patched to build, bug #) Have to check the failing package. With a fixed patch snd b11.7-4 uilds fine with the old fakeroot and with the corrected one. - gcc-snapshot 20150817-1, (20150913-1 has problems with some pthread headers when building g++,same problem on the buildd) --- a/trans/fakeroot.c.orig2015-10-08 22:32:09.0 +0200 +++ b/trans/fakeroot.c 2015-10-08 22:34:47.0 +0200 @@ -216,9 +216,9 @@ { /* The user wants openmodes we haven't tried before. */ - if (file != MACH_PORT_NULL && (nn->openmodes & ~newmodes)) + if (file != MACH_PORT_NULL && (nn->openmodes & newmodes)) { - /* Intersecting sets with no inclusion. `file' doesn't fit either, + /* Intersecting sets. `file' doesn't fit either, we need yet another new peropen on this node. */ mach_port_deallocate (mach_task_self (), file); file = MACH_PORT_NULL; I'll be submitting bug reports to make the packages build later (outside fakeroot), I'm currently connected a very low quota wireless connection (the main one is broken due to an unexpected cable being cut off. Repairs will be made later this week.) I told you, the test should be inclusive, not exclusive :)
Re: RFC: [PATCH] trans/fakeroot.c
The commit I have just pushed, which does make sense, does fix gpsd at least. Samuel
Re: RFC: [PATCH] trans/fakeroot.c
On Tue, 2015-06-09 at 17:15 +0200, Svante Signell wrote: I've built pycorrfit and hurd so far, no issues yet. Will build glibc, gnat-4.9 and gcc-5 to be sure. glibc and gnat-4.9 built fine. gcc-5 will take several hours.
Re: RFC: [PATCH] trans/fakeroot.c
On Wed, 2015-06-10 at 10:05 +0200, Svante Signell wrote: On Tue, 2015-06-09 at 17:15 +0200, Svante Signell wrote: I've built pycorrfit and hurd so far, no issues yet. Will build glibc, gnat-4.9 and gcc-5 to be sure. glibc and gnat-4.9 built fine. gcc-5 will take several hours. And gcc-5: 5.1.1-9 built fine too (after a hang and reboot, memory starvation)
Re: RFC: [PATCH] trans/fakeroot.c
On Tue, 2015-06-09 at 11:11 +0200, Samuel Thibault wrote: So the package is actually doing something stupid (yes, that's what you should have written in your mail to explain what is happening, actually :) ). But it does work as root as specified by POSIX, so we have to support it. Yes I think there is a package bug (it's up to the package maintainer to write good code, not me pointing fingers): The command should have read chmod -R 644 debian/pycorrfit/usr/share/doc/pycorrfit/examples/external_model_functions/* since there are no directories below. Nevertheless, as you write, it has to be fixed. I'd say in netfs_attempt_chmod just do real_mode |= S_IRUSR; real_mode |= S_IWUSR; if (nn is a directory) real_mode |= S_IXUSR; so we're sure of having all rights that root would have on the underlying file. New patch attached. Maybe you want to remove the second condition to add S_IXUSR unconditionally for directories. Index: hurd-0.6.git20150523/trans/fakeroot.c === --- hurd-0.6.git20150523.orig/trans/fakeroot.c +++ hurd-0.6.git20150523/trans/fakeroot.c @@ -560,12 +560,10 @@ netfs_attempt_chmod (struct iouser *cred it. */ real_mode = mode; nn = netfs_node_netnode (np); - if (nn-openmodes O_READ) real_mode |= S_IRUSR; - if (nn-openmodes O_WRITE) real_mode |= S_IWUSR; - if (nn-openmodes O_EXEC) -real_mode |= S_IXUSR; +if ((real_mode S_IFDIR) ((real_mode S_IXUSR) == 0)) + real_mode |= S_IXUSR; /* We don't bother with error checking since the fake mode change should always succeed--worst case a later open will get EACCES. */
Re: RFC: [PATCH] trans/fakeroot.c
On Tue, 2015-06-09 at 10:55 +0200, Svante Signell wrote: On Tue, 2015-06-09 at 10:43 +0200, Samuel Thibault wrote: Svante Signell, le Tue 09 Jun 2015 10:13:46 +0200, a écrit : Done so now. Attached are two versions of a patch to fakeroot.c. In netfs_get_dirents(): call netfs_attempt_chmod() before dir_readdir() to make sure that directories are accessible (executable) before changing the underlying files. Why are they not accessible? We don't want to browntape-fix the issue, but really understand what is happening. chmod -R 644 directory makes all directories drwr--r-- i.e. not accessible, as I wrote. Is that a brown-tape fix? mkdir test touch test/a chmod -R test chmod: cannot access ‘test/a’: Permission denied ls -ld test drw-r--r-- 2 srs srs 4096 Jun 9 11:00 test ls -l test ls: cannot access test/a: Permission denied total 0 -? ? ? ? ?? a
Re: RFC: [PATCH] trans/fakeroot.c
Svante Signell, le Tue 09 Jun 2015 10:55:35 +0200, a écrit : On Tue, 2015-06-09 at 10:43 +0200, Samuel Thibault wrote: Svante Signell, le Tue 09 Jun 2015 10:13:46 +0200, a écrit : Done so now. Attached are two versions of a patch to fakeroot.c. In netfs_get_dirents(): call netfs_attempt_chmod() before dir_readdir() to make sure that directories are accessible (executable) before changing the underlying files. Why are they not accessible? We don't want to browntape-fix the issue, but really understand what is happening. chmod -R 644 directory makes all directories drwr--r-- i.e. not accessible, as I wrote. Ah, right :) Sorry I'm so busy I can't even follow the thread. So the package is actually doing something stupid (yes, that's what you should have written in your mail to explain what is happening, actually :) ). But it does work as root as specified by POSIX, so we have to support it. Is that a brown-tape fix? Yes: It's still trying to fix the file mode only after the fact, only when we happen to need more permissions, rather than at the right time, i.e. when the mode is erroneously modified. That was the point of the patch commited in netfs_attempt_chmod before: when modifying the mode, keep what we need to work this the files. Thinking again about it, we added if (nn-openmodes O_READ) real_mode |= S_IRUSR; if (nn-openmodes O_WRITE) real_mode |= S_IWUSR; if (nn-openmodes O_EXEC) real_mode |= S_IXUSR; to make sure that the mode we actually set on the underlying file permit that we can continue accessing the file as needed. But root has all rights anyway, the only exception is executing a file which doesn't have +x. So netfs_attempt_chmod should could just allow everything on the underlying file. I.e. I'd say in netfs_attempt_chmod just do real_mode |= S_IRUSR; real_mode |= S_IWUSR; if (nn is a directory) real_mode |= S_IXUSR; so we're sure of having all rights that root would have on the underlying file. Samuel
Re: RFC: [PATCH] trans/fakeroot.c
On Fri, 2015-06-05 at 11:18 +0530, Samuel Thibault wrote: Hello, It seems there is still a corner case which doesn't work: the pycorrfit package fails to build with: chmod -R 644 debian/pycorrfit/usr/share/doc/pycorrfit/examples/external_model_functions/ chmod: cannot access 'debian/pycorrfit/usr/share/doc/pycorrfit/examples/external_model_functions/ExampleFunc_CS_2D+2D+S+T.txt': Permission denied etc. Could you have a look? Done so now. Attached are two versions of a patch to fakeroot.c. In netfs_get_dirents(): call netfs_attempt_chmod() before dir_readdir() to make sure that directories are accessible (executable) before changing the underlying files. The resulting directory (and file) access permissions are the same as with fakeroot-tcp and Linux. The first patch adds S_IXUSR to real_mode, the other adds O_EXEC to nn-openmodes. Your choice (if OK, of course, maybe I've missed something.) Thanks! Index: hurd-0.6.git20150523/trans/fakeroot.c === --- hurd-0.6.git20150523.orig/trans/fakeroot.c +++ hurd-0.6.git20150523/trans/fakeroot.c @@ -796,8 +796,19 @@ netfs_get_dirents (struct iouser *cred, mach_msg_type_number_t *datacnt, vm_size_t bufsize, int *amt) { - return dir_readdir (netfs_node_netnode (dir)-file, data, datacnt, + struct netnode *nn = netfs_node_netnode (dir); + mode_t real_mode = dir-nn_stat.st_mode; + error_t err = 0; + + if ((real_mode S_IFDIR) ((real_mode S_IXUSR) == 0)) +{ + err = netfs_attempt_chmod (cred, dir, real_mode | S_IXUSR); + if (err) + return err; +} + err = dir_readdir (nn-file, data, datacnt, entry, nentries, bufsize, amt); + return err; } error_t Index: hurd-0.6.git20150523/trans/fakeroot.c === --- hurd-0.6.git20150523.orig/trans/fakeroot.c +++ hurd-0.6.git20150523/trans/fakeroot.c @@ -796,8 +796,20 @@ netfs_get_dirents (struct iouser *cred, mach_msg_type_number_t *datacnt, vm_size_t bufsize, int *amt) { - return dir_readdir (netfs_node_netnode (dir)-file, data, datacnt, + struct netnode *nn = netfs_node_netnode (dir); + mode_t real_mode = dir-nn_stat.st_mode; + error_t err = 0; + + if ((real_mode S_IFDIR) ((real_mode S_IXUSR) == 0)) +{ + nn-openmodes |= O_EXEC; + err = netfs_attempt_chmod (cred, dir, real_mode); + if (err) + return err; +} + err = dir_readdir (nn-file, data, datacnt, entry, nentries, bufsize, amt); + return err; } error_t
Re: RFC: [PATCH] trans/fakeroot.c
Svante Signell, le Tue 09 Jun 2015 10:13:46 +0200, a écrit : Done so now. Attached are two versions of a patch to fakeroot.c. In netfs_get_dirents(): call netfs_attempt_chmod() before dir_readdir() to make sure that directories are accessible (executable) before changing the underlying files. Why are they not accessible? We don't want to browntape-fix the issue, but really understand what is happening. Samuel
Re: RFC: [PATCH] trans/fakeroot.c
On Tue, 2015-06-09 at 10:43 +0200, Samuel Thibault wrote: Svante Signell, le Tue 09 Jun 2015 10:13:46 +0200, a écrit : Done so now. Attached are two versions of a patch to fakeroot.c. In netfs_get_dirents(): call netfs_attempt_chmod() before dir_readdir() to make sure that directories are accessible (executable) before changing the underlying files. Why are they not accessible? We don't want to browntape-fix the issue, but really understand what is happening. chmod -R 644 directory makes all directories drwr--r-- i.e. not accessible, as I wrote. Is that a brown-tape fix?
Re: RFC: [PATCH] trans/fakeroot.c
Svante Signell, le Tue 09 Jun 2015 11:41:01 +0200, a écrit : On Tue, 2015-06-09 at 11:11 +0200, Samuel Thibault wrote: So the package is actually doing something stupid (yes, that's what you should have written in your mail to explain what is happening, actually :) ). But it does work as root as specified by POSIX, so we have to support it. Yes I think there is a package bug (it's up to the package maintainer to write good code, not me pointing fingers): Well, the code is supposed to be run by root, so it's actually sorta correct :) New patch attached. Maybe you want to remove the second condition to add S_IXUSR unconditionally for directories. There is no point in testing for the flag before setting it, indeed. You also need to fix the indentation. +if ((real_mode S_IFDIR) I don't think it's so simple, see the precise S_IFMT bit matter. That should most probably be rather an S_ISDIR call. Samuel
Re: RFC: [PATCH] trans/fakeroot.c
Hello, It seems there is still a corner case which doesn't work: the pycorrfit package fails to build with: chmod -R 644 debian/pycorrfit/usr/share/doc/pycorrfit/examples/external_model_functions/ chmod: cannot access 'debian/pycorrfit/usr/share/doc/pycorrfit/examples/external_model_functions/ExampleFunc_CS_2D+2D+S+T.txt': Permission denied etc. Could you have a look? Samuel
Re: RFC: [PATCH] trans/fakeroot.c
gnat-5 built fine indeed. Congrats again for having tracked this bug! I have switched the buildds to using fakeroot-hurd by default, and will probably bump the alternatives priority soon too. Samuel
Re: RFC: [PATCH] trans/fakeroot.c
Quoting Samuel Thibault (2015-05-23 23:53:07) I have switched the buildds to using fakeroot-hurd by default, and will probably bump the alternatives priority soon too. Awesome :) Justus
Re: RFC: [PATCH] trans/fakeroot.c
Thanks again for the explanations, that's exactly what I needed to manage to have a look at your proposed changes quickly :) Svante Signell, le Thu 21 May 2015 10:56:24 +0200, a écrit : - there are two cosmetic changes (I know they should not be there, but for code unification/readability) - struct netnode contains int openmodes;/* O_READ | O_WRITE | O_EXEC */ therefore I chose to limit the openmodes. This is not only purely cosmetic: it actually changes something in the code. This is a browntape fix. That's typically where electrical engineers and computer scientists can't agree: a browntape fix is no good in computer science, while it can be completely reasonable for electrical engineering :) Instead, I have commited a hard assertion: callers of new_node and check_openmodes are supposed to be careful (this is what the existing code does, except in one place). - the condition (nn-openmodes ~newmodes) is wrong since this triggers on newmodes being complementary to nn-openmodes Not exactly: it triggers when both `nn-openmodes' has some flag that `newmodes' doesn't have, and `newmodes' has some flag that `nn-openmodes' doesn't have. I.e. `nn-file' is missing an openmode, but `file' is missing one too, so we really need to create another file_t, in order to have all the openmodes that we need. /* Intersecting sets. We need yet another new peropen on this node. */ The correct condition for intersection is the and operation, i.e. I think it's the comment which is not precise enough, it'd rather be Intersecting sets with no inclusion. one example being nn-openmodes = 1 = O_READ and newmodes = 3 = O_READ | O_WRITE,; the intersection being O_READ. The goal of check_openmodes is not the intersection, but the union, actually, see nn-openmodes | newmodes in the dir_lookup call. For the test case given before and the wrong condition triggers the following: ./my_fakeroot-hurd rpctrace make 21 | tee rpctrace_nOK.out ... 9--154(pid16637)-dir_lookup (dev/null 1 0) Intersecting sets newmodes=1, (nn-openmodes=2 ~newmodes=376) = 2 (nn-openmodes newmodes) = 0 file == MACH_PORT_NULL nn-file=62 (nn-openmodes=2 | newmodes=1) = 3 bad_retryname=NULL, file=60 = 0 1 175--183(pid16637) with no bad effects but 146--178(pid16637)-dir_lookup (gnatvsn_from/alloc.ali 1 0) Intersecting sets newmodes=1, (nn-openmodes=2 ~newmodes=376) = 2 (nn-openmodes newmodes) = 0 file == MACH_PORT_NULL nn-file=84 (nn-openmodes=2 | newmodes=1) = 3 bad_retryname=NULL, file=0 = 0x400d (Permission denied) has, since the file returned is zero. Yes, but the ground reason is not a bogus test: here, we previously had write access to gnatvsn_from/alloc.ali (nn-openmodes = 2), but now we want read access too (newmodes = 1), so we reopen it, in order to get both. Yes, we want to have both. Using your patch would mean that we lose the write access. The test is really right: we want to reopen the file, with the union of the modes. And it's the reopen which fails. According to dir_lookup in fs.defs a file name of null is equivalent to a reopen of that file. err = dir_lookup (nn-file, , nn-openmodes | newmodes, 0, bad_retry, bad_retryname, file); Yes, and *that* is what produces the permission denied error. In the case of /dev/null, there is no error since /dev/null is always world-readable/writable. In the case of gnatvsn_from/alloc.ali, it depends on the mode of the underlying file. And then I realize what you wrote earlier in your mail: - An openmode equal to zero should not be allowed, but seems to be unavoidable. A zero openmode would mean no read or write access according to fcntl.h: # define O_NORW 0 /* Open without R/W access. */ However, things seems to work, even with openmodes being zero. Well, I guess this is where things don't actually work: an initial open of gnatvsn_from/alloc.ali with modes = 0, and thus fakeroot creates the underlying file with no access right, and then when we want to re-open it we can't since it doesn't have the permissions. So, in the end, although the effect happens in check_openmodes, the bug is somewhere between the creation of gnatvsn_from/alloc.ali and the reopen here. In your testcase, it's tar x which creates gnatvsn_from/alloc.ali, the testcase can be reduced to: (cd dst/gnatvsn_to; tar xf ../../file.tar) md5sum dst/gnatvsn_to/gnatvsn_from/alloc.ali within the same fakeroot-hurd session. To create the file, tar does: 10--67(pid3274)-dir_lookup (gnatvsn_from/alloc.ali 4194362 256) = 0 1 86--89(pid3274) 86--89(pid3274)-term_getctty () = 0xfed1 ((ipc/mig) bad request message ID) 86--89(pid3274)-io_write (V GNAT Lib v4.9\nA -nostdinc\nA -O2\nA -fPIC\nA -g\nA -mtune=generic\nA -march=i586\n -1) = 0 2267 86--89(pid3274)-file_utimes ({0 0} {1418859518 0}) = 0 86--89(pid3274)-file_chown (1000 1000) = 0 86--89(pid3274)-file_chmod (292)
Re: RFC: [PATCH] trans/fakeroot.c
Samuel Thibault, le Sat 23 May 2015 02:04:24 +0530, a écrit : Could you try the attached patch? It makes your testcase work fine, but perhaps it has other unexpected consequences. Thinking again about it, I believe it will be really fine, so commited it. Samuel
Re: RFC: [PATCH] trans/fakeroot.c
On Fri, 2015-05-15 at 20:31 +0200, Samuel Thibault wrote: Svante Signell, le Tue 12 May 2015 09:15:46 +0200, a écrit : - if (file != MACH_PORT_NULL (nn-openmodes ~newmodes)) + if (file != MACH_PORT_NULL (nn-openmodes newmodes )) /* works */ This change needs to be motivated and explained. The updated patch is now much smaller, see attached trans_fakeroot.patch and comes with an explanation, however not yet with a changelog entry. A few notes: - fakeroot works OK even without limiting the openmodes, the crucial fix is the changed condition, to be explained below. - there are two cosmetic changes (I know they should not be there, but for code unification/readability) - struct netnode contains int openmodes;/* O_READ | O_WRITE | O_EXEC */ therefore I chose to limit the openmodes. - An openmode equal to zero should not be allowed, but seems to be unavoidable. A zero openmode would mean no read or write access according to fcntl.h: # define O_NORW 0 /* Open without R/W access. */ However, things seems to work, even with openmodes being zero. - the condition (nn-openmodes ~newmodes) is wrong since this triggers on newmodes being complementary to nn-openmodes but the comment in the code says: /* Intersecting sets. We need yet another new peropen on this node. */ The correct condition for intersection is the and operation, i.e. (nn-openmodes newmodes ), one example being nn-openmodes = 1 = O_READ and newmodes = 3 = O_READ | O_WRITE,; the intersection being O_READ. For the test case given before and the wrong condition triggers the following: ./my_fakeroot-hurd rpctrace make 21 | tee rpctrace_nOK.out ... 9--154(pid16637)-dir_lookup (dev/null 1 0) Intersecting sets newmodes=1, (nn-openmodes=2 ~newmodes=376) = 2 (nn-openmodes newmodes) = 0 file == MACH_PORT_NULL nn-file=62 (nn-openmodes=2 | newmodes=1) = 3 bad_retryname=NULL, file=60 = 0 1 175--183(pid16637) with no bad effects but 146--178(pid16637)-dir_lookup (gnatvsn_from/alloc.ali 1 0) Intersecting sets newmodes=1, (nn-openmodes=2 ~newmodes=376) = 2 (nn-openmodes newmodes) = 0 file == MACH_PORT_NULL nn-file=84 (nn-openmodes=2 | newmodes=1) = 3 bad_retryname=NULL, file=0 = 0x400d (Permission denied) has, since the file returned is zero. According to dir_lookup in fs.defs a file name of null is equivalent to a reopen of that file. err = dir_lookup (nn-file, , nn-openmodes | newmodes, 0, bad_retry, bad_retryname, file); We also see from the printout that nn-openmodes = 2 = O_WRITE and newmodes = 1 = O_READ i.e. no intersecting sets. - With the correct condition this code is not triggered in the test code, but does e.g. when building gnat-4.9. I hope this explanation is sufficient. The pached fakerot has been build-tested as written before on gnumach, hurd, glibc, gnat-4.9 and gcc-5. Thanks! Index: hurd-0.6/trans/fakeroot.c === --- hurd-0.6.orig/trans/fakeroot.c +++ hurd-0.6/trans/fakeroot.c @@ -91,7 +91,11 @@ new_node (file_t file, mach_port_t idpor } nn = netfs_node_netnode (*np); nn-file = file; - nn-openmodes = openmodes; + + /* FIXME: Forbid nn-openmodes == 0 and openmodes == 0? */ + /* XXX: Limit nn-openmodes */ + nn-openmodes = openmodes (O_RDWR | O_EXEC); + if (idport != MACH_PORT_NULL) nn-idport = idport; else @@ -207,11 +211,13 @@ check_openmodes (struct netnode *nn, int { error_t err = 0; - if (newmodes ~ nn-openmodes) + /* XXX: Limit nn-openmodes */ + nn-openmodes = (O_RDWR | O_EXEC); + if (~nn-openmodes newmodes) { /* The user wants openmodes we haven't tried before. */ - if (file != MACH_PORT_NULL (nn-openmodes ~newmodes)) + if (file != MACH_PORT_NULL (nn-openmodes newmodes )) { /* Intersecting sets. We need yet another new peropen on this node. */ @@ -388,7 +394,7 @@ netfs_S_dir_lookup (struct protid *dirus } err = check_openmodes (netfs_node_netnode (np), - (flags (O_RDWR|O_EXEC)), file); + flags (O_RDWR|O_EXEC), file); pthread_mutex_unlock (idport_ihash_lock); } else
Re: RFC: [PATCH] trans/fakeroot.c
Svante Signell, le Tue 12 May 2015 09:15:46 +0200, a écrit : + /* XXX: Limit openmodes */ + if (openmodes O_ALLOWED) +openmodes = O_ALLOWED; /* works */ More precisely, which openmode posed problem here? Perhaps this is not the best place to exclude them. At the very least we need to know what exactly was posing problem before patching the source code. Also, use if (openmodes ~O_ALLOWED) rather than openmodes O_ALLOWED. It happens that O_ALLOWED contains contiguous bits from bit #0, and thus O_ALLOWED happens to produce the expected result, but that's only by luck. + /* XXX: Change nn-openmodes selectively */ + //if (newmodes nn-openmodes) + nn-openmodes = newmodes; Ditto. - if (file != MACH_PORT_NULL (nn-openmodes ~newmodes)) + if (file != MACH_PORT_NULL (nn-openmodes newmodes )) /* works */ This change needs to be motivated and explained. Samuel
Re: RFC: [PATCH] trans/fakeroot.c
Svante Signell, le Tue 12 May 2015 09:15:46 +0200, a écrit : The idea is to limit the openmodes according to the values defined in struct netnode and to change the test for overlapping sets. In which case is this needed? What happens in that case and how the patch fixes this? A patch should be provided with not only an explanation of what it does, but also why this is the right way to fix the eventual bug you want to fix. Samuel
Re: RFC: [PATCH] trans/fakeroot.c
On Tue, 2015-05-12 at 09:42 +0200, Samuel Thibault wrote: Svante Signell, le Tue 12 May 2015 09:15:46 +0200, a écrit : The idea is to limit the openmodes according to the values defined in struct netnode and to change the test for overlapping sets. In which case is this needed? What happens in that case and how the patch fixes this? I already supplied a test case. What's up?
Re: RFC: [PATCH] trans/fakeroot.c
On Tue, 2015-05-12 at 11:22 +0200, Samuel Thibault wrote: Svante Signell, le Tue 12 May 2015 10:00:26 +0200, a écrit : On Tue, 2015-05-12 at 09:42 +0200, Samuel Thibault wrote: Svante Signell, le Tue 12 May 2015 09:15:46 +0200, a écrit : The idea is to limit the openmodes according to the values defined in struct netnode and to change the test for overlapping sets. In which case is this needed? What happens in that case and how the patch fixes this? I already supplied a test case. What's up? Explain what happens. Only providing a testcase means the reviewer has to For instance here, just inventing dumb things, it's just to give an example of what I need to see explained to avoid having to spend a few hours to understand what's happening: the testcase creates a socket, Sorry for the confusion: This patch is not about the socket creation case. It is about the build failure of gnat-4.9 with fakeroot-hurd. two different bugs!
Re: RFC: [PATCH] trans/fakeroot.c
Svante Signell, le Tue 12 May 2015 10:00:26 +0200, a écrit : On Tue, 2015-05-12 at 09:42 +0200, Samuel Thibault wrote: Svante Signell, le Tue 12 May 2015 09:15:46 +0200, a écrit : The idea is to limit the openmodes according to the values defined in struct netnode and to change the test for overlapping sets. In which case is this needed? What happens in that case and how the patch fixes this? I already supplied a test case. What's up? Explain what happens. Only providing a testcase means the reviewer has to - understand what the testcase is doing - infer how the patched source code gets triggered - find out how that source code does things wrong - understand why the proposed changes fixes that behavior Which takes a lot of time, while the submitter already know all this and just has to explain it. For instance here, just inventing dumb things, it's just to give an example of what I need to see explained to avoid having to spend a few hours to understand what's happening: the testcase creates a socket, whose mode is not just read/write, and thus it test at line 1234 it erroneously takes the then branch, while it shouldn't, since it's just a socket. With the proposed changes, the function will just reject the mode, and thus the caller will correctly revert back to code path bar which does things properly: it calls foobaz(), which is what we want for the testcase. Really, doing this won't take you much time, and save the reviewer a lot of time (which is just duplicate since it's exactly what you did in your work). Samuel
Re: RFC: [PATCH] trans/fakeroot.c
Svante Signell, le Tue 12 May 2015 11:39:19 +0200, a écrit : On Tue, 2015-05-12 at 11:22 +0200, Samuel Thibault wrote: Svante Signell, le Tue 12 May 2015 10:00:26 +0200, a écrit : On Tue, 2015-05-12 at 09:42 +0200, Samuel Thibault wrote: Svante Signell, le Tue 12 May 2015 09:15:46 +0200, a écrit : The idea is to limit the openmodes according to the values defined in struct netnode and to change the test for overlapping sets. In which case is this needed? What happens in that case and how the patch fixes this? I already supplied a test case. What's up? Explain what happens. Only providing a testcase means the reviewer has to For instance here, just inventing dumb things, it's just to give an example of what I need to see explained to avoid having to spend a few hours to understand what's happening: the testcase creates a socket, Sorry for the confusion: This patch is not about the socket creation case. It is about the build failure of gnat-4.9 with fakeroot-hurd. two different bugs! Ok, this shows how explanation is more than welcome :) Samuel
Re: RFC: [PATCH] trans/fakeroot.c
Svante Signell, le Tue 12 May 2015 10:00:26 +0200, a écrit : On Tue, 2015-05-12 at 09:42 +0200, Samuel Thibault wrote: Svante Signell, le Tue 12 May 2015 09:15:46 +0200, a écrit : The idea is to limit the openmodes according to the values defined in struct netnode and to change the test for overlapping sets. In which case is this needed? What happens in that case and how the patch fixes this? I already supplied a test case. What's up? Also, in the test case, you didn't explain what happens and what is supposed to happen. Your patch seems to be dealing with modes, so perhaps it's the modes which should be observed? But when running fakeroot-hurd make the resulting file has mode 444, so it seems right. Or perhaps it's the md5sum part which is bogus? But I do get the proper md5sum. When reporting a bug, *always* explain all of - the steps to reproduce - what you get - what you expected to get and when providing a patch, explain what I mentioned in my other mail. Samuel