GNU bug report logs - #11100
Racy code in copy.c

Previous Next

Package: coreutils;

Reported by: Philipp Thomas <pth <at> suse.de>

Date: Tue, 27 Mar 2012 13:32:02 UTC

Severity: normal

Merged with 11074

Done: Jim Meyering <jim <at> meyering.net>

Bug is archived. No further changes may be made.

To add a comment to this bug, you must first unarchive it, by sending
a message to control AT debbugs.gnu.org, with unarchive 11100 in the body.
You can then email your comments to 11100 AT debbugs.gnu.org in the normal way.

Toggle the display of automated, internal messages from the tracker.

View this report as an mbox folder, status mbox, maintainer mbox


Report forwarded to bug-coreutils <at> gnu.org:
bug#11100; Package coreutils. (Tue, 27 Mar 2012 13:32:02 GMT) Full text and rfc822 format available.

Acknowledgement sent to Philipp Thomas <pth <at> suse.de>:
New bug report received and forwarded. Copy sent to bug-coreutils <at> gnu.org. (Tue, 27 Mar 2012 13:32:03 GMT) Full text and rfc822 format available.

Message #5 received at submit <at> debbugs.gnu.org (full text, mbox):

From: Philipp Thomas <pth <at> suse.de>
To: bug-coreutils <at> gnu.org
Cc: Neil F Brown <nfbrown <at> suse.com>
Subject: Racy code in copy.c
Date: Tue, 27 Mar 2012 14:58:18 +0200
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.

Philipp




Information forwarded to bug-coreutils <at> gnu.org:
bug#11100; Package coreutils. (Tue, 27 Mar 2012 14:13:01 GMT) Full text and rfc822 format available.

Message #8 received at 11100 <at> debbugs.gnu.org (full text, mbox):

From: Jim Meyering <jim <at> meyering.net>
To: Philipp Thomas <pth <at> suse.de>
Cc: 11100 <at> debbugs.gnu.org, Neil F Brown <nfbrown <at> suse.com>
Subject: Re: bug#11100: Racy code in copy.c
Date: Tue, 27 Mar 2012 15:40:25 +0200
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:

    For each source_file, the following steps shall be taken:

        ...
        If source_file is of type directory, the following steps shall be taken:

            ...

        If source_file is of type regular file, the following steps
        shall be taken:

            The behavior is unspecified if dest_file exists and was
            written by a previous step. Otherwise, if dest_file exists,
            the following steps shall be taken:

                If the -i option is in effect, the cp utility shall
                write a prompt to the standard error and read a line from
                the standard input. If the response is not affirmative,
                cp shall do nothing more with source_file and go on to
                any remaining files.

                A file descriptor for dest_file shall be obtained by
                performing actions equivalent to the open() function
                defined in the System Interfaces volume of POSIX.1-2008
                called using dest_file as the path argument, and the
                bitwise-inclusive OR of O_WRONLY and O_TRUNC as the
                oflag argument.

                If the attempt to obtain a file descriptor fails and the
                -f option is in effect, cp shall attempt to remove the
                file by performing actions equivalent to the unlink()
                function defined in the System Interfaces volume
                of POSIX.1-2008 called using dest_file as the path
                argument. If this attempt succeeds, cp shall continue
                with step 3b.

            If dest_file does not exist, a file descriptor shall be
            obtained by performing actions equivalent to the open()
            function defined in the System Interfaces volume of
            POSIX.1-2008 called using dest_file as the path argument,
            and the bitwise-inclusive OR of O_WRONLY and O_CREAT as
            the oflag argument. The file permission bits of source_file
            shall be the mode argument.

            If the attempt to obtain a file descriptor fails, cp shall
            write a diagnostic message to standard error, do nothing
            more with source_file, and go on to any remaining files.

            The contents of source_file shall be written to the file
            descriptor. Any write errors shall cause cp to write a
            diagnostic message to standard error and continue to step 3e.

            The file descriptor shall be closed.

            The cp utility shall do nothing more with source_file. If
            a write error occurred in step 3d, it is unspecified if
            cp continues with any remaining files. If no write error
            occurred in step 3d, cp shall go on to any remaining files.

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.




Information forwarded to bug-coreutils <at> gnu.org:
bug#11100; Package coreutils. (Tue, 27 Mar 2012 14:35:01 GMT) Full text and rfc822 format available.

Message #11 received at 11100 <at> debbugs.gnu.org (full text, mbox):

From: Philipp Thomas <pth <at> suse.de>
To: Jim Meyering <jim <at> meyering.net>
Cc: 11100 <at> debbugs.gnu.org, Neil F Brown <nfbrown <at> suse.com>
Subject: Re: bug#11100: Racy code in copy.c
Date: Tue, 27 Mar 2012 16:03:05 +0200
Hi Jim,

* Jim Meyering (jim <at> meyering.net) [20120327 15:40]:

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

Thanks for the clarification! In that light though I doubt there is a way :(

Philipp




Information forwarded to bug-coreutils <at> gnu.org:
bug#11100; Package coreutils. (Tue, 27 Mar 2012 14:42:01 GMT) Full text and rfc822 format available.

Message #14 received at 11100 <at> debbugs.gnu.org (full text, mbox):

From: Pádraig Brady <P <at> draigBrady.com>
To: Philipp Thomas <pth <at> suse.de>
Cc: 11100 <at> debbugs.gnu.org, Neil F Brown <nfbrown <at> suse.com>
Subject: Re: bug#11100: Racy code in copy.c
Date: Tue, 27 Mar 2012 15:09:37 +0100
On 03/27/2012 01:58 PM, 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.

True. That would result in:
  "cannot create regular file ...": ENOENT
or if -f was specified a more confusing:
  "cannot remove ...": ENOENT
You could patch to avoid that edge case,
but handling dangling symlinks would complicate things.
It's borderline whether this is warranted.

Note the opposite case where a file is
created between the stat() and the creat()
would result in:
  "cannot create regular file ...": EEXIST
even if -f was specified.
Note on NFS < 3 O_EXCL is not supported
so this condition won't be flagged at all.
Note also handling of this case would
need to honor the --no-clobber option(s).
Again awkward for an unusual edge case.

I suppose some comments would be appropriate at least.

cheers,
Pádraig.




Information forwarded to bug-coreutils <at> gnu.org:
bug#11100; Package coreutils. (Tue, 27 Mar 2012 16:35:01 GMT) Full text and rfc822 format available.

Message #17 received at 11100 <at> debbugs.gnu.org (full text, mbox):

From: Paul Eggert <eggert <at> cs.ucla.edu>
To: Philipp Thomas <pth <at> suse.de>
Cc: 11100 <at> debbugs.gnu.org, Neil F Brown <nfbrown <at> suse.com>
Subject: Re: bug#11100: Racy code in copy.c
Date: Tue, 27 Mar 2012 09:03:30 -0700
On 03/27/2012 05:58 AM, Philipp Thomas wrote:
> 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.

*NEW_DST is a bit more complicated than that.  At least for part
of the code it means the file was known not to exist, which is not
the same thing as being true if the file does not exist and false
otherwise.  (Sometimes I think I need to take a course on epistemology
to understand this code, which is not a good sign....)

In general 'cp' is not and cannot be free from races due to other
active processes.  A fix could well be needed here, to work around NFS
bugs, but it'd need to be thought through in the light of other
use cases.




Information forwarded to bug-coreutils <at> gnu.org:
bug#11100; Package coreutils. (Tue, 27 Mar 2012 21:56:02 GMT) Full text and rfc822 format available.

Message #20 received at 11100 <at> debbugs.gnu.org (full text, mbox):

From: NeilBrown <neilb <at> suse.de>
To: Jim Meyering <jim <at> meyering.net>
Cc: Philipp Thomas <pth <at> suse.de>, 11100 <at> debbugs.gnu.org
Subject: Re: bug#11100: Racy code in copy.c
Date: Wed, 28 Mar 2012 08:19:05 +1100
[Message part 1 (text/plain, inline)]
On Tue, 27 Mar 2012 15:40:25 +0200 Jim Meyering <jim <at> 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:
> 
>     For each source_file, the following steps shall be taken:
> 
>         ...
>         If source_file is of type directory, the following steps shall be taken:
> 
>             ...
> 
>         If source_file is of type regular file, the following steps
>         shall be taken:
> 
>             The behavior is unspecified if dest_file exists and was
>             written by a previous step. Otherwise, if dest_file exists,
>             the following steps shall be taken:
> 
>                 If the -i option is in effect, the cp utility shall
>                 write a prompt to the standard error and read a line from
>                 the standard input. If the response is not affirmative,
>                 cp shall do nothing more with source_file and go on to
>                 any remaining files.
> 
>                 A file descriptor for dest_file shall be obtained by
>                 performing actions equivalent to the open() function
>                 defined in the System Interfaces volume of POSIX.1-2008
>                 called using dest_file as the path argument, and the
>                 bitwise-inclusive OR of O_WRONLY and O_TRUNC as the
>                 oflag argument.
> 
>                 If the attempt to obtain a file descriptor fails and the
>                 -f option is in effect, cp shall attempt to remove the
>                 file by performing actions equivalent to the unlink()
>                 function defined in the System Interfaces volume
>                 of POSIX.1-2008 called using dest_file as the path
>                 argument. If this attempt succeeds, cp shall continue
>                 with step 3b.
> 
>             If dest_file does not exist, a file descriptor shall be
>             obtained by performing actions equivalent to the open()
>             function defined in the System Interfaces volume of
>             POSIX.1-2008 called using dest_file as the path argument,
>             and the bitwise-inclusive OR of O_WRONLY and O_CREAT as
>             the oflag argument. The file permission bits of source_file
>             shall be the mode argument.
> 
>             If the attempt to obtain a file descriptor fails, cp shall
>             write a diagnostic message to standard error, do nothing
>             more with source_file, and go on to any remaining files.
> 
>             The contents of source_file shall be written to the file
>             descriptor. Any write errors shall cause cp to write a
>             diagnostic message to standard error and continue to step 3e.
> 
>             The file descriptor shall be closed.
> 
>             The cp utility shall do nothing more with source_file. If
>             a write error occurred in step 3d, it is unspecified if
>             cp continues with any remaining files. If no write error
>             occurred in step 3d, cp shall go on to any remaining files.
> 
> 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.

       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)


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

NeilBrown
[signature.asc (application/pgp-signature, attachment)]

Information forwarded to bug-coreutils <at> gnu.org:
bug#11100; Package coreutils. (Wed, 28 Mar 2012 16:40:02 GMT) Full text and rfc822 format available.

Message #23 received at 11100 <at> debbugs.gnu.org (full text, mbox):

From: Jim Meyering <jim <at> meyering.net>
To: NeilBrown <neilb <at> suse.de>
Cc: Philipp Thomas <pth <at> suse.de>, 11100 <at> debbugs.gnu.org
Subject: Re: bug#11100: Racy code in copy.c
Date: Wed, 28 Mar 2012 18:07:51 +0200
NeilBrown wrote:
> On Tue, 27 Mar 2012 15:40:25 +0200 Jim Meyering <jim <at> 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, ...




Information forwarded to bug-coreutils <at> gnu.org:
bug#11100; Package coreutils. (Wed, 28 Mar 2012 18:59:02 GMT) Full text and rfc822 format available.

Message #26 received at 11100 <at> debbugs.gnu.org (full text, mbox):

From: Paul Eggert <eggert <at> cs.ucla.edu>
To: Jim Meyering <jim <at> meyering.net>
Cc: NeilBrown <neilb <at> suse.de>, Philipp Thomas <pth <at> suse.de>,
	11100 <at> debbugs.gnu.org
Subject: Re: bug#11100: Racy code in copy.c
Date: Wed, 28 Mar 2012 11:26:32 -0700
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.




Information forwarded to bug-coreutils <at> gnu.org:
bug#11100; Package coreutils. (Wed, 28 Mar 2012 23:36:01 GMT) Full text and rfc822 format available.

Message #29 received at 11100 <at> debbugs.gnu.org (full text, mbox):

From: NeilBrown <neilb <at> suse.de>
To: Jim Meyering <jim <at> meyering.net>
Cc: Philipp Thomas <pth <at> suse.de>, 11100 <at> debbugs.gnu.org
Subject: Re: bug#11100: Racy code in copy.c
Date: Thu, 29 Mar 2012 10:03:27 +1100
[Message part 1 (text/plain, inline)]
On Wed, 28 Mar 2012 18:07:51 +0200 Jim Meyering <jim <at> meyering.net> wrote:

> NeilBrown wrote:
> > On Tue, 27 Mar 2012 15:40:25 +0200 Jim Meyering <jim <at> 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 (application/pgp-signature, attachment)]

Information forwarded to bug-coreutils <at> gnu.org:
bug#11100; Package coreutils. (Fri, 04 May 2012 13:23:02 GMT) Full text and rfc822 format available.

Message #32 received at 11100 <at> debbugs.gnu.org (full text, mbox):

From: Philipp Thomas <pth <at> suse.de>
To: 11100 <at> debbugs.gnu.org
Subject: Re: bug#11100: Racy code in copy.c
Date: Fri, 4 May 2012 15:20:59 +0200
* Jim Meyering (jim <at> meyering.net) [20120328 18:09]:

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

Ping, it's been more than two weeks and I'm being bugged for a possible
solution and will refrain from making changes that aren't accepted upstream.

Philipp




Information forwarded to bug-coreutils <at> gnu.org:
bug#11100; Package coreutils. (Fri, 04 May 2012 14:50:02 GMT) Full text and rfc822 format available.

Message #35 received at 11100 <at> debbugs.gnu.org (full text, mbox):

From: Jim Meyering <jim <at> meyering.net>
To: Philipp Thomas <pth <at> suse.de>
Cc: 11100 <at> debbugs.gnu.org
Subject: Re: bug#11100: Racy code in copy.c
Date: Fri, 04 May 2012 16:47:51 +0200
Philipp Thomas wrote:
> * Jim Meyering (jim <at> meyering.net) [20120328 18:09]:
>
>> 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.
>
> Ping, it's been more than two weeks and I'm being bugged for a possible
> solution and will refrain from making changes that aren't accepted upstream.

Thanks for the reminder.
I did investigate it back then, but didn't make any progress.
Today I looked again and saw the light ;-)

Here's a partial patch.
Still to come: a NEWS addition and a test case.

From b85446f612846ec9c99fe3e13dd78e861428ddde Mon Sep 17 00:00:00 2001
From: Jim Meyering <meyering <at> redhat.com>
Date: Fri, 4 May 2012 16:42:31 +0200
Subject: [PATCH] cp: handle a race condition more sensibly

* src/copy.c (copy_reg): In a narrow race (stat sees dest, yet
open-without-O_CREAT fails with ENOENT), retry the open with O_CREAT.
Reported by Philipp Thomas and Neil F. Brown in
http://debbugs.gnu.org/11100
---
 src/copy.c | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)

diff --git a/src/copy.c b/src/copy.c
index 844ebcd..2558fea 100644
--- a/src/copy.c
+++ b/src/copy.c
@@ -892,6 +892,8 @@ copy_reg (char const *src_name, char const *dst_name,

   if (*new_dst)
     {
+    open_with_O_CREAT:;
+
       int open_flags = O_WRONLY | O_CREAT | O_BINARY;
       dest_desc = open (dst_name, open_flags | O_EXCL,
                         dst_mode & ~omitted_permissions);
@@ -942,6 +944,23 @@ copy_reg (char const *src_name, char const *dst_name,

   if (dest_desc < 0)
     {
+      /* If we've just failed due to ENOENT for an ostensibly preexisting
+         destination (*new_dst was 0), that's a bit of a contradiction/race:
+         the prior stat/lstat said the file existed (*new_dst was 0), yet
+         the subsequent open-existing-file failed with ENOENT.  With NFS,
+         the race window is wider still, since its meta-data caching tends
+         to make the stat succeed for a just-removed remote file, while the
+         more-definitive initial open call will fail with ENOENT.  When this
+         situation arises, we attempt to open again, but this time with
+         O_CREAT.  Do this only when not in move-mode, since when handling
+         a cross-device move, we must never open an existing destination.  */
+      if (dest_errno == ENOENT && ! *new_dst && ! x->move_mode)
+        {
+          *new_dst = 1;
+          goto open_with_O_CREAT;
+        }
+
+      /* Otherwise, it's an error.  */
       error (0, dest_errno, _("cannot create regular file %s"),
              quote (dst_name));
       return_val = false;
--
1.7.10.1.456.g16798d0




Information forwarded to bug-coreutils <at> gnu.org:
bug#11100; Package coreutils. (Fri, 04 May 2012 14:56:02 GMT) Full text and rfc822 format available.

Message #38 received at 11100 <at> debbugs.gnu.org (full text, mbox):

From: Eric Blake <eblake <at> redhat.com>
To: Jim Meyering <jim <at> meyering.net>
Cc: Philipp Thomas <pth <at> suse.de>, 11100 <at> debbugs.gnu.org
Subject: Re: bug#11100: Racy code in copy.c
Date: Fri, 04 May 2012 08:54:05 -0600
[Message part 1 (text/plain, inline)]
On 05/04/2012 08:47 AM, Jim Meyering wrote:
> 
> * src/copy.c (copy_reg): In a narrow race (stat sees dest, yet
> open-without-O_CREAT fails with ENOENT), retry the open with O_CREAT.
> Reported by Philipp Thomas and Neil F. Brown in
> http://debbugs.gnu.org/11100

Question - when we retry with adding O_CREAT, should we also add O_EXCL?
 That is, we already lost the race once, but the O_EXCL will ensure that
we don't lose the race a second time and that we really are creating a file.

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

[signature.asc (application/pgp-signature, attachment)]

Information forwarded to bug-coreutils <at> gnu.org:
bug#11100; Package coreutils. (Fri, 04 May 2012 15:01:02 GMT) Full text and rfc822 format available.

Message #41 received at 11100 <at> debbugs.gnu.org (full text, mbox):

From: Jim Meyering <jim <at> meyering.net>
To: Eric Blake <eblake <at> redhat.com>
Cc: Philipp Thomas <pth <at> suse.de>, 11100 <at> debbugs.gnu.org
Subject: Re: bug#11100: Racy code in copy.c
Date: Fri, 04 May 2012 16:58:53 +0200
Eric Blake wrote:

> On 05/04/2012 08:47 AM, Jim Meyering wrote:
>>
>> * src/copy.c (copy_reg): In a narrow race (stat sees dest, yet
>> open-without-O_CREAT fails with ENOENT), retry the open with O_CREAT.
>> Reported by Philipp Thomas and Neil F. Brown in
>> http://debbugs.gnu.org/11100
>
> Question - when we retry with adding O_CREAT, should we also add O_EXCL?
>  That is, we already lost the race once, but the O_EXCL will ensure that
> we don't lose the race a second time and that we really are creating a file.

I was concerned about that, too, but noted
it's already always done in the O_CREAT/*new_dst path:

  if (*new_dst)
    {
    open_with_O_CREAT:;

      int open_flags = O_WRONLY | O_CREAT | O_BINARY;
      dest_desc = open (dst_name, open_flags | O_EXCL,
                        dst_mode & ~omitted_permissions);




Information forwarded to bug-coreutils <at> gnu.org:
bug#11100; Package coreutils. (Fri, 04 May 2012 15:02:02 GMT) Full text and rfc822 format available.

Message #44 received at 11100 <at> debbugs.gnu.org (full text, mbox):

From: Jim Meyering <jim <at> meyering.net>
To: Eric Blake <eblake <at> redhat.com>
Cc: Philipp Thomas <pth <at> suse.de>, 11100 <at> debbugs.gnu.org
Subject: Re: bug#11100: Racy code in copy.c
Date: Fri, 04 May 2012 16:59:51 +0200
Eric Blake wrote:
> On 05/04/2012 08:47 AM, Jim Meyering wrote:
>>
>> * src/copy.c (copy_reg): In a narrow race (stat sees dest, yet
>> open-without-O_CREAT fails with ENOENT), retry the open with O_CREAT.
>> Reported by Philipp Thomas and Neil F. Brown in
>> http://debbugs.gnu.org/11100
>
> Question - when we retry with adding O_CREAT, should we also add O_EXCL?
>  That is, we already lost the race once, but the O_EXCL will ensure that
> we don't lose the race a second time and that we really are creating a file.

And thanks for looking.




Information forwarded to bug-coreutils <at> gnu.org:
bug#11100; Package coreutils. (Fri, 04 May 2012 15:32:01 GMT) Full text and rfc822 format available.

Message #47 received at 11100 <at> debbugs.gnu.org (full text, mbox):

From: Philipp Thomas <pth <at> suse.de>
To: Jim Meyering <jim <at> meyering.net>
Cc: 11100 <at> debbugs.gnu.org
Subject: Re: bug#11100: Racy code in copy.c
Date: Fri, 4 May 2012 17:29:10 +0200
* Jim Meyering (jim <at> meyering.net) [20120504 16:47]:

> Here's a partial patch.

Marvellous! That's exactly the thing I needed to finish my working week!
Thanks a bunch for your work.

have a nice weekend
Philipp




Information forwarded to bug-coreutils <at> gnu.org:
bug#11100; Package coreutils. (Fri, 04 May 2012 15:33:01 GMT) Full text and rfc822 format available.

Message #50 received at 11100 <at> debbugs.gnu.org (full text, mbox):

From: Jim Meyering <jim <at> meyering.net>
To: Philipp Thomas <pth <at> suse.de>
Cc: 11100 <at> debbugs.gnu.org
Subject: Re: bug#11100: Racy code in copy.c
Date: Fri, 04 May 2012 17:30:49 +0200
Philipp Thomas wrote:
> * Jim Meyering (jim <at> meyering.net) [20120504 16:47]:
>
>> Here's a partial patch.
>
> Marvellous! That's exactly the thing I needed to finish my working week!
> Thanks a bunch for your work.
>
> have a nice weekend

Thanks.  You too.
If there's a bugzilla reference for this, let me know
and I'll add it to the commit log.




Information forwarded to bug-coreutils <at> gnu.org:
bug#11100; Package coreutils. (Sun, 06 May 2012 09:42:02 GMT) Full text and rfc822 format available.

Message #53 received at 11100 <at> debbugs.gnu.org (full text, mbox):

From: Jim Meyering <jim <at> meyering.net>
To: Philipp Thomas <pth <at> suse.de>
Cc: 11100 <at> debbugs.gnu.org
Subject: Re: bug#11100: Racy code in copy.c
Date: Sun, 06 May 2012 11:39:01 +0200
Jim Meyering wrote:
> Philipp Thomas wrote:
>> * Jim Meyering (jim <at> meyering.net) [20120328 18:09]:
>>
>>> 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.
>>
>> Ping, it's been more than two weeks and I'm being bugged for a possible
>> solution and will refrain from making changes that aren't accepted upstream.
>
> Thanks for the reminder.
> I did investigate it back then, but didn't make any progress.
> Today I looked again and saw the light ;-)
>
> Here's a partial patch.
> Still to come: a NEWS addition and a test case.

Here's that same patch, along with a glibc-specific LD_PRELOAD-based
test and a NEWS entry.

From d8a631cb1a08ee73bde061d36b068585358ff6fe Mon Sep 17 00:00:00 2001
From: Jim Meyering <meyering <at> redhat.com>
Date: Fri, 4 May 2012 16:42:31 +0200
Subject: [PATCH 1/2] cp: handle a race condition more sensibly

* src/copy.c (copy_reg): In a narrow race (stat sees dest, yet
open-without-O_CREAT fails with ENOENT), retry the open with O_CREAT.
Reported by Philipp Thomas and Neil F. Brown in
http://bugs.gnu.org/11100
---
 THANKS.in  |  1 +
 src/copy.c | 19 +++++++++++++++++++
 2 files changed, 20 insertions(+)

diff --git a/THANKS.in b/THANKS.in
index a7403fd..d8f7a4b 100644
--- a/THANKS.in
+++ b/THANKS.in
@@ -489,6 +489,7 @@ Phil Richards                       phil.richards <at> vf.vodafone.co.uk
 Philippe De Muyter                  phdm <at> macqel.be
 Philippe Schnoebelen                Philippe.Schnoebelen <at> imag.fr
 Phillip Jones                       mouse <at> datastacks.com
+Philipp Thomas                      pth <at> suse.de
 Piergiorgio Sartor                  sartor <at> sony.de
 Pieter Bowman                       bowman <at> math.utah.edu
 Piotr Gackiewicz                    gacek <at> intertele.pl
diff --git a/src/copy.c b/src/copy.c
index 844ebcd..2558fea 100644
--- a/src/copy.c
+++ b/src/copy.c
@@ -892,6 +892,8 @@ copy_reg (char const *src_name, char const *dst_name,

   if (*new_dst)
     {
+    open_with_O_CREAT:;
+
       int open_flags = O_WRONLY | O_CREAT | O_BINARY;
       dest_desc = open (dst_name, open_flags | O_EXCL,
                         dst_mode & ~omitted_permissions);
@@ -942,6 +944,23 @@ copy_reg (char const *src_name, char const *dst_name,

   if (dest_desc < 0)
     {
+      /* If we've just failed due to ENOENT for an ostensibly preexisting
+         destination (*new_dst was 0), that's a bit of a contradiction/race:
+         the prior stat/lstat said the file existed (*new_dst was 0), yet
+         the subsequent open-existing-file failed with ENOENT.  With NFS,
+         the race window is wider still, since its meta-data caching tends
+         to make the stat succeed for a just-removed remote file, while the
+         more-definitive initial open call will fail with ENOENT.  When this
+         situation arises, we attempt to open again, but this time with
+         O_CREAT.  Do this only when not in move-mode, since when handling
+         a cross-device move, we must never open an existing destination.  */
+      if (dest_errno == ENOENT && ! *new_dst && ! x->move_mode)
+        {
+          *new_dst = 1;
+          goto open_with_O_CREAT;
+        }
+
+      /* Otherwise, it's an error.  */
       error (0, dest_errno, _("cannot create regular file %s"),
              quote (dst_name));
       return_val = false;
--
1.7.10.1.457.g8275905


From 59bee5a6bfac96bba6684e740fdf35063b4461a8 Mon Sep 17 00:00:00 2001
From: Jim Meyering <meyering <at> redhat.com>
Date: Sat, 5 May 2012 21:58:13 +0200
Subject: [PATCH 2/2] tests: test for just-fixed cp change

* tests/cp/nfs-removal-race: New file.
* tests/Makefile.am (TESTS): Add it.
* NEWS (Bug fixes): Mention it.
---
 NEWS                      |  6 ++++
 tests/Makefile.am         |  1 +
 tests/cp/nfs-removal-race | 70 +++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 77 insertions(+)
 create mode 100755 tests/cp/nfs-removal-race

diff --git a/NEWS b/NEWS
index 1c00d96..5e32f79 100644
--- a/NEWS
+++ b/NEWS
@@ -11,6 +11,12 @@ GNU coreutils NEWS                                    -*- outline -*-
   changed, the new group ID would be listed, even though it is not
   yet effective.

+  cp S D is no longer subject to a race: if D were removed between the
+  initial stat and subsequent open-without-O_CREATE, cp would fail with
+  a confusing diagnostic saying that the destination, D, was not found.
+  Now, in this unusual case, it retries the open (but with O_CREATE),
+  and hence usually succeeds.
+
 ** New features

   fmt now accepts the --goal=WIDTH (-g) option.
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 72717e3..ca19051 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -349,6 +349,7 @@ TESTS =						\
   cp/link-no-deref				\
   cp/link-preserve				\
   cp/link-symlink				\
+  cp/nfs-removal-race				\
   cp/no-deref-link1				\
   cp/no-deref-link2				\
   cp/no-deref-link3				\
diff --git a/tests/cp/nfs-removal-race b/tests/cp/nfs-removal-race
new file mode 100755
index 0000000..6a435b0
--- /dev/null
+++ b/tests/cp/nfs-removal-race
@@ -0,0 +1,70 @@
+#!/bin/sh
+# Running cp S D on an NFS client while another client has just removed D
+# would lead (w/coreutils-8.16 and earlier) to cp's initial stat call
+# seeing (via stale NFS cache) that D exists, so that cp would then call
+# open without the O_CREAT flag.  Yet, the open must actually consult
+# the server, which confesses that D has been deleted, thus causing the
+# open call to fail with ENOENT.
+#
+# This test simulates that situation by intercepting stat for a nonexistent
+# destination, D, and making the stat fill in the result struct for another
+# file and return 0.
+#
+# This test is skipped on systems that lack LD_PRELOAD support; that's fine.
+# Similarly, on a system that lacks <dlfcn.h> or __xstat, skipping it is fine.
+
+# Copyright (C) 2012 Free Software Foundation, Inc.
+
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+. "${srcdir=.}/init.sh"; path_prepend_ ../src
+print_ver_ cp
+
+# Replace each stat call with a call to this wrapper.
+cat > k.c <<'EOF' || framework_failure_
+#define _GNU_SOURCE
+#include <sys/types.h>
+#include <dlfcn.h>
+
+#define __xstat __xstat_orig
+
+#include <sys/stat.h>
+#include <stddef.h>
+
+#undef __xstat
+
+int
+__xstat (int ver, const char *path, struct stat *st)
+{
+  static int (*real_stat)(int ver, const char *path, struct stat *st) = NULL;
+  if (!real_stat)
+    real_stat = dlsym (RTLD_NEXT, "__xstat");
+  /* When asked to stat nonexistent "d",
+     return results suggesting it exists. */
+  return real_stat (ver, *path == 'd' && path[1] == 0 ? "d2" : path, st);
+}
+EOF
+
+# Then compile/link it:
+$CC -shared -fPIC -O2 k.c -o k.so \
+  || framework_failure_ 'failed to compile with -shared -fPIC'
+
+touch d2 || framework_failure_
+echo xyz > src || framework_failure_
+
+# Finally, run the test:
+LD_PRELOAD=./k.so cp src d || fail=1
+
+compare src d || fail=1
+Exit $fail
--
1.7.10.1.457.g8275905




Information forwarded to bug-coreutils <at> gnu.org:
bug#11100; Package coreutils. (Sun, 06 May 2012 10:43:01 GMT) Full text and rfc822 format available.

Message #56 received at 11100 <at> debbugs.gnu.org (full text, mbox):

From: Pádraig Brady <P <at> draigBrady.com>
To: Jim Meyering <jim <at> meyering.net>
Cc: Philipp Thomas <pth <at> suse.de>, 11100 <at> debbugs.gnu.org
Subject: Re: bug#11100: Racy code in copy.c
Date: Sun, 06 May 2012 11:40:12 +0100
I can't think of any issue with this.
Code looks good.
Test triggers the new condition.

+1

cheers,
Pádraig.




Information forwarded to bug-coreutils <at> gnu.org:
bug#11100; Package coreutils. (Sun, 06 May 2012 12:09:02 GMT) Full text and rfc822 format available.

Message #59 received at 11100 <at> debbugs.gnu.org (full text, mbox):

From: Jim Meyering <jim <at> meyering.net>
To: Pádraig Brady <P <at> draigBrady.com>
Cc: Philipp Thomas <pth <at> suse.de>, 11100 <at> debbugs.gnu.org
Subject: Re: bug#11100: Racy code in copy.c
Date: Sun, 06 May 2012 14:06:21 +0200
Pádraig Brady wrote:
> I can't think of any issue with this.
> Code looks good.
> Test triggers the new condition.

Thanks for the review.
I've squashed the test-adding commit onto the fix, added this sentence
to NEWS:

     With NFS attribute caching, the condition
     was particularly easy to trigger, since there, the removal of D
     could precede the initial stat.

I was about to push, then wondered...
I'd been assuming that the Neil Brown <neilb <at> cse.unsw.edu.au>
already listed THANKS.in is the same as the Neil F. Brown at SuSE.
We know that assuming is bad, so I checked linux's git log, which
appears to confirm.  So I have updated Neil's name (to add the F.)
and email, too.




Information forwarded to bug-coreutils <at> gnu.org:
bug#11100; Package coreutils. (Mon, 07 May 2012 11:39:02 GMT) Full text and rfc822 format available.

Message #62 received at 11100 <at> debbugs.gnu.org (full text, mbox):

From: Philipp Thomas <pth <at> suse.de>
To: Jim Meyering <jim <at> meyering.net>
Cc: 11100 <at> debbugs.gnu.org
Subject: Re: bug#11100: Racy code in copy.c
Date: Mon, 7 May 2012 13:36:46 +0200
* Jim Meyering (jim <at> meyering.net) [20120504 17:30]:

> If there's a bugzilla reference for this, let me know
> and I'll add it to the commit log.

There is, but as it's a SLES bug it's only open for SUSE employees and
customers and thus useless for a coreutils commit log. I'll instead
reference the commit from said bug report.

Philipp




Reply sent to Jim Meyering <jim <at> meyering.net>:
You have taken responsibility. (Mon, 07 May 2012 11:45:02 GMT) Full text and rfc822 format available.

Notification sent to Philipp Thomas <pth <at> suse.de>:
bug acknowledged by developer. (Mon, 07 May 2012 11:45:03 GMT) Full text and rfc822 format available.

Message #67 received at 11100-done <at> debbugs.gnu.org (full text, mbox):

From: Jim Meyering <jim <at> meyering.net>
To: Philipp Thomas <pth <at> suse.de>
Cc: 11100-done <at> debbugs.gnu.org
Subject: Re: bug#11100: Racy code in copy.c
Date: Mon, 07 May 2012 13:41:57 +0200
Philipp Thomas wrote:
> * Jim Meyering (jim <at> meyering.net) [20120504 17:30]:
>
>> If there's a bugzilla reference for this, let me know
>> and I'll add it to the commit log.
>
> There is, but as it's a SLES bug it's only open for SUSE employees and
> customers and thus useless for a coreutils commit log. I'll instead
> reference the commit from said bug report.

Ok.  I've pushed that change.




Forcibly Merged 11074 11100. Request was from Jim Meyering <jim <at> meyering.net> to control <at> debbugs.gnu.org. (Tue, 08 May 2012 09:16:02 GMT) Full text and rfc822 format available.

bug archived. Request was from Debbugs Internal Request <help-debbugs <at> gnu.org> to internal_control <at> debbugs.gnu.org. (Tue, 05 Jun 2012 11:24:03 GMT) Full text and rfc822 format available.

bug unarchived. Request was from Paul Eggert <eggert <at> cs.ucla.edu> to control <at> debbugs.gnu.org. (Thu, 18 Nov 2021 16:34:01 GMT) Full text and rfc822 format available.

Information forwarded to bug-coreutils <at> gnu.org:
bug#11100; Package coreutils. (Thu, 18 Nov 2021 16:39:01 GMT) Full text and rfc822 format available.

Message #76 received at 11100 <at> debbugs.gnu.org (full text, mbox):

From: Paul Eggert <eggert <at> cs.ucla.edu>
To: Jim Meyering <jim <at> meyering.net>
Cc: 11100 <at> debbugs.gnu.org, Philipp Thomas <pth <at> suse.de>,
 Pádraig Brady <P <at> draigBrady.com>
Subject: bug#11100: Racy code in copy.c
Date: Thu, 18 Nov 2021 08:38:40 -0800
[Message part 1 (text/plain, inline)]
I spotted a SELinux security-context race introduced by the circa-2012 
fix for Bug#11100, and installed the attached patch into coreutils 
master. This also gets rid of a label and goto (which is what led me to 
find the issue).
[0001-cp-fix-security-context-race.patch (text/x-patch, attachment)]

Information forwarded to bug-coreutils <at> gnu.org:
bug#11100; Package coreutils. (Fri, 19 Nov 2021 04:10:02 GMT) Full text and rfc822 format available.

Message #79 received at 11100 <at> debbugs.gnu.org (full text, mbox):

From: Jim Meyering <jim <at> meyering.net>
To: Paul Eggert <eggert <at> cs.ucla.edu>
Cc: 11100 <at> debbugs.gnu.org, Philipp Thomas <pth <at> suse.de>,
 Pádraig Brady <P <at> draigbrady.com>
Subject: Re: bug#11100: Racy code in copy.c
Date: Thu, 18 Nov 2021 20:09:08 -0800
On Thu, Nov 18, 2021 at 8:38 AM Paul Eggert <eggert <at> cs.ucla.edu> wrote:
> I spotted a SELinux security-context race introduced by the circa-2012
> fix for Bug#11100, and installed the attached patch into coreutils
> master. This also gets rid of a label and goto (which is what led me to
> find the issue).

Nice! Thanks for finding and fixing my old bug.




bug archived. Request was from Debbugs Internal Request <help-debbugs <at> gnu.org> to internal_control <at> debbugs.gnu.org. (Fri, 17 Dec 2021 12:24:04 GMT) Full text and rfc822 format available.

This bug report was last modified 2 years and 92 days ago.

Previous Next


GNU bug tracking system
Copyright (C) 1999 Darren O. Benham, 1997,2003 nCipher Corporation Ltd, 1994-97 Ian Jackson.