All of lore.kernel.org
 help / color / mirror / Atom feed
From: Al Viro <viro@ZenIV.linux.org.uk>
To: Valdis.Kletnieks@vt.edu
Cc: Linus Torvalds <torvalds@linux-foundation.org>,
	linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: Re: [RFC] a corner case of open(2)
Date: Tue, 26 Apr 2016 21:17:57 +0100	[thread overview]
Message-ID: <20160426201757.GR25498@ZenIV.linux.org.uk> (raw)
In-Reply-To: <92598.1461698716@turing-police.cc.vt.edu>

On Tue, Apr 26, 2016 at 03:25:16PM -0400, Valdis.Kletnieks@vt.edu wrote:
> Gaah.. I lost a few words in there - /bin/ls is *expecting* to operate on
> a directory, so to calls getdents.   I meant some generic program that
> opened a directory in error, and was expecting to act on "stream of bytes"
> 
> > We also do not allow opening directories for *write*, and in that case EISDIR
> > is the right error (and we do return it).
> 
> OK, that and ftruncate() are about the only ways to cause trouble with a
> directory opened by accident...

ftruncate() requires the file to be opened for write (which already excludes
directories) *and* it requires the file to be a regular one (which is
redundant in case of directories, but e.g. a block device can be opened
for write and ftruncate would still fail on that).  EINVAL in both cases.

truncate() for directories�should fail with EISDIR (see vfs_truncate());
for anything that is neither directory nor regular - EINVAL (same place).

O_TRUNC ends up failing with EISDIR on directories - see
        /* O_TRUNC implies we need access checks for write permissions */
        if (flags & O_TRUNC)
                acc_mode |= MAY_WRITE;
in build_open_flags() and aforementioned bit in may_open().  POSIX is
bloody vague on that topic, but that's the common behaviour since 4.3BSD
has fixed an fs-corrupting bug in the original implementation (4.2BSD
allowed open(directory, O_TRUNC), which both succeeded *and* truncated the
damn thing to zero, to great joy of fsck).  Note that v7 didn't have O_TRUNC
at all - creat(2) was the only way to get it and that opened the sucker r/w,
so the usual rules re "no opening directories for write" applied.  When
O_TRUNC had been introduced, initially they'd missed the possibility of
somebody passing it to read-only open() and the need to reject those for
directories same as open for write.

WARNING: multiple messages have this Message-ID (diff)
From: Al Viro <viro@ZenIV.linux.org.uk>
To: Valdis.Kletnieks@vt.edu
Cc: Linus Torvalds <torvalds@linux-foundation.org>,
	linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: Re: [RFC] a corner case of open(2)
Date: Tue, 26 Apr 2016 21:17:57 +0100	[thread overview]
Message-ID: <20160426201757.GR25498@ZenIV.linux.org.uk> (raw)
In-Reply-To: <92598.1461698716@turing-police.cc.vt.edu>

On Tue, Apr 26, 2016 at 03:25:16PM -0400, Valdis.Kletnieks@vt.edu wrote:
> Gaah.. I lost a few words in there - /bin/ls is *expecting* to operate on
> a directory, so to calls getdents.   I meant some generic program that
> opened a directory in error, and was expecting to act on "stream of bytes"
> 
> > We also do not allow opening directories for *write*, and in that case EISDIR
> > is the right error (and we do return it).
> 
> OK, that and ftruncate() are about the only ways to cause trouble with a
> directory opened by accident...

ftruncate() requires the file to be opened for write (which already excludes
directories) *and* it requires the file to be a regular one (which is
redundant in case of directories, but e.g. a block device can be opened
for write and ftruncate would still fail on that).  EINVAL in both cases.

truncate() for directories should fail with EISDIR (see vfs_truncate());
for anything that is neither directory nor regular - EINVAL (same place).

O_TRUNC ends up failing with EISDIR on directories - see
        /* O_TRUNC implies we need access checks for write permissions */
        if (flags & O_TRUNC)
                acc_mode |= MAY_WRITE;
in build_open_flags() and aforementioned bit in may_open().  POSIX is
bloody vague on that topic, but that's the common behaviour since 4.3BSD
has fixed an fs-corrupting bug in the original implementation (4.2BSD
allowed open(directory, O_TRUNC), which both succeeded *and* truncated the
damn thing to zero, to great joy of fsck).  Note that v7 didn't have O_TRUNC
at all - creat(2) was the only way to get it and that opened the sucker r/w,
so the usual rules re "no opening directories for write" applied.  When
O_TRUNC had been introduced, initially they'd missed the possibility of
somebody passing it to read-only open() and the need to reject those for
directories same as open for write.

  reply	other threads:[~2016-04-26 20:18 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-04-26 17:55 [RFC] a corner case of open(2) Al Viro
2016-04-26 18:05 ` Cedric Blancher
2016-04-26 18:15   ` Al Viro
2016-04-26 18:41 ` Valdis.Kletnieks
2016-04-26 19:02   ` Al Viro
2016-04-26 19:25     ` Valdis.Kletnieks
2016-04-26 20:17       ` Al Viro [this message]
2016-04-26 20:17         ` Al Viro
2016-04-27  5:34 ` Al Viro
2016-04-27  9:33   ` Miklos Szeredi
2016-04-27 19:29   ` another patch in #for-linus (was Re: [RFC] a corner case of open(2)) Al Viro
2016-05-02 21:48     ` Pavel Machek

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20160426201757.GR25498@ZenIV.linux.org.uk \
    --to=viro@zeniv.linux.org.uk \
    --cc=Valdis.Kletnieks@vt.edu \
    --cc=linux-fsdevel@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=torvalds@linux-foundation.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.