All of lore.kernel.org
 help / color / mirror / Atom feed
* Question about detecting filesystem type.
@ 2010-07-09  2:29 Tetsuo Handa
  2010-07-11 10:39 ` Tetsuo Handa
  0 siblings, 1 reply; 2+ messages in thread
From: Tetsuo Handa @ 2010-07-09  2:29 UTC (permalink / raw)
  To: linux-fsdevel

Is there a way to tell from "struct dentry" or "struct vfsmount" that whether
the directory entries are controllable from userspace's requests or not?

TOMOYO wants to use /proc/self/ rather than /proc/$PID/ if $PID matches current
thread's process ID in order to prevent current thread from accessing other
process's information unless needed. Converting "$PID" to "self" in core code
(i.e. __d_path()) was refused in the past, with a response "do the conversion
after returning from __d_path()". But since procfs can be mounted on various
locations (e.g. /proc/ /proc2/ /p/ /tmp/foo/100/p/ ), the caller of __d_path()
(i.e. TOMOYO) cannot tell that whether the numeric part in the returned string
represents process ID or not. If TOMOYO traverses the vfsmount tree up manually
in order to detect the process ID part, TOMOYO will no longer use __d_path().

Thus, I'm considering to use a different way for representing files on procfs
(e.g. proc:$PID/mounts rather than /proc/$PID/mounts) so that TOMOYO can
convert "$PID" to "self". That will be possible.

There are two types of filesystems. One is filesystems (e.g. ext3 tmpfs nfs)
where dentries can be controlled from userspace using creat()/rename()/link()
etc. The other is filesystems (e.g. procfs sysfs securityfs) where dentries
cannot be controlled from userspace using creat()/rename()/link() etc.

Using different way for representing files on only procfs sounds a bit strange.
Thus, I'm considering to use a unified way for representing files on the latter
type of filesystems (e.g. proc:$PID/mounts sys:power/state ).
But I don't know how to tell the former type and the latter type.
Is there a way to tell it from "struct dentry" or "struct vfsmount"?

Regards.

^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: Question about detecting filesystem type.
  2010-07-09  2:29 Question about detecting filesystem type Tetsuo Handa
@ 2010-07-11 10:39 ` Tetsuo Handa
  0 siblings, 0 replies; 2+ messages in thread
From: Tetsuo Handa @ 2010-07-11 10:39 UTC (permalink / raw)
  To: linux-fsdevel; +Cc: linux-security-module

Tetsuo Handa wrote:
> Is there a way to tell from "struct dentry" or "struct vfsmount" that whether
> the directory entries are controllable from userspace's requests or not?
> 
> TOMOYO wants to use /proc/self/ rather than /proc/$PID/ if $PID matches current
> thread's process ID in order to prevent current thread from accessing other
> process's information unless needed. Converting "$PID" to "self" in core code
> (i.e. __d_path()) was refused in the past, with a response "do the conversion
> after returning from __d_path()". But since procfs can be mounted on various
> locations (e.g. /proc/ /proc2/ /p/ /tmp/foo/100/p/ ), the caller of __d_path()
> (i.e. TOMOYO) cannot tell that whether the numeric part in the returned string
> represents process ID or not. If TOMOYO traverses the vfsmount tree up manually
> in order to detect the process ID part, TOMOYO will no longer use __d_path().
> 
> Thus, I'm considering to use a different way for representing files on procfs
> (e.g. proc:$PID/mounts rather than /proc/$PID/mounts) so that TOMOYO can
> convert "$PID" to "self". That will be possible.
> 
> There are two types of filesystems. One is filesystems (e.g. ext3 tmpfs nfs)
> where dentries can be controlled from userspace using creat()/rename()/link()
> etc. The other is filesystems (e.g. procfs sysfs securityfs) where dentries
> cannot be controlled from userspace using creat()/rename()/link() etc.
> 
> Using different way for representing files on only procfs sounds a bit strange.
> Thus, I'm considering to use a unified way for representing files on the latter
> type of filesystems (e.g. proc:$PID/mounts sys:power/state ).
> But I don't know how to tell the former type and the latter type.
> Is there a way to tell it from "struct dentry" or "struct vfsmount"?

In the below patch, I used whether inode_operations supports rename() or not
as a mean for detecting filesystem type. Since dentry->d_inode can be NULL,
I used dentry->d_sb->s_root->d_inode for dereferencing inode_operations.
May I do below changes?

Regards.
----------------------------------------
>From ef2cd6217b00a767333bbf5b623604551c3a6642 Mon Sep 17 00:00:00 2001
From: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
Date: Sun, 11 Jul 2010 18:56:04 +0900
Subject: [RFC][PATCH] TOMOYO: Use dentry_path() for filesystems which do not support rename() operations.

TOMOYO wants to use /proc/self/ rather than /proc/$PID/ if $PID matches current
thread's process ID in order to prevent current thread from accessing other
process's information unless needed. But since procfs can be mounted on various
locations (e.g. /proc/ /proc2/ /p/ /tmp/foo/100/p/ ), TOMOYO cannot tell that
whether the numeric part in the string returned by __d_path() represents
process ID or not.

Therefore, to be able to convert from $PID to self no matter where procfs is
mounted, this patch changes from __d_path() to dentry_path() for filesystems
which do not support rename() operation (e.g. proc, sysfs, securityfs).

  Before                                       After
  /dev/pts/0                                => devpts:/0
  /proc/tty/driver/serial                   => proc:/tty/driver/serial
  /sys/kernel/security/tomoyo/domain_policy => securityfs:/tomoyo/domain_policy
  /sys/power/state                          => sysfs:/power/state

Pathnames on filesystems which support rename() operation (e.g. ext3, tmpfs)
remain unchanged.

Signed-off-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
---
 security/tomoyo/realpath.c |   55 ++++++++++++++++++++++++++++++++++++--------
 1 files changed, 45 insertions(+), 10 deletions(-)

diff --git a/security/tomoyo/realpath.c b/security/tomoyo/realpath.c
index ed8ccd6..1d07b75 100644
--- a/security/tomoyo/realpath.c
+++ b/security/tomoyo/realpath.c
@@ -89,9 +89,11 @@ char *tomoyo_realpath_from_path(struct path *path)
 	char *name = NULL;
 	unsigned int buf_len = PAGE_SIZE / 2;
 	struct dentry *dentry = path->dentry;
+	struct super_block *sb;
 	bool is_dir;
 	if (!dentry)
 		return NULL;
+	sb = dentry->d_sb;
 	is_dir = dentry->d_inode && S_ISDIR(dentry->d_inode->i_mode);
 	while (1) {
 		struct path ns_root = { .mnt = NULL, .dentry = NULL };
@@ -102,7 +104,7 @@ char *tomoyo_realpath_from_path(struct path *path)
 		if (!buf)
 			break;
 		/* Get better name for socket. */
-		if (dentry->d_sb && dentry->d_sb->s_magic == SOCKFS_MAGIC) {
+		if (sb->s_magic == SOCKFS_MAGIC) {
 			struct inode *inode = dentry->d_inode;
 			struct socket *sock = inode ? SOCKET_I(inode) : NULL;
 			struct sock *sk = sock ? sock->sk : NULL;
@@ -124,6 +126,48 @@ char *tomoyo_realpath_from_path(struct path *path)
 			name = tomoyo_encode(pos);
 			break;
 		}
+		/*
+		 * Get local name for filesystems which do not support rename()
+		 * operation (e.g. proc, sysfs, securityfs).
+		 */
+		if (sb->s_root->d_inode && sb->s_root->d_inode->i_op &&
+		    !sb->s_root->d_inode->i_op->rename) {
+			char *cp;
+			pos = dentry_path(dentry, buf, buf_len - 1);
+			if (IS_ERR(pos))
+				continue;
+			/* Delete trailing "//deleted" part. */
+			cp = strstr(pos, "//");
+			if (cp)
+				*cp = '\0';
+			/*
+			 * Convert from $PID to self if $PID is current thread.
+			 */
+			if (sb->s_magic == PROC_SUPER_MAGIC && *pos == '/') {
+				char *ep;
+				const pid_t pid = (pid_t)
+					simple_strtoul(pos + 1, &ep, 10);
+				if (*ep == '/' && pid && pid ==
+				    task_tgid_nr_ns(current, sb->s_fs_info)) {
+					pos = ep - 5;
+					if (pos < buf)
+						continue;
+					memmove(pos, "/self", 5);
+				}
+			}
+			/* Prepend filesystem name. */
+			{
+				const char *name = sb->s_type->name;
+				const int name_len = strlen(name);
+				pos -= name_len + 1;
+				if (pos < buf)
+					continue;
+				memmove(pos, name, name_len);
+				pos[name_len] = ':';
+			}
+			name = tomoyo_encode(pos);
+			break;
+		}
 		/* If we don't have a vfsmount, we can't calculate. */
 		if (!path->mnt)
 			break;
@@ -131,15 +175,6 @@ char *tomoyo_realpath_from_path(struct path *path)
 		/* go to whatever namespace root we are under */
 		pos = __d_path(path, &ns_root, buf, buf_len);
 		spin_unlock(&dcache_lock);
-		/* Prepend "/proc" prefix if using internal proc vfs mount. */
-		if (!IS_ERR(pos) && (path->mnt->mnt_flags & MNT_INTERNAL) &&
-		    (path->mnt->mnt_sb->s_magic == PROC_SUPER_MAGIC)) {
-			pos -= 5;
-			if (pos >= buf)
-				memcpy(pos, "/proc", 5);
-			else
-				pos = ERR_PTR(-ENOMEM);
-		}
 		if (IS_ERR(pos))
 			continue;
 		name = tomoyo_encode(pos);
-- 
1.6.1

^ permalink raw reply related	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2010-07-11 10:39 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-07-09  2:29 Question about detecting filesystem type Tetsuo Handa
2010-07-11 10:39 ` Tetsuo Handa

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.