All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/3] Patches to enable chroot for all users
@ 2013-03-20 12:53 Tal Tchwella
  2013-03-20 12:53 ` [PATCH 1/3] enabled " Tal Tchwella
                   ` (3 more replies)
  0 siblings, 4 replies; 6+ messages in thread
From: Tal Tchwella @ 2013-03-20 12:53 UTC (permalink / raw)
  To: linux-kernel; +Cc: tchwella

I want to suggest adding chroot capability to all users.
The following patches enable that capability, while considering the security mechanism needed to disable escape routes for chroots by non-root users,
and keeping chroot backward-compatible for root users.
The first patch establishes the concept of multi-user chroot, while disabling checks for root user in the chroot process.
The second patch checks whether a fd that is sent to a chroot application by a non-root user refers to a directory. 
If that is the case, that fd is skipped, to disable an escape route. 
The third patch disables the option for applications that have open fds to directories to be chrooted by a non-root user.

Any comments, feedback and suggestions are appreciated!

Thanks,
Tal


Tal Tchwella (3):
  enabled chroot for all users
  socket checks for uds fds transfer
  open fds check when starting chroot

 fs/exec.c             |    3 +++
 fs/open.c             |   32 ++++++++++++++++++++++++++++++--
 include/linux/sched.h |   12 ++++++++++++
 init/main.c           |    1 +
 kernel/fork.c         |    2 ++
 net/core/scm.c        |    9 +++++++++
 6 files changed, 57 insertions(+), 2 deletions(-)

-- 
1.7.9.5


^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH 1/3] enabled chroot for all users
  2013-03-20 12:53 [PATCH 0/3] Patches to enable chroot for all users Tal Tchwella
@ 2013-03-20 12:53 ` Tal Tchwella
  2013-03-20 12:53 ` [PATCH 2/3] socket checks for uds fds transfer Tal Tchwella
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 6+ messages in thread
From: Tal Tchwella @ 2013-03-20 12:53 UTC (permalink / raw)
  To: linux-kernel; +Cc: tchwella

This patch enables chroot for all users, not just root users,
by disabling the appropriate checks in fs/open.c.
It also disables nested chroots by non-root users,
so they will not be able to break out of a chroot using classic techniques.

Signed-off-by: Tal Tchwella <tchwella@mit.edu>
---
 fs/exec.c             |    3 +++
 fs/open.c             |    8 ++++++--
 include/linux/sched.h |   12 ++++++++++++
 init/main.c           |    1 +
 kernel/fork.c         |    2 ++
 5 files changed, 24 insertions(+), 2 deletions(-)

diff --git a/fs/exec.c b/fs/exec.c
index 7d27def..e2303ef 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -1299,6 +1299,9 @@ int prepare_binprm(struct linux_binprm *bprm)
 	    !current->no_new_privs) {
 		/* Set-uid? */
 		if (mode & S_ISUID) {
+			/* chroot by a regular, non root, user? */
+			if (current->user_chroot == CHROOT_USER_MODE)
+				return -EACCES;
 			bprm->per_clear |= PER_CLEAR_ON_SETID;
 			bprm->cred->euid = inode->i_uid;
 		}
diff --git a/fs/open.c b/fs/open.c
index a47a0a7..82832d8 100644
--- a/fs/open.c
+++ b/fs/open.c
@@ -435,9 +435,13 @@ SYSCALL_DEFINE1(chroot, const char __user *, filename)
 	if (error)
 		goto dput_and_out;
 
-	error = -EPERM;
+	/* Are we in a nested chroot by a regular, non root, user? */
+	if (current->user_chroot != CHROOT_USER_MODE)
+		current->user_chroot = CHROOT_ROOT_MODE;
+
 	if (!capable(CAP_SYS_CHROOT))
-		goto dput_and_out;
+		current->user_chroot = CHROOT_USER_MODE;
+
 	error = security_path_chroot(&path);
 	if (error)
 		goto dput_and_out;
diff --git a/include/linux/sched.h b/include/linux/sched.h
index 9e960d4..315e6fe 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -30,6 +30,16 @@
 #define CLONE_NEWNET		0x40000000	/* New network namespace */
 #define CLONE_IO		0x80000000	/* Clone io context */
 
+ /*
+  * chroot syscall Modes: INIT, USER, ROOT
+  * Init mode is to be used only by main.
+  * User mode is initialized when a non-root user tries to enter chroot mode.
+  * ROOT mode is the normal mode of operation for chroot.
+  */
+#define CHROOT_INIT		0
+#define CHROOT_USER_MODE	1
+#define CHROOT_ROOT_MODE	2
+
 /*
  * Scheduling policies
  */
@@ -1232,6 +1242,8 @@ struct task_struct {
 	unsigned int flags;	/* per process flags, defined below */
 	unsigned int ptrace;
 
+	unsigned int user_chroot;
+
 #ifdef CONFIG_SMP
 	struct llist_node wake_entry;
 	int on_cpu;
diff --git a/init/main.c b/init/main.c
index 0ec0731..044c655 100644
--- a/init/main.c
+++ b/init/main.c
@@ -781,6 +781,7 @@ static noinline int init_post(void)
 
 
 	current->signal->flags |= SIGNAL_UNKILLABLE;
+	current->user_chroot = CHROOT_INIT;
 
 	if (ramdisk_execute_command) {
 		run_init_process(ramdisk_execute_command);
diff --git a/kernel/fork.c b/kernel/fork.c
index 0269b2a..7f6d662 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -276,6 +276,8 @@ static struct task_struct *dup_task_struct(struct task_struct *orig)
 	if (err)
 		goto out;
 
+	tsk->user_chroot = orig->user_chroot;
+
 	tsk->stack = ti;
 
 	setup_thread_stack(tsk, orig);
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH 2/3] socket checks for uds fds transfer
  2013-03-20 12:53 [PATCH 0/3] Patches to enable chroot for all users Tal Tchwella
  2013-03-20 12:53 ` [PATCH 1/3] enabled " Tal Tchwella
@ 2013-03-20 12:53 ` Tal Tchwella
  2013-03-20 12:53 ` [PATCH 3/3] open fds check when starting chroot Tal Tchwella
  2013-03-20 15:16 ` [PATCH 0/3] Patches to enable chroot for all users Rob Landley
  3 siblings, 0 replies; 6+ messages in thread
From: Tal Tchwella @ 2013-03-20 12:53 UTC (permalink / raw)
  To: linux-kernel; +Cc: tchwella

This patch checks whether another user is trying to send a chrooted application by
a non-root user a fd to a directory, which will allow it to escape.
By preventing this kind of fd transfer to chrooted applications by non-root users,
certain security risks are mitigated.

Signed-off-by: Tal Tchwella <tchwella@mit.edu>
---
 net/core/scm.c |    9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/net/core/scm.c b/net/core/scm.c
index ff52ad0..e505528 100644
--- a/net/core/scm.c
+++ b/net/core/scm.c
@@ -282,6 +282,15 @@ void scm_detach_fds(struct msghdr *msg, struct scm_cookie *scm)
 	for (i=0, cmfptr=(__force int __user *)CMSG_DATA(cm); i<fdmax;
 	     i++, cmfptr++)
 	{
+		/*
+		 * Restricts passing of fds via unix domain sockets to non-root
+		 * chrooted applications to files and does not allow directories
+		 * to be passed.
+		 */
+		if (current->user_chroot == CHROOT_USER_MODE) {
+			if (S_ISDIR(fp[i]->f_dentry->d_inode->i_mode))
+				continue;
+		}
 		int new_fd;
 		err = security_file_receive(fp[i]);
 		if (err)
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH 3/3] open fds check when starting chroot
  2013-03-20 12:53 [PATCH 0/3] Patches to enable chroot for all users Tal Tchwella
  2013-03-20 12:53 ` [PATCH 1/3] enabled " Tal Tchwella
  2013-03-20 12:53 ` [PATCH 2/3] socket checks for uds fds transfer Tal Tchwella
@ 2013-03-20 12:53 ` Tal Tchwella
  2013-03-20 15:16 ` [PATCH 0/3] Patches to enable chroot for all users Rob Landley
  3 siblings, 0 replies; 6+ messages in thread
From: Tal Tchwella @ 2013-03-20 12:53 UTC (permalink / raw)
  To: linux-kernel; +Cc: tchwella

This patch checks for open fds to directories when a non-root user tries to chroot,
and does not allow that user to chroot if the application has an open fd to a directory
because the appilcation has an escape path with that fd.

Signed-off-by: Tal Tchwella <tchwella@mit.edu>
---
 fs/open.c |   24 ++++++++++++++++++++++++
 1 file changed, 24 insertions(+)

diff --git a/fs/open.c b/fs/open.c
index 82832d8..6dc6443 100644
--- a/fs/open.c
+++ b/fs/open.c
@@ -426,6 +426,30 @@ SYSCALL_DEFINE1(chroot, const char __user *, filename)
 {
 	struct path path;
 	int error;
+	struct files_struct *current_files;
+	struct fdtable *files_table;
+	int i = 0;
+
+	error = -EPERM;
+	/*
+	 * Checks to see if there are open file descriptors to directories
+	 * when a user that does not have the chroot capability
+	 * tries to chroot. Since chroot is availble to all users,
+	 * want to eliminate ways to break out. The second part
+	 * of the if statement, is true by default,
+	 * since during the initilization of the kernel, it
+	 * goes into chroot mode.
+	 */
+	if (!capable(CAP_SYS_CHROOT) && current->user_chroot != CHROOT_INIT) {
+		current_files = current->files;
+		files_table = files_fdtable(current_files);
+		while (files_table->fd[i] != NULL) {
+			if (S_ISDIR(files_table->fd[i]->
+				f_dentry->d_inode->i_mode))
+					 goto out;
+			i++;
+		}
+	}
 
 	error = user_path_dir(filename, &path);
 	if (error)
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: [PATCH 0/3] Patches to enable chroot for all users
  2013-03-20 12:53 [PATCH 0/3] Patches to enable chroot for all users Tal Tchwella
                   ` (2 preceding siblings ...)
  2013-03-20 12:53 ` [PATCH 3/3] open fds check when starting chroot Tal Tchwella
@ 2013-03-20 15:16 ` Rob Landley
  3 siblings, 0 replies; 6+ messages in thread
From: Rob Landley @ 2013-03-20 15:16 UTC (permalink / raw)
  To: Tal Tchwella; +Cc: linux-kernel, tchwella

On 03/20/2013 07:53:42 AM, Tal Tchwella wrote:
> I want to suggest adding chroot capability to all users.

I note that chroot doesn't quite do what most people think it does:

   http://landley.net/notes-2011.html#02-06-2011

I've had a todo item forever to modify chroot to actually change the  
process-local mount tree, creating a bind mount if necessary for the  
new directory, reparenting the mount tree to that bind mount, and  
making sure that reference counting can free unused mounts that this  
would discard. (Except rootfs always needs a nonzero reference count.)

The problem isn't adding security checks, the problem is that having a  
"/" symlink point somewhere _other_ than the actual top of the  
process-local mount tree is obsolete now that there isn't a single  
global mount tree for all processes. (Yes, this would mean it might  
need to create a new namespace.)

Rob

^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH 2/3] socket checks for uds fds transfer
  2013-03-20 13:09 tal.tchwella
@ 2013-03-20 13:09 ` tal.tchwella
  0 siblings, 0 replies; 6+ messages in thread
From: tal.tchwella @ 2013-03-20 13:09 UTC (permalink / raw)
  To: linux-kernel; +Cc: tchwella

From: Tal Tchwella <tchwella@mit.edu>

This patch checks whether another user is trying to send a chrooted application by
a non-root user a fd to a directory, which will allow it to escape.
By preventing this kind of fd transfer to chrooted applications by non-root users,
certain security risks are mitigated.

Signed-off-by: Tal Tchwella <tchwella@mit.edu>
---
 net/core/scm.c |    9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/net/core/scm.c b/net/core/scm.c
index ff52ad0..e505528 100644
--- a/net/core/scm.c
+++ b/net/core/scm.c
@@ -282,6 +282,15 @@ void scm_detach_fds(struct msghdr *msg, struct scm_cookie *scm)
 	for (i=0, cmfptr=(__force int __user *)CMSG_DATA(cm); i<fdmax;
 	     i++, cmfptr++)
 	{
+		/*
+		 * Restricts passing of fds via unix domain sockets to non-root
+		 * chrooted applications to files and does not allow directories
+		 * to be passed.
+		 */
+		if (current->user_chroot == CHROOT_USER_MODE) {
+			if (S_ISDIR(fp[i]->f_dentry->d_inode->i_mode))
+				continue;
+		}
 		int new_fd;
 		err = security_file_receive(fp[i]);
 		if (err)
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2013-03-20 15:16 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-03-20 12:53 [PATCH 0/3] Patches to enable chroot for all users Tal Tchwella
2013-03-20 12:53 ` [PATCH 1/3] enabled " Tal Tchwella
2013-03-20 12:53 ` [PATCH 2/3] socket checks for uds fds transfer Tal Tchwella
2013-03-20 12:53 ` [PATCH 3/3] open fds check when starting chroot Tal Tchwella
2013-03-20 15:16 ` [PATCH 0/3] Patches to enable chroot for all users Rob Landley
2013-03-20 13:09 tal.tchwella
2013-03-20 13:09 ` [PATCH 2/3] socket checks for uds fds transfer tal.tchwella

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.