Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > linux.kernel > #1503007 > unrolled thread
| Started by | Michal Hocko <mhocko@kernel.org> |
|---|---|
| First post | 2016-10-18 16:00 +0200 |
| Last post | 2016-10-18 20:10 +0200 |
| Articles | 20 — 5 participants |
Back to article view | Back to linux.kernel
This discussion starts older than the indexed window; earlier articles aren't shown. The article labeled Started by
below is the oldest one visible, not the original post.
Re: [REVIEW][PATCH] mm: Add a user_ns owner to mm_struct and fix ptrace_may_access Michal Hocko <mhocko@kernel.org> - 2016-10-18 16:00 +0200
Re: [REVIEW][PATCH] mm: Add a user_ns owner to mm_struct and fix ptrace_may_access Jann Horn <jann@thejh.net> - 2016-10-18 16:00 +0200
Re: [REVIEW][PATCH] mm: Add a user_ns owner to mm_struct and fix ptrace_may_access ebiederm@xmission.com (Eric W. Biederman) - 2016-10-18 17:00 +0200
Re: [REVIEW][PATCH] mm: Add a user_ns owner to mm_struct and fix ptrace_may_access Jann Horn <jann@thejh.net> - 2016-10-18 17:10 +0200
Re: [REVIEW][PATCH] mm: Add a user_ns owner to mm_struct and fix ptrace_may_access ebiederm@xmission.com (Eric W. Biederman) - 2016-10-18 17:40 +0200
Re: [REVIEW][PATCH] mm: Add a user_ns owner to mm_struct and fix ptrace_may_access Jann Horn <jann@thejh.net> - 2016-10-18 21:20 +0200
Re: [REVIEW][PATCH] mm: Add a user_ns owner to mm_struct and fix ptrace_may_access ebiederm@xmission.com (Eric W. Biederman) - 2016-10-18 23:10 +0200
[REVIEW][PATCH] exec: Don't exec files the userns root can not read. ebiederm@xmission.com (Eric W. Biederman) - 2016-10-18 23:20 +0200
Re: [REVIEW][PATCH] exec: Don't exec files the userns root can not read. Amir Goldstein <amir73il@gmail.com> - 2016-10-19 08:20 +0200
Re: [REVIEW][PATCH] exec: Don't exec files the userns root can not read. ebiederm@xmission.com (Eric W. Biederman) - 2016-10-19 17:10 +0200
Re: [REVIEW][PATCH] exec: Don't exec files the userns root can not read. ebiederm@xmission.com (Eric W. Biederman) - 2016-10-19 19:10 +0200
Re: [REVIEW][PATCH] exec: Don't exec files the userns root can not read. Andy Lutomirski <luto@amacapital.net> - 2016-10-19 17:40 +0200
Re: [REVIEW][PATCH] exec: Don't exec files the userns root can not read. ebiederm@xmission.com (Eric W. Biederman) - 2016-10-19 19:00 +0200
Re: [REVIEW][PATCH] exec: Don't exec files the userns root can not read. Jann Horn <jann@thejh.net> - 2016-10-19 19:30 +0200
Re: [REVIEW][PATCH] exec: Don't exec files the userns root can not read. Andy Lutomirski <luto@amacapital.net> - 2016-10-19 19:40 +0200
Re: [REVIEW][PATCH] exec: Don't exec files the userns root can not read. ebiederm@xmission.com (Eric W. Biederman) - 2016-10-19 20:00 +0200
Re: [REVIEW][PATCH] exec: Don't exec files the userns root can not read. Andy Lutomirski <luto@amacapital.net> - 2016-10-19 20:40 +0200
Re: [REVIEW][PATCH] exec: Don't exec files the userns root can not read. ebiederm@xmission.com (Eric W. Biederman) - 2016-10-19 23:30 +0200
Re: [REVIEW][PATCH] exec: Don't exec files the userns root can not read. Andy Lutomirski <luto@amacapital.net> - 2016-10-20 01:20 +0200
Re: [REVIEW][PATCH] mm: Add a user_ns owner to mm_struct and fix ptrace_may_access Michal Hocko <mhocko@kernel.org> - 2016-10-18 20:10 +0200
| From | Michal Hocko <mhocko@kernel.org> |
|---|---|
| Date | 2016-10-18 16:00 +0200 |
| Subject | Re: [REVIEW][PATCH] mm: Add a user_ns owner to mm_struct and fix ptrace_may_access |
| Message-ID | <stD5T-2pf-5@gated-at.bofh.it> |
On Mon 17-10-16 11:39:49, Eric W. Biederman wrote:
>
> During exec dumpable is cleared if the file that is being executed is
> not readable by the user executing the file. A bug in
> ptrace_may_access allows reading the file if the executable happens to
> enter into a subordinate user namespace (aka clone(CLONE_NEWUSER),
> unshare(CLONE_NEWUSER), or setns(fd, CLONE_NEWUSER).
>
> This problem is fixed with only necessary userspace breakage by adding
> a user namespace owner to mm_struct, captured at the time of exec,
> so it is clear in which user namespace CAP_SYS_PTRACE must be present
> in to be able to safely give read permission to the executable.
>
> The function ptrace_may_access is modified to verify that the ptracer
> has CAP_SYS_ADMIN in task->mm->user_ns instead of task->cred->user_ns.
> This ensures that if the task changes it's cred into a subordinate
> user namespace it does not become ptraceable.
I haven't studied your patch too deeply but one thing that immediately
raised a red flag was that mm might be shared between processes (aka
thread groups). What prevents those two to sit in different user
namespaces?
I am primarily asking because this generated a lot of headache for the
memcg handling as those processes might sit in different cgroups while
there is only one correct memcg for them which can disagree with the
cgroup associated with one of the processes.
> Cc: stable@vger.kernel.org
> Fixes: 8409cca70561 ("userns: allow ptrace from non-init user namespaces")
> Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
> ---
>
> It turns out that dumpable needs to be fixed to be user namespace
> aware to fix this issue. When this patch is ready I plan to place it in
> my userns tree and send it to Linus, hopefully for -rc2.
>
> include/linux/mm_types.h | 1 +
> kernel/fork.c | 9 ++++++---
> kernel/ptrace.c | 17 ++++++-----------
> mm/init-mm.c | 2 ++
> 4 files changed, 15 insertions(+), 14 deletions(-)
>
> diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h
> index 4a8acedf4b7d..08d947fc4c59 100644
> --- a/include/linux/mm_types.h
> +++ b/include/linux/mm_types.h
> @@ -473,6 +473,7 @@ struct mm_struct {
> */
> struct task_struct __rcu *owner;
> #endif
> + struct user_namespace *user_ns;
>
> /* store ref to file /proc/<pid>/exe symlink points to */
> struct file __rcu *exe_file;
> diff --git a/kernel/fork.c b/kernel/fork.c
> index 623259fc794d..fd85c68c2791 100644
> --- a/kernel/fork.c
> +++ b/kernel/fork.c
> @@ -742,7 +742,8 @@ static void mm_init_owner(struct mm_struct *mm, struct task_struct *p)
> #endif
> }
>
> -static struct mm_struct *mm_init(struct mm_struct *mm, struct task_struct *p)
> +static struct mm_struct *mm_init(struct mm_struct *mm, struct task_struct *p,
> + struct user_namespace *user_ns)
> {
> mm->mmap = NULL;
> mm->mm_rb = RB_ROOT;
> @@ -782,6 +783,7 @@ static struct mm_struct *mm_init(struct mm_struct *mm, struct task_struct *p)
> if (init_new_context(p, mm))
> goto fail_nocontext;
>
> + mm->user_ns = get_user_ns(user_ns);
> return mm;
>
> fail_nocontext:
> @@ -827,7 +829,7 @@ struct mm_struct *mm_alloc(void)
> return NULL;
>
> memset(mm, 0, sizeof(*mm));
> - return mm_init(mm, current);
> + return mm_init(mm, current, current_user_ns());
> }
>
> /*
> @@ -842,6 +844,7 @@ void __mmdrop(struct mm_struct *mm)
> destroy_context(mm);
> mmu_notifier_mm_destroy(mm);
> check_mm(mm);
> + put_user_ns(mm->user_ns);
> free_mm(mm);
> }
> EXPORT_SYMBOL_GPL(__mmdrop);
> @@ -1123,7 +1126,7 @@ static struct mm_struct *dup_mm(struct task_struct *tsk)
>
> memcpy(mm, oldmm, sizeof(*mm));
>
> - if (!mm_init(mm, tsk))
> + if (!mm_init(mm, tsk, mm->user_ns))
> goto fail_nomem;
>
> err = dup_mmap(mm, oldmm);
> diff --git a/kernel/ptrace.c b/kernel/ptrace.c
> index 2a99027312a6..f2d1b9afb3f8 100644
> --- a/kernel/ptrace.c
> +++ b/kernel/ptrace.c
> @@ -220,7 +220,7 @@ static int ptrace_has_cap(struct user_namespace *ns, unsigned int mode)
> static int __ptrace_may_access(struct task_struct *task, unsigned int mode)
> {
> const struct cred *cred = current_cred(), *tcred;
> - int dumpable = 0;
> + struct mm_struct *mm;
> kuid_t caller_uid;
> kgid_t caller_gid;
>
> @@ -271,16 +271,11 @@ static int __ptrace_may_access(struct task_struct *task, unsigned int mode)
> return -EPERM;
> ok:
> rcu_read_unlock();
> - smp_rmb();
> - if (task->mm)
> - dumpable = get_dumpable(task->mm);
> - rcu_read_lock();
> - if (dumpable != SUID_DUMP_USER &&
> - !ptrace_has_cap(__task_cred(task)->user_ns, mode)) {
> - rcu_read_unlock();
> - return -EPERM;
> - }
> - rcu_read_unlock();
> + mm = task->mm;
> + if (!mm ||
> + ((get_dumpable(mm) != SUID_DUMP_USER) &&
> + !ptrace_has_cap(mm->user_ns, mode)))
> + return -EPERM;
>
> return security_ptrace_access_check(task, mode);
> }
> diff --git a/mm/init-mm.c b/mm/init-mm.c
> index a56a851908d2..975e49f00f34 100644
> --- a/mm/init-mm.c
> +++ b/mm/init-mm.c
> @@ -6,6 +6,7 @@
> #include <linux/cpumask.h>
>
> #include <linux/atomic.h>
> +#include <linux/user_namespace.h>
> #include <asm/pgtable.h>
> #include <asm/mmu.h>
>
> @@ -21,5 +22,6 @@ struct mm_struct init_mm = {
> .mmap_sem = __RWSEM_INITIALIZER(init_mm.mmap_sem),
> .page_table_lock = __SPIN_LOCK_UNLOCKED(init_mm.page_table_lock),
> .mmlist = LIST_HEAD_INIT(init_mm.mmlist),
> + .user_ns = &init_user_ns,
> INIT_MM_CONTEXT(init_mm)
> };
> --
> 2.8.3
>
> --
> To unsubscribe, send a message with 'unsubscribe linux-mm' in
> the body to majordomo@kvack.org. For more info on Linux MM,
> see: http://www.linux-mm.org/ .
> Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
--
Michal Hocko
SUSE Labs
[toc] | [next] | [standalone]
| From | Jann Horn <jann@thejh.net> |
|---|---|
| Date | 2016-10-18 16:00 +0200 |
| Message-ID | <stD5U-2pf-23@gated-at.bofh.it> |
| In reply to | #1503007 |
[Multipart message — attachments visible in raw view] — view raw
On Tue, Oct 18, 2016 at 03:50:32PM +0200, Michal Hocko wrote: > On Mon 17-10-16 11:39:49, Eric W. Biederman wrote: > > > > During exec dumpable is cleared if the file that is being executed is > > not readable by the user executing the file. A bug in > > ptrace_may_access allows reading the file if the executable happens to > > enter into a subordinate user namespace (aka clone(CLONE_NEWUSER), > > unshare(CLONE_NEWUSER), or setns(fd, CLONE_NEWUSER). > > > > This problem is fixed with only necessary userspace breakage by adding > > a user namespace owner to mm_struct, captured at the time of exec, > > so it is clear in which user namespace CAP_SYS_PTRACE must be present > > in to be able to safely give read permission to the executable. > > > > The function ptrace_may_access is modified to verify that the ptracer > > has CAP_SYS_ADMIN in task->mm->user_ns instead of task->cred->user_ns. > > This ensures that if the task changes it's cred into a subordinate > > user namespace it does not become ptraceable. > > I haven't studied your patch too deeply but one thing that immediately > raised a red flag was that mm might be shared between processes (aka > thread groups). You're conflating things. Threads always share memory, but sharing memory doesn't imply being part of the same thread group. > What prevents those two to sit in different user > namespaces? For thread groups: You can't change user namespace in a thread group with more than one task. For shared mm: Yeah, I think that could happen - but it doesn't matter. The patch just needs the mm to determine the namespace in which the mm was created, and that's always the same for tasks that share mm.
[toc] | [prev] | [next] | [standalone]
| From | ebiederm@xmission.com (Eric W. Biederman) |
|---|---|
| Date | 2016-10-18 17:00 +0200 |
| Subject | Re: [REVIEW][PATCH] mm: Add a user_ns owner to mm_struct and fix ptrace_may_access |
| Message-ID | <stE1Y-35H-5@gated-at.bofh.it> |
| In reply to | #1503007 |
Michal Hocko <mhocko@kernel.org> writes: > On Mon 17-10-16 11:39:49, Eric W. Biederman wrote: >> >> During exec dumpable is cleared if the file that is being executed is >> not readable by the user executing the file. A bug in >> ptrace_may_access allows reading the file if the executable happens to >> enter into a subordinate user namespace (aka clone(CLONE_NEWUSER), >> unshare(CLONE_NEWUSER), or setns(fd, CLONE_NEWUSER). >> >> This problem is fixed with only necessary userspace breakage by adding >> a user namespace owner to mm_struct, captured at the time of exec, >> so it is clear in which user namespace CAP_SYS_PTRACE must be present >> in to be able to safely give read permission to the executable. >> >> The function ptrace_may_access is modified to verify that the ptracer >> has CAP_SYS_ADMIN in task->mm->user_ns instead of task->cred->user_ns. >> This ensures that if the task changes it's cred into a subordinate >> user namespace it does not become ptraceable. > > I haven't studied your patch too deeply but one thing that immediately > raised a red flag was that mm might be shared between processes (aka > thread groups). What prevents those two to sit in different user > namespaces? > > I am primarily asking because this generated a lot of headache for the > memcg handling as those processes might sit in different cgroups while > there is only one correct memcg for them which can disagree with the > cgroup associated with one of the processes. That is a legitimate concern, but I do not see any of those kinds of issues here. Part of the memcg pain comes from the fact that control groups are process centric, and part of the pain comes from the fact that it is possible to change control groups. What I am doing is making the mm owned by a user namespace (at creation time), and I am not allowing changes to that ownership. The credentials of the tasks that use that mm may be in the same user namespace or descendent user namespaces. The core goal is to enforce the unreadability of an mm when an non-readable file is executed. This is a time of mm creation property. The enforcement of which fits very well with the security/permission checking role of the user namespace. Could this use of mm->user_ns be extended for some kind of accounting/limiting in the future? Possibly. I can imagine a limit on the total number of page table entries a group of processes are allowed to have as being a sane kind of limit in this setting much like RLIMIT_AS is sane on a single mm level. Pages don't belong to mm's so I can't imagine anything like the memcg being built on this kind of infrastructure. Eric
[toc] | [prev] | [next] | [standalone]
| From | Jann Horn <jann@thejh.net> |
|---|---|
| Date | 2016-10-18 17:10 +0200 |
| Message-ID | <stEbE-3pl-37@gated-at.bofh.it> |
| In reply to | #1503072 |
[Multipart message — attachments visible in raw view] — view raw
On Tue, Oct 18, 2016 at 09:56:53AM -0500, Eric W. Biederman wrote: > Michal Hocko <mhocko@kernel.org> writes: > > > On Mon 17-10-16 11:39:49, Eric W. Biederman wrote: > >> > >> During exec dumpable is cleared if the file that is being executed is > >> not readable by the user executing the file. A bug in > >> ptrace_may_access allows reading the file if the executable happens to > >> enter into a subordinate user namespace (aka clone(CLONE_NEWUSER), > >> unshare(CLONE_NEWUSER), or setns(fd, CLONE_NEWUSER). > >> > >> This problem is fixed with only necessary userspace breakage by adding > >> a user namespace owner to mm_struct, captured at the time of exec, > >> so it is clear in which user namespace CAP_SYS_PTRACE must be present > >> in to be able to safely give read permission to the executable. > >> > >> The function ptrace_may_access is modified to verify that the ptracer > >> has CAP_SYS_ADMIN in task->mm->user_ns instead of task->cred->user_ns. > >> This ensures that if the task changes it's cred into a subordinate > >> user namespace it does not become ptraceable. > > > > I haven't studied your patch too deeply but one thing that immediately > > raised a red flag was that mm might be shared between processes (aka > > thread groups). What prevents those two to sit in different user > > namespaces? > > > > I am primarily asking because this generated a lot of headache for the > > memcg handling as those processes might sit in different cgroups while > > there is only one correct memcg for them which can disagree with the > > cgroup associated with one of the processes. > > That is a legitimate concern, but I do not see any of those kinds of > issues here. > > Part of the memcg pain comes from the fact that control groups are > process centric, and part of the pain comes from the fact that it is > possible to change control groups. What I am doing is making the mm > owned by a user namespace (at creation time), and I am not allowing > changes to that ownership. The credentials of the tasks that use that mm > may be in the same user namespace or descendent user namespaces. > > The core goal is to enforce the unreadability of an mm when an > non-readable file is executed. This is a time of mm creation property. > The enforcement of which fits very well with the security/permission > checking role of the user namespace. How is that going to work? I thought the core goal was better security for entering containers. If I want to dump a non-readable file, afaik, I can just make a new user namespace, then run the file in there and dump its memory. I guess you could fix that by entirely prohibiting the execution of a non-readable file whose owner UID is not mapped. (Adding more dumping restrictions wouldn't help much because you could still e.g. supply a malicious dynamic linker if you control the mount namespace.)
[toc] | [prev] | [next] | [standalone]
| From | ebiederm@xmission.com (Eric W. Biederman) |
|---|---|
| Date | 2016-10-18 17:40 +0200 |
| Subject | Re: [REVIEW][PATCH] mm: Add a user_ns owner to mm_struct and fix ptrace_may_access |
| Message-ID | <stEEF-3BE-29@gated-at.bofh.it> |
| In reply to | #1503088 |
Jann Horn <jann@thejh.net> writes: > On Tue, Oct 18, 2016 at 09:56:53AM -0500, Eric W. Biederman wrote: >> Michal Hocko <mhocko@kernel.org> writes: >> >> > On Mon 17-10-16 11:39:49, Eric W. Biederman wrote: >> >> >> >> During exec dumpable is cleared if the file that is being executed is >> >> not readable by the user executing the file. A bug in >> >> ptrace_may_access allows reading the file if the executable happens to >> >> enter into a subordinate user namespace (aka clone(CLONE_NEWUSER), >> >> unshare(CLONE_NEWUSER), or setns(fd, CLONE_NEWUSER). >> >> >> >> This problem is fixed with only necessary userspace breakage by adding >> >> a user namespace owner to mm_struct, captured at the time of exec, >> >> so it is clear in which user namespace CAP_SYS_PTRACE must be present >> >> in to be able to safely give read permission to the executable. >> >> >> >> The function ptrace_may_access is modified to verify that the ptracer >> >> has CAP_SYS_ADMIN in task->mm->user_ns instead of task->cred->user_ns. >> >> This ensures that if the task changes it's cred into a subordinate >> >> user namespace it does not become ptraceable. >> > >> > I haven't studied your patch too deeply but one thing that immediately >> > raised a red flag was that mm might be shared between processes (aka >> > thread groups). What prevents those two to sit in different user >> > namespaces? >> > >> > I am primarily asking because this generated a lot of headache for the >> > memcg handling as those processes might sit in different cgroups while >> > there is only one correct memcg for them which can disagree with the >> > cgroup associated with one of the processes. >> >> That is a legitimate concern, but I do not see any of those kinds of >> issues here. >> >> Part of the memcg pain comes from the fact that control groups are >> process centric, and part of the pain comes from the fact that it is >> possible to change control groups. What I am doing is making the mm >> owned by a user namespace (at creation time), and I am not allowing >> changes to that ownership. The credentials of the tasks that use that mm >> may be in the same user namespace or descendent user namespaces. >> >> The core goal is to enforce the unreadability of an mm when an >> non-readable file is executed. This is a time of mm creation property. >> The enforcement of which fits very well with the security/permission >> checking role of the user namespace. > > How is that going to work? I thought the core goal was better security for > entering containers. The better security when entering containers came from fixing the the check for unreadable files. Because that is fundamentally what the mm dumpable settings are for. > If I want to dump a non-readable file, afaik, I can just make a new user > namespace, then run the file in there and dump its memory. > I guess you could fix that by entirely prohibiting the execution of a > non-readable file whose owner UID is not mapped. (Adding more dumping > restrictions wouldn't help much because you could still e.g. supply a > malicious dynamic linker if you control the mount namespace.) That seems to be a part of this puzzle I have incompletely addressed, thank you. It looks like I need to change either the owning user namespace or fail the exec. Malicious dynamic linkers are doubly interesting. As mount name spaces are also owned if I have privileges I can address the possibility of a malicious dynamic linker that way. AKA who cares about the link if the owner of the mount namespace has permissions to read the file. I am going to look at failing the exec if the owning user namespace of the mm would not have permissions to read the file. That should just be a couple of lines of code and easy to maintain. Plus it does not appear that non-readable executables are particularly common. Eric
[toc] | [prev] | [next] | [standalone]
| From | Jann Horn <jann@thejh.net> |
|---|---|
| Date | 2016-10-18 21:20 +0200 |
| Message-ID | <stI5z-6a9-9@gated-at.bofh.it> |
| In reply to | #1503114 |
On Tue, Oct 18, 2016 at 10:35:23AM -0500, Eric W. Biederman wrote: > Jann Horn <jann@thejh.net> writes: > > > On Tue, Oct 18, 2016 at 09:56:53AM -0500, Eric W. Biederman wrote: > >> Michal Hocko <mhocko@kernel.org> writes: > >> > >> > On Mon 17-10-16 11:39:49, Eric W. Biederman wrote: > >> >> > >> >> During exec dumpable is cleared if the file that is being executed is > >> >> not readable by the user executing the file. A bug in > >> >> ptrace_may_access allows reading the file if the executable happens to > >> >> enter into a subordinate user namespace (aka clone(CLONE_NEWUSER), > >> >> unshare(CLONE_NEWUSER), or setns(fd, CLONE_NEWUSER). > >> >> > >> >> This problem is fixed with only necessary userspace breakage by adding > >> >> a user namespace owner to mm_struct, captured at the time of exec, > >> >> so it is clear in which user namespace CAP_SYS_PTRACE must be present > >> >> in to be able to safely give read permission to the executable. > >> >> > >> >> The function ptrace_may_access is modified to verify that the ptracer > >> >> has CAP_SYS_ADMIN in task->mm->user_ns instead of task->cred->user_ns. > >> >> This ensures that if the task changes it's cred into a subordinate > >> >> user namespace it does not become ptraceable. > >> > > >> > I haven't studied your patch too deeply but one thing that immediately > >> > raised a red flag was that mm might be shared between processes (aka > >> > thread groups). What prevents those two to sit in different user > >> > namespaces? > >> > > >> > I am primarily asking because this generated a lot of headache for the > >> > memcg handling as those processes might sit in different cgroups while > >> > there is only one correct memcg for them which can disagree with the > >> > cgroup associated with one of the processes. > >> > >> That is a legitimate concern, but I do not see any of those kinds of > >> issues here. > >> > >> Part of the memcg pain comes from the fact that control groups are > >> process centric, and part of the pain comes from the fact that it is > >> possible to change control groups. What I am doing is making the mm > >> owned by a user namespace (at creation time), and I am not allowing > >> changes to that ownership. The credentials of the tasks that use that mm > >> may be in the same user namespace or descendent user namespaces. > >> > >> The core goal is to enforce the unreadability of an mm when an > >> non-readable file is executed. This is a time of mm creation property. > >> The enforcement of which fits very well with the security/permission > >> checking role of the user namespace. > > > > How is that going to work? I thought the core goal was better security for > > entering containers. > > The better security when entering containers came from fixing the the > check for unreadable files. Because that is fundamentally what > the mm dumpable settings are for. Oh, interesting. > > If I want to dump a non-readable file, afaik, I can just make a new user > > namespace, then run the file in there and dump its memory. > > I guess you could fix that by entirely prohibiting the execution of a > > non-readable file whose owner UID is not mapped. (Adding more dumping > > restrictions wouldn't help much because you could still e.g. supply a > > malicious dynamic linker if you control the mount namespace.) > > That seems to be a part of this puzzle I have incompletely addressed, > thank you. > > It looks like I need to change either the owning user namespace or > fail the exec. Malicious dynamic linkers are doubly interesting. > > As mount name spaces are also owned if I have privileges I can address > the possibility of a malicious dynamic linker that way. AKA who cares > about the link if the owner of the mount namespace has permissions to > read the file. If you just check the owner of the mount namespace, someone could still use a user namespace to chroot() the process. That should also be sufficient to get the evil linker in. I think it really needs to be the user namespace of the executing process that's checked, not the user namespace associated with some mount namespace. > I am going to look at failing the exec if the owning user namespace > of the mm would not have permissions to read the file. That should just > be a couple of lines of code and easy to maintain. Plus it does not > appear that non-readable executables are particularly common. Hm. Yeah, I guess mode 04111 probably isn't sooo common. From a security perspective, I think that should work.
[toc] | [prev] | [next] | [standalone]
| From | ebiederm@xmission.com (Eric W. Biederman) |
|---|---|
| Date | 2016-10-18 23:10 +0200 |
| Subject | Re: [REVIEW][PATCH] mm: Add a user_ns owner to mm_struct and fix ptrace_may_access |
| Message-ID | <stJO2-7sS-41@gated-at.bofh.it> |
| In reply to | #1503304 |
Jann Horn <jann@thejh.net> writes: > On Tue, Oct 18, 2016 at 10:35:23AM -0500, Eric W. Biederman wrote: >> Jann Horn <jann@thejh.net> writes: >> >> > On Tue, Oct 18, 2016 at 09:56:53AM -0500, Eric W. Biederman wrote: >> >> Michal Hocko <mhocko@kernel.org> writes: >> >> >> >> > On Mon 17-10-16 11:39:49, Eric W. Biederman wrote: >> >> >> >> >> >> During exec dumpable is cleared if the file that is being executed is >> >> >> not readable by the user executing the file. A bug in >> >> >> ptrace_may_access allows reading the file if the executable happens to >> >> >> enter into a subordinate user namespace (aka clone(CLONE_NEWUSER), >> >> >> unshare(CLONE_NEWUSER), or setns(fd, CLONE_NEWUSER). >> >> >> >> >> >> This problem is fixed with only necessary userspace breakage by adding >> >> >> a user namespace owner to mm_struct, captured at the time of exec, >> >> >> so it is clear in which user namespace CAP_SYS_PTRACE must be present >> >> >> in to be able to safely give read permission to the executable. >> >> >> >> >> >> The function ptrace_may_access is modified to verify that the ptracer >> >> >> has CAP_SYS_ADMIN in task->mm->user_ns instead of task->cred->user_ns. >> >> >> This ensures that if the task changes it's cred into a subordinate >> >> >> user namespace it does not become ptraceable. >> >> > >> >> > I haven't studied your patch too deeply but one thing that immediately >> >> > raised a red flag was that mm might be shared between processes (aka >> >> > thread groups). What prevents those two to sit in different user >> >> > namespaces? >> >> > >> >> > I am primarily asking because this generated a lot of headache for the >> >> > memcg handling as those processes might sit in different cgroups while >> >> > there is only one correct memcg for them which can disagree with the >> >> > cgroup associated with one of the processes. >> >> >> >> That is a legitimate concern, but I do not see any of those kinds of >> >> issues here. >> >> >> >> Part of the memcg pain comes from the fact that control groups are >> >> process centric, and part of the pain comes from the fact that it is >> >> possible to change control groups. What I am doing is making the mm >> >> owned by a user namespace (at creation time), and I am not allowing >> >> changes to that ownership. The credentials of the tasks that use that mm >> >> may be in the same user namespace or descendent user namespaces. >> >> >> >> The core goal is to enforce the unreadability of an mm when an >> >> non-readable file is executed. This is a time of mm creation property. >> >> The enforcement of which fits very well with the security/permission >> >> checking role of the user namespace. >> > >> > How is that going to work? I thought the core goal was better security for >> > entering containers. >> >> The better security when entering containers came from fixing the the >> check for unreadable files. Because that is fundamentally what >> the mm dumpable settings are for. > > Oh, interesting. > > >> > If I want to dump a non-readable file, afaik, I can just make a new user >> > namespace, then run the file in there and dump its memory. >> > I guess you could fix that by entirely prohibiting the execution of a >> > non-readable file whose owner UID is not mapped. (Adding more dumping >> > restrictions wouldn't help much because you could still e.g. supply a >> > malicious dynamic linker if you control the mount namespace.) >> >> That seems to be a part of this puzzle I have incompletely addressed, >> thank you. >> >> It looks like I need to change either the owning user namespace or >> fail the exec. Malicious dynamic linkers are doubly interesting. >> >> As mount name spaces are also owned if I have privileges I can address >> the possibility of a malicious dynamic linker that way. AKA who cares >> about the link if the owner of the mount namespace has permissions to >> read the file. > > If you just check the owner of the mount namespace, someone could still > use a user namespace to chroot() the process. That should also be > sufficient to get the evil linker in. I think it really needs to be the > user namespace of the executing process that's checked, not the user > namespace associated with some mount namespace. Something. I will just note that this is hard to analyze and theoretically possible for now, since I don't intend to pursue that solution. >> I am going to look at failing the exec if the owning user namespace >> of the mm would not have permissions to read the file. That should just >> be a couple of lines of code and easy to maintain. Plus it does not >> appear that non-readable executables are particularly common. > > Hm. Yeah, I guess mode 04111 probably isn't sooo common. > From a security perspective, I think that should work. Well there is at least one common distro that installs sudo that way so I would not say uncommon. But we already ignore the suid and sgid bit when executing such executables as without having the uid or gid mapping into a user namespace suid and sgid can not be supported. So the only case that could cause a real regression/loss of functionality is if there are unreadable executables without the suid or sgid bit set. I can't find any of those. Patch for this second bug in a moment. Eric
[toc] | [prev] | [next] | [standalone]
| From | ebiederm@xmission.com (Eric W. Biederman) |
|---|---|
| Date | 2016-10-18 23:20 +0200 |
| Subject | [REVIEW][PATCH] exec: Don't exec files the userns root can not read. |
| Message-ID | <stJXI-7yE-13@gated-at.bofh.it> |
| In reply to | #1503356 |
When the user namespace support was merged the need to prevent
ptracing an executable that is not readable was overlooked.
Correct this oversight by not letting exec succeed if during exec an
executable is not readable and the current user namespace capabilities
do not apply to the executable's file.
While it happens that distros install some files setuid and
non-readable I have not found any executable files just installed
non-readalbe. Executables that are setuid to a user not mapped in a
user namespace are worthless, so I don't expect this to introduce
any problems in practice.
There may be a way to allow this execution to happen by setting
mm->user_ns to a more privileged user namespace and watching out for
the possibility of using dynamic linkers or other shared libraries
that the kernel loads into the mm to bypass the read-only
restriction. But the analysis is more difficult and it would
require more code churn so I don't think the effort is worth it.
Cc: stable@vger.kernel.org
Reported-by: Jann Horn <jann@thejh.net>
Fixes: 9e4a36ece652 ("userns: Fail exec for suid and sgid binaries with ids outside our user namespace.")
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
---
Tossing this out for review in case I missed something silly but this
patch seems pretty trivial.
arch/x86/ia32/ia32_aout.c | 4 +++-
fs/binfmt_aout.c | 4 +++-
fs/binfmt_elf.c | 4 +++-
fs/binfmt_elf_fdpic.c | 4 +++-
fs/binfmt_flat.c | 4 +++-
fs/exec.c | 19 ++++++++++++++++---
include/linux/binfmts.h | 6 +++++-
7 files changed, 36 insertions(+), 9 deletions(-)
diff --git a/arch/x86/ia32/ia32_aout.c b/arch/x86/ia32/ia32_aout.c
index cb26f18d43af..7ad20dedd929 100644
--- a/arch/x86/ia32/ia32_aout.c
+++ b/arch/x86/ia32/ia32_aout.c
@@ -294,7 +294,9 @@ static int load_aout_binary(struct linux_binprm *bprm)
set_personality(PER_LINUX);
set_personality_ia32(false);
- setup_new_exec(bprm);
+ retval = setup_new_exec(bprm);
+ if (retval)
+ return retval;
regs->cs = __USER32_CS;
regs->r8 = regs->r9 = regs->r10 = regs->r11 = regs->r12 =
diff --git a/fs/binfmt_aout.c b/fs/binfmt_aout.c
index ae1b5404fced..b7b8aa03ccd0 100644
--- a/fs/binfmt_aout.c
+++ b/fs/binfmt_aout.c
@@ -242,7 +242,9 @@ static int load_aout_binary(struct linux_binprm * bprm)
#else
set_personality(PER_LINUX);
#endif
- setup_new_exec(bprm);
+ retval = setup_new_exec(bprm);
+ if (retval)
+ return retval;
current->mm->end_code = ex.a_text +
(current->mm->start_code = N_TXTADDR(ex));
diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c
index 2472af2798c7..423fece0b8c4 100644
--- a/fs/binfmt_elf.c
+++ b/fs/binfmt_elf.c
@@ -852,7 +852,9 @@ static int load_elf_binary(struct linux_binprm *bprm)
if (!(current->personality & ADDR_NO_RANDOMIZE) && randomize_va_space)
current->flags |= PF_RANDOMIZE;
- setup_new_exec(bprm);
+ retval = setup_new_exec(bprm);
+ if (retval)
+ goto out_free_dentry;
install_exec_creds(bprm);
/* Do this so that we can load the interpreter, if need be. We will
diff --git a/fs/binfmt_elf_fdpic.c b/fs/binfmt_elf_fdpic.c
index 464a972e88c1..d3099caff96d 100644
--- a/fs/binfmt_elf_fdpic.c
+++ b/fs/binfmt_elf_fdpic.c
@@ -352,7 +352,9 @@ static int load_elf_fdpic_binary(struct linux_binprm *bprm)
if (elf_read_implies_exec(&exec_params.hdr, executable_stack))
current->personality |= READ_IMPLIES_EXEC;
- setup_new_exec(bprm);
+ retval = setup_new_exec(bprm);
+ if (retval)
+ goto error;
set_binfmt(&elf_fdpic_format);
diff --git a/fs/binfmt_flat.c b/fs/binfmt_flat.c
index 9b2917a30294..25ca68940ad4 100644
--- a/fs/binfmt_flat.c
+++ b/fs/binfmt_flat.c
@@ -524,7 +524,9 @@ static int load_flat_file(struct linux_binprm *bprm,
/* OK, This is the point of no return */
set_personality(PER_LINUX_32BIT);
- setup_new_exec(bprm);
+ ret = setup_new_exec(bprm);
+ if (ret)
+ goto err;
}
/*
diff --git a/fs/exec.c b/fs/exec.c
index 6fcfb3f7b137..f724ed94ba7a 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -1270,12 +1270,21 @@ EXPORT_SYMBOL(flush_old_exec);
void would_dump(struct linux_binprm *bprm, struct file *file)
{
- if (inode_permission(file_inode(file), MAY_READ) < 0)
+ struct inode *inode = file_inode(file);
+ if (inode_permission(inode, MAY_READ) < 0) {
+ struct user_namespace *user_ns = current->mm->user_ns;
bprm->interp_flags |= BINPRM_FLAGS_ENFORCE_NONDUMP;
+
+ /* May the user_ns root read the executable? */
+ if (!kuid_has_mapping(user_ns, inode->i_uid) ||
+ !kgid_has_mapping(user_ns, inode->i_gid)) {
+ bprm->interp_flags |= BINPRM_FLAGS_EXEC_INACCESSIBLE;
+ }
+ }
}
EXPORT_SYMBOL(would_dump);
-void setup_new_exec(struct linux_binprm * bprm)
+int setup_new_exec(struct linux_binprm * bprm)
{
arch_pick_mmap_layout(current->mm);
@@ -1296,12 +1305,15 @@ void setup_new_exec(struct linux_binprm * bprm)
*/
current->mm->task_size = TASK_SIZE;
+ would_dump(bprm, bprm->file);
+ if (bprm->interp_flags & BINPRM_FLAGS_EXEC_INACCESSIBLE)
+ return -EPERM;
+
/* install the new credentials */
if (!uid_eq(bprm->cred->uid, current_euid()) ||
!gid_eq(bprm->cred->gid, current_egid())) {
current->pdeath_signal = 0;
} else {
- would_dump(bprm, bprm->file);
if (bprm->interp_flags & BINPRM_FLAGS_ENFORCE_NONDUMP)
set_dumpable(current->mm, suid_dumpable);
}
@@ -1311,6 +1323,7 @@ void setup_new_exec(struct linux_binprm * bprm)
current->self_exec_id++;
flush_signal_handlers(current, 0);
do_close_on_exec(current->files);
+ return 0;
}
EXPORT_SYMBOL(setup_new_exec);
diff --git a/include/linux/binfmts.h b/include/linux/binfmts.h
index 1303b570b18c..8e5fb9eca2ee 100644
--- a/include/linux/binfmts.h
+++ b/include/linux/binfmts.h
@@ -57,6 +57,10 @@ struct linux_binprm {
#define BINPRM_FLAGS_PATH_INACCESSIBLE_BIT 2
#define BINPRM_FLAGS_PATH_INACCESSIBLE (1 << BINPRM_FLAGS_PATH_INACCESSIBLE_BIT)
+/* executable is inaccessible for performing exec */
+#define BINPRM_FLAGS_EXEC_INACCESSIBLE_BIT 3
+#define BINPRM_FLAGS_EXEC_INACCESSIBLE (1 << BINPRM_FLAGS_EXEC_INACCESSIBLE_BIT)
+
/* Function parameter for binfmt->coredump */
struct coredump_params {
const siginfo_t *siginfo;
@@ -100,7 +104,7 @@ extern int prepare_binprm(struct linux_binprm *);
extern int __must_check remove_arg_zero(struct linux_binprm *);
extern int search_binary_handler(struct linux_binprm *);
extern int flush_old_exec(struct linux_binprm * bprm);
-extern void setup_new_exec(struct linux_binprm * bprm);
+extern int setup_new_exec(struct linux_binprm * bprm);
extern void would_dump(struct linux_binprm *, struct file *);
extern int suid_dumpable;
--
2.8.3
[toc] | [prev] | [next] | [standalone]
| From | Amir Goldstein <amir73il@gmail.com> |
|---|---|
| Date | 2016-10-19 08:20 +0200 |
| Subject | Re: [REVIEW][PATCH] exec: Don't exec files the userns root can not read. |
| Message-ID | <stSoh-5BC-9@gated-at.bofh.it> |
| In reply to | #1503372 |
On Wed, Oct 19, 2016 at 12:15 AM, Eric W. Biederman
<ebiederm@xmission.com> wrote:
>
> When the user namespace support was merged the need to prevent
> ptracing an executable that is not readable was overlooked.
>
> Correct this oversight by not letting exec succeed if during exec an
> executable is not readable and the current user namespace capabilities
> do not apply to the executable's file.
>
> While it happens that distros install some files setuid and
> non-readable I have not found any executable files just installed
> non-readalbe. Executables that are setuid to a user not mapped in a
> user namespace are worthless, so I don't expect this to introduce
> any problems in practice.
>
> There may be a way to allow this execution to happen by setting
> mm->user_ns to a more privileged user namespace and watching out for
> the possibility of using dynamic linkers or other shared libraries
> that the kernel loads into the mm to bypass the read-only
> restriction. But the analysis is more difficult and it would
> require more code churn so I don't think the effort is worth it.
>
> Cc: stable@vger.kernel.org
> Reported-by: Jann Horn <jann@thejh.net>
> Fixes: 9e4a36ece652 ("userns: Fail exec for suid and sgid binaries with ids outside our user namespace.")
> Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
> ---
>
> Tossing this out for review in case I missed something silly but this
> patch seems pretty trivial.
>
> arch/x86/ia32/ia32_aout.c | 4 +++-
> fs/binfmt_aout.c | 4 +++-
> fs/binfmt_elf.c | 4 +++-
> fs/binfmt_elf_fdpic.c | 4 +++-
> fs/binfmt_flat.c | 4 +++-
> fs/exec.c | 19 ++++++++++++++++---
> include/linux/binfmts.h | 6 +++++-
> 7 files changed, 36 insertions(+), 9 deletions(-)
>
> diff --git a/arch/x86/ia32/ia32_aout.c b/arch/x86/ia32/ia32_aout.c
> index cb26f18d43af..7ad20dedd929 100644
> --- a/arch/x86/ia32/ia32_aout.c
> +++ b/arch/x86/ia32/ia32_aout.c
> @@ -294,7 +294,9 @@ static int load_aout_binary(struct linux_binprm *bprm)
> set_personality(PER_LINUX);
> set_personality_ia32(false);
>
> - setup_new_exec(bprm);
> + retval = setup_new_exec(bprm);
> + if (retval)
> + return retval;
>
> regs->cs = __USER32_CS;
> regs->r8 = regs->r9 = regs->r10 = regs->r11 = regs->r12 =
> diff --git a/fs/binfmt_aout.c b/fs/binfmt_aout.c
> index ae1b5404fced..b7b8aa03ccd0 100644
> --- a/fs/binfmt_aout.c
> +++ b/fs/binfmt_aout.c
> @@ -242,7 +242,9 @@ static int load_aout_binary(struct linux_binprm * bprm)
> #else
> set_personality(PER_LINUX);
> #endif
> - setup_new_exec(bprm);
> + retval = setup_new_exec(bprm);
> + if (retval)
> + return retval;
>
> current->mm->end_code = ex.a_text +
> (current->mm->start_code = N_TXTADDR(ex));
> diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c
> index 2472af2798c7..423fece0b8c4 100644
> --- a/fs/binfmt_elf.c
> +++ b/fs/binfmt_elf.c
> @@ -852,7 +852,9 @@ static int load_elf_binary(struct linux_binprm *bprm)
> if (!(current->personality & ADDR_NO_RANDOMIZE) && randomize_va_space)
> current->flags |= PF_RANDOMIZE;
>
> - setup_new_exec(bprm);
> + retval = setup_new_exec(bprm);
> + if (retval)
> + goto out_free_dentry;
> install_exec_creds(bprm);
>
> /* Do this so that we can load the interpreter, if need be. We will
> diff --git a/fs/binfmt_elf_fdpic.c b/fs/binfmt_elf_fdpic.c
> index 464a972e88c1..d3099caff96d 100644
> --- a/fs/binfmt_elf_fdpic.c
> +++ b/fs/binfmt_elf_fdpic.c
> @@ -352,7 +352,9 @@ static int load_elf_fdpic_binary(struct linux_binprm *bprm)
> if (elf_read_implies_exec(&exec_params.hdr, executable_stack))
> current->personality |= READ_IMPLIES_EXEC;
>
> - setup_new_exec(bprm);
> + retval = setup_new_exec(bprm);
> + if (retval)
> + goto error;
>
> set_binfmt(&elf_fdpic_format);
>
> diff --git a/fs/binfmt_flat.c b/fs/binfmt_flat.c
> index 9b2917a30294..25ca68940ad4 100644
> --- a/fs/binfmt_flat.c
> +++ b/fs/binfmt_flat.c
> @@ -524,7 +524,9 @@ static int load_flat_file(struct linux_binprm *bprm,
>
> /* OK, This is the point of no return */
> set_personality(PER_LINUX_32BIT);
> - setup_new_exec(bprm);
> + ret = setup_new_exec(bprm);
> + if (ret)
> + goto err;
> }
>
> /*
> diff --git a/fs/exec.c b/fs/exec.c
> index 6fcfb3f7b137..f724ed94ba7a 100644
> --- a/fs/exec.c
> +++ b/fs/exec.c
> @@ -1270,12 +1270,21 @@ EXPORT_SYMBOL(flush_old_exec);
>
> void would_dump(struct linux_binprm *bprm, struct file *file)
> {
> - if (inode_permission(file_inode(file), MAY_READ) < 0)
> + struct inode *inode = file_inode(file);
> + if (inode_permission(inode, MAY_READ) < 0) {
> + struct user_namespace *user_ns = current->mm->user_ns;
> bprm->interp_flags |= BINPRM_FLAGS_ENFORCE_NONDUMP;
> +
> + /* May the user_ns root read the executable? */
> + if (!kuid_has_mapping(user_ns, inode->i_uid) ||
> + !kgid_has_mapping(user_ns, inode->i_gid)) {
> + bprm->interp_flags |= BINPRM_FLAGS_EXEC_INACCESSIBLE;
> + }
This feels like it should belong inside
inode_permission(file_inode(file), MAY_EXEC)
which hopefully should be checked long before getting here??
> + }
> }
> EXPORT_SYMBOL(would_dump);
>
> -void setup_new_exec(struct linux_binprm * bprm)
> +int setup_new_exec(struct linux_binprm * bprm)
> {
> arch_pick_mmap_layout(current->mm);
>
> @@ -1296,12 +1305,15 @@ void setup_new_exec(struct linux_binprm * bprm)
> */
> current->mm->task_size = TASK_SIZE;
>
> + would_dump(bprm, bprm->file);
> + if (bprm->interp_flags & BINPRM_FLAGS_EXEC_INACCESSIBLE)
> + return -EPERM;
> +
> /* install the new credentials */
> if (!uid_eq(bprm->cred->uid, current_euid()) ||
> !gid_eq(bprm->cred->gid, current_egid())) {
> current->pdeath_signal = 0;
> } else {
> - would_dump(bprm, bprm->file);
> if (bprm->interp_flags & BINPRM_FLAGS_ENFORCE_NONDUMP)
> set_dumpable(current->mm, suid_dumpable);
> }
> @@ -1311,6 +1323,7 @@ void setup_new_exec(struct linux_binprm * bprm)
> current->self_exec_id++;
> flush_signal_handlers(current, 0);
> do_close_on_exec(current->files);
> + return 0;
> }
> EXPORT_SYMBOL(setup_new_exec);
>
> diff --git a/include/linux/binfmts.h b/include/linux/binfmts.h
> index 1303b570b18c..8e5fb9eca2ee 100644
> --- a/include/linux/binfmts.h
> +++ b/include/linux/binfmts.h
> @@ -57,6 +57,10 @@ struct linux_binprm {
> #define BINPRM_FLAGS_PATH_INACCESSIBLE_BIT 2
> #define BINPRM_FLAGS_PATH_INACCESSIBLE (1 << BINPRM_FLAGS_PATH_INACCESSIBLE_BIT)
>
> +/* executable is inaccessible for performing exec */
> +#define BINPRM_FLAGS_EXEC_INACCESSIBLE_BIT 3
> +#define BINPRM_FLAGS_EXEC_INACCESSIBLE (1 << BINPRM_FLAGS_EXEC_INACCESSIBLE_BIT)
> +
> /* Function parameter for binfmt->coredump */
> struct coredump_params {
> const siginfo_t *siginfo;
> @@ -100,7 +104,7 @@ extern int prepare_binprm(struct linux_binprm *);
> extern int __must_check remove_arg_zero(struct linux_binprm *);
> extern int search_binary_handler(struct linux_binprm *);
> extern int flush_old_exec(struct linux_binprm * bprm);
> -extern void setup_new_exec(struct linux_binprm * bprm);
> +extern int setup_new_exec(struct linux_binprm * bprm);
> extern void would_dump(struct linux_binprm *, struct file *);
>
> extern int suid_dumpable;
> --
> 2.8.3
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
[toc] | [prev] | [next] | [standalone]
| From | ebiederm@xmission.com (Eric W. Biederman) |
|---|---|
| Date | 2016-10-19 17:10 +0200 |
| Subject | Re: [REVIEW][PATCH] exec: Don't exec files the userns root can not read. |
| Message-ID | <su0Fc-2Wq-45@gated-at.bofh.it> |
| In reply to | #1503571 |
Amir Goldstein <amir73il@gmail.com> writes:
>> diff --git a/fs/exec.c b/fs/exec.c
>> index 6fcfb3f7b137..f724ed94ba7a 100644
>> --- a/fs/exec.c
>> +++ b/fs/exec.c
>> @@ -1270,12 +1270,21 @@ EXPORT_SYMBOL(flush_old_exec);
>>
>> void would_dump(struct linux_binprm *bprm, struct file *file)
>> {
>> - if (inode_permission(file_inode(file), MAY_READ) < 0)
>> + struct inode *inode = file_inode(file);
>> + if (inode_permission(inode, MAY_READ) < 0) {
>> + struct user_namespace *user_ns = current->mm->user_ns;
>> bprm->interp_flags |= BINPRM_FLAGS_ENFORCE_NONDUMP;
>> +
>> + /* May the user_ns root read the executable? */
>> + if (!kuid_has_mapping(user_ns, inode->i_uid) ||
>> + !kgid_has_mapping(user_ns, inode->i_gid)) {
>> + bprm->interp_flags |= BINPRM_FLAGS_EXEC_INACCESSIBLE;
>> + }
>
> This feels like it should belong inside
> inode_permission(file_inode(file), MAY_EXEC)
> which hopefully should be checked long before getting here??
It is the active ingredient in capable_wrt_inode_uidgid and is indeed
inside of inode_permission.
What I am testing for here is if I have a process with a full
set of capabilities in current->mm->user_ns will the inode be readable.
I can see an argument for calling prepare_creds stuffing the new cred
full of capabilities. Calling override_cred. Calling inode_permission,
restoring the credentials. But it seems very much like overkill and
more error prone because of the more code involved.
So I have done the simple thing that doesn't hide what is really going on.
Eric
[toc] | [prev] | [next] | [standalone]
| From | ebiederm@xmission.com (Eric W. Biederman) |
|---|---|
| Date | 2016-10-19 19:10 +0200 |
| Subject | Re: [REVIEW][PATCH] exec: Don't exec files the userns root can not read. |
| Message-ID | <su2xj-4eW-11@gated-at.bofh.it> |
| In reply to | #1503821 |
ebiederm@xmission.com (Eric W. Biederman) writes:
> Amir Goldstein <amir73il@gmail.com> writes:
>
>>> diff --git a/fs/exec.c b/fs/exec.c
>>> index 6fcfb3f7b137..f724ed94ba7a 100644
>>> --- a/fs/exec.c
>>> +++ b/fs/exec.c
>>> @@ -1270,12 +1270,21 @@ EXPORT_SYMBOL(flush_old_exec);
>>>
>>> void would_dump(struct linux_binprm *bprm, struct file *file)
>>> {
>>> - if (inode_permission(file_inode(file), MAY_READ) < 0)
>>> + struct inode *inode = file_inode(file);
>>> + if (inode_permission(inode, MAY_READ) < 0) {
>>> + struct user_namespace *user_ns = current->mm->user_ns;
>>> bprm->interp_flags |= BINPRM_FLAGS_ENFORCE_NONDUMP;
>>> +
>>> + /* May the user_ns root read the executable? */
>>> + if (!kuid_has_mapping(user_ns, inode->i_uid) ||
>>> + !kgid_has_mapping(user_ns, inode->i_gid)) {
>>> + bprm->interp_flags |= BINPRM_FLAGS_EXEC_INACCESSIBLE;
>>> + }
>>
>> This feels like it should belong inside
>> inode_permission(file_inode(file), MAY_EXEC)
>> which hopefully should be checked long before getting here??
>
> It is the active ingredient in capable_wrt_inode_uidgid and is indeed
> inside of inode_permission.
>
> What I am testing for here is if I have a process with a full
> set of capabilities in current->mm->user_ns will the inode be readable.
>
> I can see an argument for calling prepare_creds stuffing the new cred
> full of capabilities. Calling override_cred. Calling inode_permission,
> restoring the credentials. But it seems very much like overkill and
> more error prone because of the more code involved.
>
> So I have done the simple thing that doesn't hide what is really going on.
At the same time I can see the addition of a helper function
bool ns_inode(struct user_namespace *user_ns, struct inode *inode)
{
return kuid_has_mapping(user_ns, inode->i_uid) &&
kgid_has_mapping(user_ns, inode->i_gid);
}
That abstracts out the concept instead of open codes it.
Eric
[toc] | [prev] | [next] | [standalone]
| From | Andy Lutomirski <luto@amacapital.net> |
|---|---|
| Date | 2016-10-19 17:40 +0200 |
| Subject | Re: [REVIEW][PATCH] exec: Don't exec files the userns root can not read. |
| Message-ID | <su18e-37s-49@gated-at.bofh.it> |
| In reply to | #1503372 |
On Tue, Oct 18, 2016 at 2:15 PM, Eric W. Biederman <ebiederm@xmission.com> wrote: > > When the user namespace support was merged the need to prevent > ptracing an executable that is not readable was overlooked. Before getting too excited about this fix, isn't there a much bigger hole that's been there forever? Simply ptrace yourself, exec the program, and then dump the program out. A program that really wants to be unreadable should have a stub: the stub is setuid and readable, but all the stub does is to exec the real program, and the real program should have mode 0500 or similar. ISTM the "right" check would be to enforce that the program's new creds can read the program, but that will break backwards compatibility. --Andy
[toc] | [prev] | [next] | [standalone]
| From | ebiederm@xmission.com (Eric W. Biederman) |
|---|---|
| Date | 2016-10-19 19:00 +0200 |
| Subject | Re: [REVIEW][PATCH] exec: Don't exec files the userns root can not read. |
| Message-ID | <su2nE-3Wn-71@gated-at.bofh.it> |
| In reply to | #1503936 |
Andy Lutomirski <luto@amacapital.net> writes: > On Tue, Oct 18, 2016 at 2:15 PM, Eric W. Biederman > <ebiederm@xmission.com> wrote: >> >> When the user namespace support was merged the need to prevent >> ptracing an executable that is not readable was overlooked. > > Before getting too excited about this fix, isn't there a much bigger > hole that's been there forever? In this case it was a newish hole (2011) that the user namespace support added that I am closing. I am not super excited but I figure it is useful to make the kernel semantics at least as secure as they were before. > Simply ptrace yourself, exec the > program, and then dump the program out. A program that really wants > to be unreadable should have a stub: the stub is setuid and readable, > but all the stub does is to exec the real program, and the real > program should have mode 0500 or similar. > > ISTM the "right" check would be to enforce that the program's new > creds can read the program, but that will break backwards > compatibility. Last I looked I had the impression that exec of a setuid program kills the ptrace. If we are talking about a exec of a simple unreadable executable (aka something that sets undumpable but is not setuid or setgid). Then I agree it should break the ptrace as well and since those programs are as rare as hens teeth I don't see any problem with changing the ptrace behavior in that case. Eric
[toc] | [prev] | [next] | [standalone]
| From | Jann Horn <jann@thejh.net> |
|---|---|
| Date | 2016-10-19 19:30 +0200 |
| Subject | Re: [REVIEW][PATCH] exec: Don't exec files the userns root can not read. |
| Message-ID | <su2QF-4lW-15@gated-at.bofh.it> |
| In reply to | #1504141 |
On Wed, Oct 19, 2016 at 11:52:50AM -0500, Eric W. Biederman wrote: > Andy Lutomirski <luto@amacapital.net> writes: > > Simply ptrace yourself, exec the > > program, and then dump the program out. A program that really wants > > to be unreadable should have a stub: the stub is setuid and readable, > > but all the stub does is to exec the real program, and the real > > program should have mode 0500 or similar. > > > > ISTM the "right" check would be to enforce that the program's new > > creds can read the program, but that will break backwards > > compatibility. > > Last I looked I had the impression that exec of a setuid program kills > the ptrace. > > If we are talking about a exec of a simple unreadable executable (aka > something that sets undumpable but is not setuid or setgid). Then I > agree it should break the ptrace as well and since those programs are as > rare as hens teeth I don't see any problem with changing the ptrace behavior > in that case. Nope. check_unsafe_exec() sets LSM_UNSAFE_* flags in bprm->unsafe, and then the flags are checked by the LSMs and cap_bprm_set_creds() in commoncap.c. cap_bprm_set_creds() just degrades the execution to a non-setuid-ish one, and e.g. ptracers stay attached. Same thing happens if the fs struct is shared with another process or if NO_NEW_PRIVS is active. (Actually, it's still a bit like normal setuid execution: IIRC AT_SECURE stays active, and the resulting process still won't be dumpable, so it's not possible for a *new* ptracer to attach afterwards. But this is just from memory, I'm not entirely sure.)
[toc] | [prev] | [next] | [standalone]
| From | Andy Lutomirski <luto@amacapital.net> |
|---|---|
| Date | 2016-10-19 19:40 +0200 |
| Subject | Re: [REVIEW][PATCH] exec: Don't exec files the userns root can not read. |
| Message-ID | <su30l-4pj-13@gated-at.bofh.it> |
| In reply to | #1504159 |
On Wed, Oct 19, 2016 at 10:29 AM, Jann Horn <jann@thejh.net> wrote: > On Wed, Oct 19, 2016 at 11:52:50AM -0500, Eric W. Biederman wrote: >> Andy Lutomirski <luto@amacapital.net> writes: >> > Simply ptrace yourself, exec the >> > program, and then dump the program out. A program that really wants >> > to be unreadable should have a stub: the stub is setuid and readable, >> > but all the stub does is to exec the real program, and the real >> > program should have mode 0500 or similar. >> > >> > ISTM the "right" check would be to enforce that the program's new >> > creds can read the program, but that will break backwards >> > compatibility. >> >> Last I looked I had the impression that exec of a setuid program kills >> the ptrace. >> >> If we are talking about a exec of a simple unreadable executable (aka >> something that sets undumpable but is not setuid or setgid). Then I >> agree it should break the ptrace as well and since those programs are as >> rare as hens teeth I don't see any problem with changing the ptrace behavior >> in that case. > > Nope. check_unsafe_exec() sets LSM_UNSAFE_* flags in bprm->unsafe, and then > the flags are checked by the LSMs and cap_bprm_set_creds() in commoncap.c. > cap_bprm_set_creds() just degrades the execution to a non-setuid-ish one, > and e.g. ptracers stay attached. I think you're right. I ought to be completely sure because I rewrote that code back in 2005 or so back when I thought kernel programming was only for the cool kids. It was probably my first kernel patch ever and it closed an awkward-to-exploit root hole. But it's been a while. (Too bad my second (IIRC) kernel patch was more mundane and fixed the mute button on "new" Lenovo X60-era laptops and spend several years in limbo...) --Andy
[toc] | [prev] | [next] | [standalone]
| From | ebiederm@xmission.com (Eric W. Biederman) |
|---|---|
| Date | 2016-10-19 20:00 +0200 |
| Subject | Re: [REVIEW][PATCH] exec: Don't exec files the userns root can not read. |
| Message-ID | <su3jH-4wR-3@gated-at.bofh.it> |
| In reply to | #1504173 |
Andy Lutomirski <luto@amacapital.net> writes: > On Wed, Oct 19, 2016 at 10:29 AM, Jann Horn <jann@thejh.net> wrote: >> On Wed, Oct 19, 2016 at 11:52:50AM -0500, Eric W. Biederman wrote: >>> Andy Lutomirski <luto@amacapital.net> writes: >>> > Simply ptrace yourself, exec the >>> > program, and then dump the program out. A program that really wants >>> > to be unreadable should have a stub: the stub is setuid and readable, >>> > but all the stub does is to exec the real program, and the real >>> > program should have mode 0500 or similar. >>> > >>> > ISTM the "right" check would be to enforce that the program's new >>> > creds can read the program, but that will break backwards >>> > compatibility. >>> >>> Last I looked I had the impression that exec of a setuid program kills >>> the ptrace. >>> >>> If we are talking about a exec of a simple unreadable executable (aka >>> something that sets undumpable but is not setuid or setgid). Then I >>> agree it should break the ptrace as well and since those programs are as >>> rare as hens teeth I don't see any problem with changing the ptrace behavior >>> in that case. >> >> Nope. check_unsafe_exec() sets LSM_UNSAFE_* flags in bprm->unsafe, and then >> the flags are checked by the LSMs and cap_bprm_set_creds() in commoncap.c. >> cap_bprm_set_creds() just degrades the execution to a non-setuid-ish one, >> and e.g. ptracers stay attached. > > I think you're right. I ought to be completely sure because I rewrote > that code back in 2005 or so back when I thought kernel programming > was only for the cool kids. It was probably my first kernel patch > ever and it closed an awkward-to-exploit root hole. But it's been a > while. (Too bad my second (IIRC) kernel patch was more mundane and > fixed the mute button on "new" Lenovo X60-era laptops and spend > several years in limbo...) Ah yes and this is only a problem if the ptracer does not have CAP_SYS_PTRACE. If the tracer does not have sufficient permissions any opinions on failing the exec or kicking out the ptracer? I am leaning towards failing the exec as it is more obvious if someone cares. Dropping the ptracer could be a major mystery. Eric
[toc] | [prev] | [next] | [standalone]
| From | Andy Lutomirski <luto@amacapital.net> |
|---|---|
| Date | 2016-10-19 20:40 +0200 |
| Subject | Re: [REVIEW][PATCH] exec: Don't exec files the userns root can not read. |
| Message-ID | <su3Wq-53C-39@gated-at.bofh.it> |
| In reply to | #1504190 |
On Wed, Oct 19, 2016 at 10:55 AM, Eric W. Biederman
<ebiederm@xmission.com> wrote:
> Andy Lutomirski <luto@amacapital.net> writes:
>
>> On Wed, Oct 19, 2016 at 10:29 AM, Jann Horn <jann@thejh.net> wrote:
>>> On Wed, Oct 19, 2016 at 11:52:50AM -0500, Eric W. Biederman wrote:
>>>> Andy Lutomirski <luto@amacapital.net> writes:
>>>> > Simply ptrace yourself, exec the
>>>> > program, and then dump the program out. A program that really wants
>>>> > to be unreadable should have a stub: the stub is setuid and readable,
>>>> > but all the stub does is to exec the real program, and the real
>>>> > program should have mode 0500 or similar.
>>>> >
>>>> > ISTM the "right" check would be to enforce that the program's new
>>>> > creds can read the program, but that will break backwards
>>>> > compatibility.
>>>>
>>>> Last I looked I had the impression that exec of a setuid program kills
>>>> the ptrace.
>>>>
>>>> If we are talking about a exec of a simple unreadable executable (aka
>>>> something that sets undumpable but is not setuid or setgid). Then I
>>>> agree it should break the ptrace as well and since those programs are as
>>>> rare as hens teeth I don't see any problem with changing the ptrace behavior
>>>> in that case.
>>>
>>> Nope. check_unsafe_exec() sets LSM_UNSAFE_* flags in bprm->unsafe, and then
>>> the flags are checked by the LSMs and cap_bprm_set_creds() in commoncap.c.
>>> cap_bprm_set_creds() just degrades the execution to a non-setuid-ish one,
>>> and e.g. ptracers stay attached.
>>
>> I think you're right. I ought to be completely sure because I rewrote
>> that code back in 2005 or so back when I thought kernel programming
>> was only for the cool kids. It was probably my first kernel patch
>> ever and it closed an awkward-to-exploit root hole. But it's been a
>> while. (Too bad my second (IIRC) kernel patch was more mundane and
>> fixed the mute button on "new" Lenovo X60-era laptops and spend
>> several years in limbo...)
>
> Ah yes and this is only a problem if the ptracer does not have
> CAP_SYS_PTRACE.
>
> If the tracer does not have sufficient permissions any opinions on
> failing the exec or kicking out the ptracer? I am leaning towards failing
> the exec as it is more obvious if someone cares. Dropping the ptracer
> could be a major mystery.
I would suggest leaving it alone. Changing it could break enough
things that a sysctl would be needed, and I just don't see how this is
a significant issue, especially since it's been insecure forever.
Anyone who cares should do the stub executable trick:
/sbin/foo: 04755, literally just does execve("/sbin/foo-helper");
/sbin/foo-helper: 0500.
--Andy
[toc] | [prev] | [next] | [standalone]
| From | ebiederm@xmission.com (Eric W. Biederman) |
|---|---|
| Date | 2016-10-19 23:30 +0200 |
| Subject | Re: [REVIEW][PATCH] exec: Don't exec files the userns root can not read. |
| Message-ID | <su6AW-6Om-1@gated-at.bofh.it> |
| In reply to | #1504233 |
Andy Lutomirski <luto@amacapital.net> writes:
> On Wed, Oct 19, 2016 at 10:55 AM, Eric W. Biederman
> <ebiederm@xmission.com> wrote:
>> Andy Lutomirski <luto@amacapital.net> writes:
>>
>>> On Wed, Oct 19, 2016 at 10:29 AM, Jann Horn <jann@thejh.net> wrote:
>>>> On Wed, Oct 19, 2016 at 11:52:50AM -0500, Eric W. Biederman wrote:
>>>>> Andy Lutomirski <luto@amacapital.net> writes:
>>>>> > Simply ptrace yourself, exec the
>>>>> > program, and then dump the program out. A program that really wants
>>>>> > to be unreadable should have a stub: the stub is setuid and readable,
>>>>> > but all the stub does is to exec the real program, and the real
>>>>> > program should have mode 0500 or similar.
>>>>> >
>>>>> > ISTM the "right" check would be to enforce that the program's new
>>>>> > creds can read the program, but that will break backwards
>>>>> > compatibility.
>>>>>
>>>>> Last I looked I had the impression that exec of a setuid program kills
>>>>> the ptrace.
>>>>>
>>>>> If we are talking about a exec of a simple unreadable executable (aka
>>>>> something that sets undumpable but is not setuid or setgid). Then I
>>>>> agree it should break the ptrace as well and since those programs are as
>>>>> rare as hens teeth I don't see any problem with changing the ptrace behavior
>>>>> in that case.
>>>>
>>>> Nope. check_unsafe_exec() sets LSM_UNSAFE_* flags in bprm->unsafe, and then
>>>> the flags are checked by the LSMs and cap_bprm_set_creds() in commoncap.c.
>>>> cap_bprm_set_creds() just degrades the execution to a non-setuid-ish one,
>>>> and e.g. ptracers stay attached.
>>>
>>> I think you're right. I ought to be completely sure because I rewrote
>>> that code back in 2005 or so back when I thought kernel programming
>>> was only for the cool kids. It was probably my first kernel patch
>>> ever and it closed an awkward-to-exploit root hole. But it's been a
>>> while. (Too bad my second (IIRC) kernel patch was more mundane and
>>> fixed the mute button on "new" Lenovo X60-era laptops and spend
>>> several years in limbo...)
>>
>> Ah yes and this is only a problem if the ptracer does not have
>> CAP_SYS_PTRACE.
>>
>> If the tracer does not have sufficient permissions any opinions on
>> failing the exec or kicking out the ptracer? I am leaning towards failing
>> the exec as it is more obvious if someone cares. Dropping the ptracer
>> could be a major mystery.
>
> I would suggest leaving it alone. Changing it could break enough
> things that a sysctl would be needed, and I just don't see how this is
> a significant issue, especially since it's been insecure forever.
> Anyone who cares should do the stub executable trick:
>
> /sbin/foo: 04755, literally just does execve("/sbin/foo-helper");
>
> /sbin/foo-helper: 0500.
I can't imagine what non-malware would depend on being able to
circumvent file permissions and ptrace a read-only executable. Is there
something you are thinking of?
I know I saw someone depending on read-only executables being read-only
earlier this week on the security list, and it could definitely act as
part of a counter measure to make binaries harder to exploit.
So given that people actually expect no-read permissions to be honored
on executables (with what seem valid and sensible use cases), that
I can't see any valid reason not to honor no-read permissions, that it
takes a really convoluted setup to bypass the current no-read
permissions, and that I can't believe anyone cares about the current
behavior of ptrace I think this is worth fixing.
Eric
[toc] | [prev] | [next] | [standalone]
| From | Andy Lutomirski <luto@amacapital.net> |
|---|---|
| Date | 2016-10-20 01:20 +0200 |
| Subject | Re: [REVIEW][PATCH] exec: Don't exec files the userns root can not read. |
| Message-ID | <su8jn-7Y3-9@gated-at.bofh.it> |
| In reply to | #1504349 |
On Oct 19, 2016 2:28 PM, "Eric W. Biederman" <ebiederm@xmission.com> wrote:
>
> Andy Lutomirski <luto@amacapital.net> writes:
>
> > On Wed, Oct 19, 2016 at 10:55 AM, Eric W. Biederman
> > <ebiederm@xmission.com> wrote:
> >> Andy Lutomirski <luto@amacapital.net> writes:
> >>
> >>> On Wed, Oct 19, 2016 at 10:29 AM, Jann Horn <jann@thejh.net> wrote:
> >>>> On Wed, Oct 19, 2016 at 11:52:50AM -0500, Eric W. Biederman wrote:
> >>>>> Andy Lutomirski <luto@amacapital.net> writes:
> >>>>> > Simply ptrace yourself, exec the
> >>>>> > program, and then dump the program out. A program that really wants
> >>>>> > to be unreadable should have a stub: the stub is setuid and readable,
> >>>>> > but all the stub does is to exec the real program, and the real
> >>>>> > program should have mode 0500 or similar.
> >>>>> >
> >>>>> > ISTM the "right" check would be to enforce that the program's new
> >>>>> > creds can read the program, but that will break backwards
> >>>>> > compatibility.
> >>>>>
> >>>>> Last I looked I had the impression that exec of a setuid program kills
> >>>>> the ptrace.
> >>>>>
> >>>>> If we are talking about a exec of a simple unreadable executable (aka
> >>>>> something that sets undumpable but is not setuid or setgid). Then I
> >>>>> agree it should break the ptrace as well and since those programs are as
> >>>>> rare as hens teeth I don't see any problem with changing the ptrace behavior
> >>>>> in that case.
> >>>>
> >>>> Nope. check_unsafe_exec() sets LSM_UNSAFE_* flags in bprm->unsafe, and then
> >>>> the flags are checked by the LSMs and cap_bprm_set_creds() in commoncap.c.
> >>>> cap_bprm_set_creds() just degrades the execution to a non-setuid-ish one,
> >>>> and e.g. ptracers stay attached.
> >>>
> >>> I think you're right. I ought to be completely sure because I rewrote
> >>> that code back in 2005 or so back when I thought kernel programming
> >>> was only for the cool kids. It was probably my first kernel patch
> >>> ever and it closed an awkward-to-exploit root hole. But it's been a
> >>> while. (Too bad my second (IIRC) kernel patch was more mundane and
> >>> fixed the mute button on "new" Lenovo X60-era laptops and spend
> >>> several years in limbo...)
> >>
> >> Ah yes and this is only a problem if the ptracer does not have
> >> CAP_SYS_PTRACE.
> >>
> >> If the tracer does not have sufficient permissions any opinions on
> >> failing the exec or kicking out the ptracer? I am leaning towards failing
> >> the exec as it is more obvious if someone cares. Dropping the ptracer
> >> could be a major mystery.
> >
> > I would suggest leaving it alone. Changing it could break enough
> > things that a sysctl would be needed, and I just don't see how this is
> > a significant issue, especially since it's been insecure forever.
> > Anyone who cares should do the stub executable trick:
> >
> > /sbin/foo: 04755, literally just does execve("/sbin/foo-helper");
> >
> > /sbin/foo-helper: 0500.
>
> I can't imagine what non-malware would depend on being able to
> circumvent file permissions and ptrace a read-only executable. Is there
> something you are thinking of?
$ strace sudo foobar
or
$ strace auditctl
I find the current behavior somewhat odd, but I've taken advantage of
it on a semi-regular basis.
That being said, the "May the user_ns root read the executable?" test
in your patch is not strictly correct. Do we keep a struct cred
around for the ns root?
[toc] | [prev] | [next] | [standalone]
| From | Michal Hocko <mhocko@kernel.org> |
|---|---|
| Date | 2016-10-18 20:10 +0200 |
| Message-ID | <stGZP-5pH-11@gated-at.bofh.it> |
| In reply to | #1503072 |
On Tue 18-10-16 09:56:53, Eric W. Biederman wrote: > Michal Hocko <mhocko@kernel.org> writes: > > > On Mon 17-10-16 11:39:49, Eric W. Biederman wrote: > >> > >> During exec dumpable is cleared if the file that is being executed is > >> not readable by the user executing the file. A bug in > >> ptrace_may_access allows reading the file if the executable happens to > >> enter into a subordinate user namespace (aka clone(CLONE_NEWUSER), > >> unshare(CLONE_NEWUSER), or setns(fd, CLONE_NEWUSER). > >> > >> This problem is fixed with only necessary userspace breakage by adding > >> a user namespace owner to mm_struct, captured at the time of exec, > >> so it is clear in which user namespace CAP_SYS_PTRACE must be present > >> in to be able to safely give read permission to the executable. > >> > >> The function ptrace_may_access is modified to verify that the ptracer > >> has CAP_SYS_ADMIN in task->mm->user_ns instead of task->cred->user_ns. > >> This ensures that if the task changes it's cred into a subordinate > >> user namespace it does not become ptraceable. > > > > I haven't studied your patch too deeply but one thing that immediately > > raised a red flag was that mm might be shared between processes (aka > > thread groups). What prevents those two to sit in different user > > namespaces? > > > > I am primarily asking because this generated a lot of headache for the > > memcg handling as those processes might sit in different cgroups while > > there is only one correct memcg for them which can disagree with the > > cgroup associated with one of the processes. > > That is a legitimate concern, but I do not see any of those kinds of > issues here. > > Part of the memcg pain comes from the fact that control groups are > process centric, and part of the pain comes from the fact that it is > possible to change control groups. What I am doing is making the mm > owned by a user namespace (at creation time), and I am not allowing > changes to that ownership. The credentials of the tasks that use that mm > may be in the same user namespace or descendent user namespaces. OK, then my worries about this weird "threading" model is void. Thanks for the clarification. -- Michal Hocko SUSE Labs
[toc] | [prev] | [standalone]
Back to top | Article view | linux.kernel
csiph-web