GNU bug report logs - #11761
Slight bug in split :-)

Previous Next

Package: coreutils;

Reported by: Jim Meyering <jim <at> meyering.net>

Date: Thu, 21 Jun 2012 22:16:02 UTC

Severity: normal

Done: Pádraig Brady <P <at> draigBrady.com>

Bug is archived. No further changes may be made.

Full log


View this message in rfc822 format

From: Jim Meyering <jim <at> meyering.net>
To: Pádraig Brady <P <at> draigBrady.com>
Cc: 11761 <at> debbugs.gnu.org, François Pinard <pinard <at> iro.umontreal.ca>
Subject: bug#11761: Slight bug in split :-)
Date: Fri, 22 Jun 2012 09:56:24 +0200
Pádraig Brady wrote:
...
> diff --git a/src/split.c b/src/split.c
> index 53ee271..3e3313a 100644
> --- a/src/split.c
> +++ b/src/split.c
> @@ -92,6 +92,9 @@ static char const *additional_suffix;
>  /* Name of input file.  May be "-".  */
>  static char *infile;
>
> +/* stat buf for input file.  */
> +static struct stat in_stat_buf;
> +
>  /* Descriptor on which output file is open.  */
>  static int output_desc = -1;
>
> @@ -362,6 +365,17 @@ create (const char *name)
>      {
>        if (verbose)
>          fprintf (stdout, _("creating file %s\n"), quote (name));
> +
> +      struct stat out_stat_buf;
> +      if (stat (name, &out_stat_buf) == 0)
> +        {
> +          if (SAME_INODE (in_stat_buf, out_stat_buf))
> +            error (EXIT_FAILURE, 0, _("%s would overwrite input. Aborting."),
> +                   quote (name));
> +        }
> +      else if (errno != ENOENT)
> +        error (EXIT_FAILURE, errno, _("cannot stat %s"), quote (name));
> +
>        return open (name, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY,
>                     (S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH))
>      }

Hi Pádraig,

Thanks for taking this on.
That introduces a minor TOCTOU race.
It would probably never matter in practice,
but who knows... if we can avoid it, why not?
What do you think about something like this?

    int fd = open (name, (... as above, but without O_TRUNC...)...
    if (fd < 0)
      return fd;
    if ( ! fstat (fd, &out_stat_buf))
      error (EXIT_FAILURE, errno, _("failed to fstat %s"), quote (name));
    if (SAME_INODE (in_stat_buf, out_stat_buf))
      error (EXIT_FAILURE, 0, _("%s would overwrite input. Aborting."),
             quote (name));
    if ( ! ftruncate (fd, 0))
      error ...
    return fd;

The above might even be a tiny bit faster for long names,
since it resolves each name only once.




This bug report was last modified 13 years and 22 days ago.

Previous Next


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