All of lore.kernel.org
 help / color / mirror / Atom feed
From: Eric Paris <eparis@redhat.com>
To: Kees Cook <kees.cook@canonical.com>
Cc: linux-kernel@vger.kernel.org,
	linux-security-module@vger.kernel.org,
	linux-fsdevel@vger.kernel.org, linux-doc@vger.kernel.org,
	Randy Dunlap <rdunlap@xenotime.net>,
	Andrew Morton <akpm@linux-foundation.org>,
	Jiri Kosina <jkosina@suse.cz>,
	Dave Young <hidave.darkstar@gmail.com>,
	Martin Schwidefsky <schwidefsky@de.ibm.com>,
	James Morris <jmorris@namei.org>,
	David Howells <dhowells@redhat.com>, Ingo Molnar <mingo@elte.hu>,
	Peter Zijlstra <a.p.zijlstra@chello.nl>,
	"Eric W. Biederman" <ebiederm@xmission.com>,
	Tim Gardner <tim.gardner@canonical.com>,
	"Serge E. Hallyn" <serue@us.ibm.com>,
	sds@tycho.nsa.gov, selinux@tycho.nsa.gov
Subject: Re: [PATCH v2] fs: block cross-uid sticky symlinks
Date: Sun, 30 May 2010 23:54:23 -0400	[thread overview]
Message-ID: <1275278063.20730.16.camel@localhost> (raw)
In-Reply-To: <20100531030402.GQ6056@outflux.net>

On Sun, 2010-05-30 at 20:04 -0700, Kees Cook wrote:
> A long-standing class of security issues is the symlink-based
> time-of-check-time-of-use race, most commonly seen in world-writable
> directories like /tmp. The common method of exploitation of this flaw
> is to cross privilege boundaries when following a given symlink (i.e. a
> root process follows a symlink belonging to another user).  For a likely
> incomplete list of hundreds of examples across the years, please see:
> http://cve.mitre.org/cgi-bin/cvekey.cgi?keyword=/tmp
> 
> The solution is to permit symlinks to only be followed when outside a sticky
> world-writable directory, or when the uid of the symlink and follower match,
> or when the directory owner matches the symlink's owner.
> 
> Some pointers to the history of earlier discussion that I could find:
> 
>  1996 Aug, Zygo Blaxell
>   http://marc.info/?l=bugtraq&m=87602167419830&w=2
>  1996 Oct, Andrew Tridgell
>   http://lkml.indiana.edu/hypermail/linux/kernel/9610.2/0086.html
>  1997 Dec, Albert D Cahalan
>   http://lkml.org/lkml/1997/12/16/4
>  2005 Feb, Lorenzo Hernández García-Hierro
>   http://lkml.indiana.edu/hypermail/linux/kernel/0502.0/1896.html
> 
> Past objections and rebuttals could be summarized as:
> 
>  - Violates POSIX.
>    - POSIX didn't consider this situation and it's not useful to follow
>      a broken specification at the cost of security.
>  - Might break unknown applications that use this feature.
>    - Applications that break because of the change are easy to spot and
>      fix. Applications that are vulnerable to symlink ToCToU by not having
>      the change aren't.
>  - Applications should just use mkstemp() or O_CREATE|O_EXCL.
>    - True, but applications are not perfect, and new software is written
>      all the time that makes these mistakes; blocking this flaw at the
>      kernel is a single solution to the entire class of vulnerability.
> 
> This patch is based on the patch in Openwall and grsecurity.  I have
> added a sysctl to toggle the behavior back to the old logic via
> /proc/sys/fs/weak-sticky-symlinks, documentation, and a ratelimited
> warning.
> 
> v2:
>  - dropped redundant S_ISLNK check.
>  - moved sysctl extern into security.h.
>  - asked to include CC to linux-fsdevel.

We need to call this function in the SELinux case.  So you'll need a
patch like the one attached (not even compiled but I think it is right)

diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 5c9f25b..d6ebee2 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -2668,8 +2668,13 @@ static int selinux_inode_readlink(struct dentry *dentry)
 
 static int selinux_inode_follow_link(struct dentry *dentry, struct nameidata *nameidata)
 {
+       int rc;
        const struct cred *cred = current_cred();
 
+       rc = cap_inode_follow_link(dentry, nameidata);
+       if (rc)
+               return rc;
+
        return dentry_has_perm(cred, NULL, dentry, FILE__READ);
 }
 

> +int cap_inode_follow_link(struct dentry *dentry,
> +			  struct nameidata *nameidata)
> +{
> +	const struct inode *parent = dentry->d_parent->d_inode;
> +	const struct inode *inode = dentry->d_inode;
> +	const struct cred *cred = current_cred();
> +
> +	if (weak_sticky_symlinks)
> +		return 0;
> +
> +	if ((parent->i_mode & (S_ISVTX|S_IWOTH)) == (S_ISVTX|S_IWOTH) &&
> +	    parent->i_uid != inode->i_uid &&
> +	    cred->fsuid != inode->i_uid) {
> +		printk_ratelimited(KERN_NOTICE "non-matching-uid symlink "
> +			"following attempted in sticky-directory by "
> +			"%s (fsuid %d)\n", current->comm, cred->fsuid);
> +		return -EACCES;
> +	}
> +	return 0;
> +}

What stops us from racing between the assignment of parent and it's
first use with a rename on our object and rmdir on the old parent?  I'm
wondering if we need to be doing this test holding dentry->d_lock (which
is what protects dentry->d_parent if I recall correctly)

Certainly doesn't fix all of the raciness, but I think it would close
the opps part.  Maybe someone who knows the VFS better can tell me if I
am misguided.

-Eric



--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.

WARNING: multiple messages have this Message-ID (diff)
From: Eric Paris <eparis@redhat.com>
To: Kees Cook <kees.cook@canonical.com>
Cc: linux-kernel@vger.kernel.org,
	linux-security-module@vger.kernel.org,
	linux-fsdevel@vger.kernel.org, linux-doc@vger.kernel.org,
	Randy Dunlap <rdunlap@xenotime.net>,
	Andrew Morton <akpm@linux-foundation.org>,
	Jiri Kosina <jkosina@suse.cz>,
	Dave Young <hidave.darkstar@gmail.com>,
	Martin Schwidefsky <schwidefsky@de.ibm.com>,
	James Morris <jmorris@namei.org>,
	David Howells <dhowells@redhat.com>, Ingo Molnar <mingo@elte.hu>,
	Peter Zijlstra <a.p.zijlstra@chello.nl>,
	"Eric W. Biederman" <ebiederm@xmission.com>,
	Tim Gardner <tim.gardner@canonical.com>,
	"Serge E. Hallyn" <serue@us.ibm.com>,
	sds@tycho.nsa.gov, selinux@tycho.nsa.gov
Subject: Re: [PATCH v2] fs: block cross-uid sticky symlinks
Date: Sun, 30 May 2010 23:54:23 -0400	[thread overview]
Message-ID: <1275278063.20730.16.camel@localhost> (raw)
In-Reply-To: <20100531030402.GQ6056@outflux.net>

On Sun, 2010-05-30 at 20:04 -0700, Kees Cook wrote:
> A long-standing class of security issues is the symlink-based
> time-of-check-time-of-use race, most commonly seen in world-writable
> directories like /tmp. The common method of exploitation of this flaw
> is to cross privilege boundaries when following a given symlink (i.e. a
> root process follows a symlink belonging to another user).  For a likely
> incomplete list of hundreds of examples across the years, please see:
> http://cve.mitre.org/cgi-bin/cvekey.cgi?keyword=/tmp
> 
> The solution is to permit symlinks to only be followed when outside a sticky
> world-writable directory, or when the uid of the symlink and follower match,
> or when the directory owner matches the symlink's owner.
> 
> Some pointers to the history of earlier discussion that I could find:
> 
>  1996 Aug, Zygo Blaxell
>   http://marc.info/?l=bugtraq&m=87602167419830&w=2
>  1996 Oct, Andrew Tridgell
>   http://lkml.indiana.edu/hypermail/linux/kernel/9610.2/0086.html
>  1997 Dec, Albert D Cahalan
>   http://lkml.org/lkml/1997/12/16/4
>  2005 Feb, Lorenzo Hernández García-Hierro
>   http://lkml.indiana.edu/hypermail/linux/kernel/0502.0/1896.html
> 
> Past objections and rebuttals could be summarized as:
> 
>  - Violates POSIX.
>    - POSIX didn't consider this situation and it's not useful to follow
>      a broken specification at the cost of security.
>  - Might break unknown applications that use this feature.
>    - Applications that break because of the change are easy to spot and
>      fix. Applications that are vulnerable to symlink ToCToU by not having
>      the change aren't.
>  - Applications should just use mkstemp() or O_CREATE|O_EXCL.
>    - True, but applications are not perfect, and new software is written
>      all the time that makes these mistakes; blocking this flaw at the
>      kernel is a single solution to the entire class of vulnerability.
> 
> This patch is based on the patch in Openwall and grsecurity.  I have
> added a sysctl to toggle the behavior back to the old logic via
> /proc/sys/fs/weak-sticky-symlinks, documentation, and a ratelimited
> warning.
> 
> v2:
>  - dropped redundant S_ISLNK check.
>  - moved sysctl extern into security.h.
>  - asked to include CC to linux-fsdevel.

We need to call this function in the SELinux case.  So you'll need a
patch like the one attached (not even compiled but I think it is right)

diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 5c9f25b..d6ebee2 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -2668,8 +2668,13 @@ static int selinux_inode_readlink(struct dentry *dentry)
 
 static int selinux_inode_follow_link(struct dentry *dentry, struct nameidata *nameidata)
 {
+       int rc;
        const struct cred *cred = current_cred();
 
+       rc = cap_inode_follow_link(dentry, nameidata);
+       if (rc)
+               return rc;
+
        return dentry_has_perm(cred, NULL, dentry, FILE__READ);
 }
 

> +int cap_inode_follow_link(struct dentry *dentry,
> +			  struct nameidata *nameidata)
> +{
> +	const struct inode *parent = dentry->d_parent->d_inode;
> +	const struct inode *inode = dentry->d_inode;
> +	const struct cred *cred = current_cred();
> +
> +	if (weak_sticky_symlinks)
> +		return 0;
> +
> +	if ((parent->i_mode & (S_ISVTX|S_IWOTH)) == (S_ISVTX|S_IWOTH) &&
> +	    parent->i_uid != inode->i_uid &&
> +	    cred->fsuid != inode->i_uid) {
> +		printk_ratelimited(KERN_NOTICE "non-matching-uid symlink "
> +			"following attempted in sticky-directory by "
> +			"%s (fsuid %d)\n", current->comm, cred->fsuid);
> +		return -EACCES;
> +	}
> +	return 0;
> +}

What stops us from racing between the assignment of parent and it's
first use with a rename on our object and rmdir on the old parent?  I'm
wondering if we need to be doing this test holding dentry->d_lock (which
is what protects dentry->d_parent if I recall correctly)

Certainly doesn't fix all of the raciness, but I think it would close
the opps part.  Maybe someone who knows the VFS better can tell me if I
am misguided.

-Eric



  parent reply	other threads:[~2010-05-31  3:54 UTC|newest]

Thread overview: 24+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-05-31  3:04 [PATCH v2] fs: block cross-uid sticky symlinks Kees Cook
2010-05-31  3:50 ` Eric W. Biederman
2010-05-31  4:12   ` Kees Cook
2010-05-31  3:54 ` Eric Paris [this message]
2010-05-31  3:54   ` Eric Paris
2010-05-31  4:23   ` Kees Cook
2010-05-31 10:23 ` Alan Cox
2010-05-31 17:50   ` Kees Cook
2010-05-31 18:09     ` Alan Cox
2010-05-31 19:07       ` Kees Cook
2010-05-31 19:52         ` Al Viro
2010-05-31 22:00           ` Kees Cook
2010-05-31 19:27     ` Al Viro
2010-05-31 10:35 ` Christoph Hellwig
2010-05-31 17:57   ` Kees Cook
2010-05-31 23:09     ` James Morris
2010-06-01  3:24       ` Kees Cook
2010-06-01  7:55         ` Christoph Hellwig
2010-06-01 11:55           ` Eric Paris
2010-06-01 14:52             ` Kees Cook
2010-06-01 15:34               ` Eric Paris
2010-06-01 17:31                 ` tytso
2010-06-01 15:00           ` Kees Cook
2010-05-31 10:47 ` tytso

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1275278063.20730.16.camel@localhost \
    --to=eparis@redhat.com \
    --cc=a.p.zijlstra@chello.nl \
    --cc=akpm@linux-foundation.org \
    --cc=dhowells@redhat.com \
    --cc=ebiederm@xmission.com \
    --cc=hidave.darkstar@gmail.com \
    --cc=jkosina@suse.cz \
    --cc=jmorris@namei.org \
    --cc=kees.cook@canonical.com \
    --cc=linux-doc@vger.kernel.org \
    --cc=linux-fsdevel@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-security-module@vger.kernel.org \
    --cc=mingo@elte.hu \
    --cc=rdunlap@xenotime.net \
    --cc=schwidefsky@de.ibm.com \
    --cc=sds@tycho.nsa.gov \
    --cc=selinux@tycho.nsa.gov \
    --cc=serue@us.ibm.com \
    --cc=tim.gardner@canonical.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.