* [PATCH] fs: allow unprivileged chroot()
@ 2016-01-02 7:52 Jann Horn
2016-01-03 11:09 ` Richard Weinberger
0 siblings, 1 reply; 5+ messages in thread
From: Jann Horn @ 2016-01-02 7:52 UTC (permalink / raw)
To: Alexander Viro, linux-fsdevel
Allow unprivileged processes to chroot() themselves, under the
following conditions:
- The caller must have set NO_NEW_PRIVS to prevent him from
invoking setuid/setgid/setcap executables in the chroot that
could be tricked into opening files from the chroot.
- The fs_struct must not be shared to prevent the caller from
chrooting another process that does not have NO_NEW_PRIVS
active.
- chroot() is sometimes (mis-)used for sandboxing purposes.
To prevent a simple chroot breakout using e.g. the
double-chroot trick (chdir("/"), chroot("/foo"),
chroot("../../../../../../../../")), require the process to
be un-chrooted before performing chroot()
Signed-off-by: Jann Horn <jann@thejh.net>
---
fs/open.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/fs/open.c b/fs/open.c
index b6f1e96..a07026b 100644
--- a/fs/open.c
+++ b/fs/open.c
@@ -481,7 +481,9 @@ retry:
goto dput_and_out;
error = -EPERM;
- if (!ns_capable(current_user_ns(), CAP_SYS_CHROOT))
+ if ((current->fs->users != 1 || !task_no_new_privs(current)
+ || current_chrooted())
+ && !ns_capable(current_user_ns(), CAP_SYS_CHROOT))
goto dput_and_out;
error = security_path_chroot(&path);
if (error)
--
2.1.4
^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [PATCH] fs: allow unprivileged chroot()
2016-01-02 7:52 [PATCH] fs: allow unprivileged chroot() Jann Horn
@ 2016-01-03 11:09 ` Richard Weinberger
2016-01-04 1:39 ` Jann Horn
0 siblings, 1 reply; 5+ messages in thread
From: Richard Weinberger @ 2016-01-03 11:09 UTC (permalink / raw)
To: Jann Horn; +Cc: Alexander Viro, linux-fsdevel
On Sat, Jan 2, 2016 at 8:52 AM, Jann Horn <jann@thejh.net> wrote:
> Allow unprivileged processes to chroot() themselves, under the
> following conditions:
>
> - The caller must have set NO_NEW_PRIVS to prevent him from
> invoking setuid/setgid/setcap executables in the chroot that
> could be tricked into opening files from the chroot.
> - The fs_struct must not be shared to prevent the caller from
> chrooting another process that does not have NO_NEW_PRIVS
> active.
> - chroot() is sometimes (mis-)used for sandboxing purposes.
> To prevent a simple chroot breakout using e.g. the
> double-chroot trick (chdir("/"), chroot("/foo"),
> chroot("../../../../../../../../")), require the process to
> be un-chrooted before performing chroot()
What is the use case?
If you want to jail yourself as non-root you can create a new user and
mount namespace.
Then you're allowed to change root.
--
Thanks,
//richard
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] fs: allow unprivileged chroot()
2016-01-03 11:09 ` Richard Weinberger
@ 2016-01-04 1:39 ` Jann Horn
2016-01-04 1:51 ` Richard Weinberger
0 siblings, 1 reply; 5+ messages in thread
From: Jann Horn @ 2016-01-04 1:39 UTC (permalink / raw)
To: Richard Weinberger; +Cc: Alexander Viro, linux-fsdevel
[-- Attachment #1: Type: text/plain, Size: 2627 bytes --]
On Sun, Jan 03, 2016 at 12:09:36PM +0100, Richard Weinberger wrote:
> On Sat, Jan 2, 2016 at 8:52 AM, Jann Horn <jann@thejh.net> wrote:
> > Allow unprivileged processes to chroot() themselves, under the
> > following conditions:
> >
> > - The caller must have set NO_NEW_PRIVS to prevent him from
> > invoking setuid/setgid/setcap executables in the chroot that
> > could be tricked into opening files from the chroot.
> > - The fs_struct must not be shared to prevent the caller from
> > chrooting another process that does not have NO_NEW_PRIVS
> > active.
> > - chroot() is sometimes (mis-)used for sandboxing purposes.
> > To prevent a simple chroot breakout using e.g. the
> > double-chroot trick (chdir("/"), chroot("/foo"),
> > chroot("../../../../../../../../")), require the process to
> > be un-chrooted before performing chroot()
>
> What is the use case?
> If you want to jail yourself as non-root you can create a new user and
> mount namespace.
> Then you're allowed to change root.
Yes, on a normal vanilla kernel with a standard config, that works
with just a new user namespace.
There are a lot of systems with kernels that require caps for
CLONE_NEWUSER by default because of distro patches (e.g. Debian
and grsecurity) or that disable namespaces entirely (e.g. Android).
AFAIK Debian and grsecurity do it because from a security
perspective, unprivileged namespaces are pretty scary and likely
to still contain a bunch of unfixed issues.
As far as I can tell, unprivileged chroot() would expose far less
new attack surface than full unprivileged namespaces support
and would still be usable for lightweight linux-in-linux stuff
(similar to fakechroot, although it wouldn't allow you to keep
procfs, so maybe it wouldn't be sooo useful for that) and,
more importantly IMO, it would allow adding sandboxing to
programs that, while not perfect, "just works" across distros
if the kernel is new enough, doesn't change uid mappings, is
mostly reliable when used together with seccomp (apart from the
case where folders are moved out of the chroot) and doesn't
require the use of special APIs everywhere.
(Maybe I should send another patch for a user namespace flag
that causes the namespace to have its parent's uid mappings from
the perspective of processes inside it, but its real uid mappings
from the kernel's perspective? That would, on vanilla kernels,
at least allow unprivileged fileserver processes or so to sandbox
themselves using user+mount namespaces without losing the ability
to identify file owners and groups.)
[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 819 bytes --]
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] fs: allow unprivileged chroot()
2016-01-04 1:39 ` Jann Horn
@ 2016-01-04 1:51 ` Richard Weinberger
2016-01-04 1:54 ` Jann Horn
0 siblings, 1 reply; 5+ messages in thread
From: Richard Weinberger @ 2016-01-04 1:51 UTC (permalink / raw)
To: Jann Horn; +Cc: Alexander Viro, linux-fsdevel
Am 04.01.2016 um 02:39 schrieb Jann Horn:
> On Sun, Jan 03, 2016 at 12:09:36PM +0100, Richard Weinberger wrote:
>> On Sat, Jan 2, 2016 at 8:52 AM, Jann Horn <jann@thejh.net> wrote:
>>> Allow unprivileged processes to chroot() themselves, under the
>>> following conditions:
>>>
>>> - The caller must have set NO_NEW_PRIVS to prevent him from
>>> invoking setuid/setgid/setcap executables in the chroot that
>>> could be tricked into opening files from the chroot.
>>> - The fs_struct must not be shared to prevent the caller from
>>> chrooting another process that does not have NO_NEW_PRIVS
>>> active.
>>> - chroot() is sometimes (mis-)used for sandboxing purposes.
>>> To prevent a simple chroot breakout using e.g. the
>>> double-chroot trick (chdir("/"), chroot("/foo"),
>>> chroot("../../../../../../../../")), require the process to
>>> be un-chrooted before performing chroot()
>>
>> What is the use case?
>> If you want to jail yourself as non-root you can create a new user and
>> mount namespace.
>> Then you're allowed to change root.
>
> Yes, on a normal vanilla kernel with a standard config, that works
> with just a new user namespace.
>
> There are a lot of systems with kernels that require caps for
> CLONE_NEWUSER by default because of distro patches (e.g. Debian
> and grsecurity) or that disable namespaces entirely (e.g. Android).
Well, let us focus on vanilla kernels.
> AFAIK Debian and grsecurity do it because from a security
> perspective, unprivileged namespaces are pretty scary and likely
> to still contain a bunch of unfixed issues.
FUD
> As far as I can tell, unprivileged chroot() would expose far less
> new attack surface than full unprivileged namespaces support
> and would still be usable for lightweight linux-in-linux stuff
> (similar to fakechroot, although it wouldn't allow you to keep
> procfs, so maybe it wouldn't be sooo useful for that) and,
> more importantly IMO, it would allow adding sandboxing to
> programs that, while not perfect, "just works" across distros
> if the kernel is new enough, doesn't change uid mappings, is
> mostly reliable when used together with seccomp (apart from the
> case where folders are moved out of the chroot) and doesn't
> require the use of special APIs everywhere.
IMHO it is not an excuse for adding hacks to the core code
to allow unprivileged chroot().
We have the user namespace for reasons.
> (Maybe I should send another patch for a user namespace flag
> that causes the namespace to have its parent's uid mappings from
> the perspective of processes inside it, but its real uid mappings
> from the kernel's perspective? That would, on vanilla kernels,
> at least allow unprivileged fileserver processes or so to sandbox
> themselves using user+mount namespaces without losing the ability
> to identify file owners and groups.)
Sounds promising. :-)
Thanks,
//richard
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] fs: allow unprivileged chroot()
2016-01-04 1:51 ` Richard Weinberger
@ 2016-01-04 1:54 ` Jann Horn
0 siblings, 0 replies; 5+ messages in thread
From: Jann Horn @ 2016-01-04 1:54 UTC (permalink / raw)
To: Richard Weinberger; +Cc: Alexander Viro, linux-fsdevel
[-- Attachment #1: Type: text/plain, Size: 2377 bytes --]
On Mon, Jan 04, 2016 at 02:51:37AM +0100, Richard Weinberger wrote:
> Am 04.01.2016 um 02:39 schrieb Jann Horn:
> > On Sun, Jan 03, 2016 at 12:09:36PM +0100, Richard Weinberger wrote:
> >> On Sat, Jan 2, 2016 at 8:52 AM, Jann Horn <jann@thejh.net> wrote:
> >>> Allow unprivileged processes to chroot() themselves, under the
> >>> following conditions:
> >>>
> >>> - The caller must have set NO_NEW_PRIVS to prevent him from
> >>> invoking setuid/setgid/setcap executables in the chroot that
> >>> could be tricked into opening files from the chroot.
> >>> - The fs_struct must not be shared to prevent the caller from
> >>> chrooting another process that does not have NO_NEW_PRIVS
> >>> active.
> >>> - chroot() is sometimes (mis-)used for sandboxing purposes.
> >>> To prevent a simple chroot breakout using e.g. the
> >>> double-chroot trick (chdir("/"), chroot("/foo"),
> >>> chroot("../../../../../../../../")), require the process to
> >>> be un-chrooted before performing chroot()
> >>
> >> What is the use case?
> >> If you want to jail yourself as non-root you can create a new user and
> >> mount namespace.
> >> Then you're allowed to change root.
> >
> > Yes, on a normal vanilla kernel with a standard config, that works
> > with just a new user namespace.
> >
> > There are a lot of systems with kernels that require caps for
> > CLONE_NEWUSER by default because of distro patches (e.g. Debian
> > and grsecurity) or that disable namespaces entirely (e.g. Android).
>
> Well, let us focus on vanilla kernels.
Okay. Yeah, true, it's not so useful on vanilla kernels.
> > AFAIK Debian and grsecurity do it because from a security
> > perspective, unprivileged namespaces are pretty scary and likely
> > to still contain a bunch of unfixed issues.
>
> FUD
It's not. :D
> > (Maybe I should send another patch for a user namespace flag
> > that causes the namespace to have its parent's uid mappings from
> > the perspective of processes inside it, but its real uid mappings
> > from the kernel's perspective? That would, on vanilla kernels,
> > at least allow unprivileged fileserver processes or so to sandbox
> > themselves using user+mount namespaces without losing the ability
> > to identify file owners and groups.)
>
> Sounds promising. :-)
I'll try that tomorrow.
[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 819 bytes --]
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2016-01-04 1:54 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2016-01-02 7:52 [PATCH] fs: allow unprivileged chroot() Jann Horn
2016-01-03 11:09 ` Richard Weinberger
2016-01-04 1:39 ` Jann Horn
2016-01-04 1:51 ` Richard Weinberger
2016-01-04 1:54 ` Jann Horn
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).