Re: [RFC][PATCH] security/selinux: Simplify proc inode to securitylabel mapping.

From: Tetsuo Handa
Date: Sun Nov 22 2009 - 21:10:43 EST


James Morris wrote:
> I need to investigate this further, but one immediate issue is that
> Tomoyo seems to have similar code.

tomoyo_sysctl hook and related functions will be removed soon.

> On Fri, 20 Nov 2009, Eric W. Biederman wrote:
> > caveat: Because the dentry may not yet be hashed I think dentry_path will
> > append (deleted) and thus is not the right function to call.

SELinux, TOMOYO, AppArmor want pathname calculation functions which don't
append " (deleted)" suffix.

Regarding TOMOYO, I want to use below function.
It is impossible to convert "pid" to "self" outside __d_path() because string
returned by __d_path() does not have hints for telling whether "pid" part is
procfs or not. As a result, I have to traverse dentry/vfsmount tree manually
in order to tell whether "pid" part is procfs or not, which makes __d_path()
useless for TOMOYO.

/**
* tomoyo_get_absolute_path - Get the path of a dentry but ignores chroot'ed root.
*
* @path: Pointer to "struct path".
* @buffer: Pointer to buffer to return value in.
* @buflen: Sizeof @buffer.
*
* Returns the buffer on success, an error code otherwise.
*
* Caller holds the dcache_lock and vfsmount_lock.
* Based on __d_path() in fs/dcache.c
*
* If dentry is a directory, trailing '/' is appended.
* /proc/pid is represented as /proc/self if pid is current.
*/
static char *tomoyo_get_absolute_path(struct path *path, char * const buffer,
const int buflen)
{
char *pos = buffer + buflen - 1;
struct dentry *dentry = path->dentry;
struct vfsmount *vfsmnt = path->mnt;
bool is_dir = (dentry->d_inode && S_ISDIR(dentry->d_inode->i_mode));
const char *name;
int len;

if (buflen < 256)
goto out;

*pos = '\0';
for (;;) {
struct dentry *parent;
if (dentry == vfsmnt->mnt_root || IS_ROOT(dentry)) {
if (vfsmnt->mnt_parent == vfsmnt)
break;
dentry = vfsmnt->mnt_mountpoint;
vfsmnt = vfsmnt->mnt_parent;
continue;
}
if (is_dir) {
is_dir = false;
*--pos = '/';
}
parent = dentry->d_parent;
name = dentry->d_name.name;
len = dentry->d_name.len;
if (IS_ROOT(parent) && *name > '0' && *name <= '9' &&
parent->d_sb &&
parent->d_sb->s_magic == PROC_SUPER_MAGIC) {
char *ep;
const pid_t pid = (pid_t) simple_strtoul(name, &ep,
10);
const pid_t tgid = task_tgid_nr_ns(current,
dentry->d_sb->
s_fs_info);
if (!*ep && pid == tgid && tgid) {
name = "self";
len = 4;
}
}
pos -= len;
if (pos <= buffer)
goto out;
memmove(pos, name, len);
*--pos = '/';
dentry = parent;
}
if (*pos == '/')
pos++;
len = dentry->d_name.len;
pos -= len;
if (pos < buffer)
goto out;
memmove(pos, dentry->d_name.name, len);
return pos;
out:
return ERR_PTR(-ENOMEM);
}
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/