FAQ Search Today's Posts Mark Forums Read
» Video Reviews

» Linux Archive

Linux-archive is a website aiming to archive linux email lists and to make them easily accessible for linux users/developers.


» Sponsor

» Partners

» Sponsor

Go Back   Linux Archive > Ubuntu > Ubuntu Kernel Team

 
 
LinkBack Thread Tools
 
Old 05-21-2010, 03:03 PM
 
Default Maverick pull request, soft/hard link protection

I've boot tested with these soft and hard link patches and
can find no obvious signs of carnage.

The following changes since commit 82222c9b7caca5df688c007c767bc3085fae821e:
Chase Douglas (1):
Revert "UBUNTU: SAUCE: Disable function tracing after hitting __schedule_bug"

are available in the git repository at:

git://kernel.ubuntu.com/rtg/ubuntu-maverick.git links

Kees Cook (2):
UBUNTU: SAUCE: fs: block cross-uid sticky symlinks
UBUNTU: SAUCE: fs: block hardlinks to non-accessible sources

include/linux/security.h | 5 +++
kernel/sysctl.c | 18 ++++++++++++
security/apparmor/lsm.c | 5 +++-
security/capability.c | 12 --------
security/commoncap.c | 68 ++++++++++++++++++++++++++++++++++++++++++++++
5 files changed, 95 insertions(+), 13 deletions(-)
From ef2f4f2445a49b395058d08484cfa6cd59ee474a Mon Sep 17 00:00:00 2001
From: Kees Cook <kees@ubuntu.com>
Date: Tue, 11 May 2010 16:51:24 -0700
Subject: [PATCH 1/2] UBUNTU: SAUCE: fs: block cross-uid sticky symlinks
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

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).

The solution is to not permit symlinks to be followed when users do not
match, but only in a world-writable sticky directory (with an additional
improvement that the directory owner's symlinks can always be followed,
regardless who is following them).

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. Also, please reference
where POSIX says this.
- 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 grsecurity, which is similar to the
patch in Openwall. I have added a sysctl to toggle the behavior back
to the old handling via /proc/sys/fs/weak-sticky-symlinks, as well as
a ratelimited deprecation warning.

Signed-off-by: Kees Cook <kees.cook@canonical.com>
---
include/linux/security.h | 1 +
kernel/sysctl.c | 8 ++++++++
security/capability.c | 6 ------
security/commoncap.c | 24 ++++++++++++++++++++++++
4 files changed, 33 insertions(+), 6 deletions(-)

diff --git a/include/linux/security.h b/include/linux/security.h
index 3158dd9..92eca95 100644
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -67,6 +67,7 @@ extern int cap_inode_setxattr(struct dentry *dentry, const char *name,
extern int cap_inode_removexattr(struct dentry *dentry, const char *name);
extern int cap_inode_need_killpriv(struct dentry *dentry);
extern int cap_inode_killpriv(struct dentry *dentry);
+extern int cap_inode_follow_link(struct dentry *dentry, struct nameidata *nd);
extern int cap_file_mmap(struct file *file, unsigned long reqprot,
unsigned long prot, unsigned long flags,
unsigned long addr, unsigned long addr_only);
diff --git a/kernel/sysctl.c b/kernel/sysctl.c
index 8686b0f..36a104c 100644
--- a/kernel/sysctl.c
+++ b/kernel/sysctl.c
@@ -86,6 +86,7 @@ extern int sysctl_oom_dump_tasks;
extern int max_threads;
extern int core_uses_pid;
extern int suid_dumpable;
+extern int weak_sticky_symlinks;
extern char core_pattern[];
extern unsigned int core_pipe_limit;
extern int pid_max;
@@ -1416,6 +1417,13 @@ static struct ctl_table fs_table[] = {
.extra1 = &zero,
.extra2 = &two,
},
+ {
+ .procname = "weak-sticky-symlinks",
+ .data = &weak_sticky_symlinks,
+ .maxlen = sizeof(int),
+ .mode = 0644,
+ .proc_handler = &proc_dointvec,
+ },
#if defined(CONFIG_BINFMT_MISC) || defined(CONFIG_BINFMT_MISC_MODULE)
{
.procname = "binfmt_misc",
diff --git a/security/capability.c b/security/capability.c
index 4875142..d4633f3 100644
--- a/security/capability.c
+++ b/security/capability.c
@@ -200,12 +200,6 @@ static int cap_inode_readlink(struct dentry *dentry)
return 0;
}

-static int cap_inode_follow_link(struct dentry *dentry,
- struct nameidata *nameidata)
-{
- return 0;
-}
-
static int cap_inode_permission(struct inode *inode, int mask)
{
return 0;
diff --git a/security/commoncap.c b/security/commoncap.c
index 6166973..4a6b670 100644
--- a/security/commoncap.c
+++ b/security/commoncap.c
@@ -29,6 +29,9 @@
#include <linux/securebits.h>
#include <linux/syslog.h>

+/* sysctl for symlink permissions checking */
+int weak_sticky_symlinks;
+
/*
* If a non-root user executes a setuid-root binary in
* !secure(SECURE_NOROOT) mode, then we raise capabilities.
@@ -281,6 +284,27 @@ int cap_inode_killpriv(struct dentry *dentry)
return inode->i_op->removexattr(dentry, XATTR_NAME_CAPS);
}

+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 (S_ISLNK(inode->i_mode) && (parent->i_mode & S_ISVTX) &&
+ (parent->i_mode & S_IWOTH) && (parent->i_uid != inode->i_uid) &&
+ (cred->fsuid != inode->i_uid)) {
+ printk_ratelimited(KERN_INFO "deprecated sticky-directory"
+ " non-matching uid symlink following was attempted"
+ " by: %s
", current->comm);
+ return -EACCES;
+ }
+ return 0;
+}
+
/*
* Calculate the new process capability sets from the capability sets attached
* to a file.
--
1.7.0.4
 
Old 05-21-2010, 05:05 PM
Leann Ogasawara
 
Default Maverick pull request, soft/hard link protection

Definitely want to get these in early and exposed to testing. Applied
to Maverick master.

Thanks,
Leann


--
kernel-team mailing list
kernel-team@lists.ubuntu.com
https://lists.ubuntu.com/mailman/listinfo/kernel-team
 

Thread Tools




All times are GMT. The time now is 03:28 PM.

VBulletin, Copyright ©2000 - 2014, Jelsoft Enterprises Ltd.
Content Relevant URLs by vBSEO ©2007, Crawlability, Inc.
Copyright ©2007 - 2008, www.linux-archive.org