Re: Question about detecting filesystem type.

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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@xxxxxxxxxxxxxxxxxxx>
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@xxxxxxxxxxxxxxxxxxx>
---
 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
--
To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Ext4 Filesystem]     [Union Filesystem]     [Filesystem Testing]     [Ceph Users]     [Ecryptfs]     [AutoFS]     [Kernel Newbies]     [Share Photos]     [Security]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux Cachefs]     [Reiser Filesystem]     [Linux RAID]     [Samba]     [Device Mapper]     [CEPH Development]
  Powered by Linux