All of lore.kernel.org
 help / color / mirror / Atom feed
From: Ulrich Drepper <drepper@redhat.com>
To: Linux Kernel <linux-kernel@vger.kernel.org>,
	Andrew Morton <akpm@osdl.org>
Cc: Linus Torvalds <torvalds@osdl.org>
Subject: [PATCH] O_DIRECTORY|O_CREAT handling
Date: Sun, 21 Dec 2003 01:40:39 -0800	[thread overview]
Message-ID: <3FE56A97.3060901@redhat.com> (raw)

[-- Attachment #1: Type: text/plain, Size: 1733 bytes --]

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

The kernel currently handles open() calls with flags having at least
O_DIRECTORY|O_CREAT set strangely (to say the least).  It creates a
regular file, completely ignoring the O_DIRECTORY bit.  One can argue
that open() does not perform any real checking on the parameters and
that it is the programmers responsibility, but there is a twist.

Some programs create temporary directory which they afterward use as the
working directory or changed root.  I.e., we have code like this:

  mkdir ("/some/dirRANDOM");
  chdir ("/some/dirRANDOM");

or

  mkdir ("/some/dirRANDOM");
  fd = open ("/some/dirRANDOM", O_DIRECTORY);
  fchdir (fd);

or

  mkdir ("/some/dirRANDOM");
  chroot ("/some/dirRANDOM");

All these pieces of code have an obvious flaw, a race.  There is no
atomic way to do what we want.

Now combine these two problems.  How about making this work?

  fd = open ("/some/dirRANDOM", O_RDONLY|O_CREAT|O_DIRECTORY|O_EXCL, 0700);
  fchdir (fd);

(and similarly for a new interface fchroot which I can add to glibc).

I've attached a little patch which does just that.  Some comments on the
code:

 ~ if an existing directory is opened with O_RDWR open() returns
- -EISDIR.  I've mimicked this, allthough the error code might not be the
most obvious.

 ~ O_TRUNC is not allowed.


The small attached patch implements this proposal.  At least it does
what I want it to do, no idea what bugs I introduce.

- --
➧ Ulrich Drepper ➧ Red Hat, Inc. ➧ 444 Castro St ➧ Mountain View, CA ❖
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.3 (GNU/Linux)

iD8DBQE/5WqW2ijCOnn/RHQRAjZEAJ9SxzM1O6B/hQZN5jabqSSzXXtZwQCdH2sd
hRr+ejRNAU4Cl9V8MXpBIYo=
=jXqY
-----END PGP SIGNATURE-----

[-- Attachment #2: d-opendir --]
[-- Type: text/plain, Size: 1092 bytes --]

--- linux-2.6/fs/namei.c-opendir	2003-12-20 21:32:50.000000000 -0800
+++ linux-2.6/fs/namei.c	2003-12-21 01:37:09.000000000 -0800
@@ -1295,7 +1295,12 @@
 	if (!dentry->d_inode) {
 		if (!IS_POSIXACL(dir->d_inode))
 			mode &= ~current->fs->umask;
-		error = vfs_create(dir->d_inode, dentry, mode, nd);
+		if (unlikely(flag & O_DIRECTORY)) {
+			error = -EISDIR;
+			if (!(flag & FMODE_WRITE))
+				error = vfs_mkdir(dir->d_inode, dentry, mode);
+		} else
+			error = vfs_create(dir->d_inode, dentry, mode, nd);
 		up(&dir->d_inode->i_sem);
 		dput(nd->dentry);
 		nd->dentry = dentry;
@@ -1331,7 +1336,11 @@
 	dput(nd->dentry);
 	nd->dentry = dentry;
 	error = -EISDIR;
-	if (dentry->d_inode && S_ISDIR(dentry->d_inode->i_mode))
+	/* Since we allow creating directories with open(2) we forbid
+	   opening an existing directory with O_CREAT only if the
+	   O_DIRECTORY flag is not set or if truncation is requested.  */
+	if (dentry->d_inode && S_ISDIR(dentry->d_inode->i_mode) &&
+	    (!(flag & O_DIRECTORY) || (flag & O_TRUNC)))
 		goto exit;
 ok:
 	error = may_open(nd, acc_mode, flag);

             reply	other threads:[~2003-12-21  9:42 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2003-12-21  9:40 Ulrich Drepper [this message]
2003-12-21 10:51 ` [PATCH] O_DIRECTORY|O_CREAT handling Willy Tarreau
2003-12-28 18:03   ` Andrew Pimlott
2003-12-28 18:25     ` viro

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=3FE56A97.3060901@redhat.com \
    --to=drepper@redhat.com \
    --cc=akpm@osdl.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=torvalds@osdl.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.