49 lines
1.9 KiB
Diff
49 lines
1.9 KiB
Diff
From: "Eric W. Biederman" <ebiederm@xmission.com>
|
|
Date: Fri, 5 Dec 2014 17:51:47 -0600
|
|
Subject: [PATCH] userns: Document what the invariant required for safe
|
|
unprivileged mappings.
|
|
|
|
The rule is simple. Don't allow anything that wouldn't be allowed
|
|
without unprivileged mappings.
|
|
|
|
It was previously overlooked that establishing gid mappings would
|
|
allow dropping groups and potentially gaining permission to files and
|
|
directories that had lesser permissions for a specific group than for
|
|
all other users.
|
|
|
|
This is the rule needed to fix CVE-2014-8989 and prevent any other
|
|
security issues with new_idmap_permitted.
|
|
|
|
The reason for this rule is that the unix permission model is old and
|
|
there are programs out there somewhere that take advantage of every
|
|
little corner of it. So allowing a uid or gid mapping to be
|
|
established without privielge that would allow anything that would not
|
|
be allowed without that mapping will result in expectations from some
|
|
code somewhere being violated. Violated expectations about the
|
|
behavior of the OS is a long way to say a security issue.
|
|
|
|
Cc: stable@vger.kernel.org
|
|
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
|
|
---
|
|
kernel/user_namespace.c | 4 +++-
|
|
1 file changed, 3 insertions(+), 1 deletion(-)
|
|
|
|
diff --git a/kernel/user_namespace.c b/kernel/user_namespace.c
|
|
index aa312b0dc3ec..b99c862a2e3f 100644
|
|
--- a/kernel/user_namespace.c
|
|
+++ b/kernel/user_namespace.c
|
|
@@ -812,7 +812,9 @@ static bool new_idmap_permitted(const struct file *file,
|
|
struct user_namespace *ns, int cap_setid,
|
|
struct uid_gid_map *new_map)
|
|
{
|
|
- /* Allow mapping to your own filesystem ids */
|
|
+ /* Don't allow mappings that would allow anything that wouldn't
|
|
+ * be allowed without the establishment of unprivileged mappings.
|
|
+ */
|
|
if ((new_map->nr_extents == 1) && (new_map->extent[0].count == 1)) {
|
|
u32 id = new_map->extent[0].lower_first;
|
|
if (cap_setid == CAP_SETUID) {
|
|
--
|
|
2.1.0
|
|
|