LKML Archive on lore.kernel.org
help / color / mirror / Atom feed
From: Kentaro Takeda <takedakn@nttdata.co.jp>
To: Andrew Morton <akpm@linux-foundation.org>
Cc: Toshiharu Harada <haradats@nttdata.co.jp>,
	linux-security-module@vger.kernel.org,
	linux-kernel@vger.kernel.org,
	Kentaro Takeda <takedakn@nttdata.co.jp>,
	Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
Subject: [TOMOYO #12 (2.6.28-rc2-mm1) 04/11] Introduce d_realpath().
Date: Tue, 04 Nov 2008 15:08:51 +0900	[thread overview]
Message-ID: <20081104060948.233911964@nttdata.co.jp> (raw)
In-Reply-To: 20081104060847.086543472@nttdata.co.jp

To remove factors that make pathname based access control difficult
(e.g. symbolic links, "..", "//", chroot() etc.), a variant of d_path()
which traverses up to the root of the namespace is needed.

Three differences compared to d_path().
(1) Ignores current process's root directory.
(2) Trailing '/' is added if the pathname refers to a directory.
(3) /proc/PID/ is represented as /proc/self/ if PID equals current->tgid.

Signed-off-by: Kentaro Takeda <takedakn@nttdata.co.jp>
Signed-off-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
Signed-off-by: Toshiharu Harada <haradats@nttdata.co.jp>
---
 fs/dcache.c            |   84 +++++++++++++++++++++++++++++++++++++++++++++++++
 include/linux/dcache.h |    1 
 2 files changed, 85 insertions(+)

--- linux-2.6.28-rc2-mm1.orig/fs/dcache.c
+++ linux-2.6.28-rc2-mm1/fs/dcache.c
@@ -32,6 +32,7 @@
 #include <linux/seqlock.h>
 #include <linux/swap.h>
 #include <linux/bootmem.h>
+#include <linux/magic.h>
 #include "internal.h"
 
 
@@ -1980,6 +1981,89 @@ Elong:
 }
 
 /**
+ * d_realpath - Get the realpath of a dentry.
+ *
+ * @path: Pointer to "struct path".
+ * @buffer: Pointer to buffer to return value in.
+ * @buflen: Sizeof @buffer.
+ *
+ * Returns pointer to the realpath on success, an error code othersize.
+ *
+ * If @dentry is a directory, trailing '/' is appended.
+ * /proc/PID/ is replaced by /proc/self/ if PID == task_tgid_nr_ns(current).
+ */
+char *d_realpath(struct path *path, char *buffer, int buflen)
+{
+	struct dentry *dentry = path->dentry;
+	struct vfsmount *vfsmnt = path->mnt;
+	char *end = buffer + buflen;
+
+	spin_lock(&dcache_lock);
+	spin_lock(&vfsmount_lock);
+	if (buflen < 1 || prepend(&end, &buflen, "", 1))
+		goto Elong;
+	/*
+	 * Exception: Add trailing '/' for directory.
+	 */
+	if (dentry->d_inode && S_ISDIR(dentry->d_inode->i_mode) &&
+	    prepend(&end, &buflen, "/", 1))
+		goto Elong;
+	for (;;) {
+		struct dentry *parent;
+		const char *name;
+		int name_len;
+		unsigned long pid;
+
+		if (dentry == vfsmnt->mnt_root || IS_ROOT(dentry)) {
+			/* Global root? */
+			if (vfsmnt->mnt_parent == vfsmnt)
+				break;
+			dentry = vfsmnt->mnt_mountpoint;
+			vfsmnt = vfsmnt->mnt_parent;
+			continue;
+		}
+		parent = dentry->d_parent;
+		prefetch(parent);
+		/*
+		 * Exception: Use /proc/self/ rather than /proc/\$/
+		 * for current process.
+		 */
+		name = dentry->d_name.name;
+		name_len = dentry->d_name.len;
+		if (IS_ROOT(parent) &&
+		    parent->d_sb->s_magic == PROC_SUPER_MAGIC &&
+		    !strict_strtoul(name, 10, &pid)) {
+			const pid_t tgid
+				= task_tgid_nr_ns(current,
+						  dentry->d_sb->s_fs_info);
+			if (tgid && (pid_t) pid == tgid) {
+				name = "self";
+				name_len = 4;
+			}
+		}
+		if (prepend(&end, &buflen, name, name_len))
+			goto Elong;
+		if (prepend(&end, &buflen, "/", 1))
+			goto Elong;
+		dentry = parent;
+	}
+	if (*end == '/') {
+		/* hit the slash */
+		buflen++;
+		end++;
+	}
+	if (prepend_name(&end, &buflen, &dentry->d_name))
+		goto Elong;
+ out:
+	spin_unlock(&vfsmount_lock);
+	spin_unlock(&dcache_lock);
+	return end;
+ Elong:
+	end = ERR_PTR(-ENAMETOOLONG);
+	goto out;
+}
+
+/**
  * d_path - return the path of a dentry
  * @path: path to report
  * @buf: buffer to return value in
--- linux-2.6.28-rc2-mm1.orig/include/linux/dcache.h
+++ linux-2.6.28-rc2-mm1/include/linux/dcache.h
@@ -305,6 +305,7 @@ extern char *dynamic_dname(struct dentry
 extern char *__d_path(const struct path *path, struct path *root, char *, int);
 extern char *d_path(const struct path *, char *, int);
 extern char *dentry_path(struct dentry *, char *, int);
+extern char *d_realpath(struct path *, char *, int);
 
 /* Allocation counts.. */
 

--


  parent reply	other threads:[~2008-11-04  6:11 UTC|newest]

Thread overview: 32+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-11-04  6:08 [TOMOYO #12 (2.6.28-rc2-mm1) 00/11] TOMOYO Linux Kentaro Takeda
2008-11-04  6:08 ` [TOMOYO #12 (2.6.28-rc2-mm1) 01/11] Introduce security_path_clear() hook Kentaro Takeda
2008-11-04  6:08 ` [TOMOYO #12 (2.6.28-rc2-mm1) 02/11] Add in_execve flag into task_struct Kentaro Takeda
2008-11-05 23:12   ` Andrew Morton
2008-11-04  6:08 ` [TOMOYO #12 (2.6.28-rc2-mm1) 03/11] Singly linked list implementation Kentaro Takeda
2008-11-05 23:12   ` Andrew Morton
2008-11-04  6:08 ` Kentaro Takeda [this message]
2008-11-05 23:12   ` [TOMOYO #12 (2.6.28-rc2-mm1) 04/11] Introduce d_realpath() Andrew Morton
2008-11-17  6:52     ` Kentaro Takeda
2008-11-04  6:08 ` [TOMOYO #12 (2.6.28-rc2-mm1) 05/11] Memory and pathname management functions Kentaro Takeda
2008-11-05 23:12   ` Andrew Morton
2008-11-10 10:34     ` Kentaro Takeda
2008-11-11  5:04       ` Andrew Morton
2008-11-11  6:34         ` Kentaro Takeda
2008-11-11  6:46           ` Andrew Morton
2008-11-11  7:32             ` Kentaro Takeda
2008-11-04  6:08 ` [TOMOYO #12 (2.6.28-rc2-mm1) 06/11] Common functions for TOMOYO Linux Kentaro Takeda
2008-11-05 23:12   ` Andrew Morton
2008-11-06 21:46     ` [TOMOYO #12 (2.6.28-rc2-mm1) 06/11] Common functions for TOMOYOLinux Tetsuo Handa
2008-11-08 16:38     ` Tetsuo Handa
2008-11-10  0:41       ` Serge E. Hallyn
2008-11-10  2:24         ` Tetsuo Handa
2008-11-10  2:52           ` Serge E. Hallyn
2008-11-10  3:30             ` Tetsuo Handa
2008-11-10 14:00               ` Serge E. Hallyn
2008-11-10 10:35     ` [TOMOYO #12 (2.6.28-rc2-mm1) 06/11] Common functions for TOMOYO Linux Kentaro Takeda
2008-11-14  9:22     ` Kentaro Takeda
2008-11-04  6:08 ` [TOMOYO #12 (2.6.28-rc2-mm1) 07/11] File operation restriction part Kentaro Takeda
2008-11-04  6:08 ` [TOMOYO #12 (2.6.28-rc2-mm1) 08/11] Domain transition handler Kentaro Takeda
2008-11-04  6:08 ` [TOMOYO #12 (2.6.28-rc2-mm1) 09/11] LSM adapter functions Kentaro Takeda
2008-11-04  6:08 ` [TOMOYO #12 (2.6.28-rc2-mm1) 10/11] Kconfig and Makefile Kentaro Takeda
2008-11-04  6:08 ` [TOMOYO #12 (2.6.28-rc2-mm1) 11/11] MAINTAINERS info Kentaro Takeda

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=20081104060948.233911964@nttdata.co.jp \
    --to=takedakn@nttdata.co.jp \
    --cc=akpm@linux-foundation.org \
    --cc=haradats@nttdata.co.jp \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-security-module@vger.kernel.org \
    --cc=penguin-kernel@I-love.SAKURA.ne.jp \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).