lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date:	Mon, 5 Jan 2009 20:08:50 +1100 (EST)
From:	James Morris <jmorris@...ei.org>
To:	Tetsuo Handa <penguin-kernel@...ove.SAKURA.ne.jp>
cc:	Andrew Morton <akpm@...ux-foundation.org>,
	linux-security-module@...r.kernel.org,
	linux-kernel@...r.kernel.org,
	Kentaro Takeda <takedakn@...data.co.jp>,
	Toshiharu Harada <haradats@...data.co.jp>
Subject: Re: [TOMOYO #14 (mmotm 2008-12-30-16-05) 03/10] Introduce
 d_realpath().

On Thu, 1 Jan 2009, Tetsuo Handa wrote:

> 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.
> 
> This patch introduces d_realpath(), a variant of d_path().
> While d_path() stops traversing at current->fs->root,
> d_realpath() doesn't stop traversiong at current->fs->root.
> 
> 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.
> 

This needs an ack from Al and/or Christoph.

> Signed-off-by: Kentaro Takeda <takedakn@...data.co.jp>
> Signed-off-by: Tetsuo Handa <penguin-kernel@...ove.SAKURA.ne.jp>
> Signed-off-by: Toshiharu Harada <haradats@...data.co.jp>
> ---
>  fs/dcache.c            |   84 +++++++++++++++++++++++++++++++++++++++++++++++++
>  include/linux/dcache.h |    1 
>  2 files changed, 85 insertions(+)
> 
> --- linux-2.6.28-mm1.orig/fs/dcache.c
> +++ linux-2.6.28-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"
>  
>  
> @@ -1978,6 +1979,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-mm1.orig/include/linux/dcache.h
> +++ linux-2.6.28-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.. */
>  
> 
> -- 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-security-module" in
> the body of a message to majordomo@...r.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 

-- 
James Morris
<jmorris@...ei.org>
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ