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