bug#11108: [PATCH] chmod: fix symlink race condition

2012-03-28 Thread Jim Meyering
Paul Eggert wrote:
 This fixes what I hope is an obvious race condition
 that can occur if some other process substitutes a
 symlink for a non-symlink while chmod is running.

Good catch.  I'll bet that's exploitable by anyone who
can convince root to run chmod -r ... DIR on files they own.

The chmodat-introducing commit was v5.92-656-gc97a36e,
but the preceding use of chmod was just as vulnerable.
If you reference a commit in your log, please use git describe
output, not the bare-8-byte-SHA1 like we've done in the past.
While git describe output is not converted to a clickable link
by a released gitk, with the one in upcoming git-1.7.10, it is.

I presume you'll update NEWS, too, where you can say
[bug introduced in the beginning]
I've confirmed that the very first version of chmod.c has the same
problem: it calls stat, then calls chmod whenever !S_ISLNK.

I note also that this doesn't protect anyone who is using
a system that lacks both fchmodat and lchmod.
For that, we'd have to openat each file to get a file descriptor,
then fstat that FD to verify it's the same dev/ino as
found by the fts-run stat call, and only then, call fchmod.

 =
 * src/chmod.c (process_file): Don't follow symlink if we
 think the file is not a symlink.
 ---
  src/chmod.c |   10 +-
  1 files changed, 9 insertions(+), 1 deletions(-)

 diff --git a/src/chmod.c b/src/chmod.c
 index aa4ac77..2e1f1c7 100644
 --- a/src/chmod.c
 +++ b/src/chmod.c
 @@ -268,7 +268,15 @@ process_file (FTS *fts, FTSENT *ent)

if (! S_ISLNK (old_mode))
  {
 -  if (chmodat (fts-fts_cwd_fd, file, new_mode) == 0)
 +  /* Use any native support for AT_SYMLINK_NOFOLLOW, to avoid
 + following a symlink if there is a race.  */
 +  #if HAVE_FCHMODAT || HAVE_LCHMOD
 +  int follow_flag = AT_SYMLINK_NOFOLLOW;
 +  #else
 +  int follow_flag = 0;
 +  #endif
 +
 +  if (fchmodat (fts-fts_cwd_fd, file, new_mode, follow_flag) == 0)
  chmod_succeeded = true;
else
  {





bug#11111: Problems with mkdir -p usage

2012-03-28 Thread AngusC

Hello

I am using cygwin and have copied the core cygwin files to a folder called
binarytools on my Windows PC.  This folder is first item in path env
variable.

When I run make it has commands to do a mkdir -p foldername

But mkdir -p myfolder creates a folder called -p and also a folder called
myfolder???

Why the strange behaviour?

If I do which mkdir - it displays as below:
D:\which mkdir
/binaryTools/mkdir

So it must be using the Cygwin version?

Angus

-- 
View this message in context: 
http://old.nabble.com/Problems-with-mkdir--p-usage-tp33544820p33544820.html
Sent from the Gnu - Coreutils - Discuss mailing list archive at Nabble.com.






bug#11111: Problems with mkdir -p usage

2012-03-28 Thread Eric Blake
tag 1 notabug
thanks

On 03/28/2012 03:46 AM, AngusC wrote:
 
 Hello
 
 I am using cygwin and have copied the core cygwin files to a folder called
 binarytools on my Windows PC.  This folder is first item in path env
 variable.
 
 When I run make it has commands to do a mkdir -p foldername
 
 But mkdir -p myfolder creates a folder called -p and also a folder called
 myfolder???
 
 Why the strange behaviour?

Probably because you are using cmd.exe as your shell, and thus invoking
the built-in 'mkdir' of that shell (which does not understand -p).

 
 If I do which mkdir - it displays as below:
 D:\which mkdir
 /binaryTools/mkdir

'which' only knows how to interpret your PATH; it doesn't know about the
built-ins of cmd that get used in preference to a PATH search.

To solve your problem, either invoke mkdir by using a full pathname, or
switch to a better shell than cmd (cygwin ships bash for a reason).

As this is not a bug in coreutils, so much as a usage error on your
part, I'm closing out this bug report.  Feel free to add further
comments if you feel the need, and you may also get better support if
you ask on the cygwin list.

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



signature.asc
Description: OpenPGP digital signature


bug#8700: Simple way to switch user/group permissions without requiring PAM sessions

2012-03-28 Thread Pádraig Brady
On 05/19/2011 03:22 PM, Jim Meyering wrote:
 Colin Watson wrote:
 Every so often I wish that there existed (preferably in the Debian base
 system) a tool analogous to chroot that drops privileges from root to a
 nominated user, group, etc. and runs a given program.

 Of course I do know about su, sudo, etc., but:

  * su and sudo are often configured to start a PAM session with noisy
logging etc.;

  * su has a messy historical command-line syntax that requires fiddly
quoting;

  * sudo isn't installed everywhere;

  * these programs all have lots of authentication baggage, which is
thoroughly overkill when I'm writing shell scripts that run as root
and just want to quickly run a program as some other user.

 One example of when I want to use this is in Debian's
 /etc/cron.daily/man-db script.  Towards the end of this, I want to run
 the mandb program as the 'man' user.  I ended up using Debian's
 start-stop-daemon, which happens to be able to run something in the
 foreground as a different user; but mandb is not a daemon,
 start-stop-daemon isn't universal, and so this all feels like a hack.

 In other similar situations I've ended up with a couple of lines of
 Perl, something like:

 perl -e '@pwd = getpwnam(man); $( = $) = $pwd[3]; $ = $ = $pwd[2];
  exec /usr/bin/mandb, @ARGV' -- $@

 Again, though: punctuation-heavy, not trivial to get exactly right,
 delicate quoting, and so on.

 It seems to me that we could use something which can do ID switches away
 from root without all the authentication stuff, and could be simple
 enough to go in coreutils and ultimately end up on all GNUish systems.
 When I complained about the lack of this on a local IRC channel, Ian
 Jackson (CCed) pointed out that his 'really' tool is pretty close to
 this; it does have some very simple authentication code, but that's easy
 to strip out, and the rest is almost identical to what I'd want to see
 in such a tool.  He did say that he'd prefer it not to be called
 'really' if it's not installed setuid; I suggest 'chid' by analogy with
 chroot, chcon, etc.

 The source for 'really' is here (and though while I can't speak for him
 I suspect Ian would be happy to do FSF assignment and such, since he's
 already a GNU maintainer):

   
 http://www.chiark.greenend.org.uk/ucgi/~ian/git?p=chiark-utils.git;a=tree;f=cprogs

 Another piece of prior art is the 'runas' tool in titantools.  However,
 this is under a non-free licence and its command line interface is not
 all that great IMO, so it's probably only useful to know about it to
 avoid using the same (tempting) name.
 
 Hi Colin,
 coreutils already has a minimalist src/setuidgid.c, but currently it's
 not installed.  Rather, it is used only when running the test suite:
 
   $ ./setuidgid --help
   Usage: ./setuidgid [SHORT-OPTION]... USER COMMAND [ARGUMENT]...
 or:  ./setuidgid LONG-OPTION
   Drop any supplemental groups, assume the user-ID and group-ID of the 
 specified
   USER (numeric ID or user name), and run COMMAND with any specified 
 ARGUMENTs.
   Exit with status 111 if unable to assume the required user and group ID.
   Otherwise, exit with the exit status of COMMAND.
   This program is useful only when run by root (user ID zero).
 
 -g GID[,GID1...]  also set the primary group-ID to the numeric GID, and
   (if specified) supplemental group IDs to GID1, ...
 --help display this help and exit
 --version  output version information and exit
 
 Does that do what you'd like?
 If so, do you feel like writing a few words in coreutils.texi
 so this part of it's --help is no longer a lie?
 
 For complete documentation, run: info coreutils 'setuidgid invocation'
 
 Also, if we're going to install it, we'd have to have a few tests,
 just for it, to exercise its functionality.
 
 I like your proposed name of chid.
 
 I took a peek at really and see that it has several more options
 than setuidgid.  If you'd expect to use some of those, we should
 discuss.  For example, is --chroot just a convenience?  It'd be
 useful to explain in the documentation when/how it can be useful.
 
 I'm game if you are willing to write the patch, with documentation and tests.

This is essentially what the runuser command from Fedora does,
and that is based on the coreutils su command.
How about we just incorporate `runuser` into coreutils upstream?

cheers,
Pádraig.





bug#11100: Racy code in copy.c

2012-03-28 Thread Jim Meyering
NeilBrown wrote:
 On Tue, 27 Mar 2012 15:40:25 +0200 Jim Meyering j...@meyering.net wrote:

 Philipp Thomas wrote:
  I'd like to pass on observations from my collegue Neil Brown:
 
  in src/copy.c, copy_reg() is passed bool *new_dst.
 
  This is 'false' if the file already exists, in which case it attempts to
  open the file with O_WRONLY | O_TRUNC | O_BINARY.
  If it is 'true', only then does it use O_CREAT (and others).
 
  Somewhere up the call chain - I'm not sure where - new_dst is set if 'stat'
  on the file succeeds.  The above mentioned code assumes that the file still
  exists.  This is racy - particularly for NFS where deletions from other
  clients can take a while to appear.

 Thanks for the report.
 However, much of what cp does is mandated by the POSIX spec, including
 that inevitable-looking (POSIX-mandated) TOCTOU race.  Here's part of that
 spec, from http://pubs.opengroup.org/onlinepubs/9699919799/utilities/cp.html:
...
 If you can find a way to make cp work sensibly in your specific case,
 yet without impacting any other use case, please let us know.

 The above doesn't specify how you determine if the dest file exists.
 You could do this with stat plus open(O_WRONLY).
 Only try the open on REG files.

It seems that any change here would be working around the non-POSIX
nature of NFS: note that POSIX seems clear[*] that stat must tell us
whether a file exists (barring additional or alternate file access
control mechanisms which aren't an issue here).

I.e., this is an RFE: avoid NFS races due to inherent
POSIX-non-compliance of NFS, rather than a bug.

if ((use_stat
 -   ? stat (dst_name, dst_sb)
 +   ? (stat (dst_name, dst_sb)  0 ? -1 :
 +   (fd = open (dst_name, O_WRONLY))  0 ? -1 : 0)
 : lstat (dst_name, dst_sb))
!= 0)

At first glance, that might be reasonable: the additional open
is incurred only after a failed stat.
I'll look more closely in a week or two if no one else investigates.

One thing that would help a lot is a test case (even using gdb, strace,
stap, inotify, fuse, etc.) that consistently triggers the failure without
the need for an NFS set-up.

 If the stat fails, or the open fails with ENOENT, then the file doesn't
 exist, otherwise assume it does.
 Keep the file descriptor around (if there is one) and then the actions
 equivalent to open() ... would be
if (fd  0)
  fd = open(pathname, O_WRONLY | O_TRUNC);
else
  ftruncate(fd, 0);


 I started making a patch - but it got messy quickly.  Too many conditional
 calls to close().
 And at over 1000 lines, copy_internal was too big for me to work with :-(

[*] excerpt from a possibly dated spec:

The stat() function shall obtain information about the named file and
write it to the area pointed to by the buf argument. The path argument
points to a pathname naming a file. Read, write, or execute permission
of the named file is not required. An implementation that provides
additional or alternate file access control mechanisms may, under
implementation-defined conditions, cause stat() to fail. In particular,
the system may deny the existence of the file specified by path.

If the named file is a symbolic link, the stat() function shall
continue pathname resolution using the contents of the symbolic link,
and shall return information pertaining to the resulting file if the file
exists. The buf argument is a pointer to a stat structure, as defined
in the sys/stat.h header, into which information is placed concerning
the file. The stat() function shall update any time-related fields
(as described in XBD Section 4.8, on page 109), before writing into the
stat structure.

If the named file is a shared memory object, ...

If the named file is a typed memory object, ...





bug#8700: Simple way to switch user/group permissions without requiring PAM sessions

2012-03-28 Thread Ian Jackson
Pádraig Brady writes (Re: bug#8700: Simple way to switch user/group 
permissions without requiring PAM sessions):
 On 05/19/2011 03:22 PM, Jim Meyering wrote:
  Colin Watson wrote:
  Every so often I wish that there existed (preferably in the Debian base
  system) a tool analogous to chroot that drops privileges from root to a
  nominated user, group, etc. and runs a given program.

chiark-really (Source: chiark-utils) has really which can do this,
but of course it's not in Debian base and being set-id for its other
purpose it's probably not suitable.

OTOH the code is trivial and the behaviour is I think exactly as
desired.

Ian.





bug#11115: linux date arithmetic

2012-03-28 Thread Stefan Karamuz

Please check the 2 linux commands:

date -d $(date +%F\ %H:%M:%S) +%F\ %H:%M:%S
date -d $(date +%F\ %H:%M:%S) + 1 minute +%F\ %H:%M:%S

It's very confusing, because the results of the two commands differ in 
one hour and one minute, except of one minute only.


[~]$ date -d $(date +%F\ %H:%M) +%F\ %H:%M:%S
2012-03-28 14:06:00

... and after a few seconds:

[~]$ date -d $(date +%F\ %H:%M:%S) + 1 minute +%F\ %H:%M:%S
2012-03-28 15:07:20

It's a bug or I don't understand something?

The systems tested include:

Fedora 16
Centos 6.2
Debian *6.0.4

*Best Regards,

Stefan Karamuz












bug#11115: linux date arithmetic

2012-03-28 Thread Eric Blake
[adding bug-gnulib]

On 03/28/2012 06:39 AM, Stefan Karamuz wrote:
 Please check the 2 linux commands:
 
 date -d $(date +%F\ %H:%M:%S) +%F\ %H:%M:%S
 date -d $(date +%F\ %H:%M:%S) + 1 minute +%F\ %H:%M:%S
 
 It's very confusing, because the results of the two commands differ in
 one hour and one minute, except of one minute only.
 
 [~]$ date -d $(date +%F\ %H:%M) +%F\ %H:%M:%S
 2012-03-28 14:06:00
 
 ... and after a few seconds:
 
 [~]$ date -d $(date +%F\ %H:%M:%S) + 1 minute +%F\ %H:%M:%S
 2012-03-28 15:07:20

Thanks for the report.  It's easier to debug if you use the same
starting point for both commands rather than nesting an ever-changing
$(date) to feed the outermost 'date -d', but I can indeed reproduce your
behavior, as well as explain it:

$ date -d '2012-03-28 11:38'+%H:%M:%S
11:38:00

Starting point.

$ date -d '2012-03-28 11:38 +1' +%H:%M:%S
04:38:00

Aha - '11:38 +1' is parsed as a time zone designation.  In my case,
since I'm in UTC-6, or 7 time zones away from UTC+1, that explains why
my output jumped backwards by 7 hours; I'm assuming your location is at
UTC+2.

$ date -d '2012-03-28 11:38 +minute'+%H:%M:%S
11:39:00

Notice that 'minute' can be parsed without units.

$ date -d '2012-03-28 11:38 + 1 minute' +%H:%M:%S
04:39:00

Therefore, the parser is faced with an ambiguity between:

(11:38 +1) minute
11:38 (+1 minute)

and happened to choose the result you consider to be less intuitive.
But looks what happen if you rearrange the command line:

$ date -d '+1 minute 2012-03-28 11:38'  +%H:%M:%S
11:39:00

Now there is no ambiguity.

I don't know if this is something adequately explained in our FAQ:
https://www.gnu.org/software/coreutils/faq/#The-date-command-is-not-working-right_002e

nor do I know if it might be possible to patch gnulib's getdate.y to
make the parsing smarter, but you are welcome to try patching it.  In
fact, I'd go so far as to say getdate.y has a bug; '+1' is a reasonable
time zone designator when it occurs after hh:mm, but I've never seen '+
1' meant as a time zone, so it seems like the presence of space after
'+' should be used to alter the parse precedence.

So I'm not sure whether to leave this bug open (in hopes of someone
writing a patch) or to close it (since the behavior is explainable, even
if not what you wanted, and can be worked around with a little
reordering on your part).

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



signature.asc
Description: OpenPGP digital signature


bug#11108: [PATCH] chmod: fix symlink race condition

2012-03-28 Thread Paul Eggert
On 03/28/2012 12:36 AM, Jim Meyering wrote:
 I presume you'll update NEWS, too, where you can say
 [bug introduced in the beginning]

Thanks, good point.  I did that in the version I just committed
to the master.

 I note also that this doesn't protect anyone who is using
 a system that lacks both fchmodat and lchmod.

Right; I put that in the NEWS entry.

There are still problems, in the sense that the attacker
can use a hard link to target any visible file on the same filesystem,
by using hard links; but this problem is unavoidable.

 we'd have to openat each file to get a file descriptor,
 then fstat that FD to verify it's the same dev/ino as
 found by the fts-run stat call, and only then, call fchmod.

This might be useful to close other (more-subtle) races
involving things like hard-link manipulation and chmod +X,
where the new mode depends on the old.  A general problem
with using 'open' for this sort of thing, though,
is that 'open' can have side effects on devices.  I wish
there was a variant of 'open' guaranteed to never
hang and never have side effects; then we could play this
sort of game more reliably.





bug#11115: linux date arithmetic

2012-03-28 Thread Ruediger Meier
On Wednesday 28 March 2012, Eric Blake wrote:
 [adding bug-gnulib]

 On 03/28/2012 06:39 AM, Stefan Karamuz wrote:
  Please check the 2 linux commands:
 
  date -d $(date +%F\ %H:%M:%S) +%F\ %H:%M:%S
  date -d $(date +%F\ %H:%M:%S) + 1 minute +%F\ %H:%M:%S
 
  It's very confusing, because the results of the two commands differ
  in one hour and one minute, except of one minute only.
 
  [~]$ date -d $(date +%F\ %H:%M) +%F\ %H:%M:%S
  2012-03-28 14:06:00
 
  ... and after a few seconds:
 
  [~]$ date -d $(date +%F\ %H:%M:%S) + 1 minute +%F\ %H:%M:%S
  2012-03-28 15:07:20

 Thanks for the report.  It's easier to debug if you use the same
 starting point for both commands rather than nesting an ever-changing
 $(date) to feed the outermost 'date -d', but I can indeed reproduce
 your behavior, as well as explain it:

 $ date -d '2012-03-28 11:38'+%H:%M:%S
 11:38:00

 Starting point.

 $ date -d '2012-03-28 11:38 +1' +%H:%M:%S
 04:38:00

 Aha - '11:38 +1' is parsed as a time zone designation.  In my case,
 since I'm in UTC-6, or 7 time zones away from UTC+1, that explains
 why my output jumped backwards by 7 hours; I'm assuming your location
 is at UTC+2.

 $ date -d '2012-03-28 11:38 +minute'+%H:%M:%S
 11:39:00

 Notice that 'minute' can be parsed without units.

BTW I think that the parser syntax for -d got very unlucky implemented. 
IMO dates and intervals should have been clearly separated somehow. For 
me the parser is too much intelligent and does not what the user would 
expect.

Maybe there should be a separate option --add which takes only intervals 
(negative or positive) to be added to the stamp comming from -r,-d,-f 
or now.

cu,
Rudi

 $ date -d '2012-03-28 11:38 + 1 minute' +%H:%M:%S
 04:39:00

 Therefore, the parser is faced with an ambiguity between:

 (11:38 +1) minute
 11:38 (+1 minute)

 and happened to choose the result you consider to be less intuitive.
 But looks what happen if you rearrange the command line:

 $ date -d '+1 minute 2012-03-28 11:38'  +%H:%M:%S
 11:39:00

 Now there is no ambiguity.

 I don't know if this is something adequately explained in our FAQ:
 https://www.gnu.org/software/coreutils/faq/#The-date-command-is-not-w
orking-right_002e

 nor do I know if it might be possible to patch gnulib's getdate.y to
 make the parsing smarter, but you are welcome to try patching it.  In
 fact, I'd go so far as to say getdate.y has a bug; '+1' is a
 reasonable time zone designator when it occurs after hh:mm, but I've
 never seen '+ 1' meant as a time zone, so it seems like the presence
 of space after '+' should be used to alter the parse precedence.

 So I'm not sure whether to leave this bug open (in hopes of someone
 writing a patch) or to close it (since the behavior is explainable,
 even if not what you wanted, and can be worked around with a little
 reordering on your part).





bug#11117: Suggestion to mark the the arrow for translation

2012-03-28 Thread Göran Uddeborg
When printing a symbolic link in ls, the target of the link is printed
like this:

  if (f-linkname)
{
  DIRED_FPUTS_LITERAL ( - , stdout);
  print_name_with_quoting (f, true, NULL, (p - buf) + w + 4);

I would suggest marking the arrow for translation.

  DIRED_FPUTS_LITERAL (_( - ), stdout);

In translations using Unicode a real arrow, the rightwards arrow
(U+2192), can be used instead of the ascii art arrow traditionally
used.





bug#11100: Racy code in copy.c

2012-03-28 Thread NeilBrown
On Wed, 28 Mar 2012 18:07:51 +0200 Jim Meyering j...@meyering.net wrote:

 NeilBrown wrote:
  On Tue, 27 Mar 2012 15:40:25 +0200 Jim Meyering j...@meyering.net wrote:
 
  Philipp Thomas wrote:
   I'd like to pass on observations from my collegue Neil Brown:
  
   in src/copy.c, copy_reg() is passed bool *new_dst.
  
   This is 'false' if the file already exists, in which case it attempts to
   open the file with O_WRONLY | O_TRUNC | O_BINARY.
   If it is 'true', only then does it use O_CREAT (and others).
  
   Somewhere up the call chain - I'm not sure where - new_dst is set if 
   'stat'
   on the file succeeds.  The above mentioned code assumes that the file 
   still
   exists.  This is racy - particularly for NFS where deletions from other
   clients can take a while to appear.
 
  Thanks for the report.
  However, much of what cp does is mandated by the POSIX spec, including
  that inevitable-looking (POSIX-mandated) TOCTOU race.  Here's part of that
  spec, from 
  http://pubs.opengroup.org/onlinepubs/9699919799/utilities/cp.html:
 ...
  If you can find a way to make cp work sensibly in your specific case,
  yet without impacting any other use case, please let us know.
 
  The above doesn't specify how you determine if the dest file exists.
  You could do this with stat plus open(O_WRONLY).
  Only try the open on REG files.
 
 It seems that any change here would be working around the non-POSIX
 nature of NFS: note that POSIX seems clear[*] that stat must tell us
 whether a file exists (barring additional or alternate file access
 control mechanisms which aren't an issue here).

stat() cannot tell whether a file exists - only whether it existed very
recently.  open() can ensure that the file still exists - though there is no
guarantee that the name still exists...

 
 I.e., this is an RFE: avoid NFS races due to inherent
 POSIX-non-compliance of NFS, rather than a bug.

Maybe .

Suppose a 'cp' and an 'rm' are racing.  i.e you cp to 'foo' at much the same
time that someone else does 'rm foo'.
What results are valid?
Certain it is valid for both to succeed and 'foo' not to exist if 'rm foo'
happened last.
Similarly it is valid for both to succeed and foo to be a newly created file
if 'cp' happened last.
But is it valid for 'rm' to succeed and 'cp' to report that it couldn't
create the target because no such file or directory ?

I would suggest not, though I doubt the spec is at all clear on this.
However that is what the current code allows.

NFS doesn't exactly introduce new behaviour, it just makes a particular race
condition much easier to hit.

So I'll not press that it is a bug in cp, but I would suggest that it is an
opportunity to improve behaviour in a corner-case.


 
 if ((use_stat
  -   ? stat (dst_name, dst_sb)
  +   ? (stat (dst_name, dst_sb)  0 ? -1 :
  + (fd = open (dst_name, O_WRONLY))  0 ? -1 : 0)
  : lstat (dst_name, dst_sb))
 != 0)
 
 At first glance, that might be reasonable: the additional open
 is incurred only after a failed stat.

This isn't what the proposed code does.  The open is incurred after a
*successful* stat (though it should only be tried if stat reported S_IFREG).
And it is not intended as an 'additional' open.  Rather the open that we
would expect anyway is being performed earlier to avoid a race condition.

 I'll look more closely in a week or two if no one else investigates.
 
 One thing that would help a lot is a test case (even using gdb, strace,
 stap, inotify, fuse, etc.) that consistently triggers the failure without
 the need for an NFS set-up.

gdb cp
run cp foo # this succeeds ofcourse - 'foo' is a copy of 'cp'
break copy.c:1679  # this is 'have_dst_lstat = !use_stat;'
shell rm foo
c

Result:

/home/git/coreutils/src/cp: cannot create regular file 'foo': No such file or 
directory

With NFS, the 'rm' happens on a different machine and due to the caching
protocol of NFS the unlink is not visible to the 'stat', but it is to the
subsequent 'open' - it is as though it happened between those two calls.

NeilBrown



signature.asc
Description: PGP signature


bug#11108: [PATCH] chmod: fix symlink race condition

2012-03-28 Thread Jim Meyering
Paul Eggert wrote:
 On 03/28/2012 12:36 AM, Jim Meyering wrote:
 I presume you'll update NEWS, too, where you can say
 [bug introduced in the beginning]

 Thanks, good point.  I did that in the version I just committed
 to the master.

 I note also that this doesn't protect anyone who is using
 a system that lacks both fchmodat and lchmod.

 Right; I put that in the NEWS entry.

 There are still problems, in the sense that the attacker
 can use a hard link to target any visible file on the same filesystem,
 by using hard links; but this problem is unavoidable.

 we'd have to openat each file to get a file descriptor,
 then fstat that FD to verify it's the same dev/ino as
 found by the fts-run stat call, and only then, call fchmod.

 This might be useful to close other (more-subtle) races
 involving things like hard-link manipulation and chmod +X,
 where the new mode depends on the old.  A general problem
 with using 'open' for this sort of thing, though,
 is that 'open' can have side effects on devices.  I wish
 there was a variant of 'open' guaranteed to never
 hang and never have side effects; then we could play this
 sort of game more reliably.

Oops.  I should not have suggested using open, since it cannot
work in general: it would fail for any file that is neither
readable nor writable.





bug#11108: [PATCH] chmod: fix symlink race condition

2012-03-28 Thread Jim Meyering
Paul Eggert wrote:
 On 03/28/2012 12:36 AM, Jim Meyering wrote:
 I presume you'll update NEWS, too, where you can say
 [bug introduced in the beginning]

 Thanks, good point.  I did that in the version I just committed
 to the master.

Rats:

$ ./chmod u+w f
./chmod: changing permissions of 'f': Operation not supported

That fix introduces chmod failures on several important systems,
including my Fedora 17 desktop ;-)

I confess that I had not tested it, and had missed or forgotten
this part of the GNU/Linux/fchmodat documentation:

   AT_SYMLINK_NOFOLLOW
  If pathname is a symbolic link, do not dereference  it:  instead
  operate  on  the link itself.  This flag is not currently imple-
  mented.

The nixos/hydra build server is reporting failures, too:

  http://hydra.nixos.org/build/2341393
  http://hydra.nixos.org/build/2341397
  http://hydra.nixos.org/build/2341395





bug#11100: Racy code in copy.c

2012-03-28 Thread Paul Eggert
On 03/28/2012 09:07 AM, Jim Meyering wrote:
if ((use_stat
  -   ? stat (dst_name, dst_sb)
  +   ? (stat (dst_name, dst_sb)  0 ? -1 :
  +(fd = open (dst_name, O_WRONLY))  0 ? -1 : 0)
  : lstat (dst_name, dst_sb))
 != 0)
 At first glance, that might be reasonable: the additional open
 is incurred only after a failed stat.
 I'll look more closely in a week or two if no one else investigates.

Come to think of it, wouldn't it be more efficient to
do an open (dst_name, O_WRONLY | O_BINARY), and then
fstat the resulting fd, falling back on 'stat' only if the
open fails with errno == EACCES?   That should be
more efficient in the usual case, since it'd resolve
the file name fewer times in the usual case.





bug#11115: linux date arithmetic

2012-03-28 Thread Eric Blake
On 03/28/2012 03:23 PM, Bruno Haible wrote:
 Eric Blake wrote:
 the parser is faced with an ambiguity between:

 (11:38 +1) minute
 11:38 (+1 minute)
 
 What is the first interpretation meant to mean?

The time 11:38 in the timezone UTC+1, plus the unit represented by 'minute'.

 10:38 minute or 12:38 minute is not a time designation I have ever heard
 in spoken nor written English.

True, 'minute' in isolation, without a 'plus one' qualifier, is unusual;
but we have to continue to parse it in isolation since scripts may now
be relying on it.

 
 If you ditch this interpretation, there is no ambiguity.

Yes, we're in violent agreement here: the added context of a +1 (and in
particular, of a '+ 1' with a space after the +), should indeed favor
the spoken preference of a time with no timezone, followed by a
completed relative designation; rather than of a relative designation
with only an implied quantity.  It's just that getdate.y is a hairy mess
to properly implement that change without breaking other worthwhile
constructs, so I won't be the one volunteering.

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



signature.asc
Description: OpenPGP digital signature


bug#11115: linux date arithmetic

2012-03-28 Thread Bruno Haible
Eric Blake wrote:
 the parser is faced with an ambiguity between:
 
 (11:38 +1) minute
 11:38 (+1 minute)

What is the first interpretation meant to mean?
10:38 minute or 12:38 minute is not a time designation I have ever heard
in spoken nor written English.

If you ditch this interpretation, there is no ambiguity.

Bruno






bug#11115: linux date arithmetic

2012-03-28 Thread Ruediger Meier
On Wednesday 28 March 2012, Eric Blake wrote:
 On 03/28/2012 03:23 PM, Bruno Haible wrote:
  Eric Blake wrote:
  the parser is faced with an ambiguity between:
 
  (11:38 +1) minute
  11:38 (+1 minute)
 
  What is the first interpretation meant to mean?

 The time 11:38 in the timezone UTC+1, plus the unit represented by
 'minute'.

  10:38 minute or 12:38 minute is not a time designation I have
  ever heard in spoken nor written English.

 True, 'minute' in isolation, without a 'plus one' qualifier, is
 unusual; but we have to continue to parse it in isolation since
 scripts may now be relying on it.

  If you ditch this interpretation, there is no ambiguity.

 Yes, we're in violent agreement here: the added context of a +1 (and
 in particular, of a '+ 1' with a space after the +), should indeed
 favor the spoken preference of a time with no timezone, followed by a
 completed relative designation; rather than of a relative designation
 with only an implied quantity.  It's just that getdate.y is a hairy
 mess to properly implement that change without breaking other
 worthwhile constructs, so I won't be the one volunteering.

BTW there is an interesting dateutils project not yet finished but worth 
to have look
https://github.com/hroptatyr/dateutils

cu,
Rudi





bug#11108: [PATCH] chmod: fix symlink race condition

2012-03-28 Thread Paul Eggert
On 03/28/2012 01:13 PM, Jim Meyering wrote:
 $ ./chmod u+w f
 ./chmod: changing permissions of 'f': Operation not supported

Yeouch.  I undid the change for now.
Hmm, why did make check work for me?
I'll have to investigate later, alas.