diff options
Diffstat (limited to 'kernel/user_namespace.c')
| -rw-r--r-- | kernel/user_namespace.c | 44 | 
1 files changed, 44 insertions, 0 deletions
diff --git a/kernel/user_namespace.c b/kernel/user_namespace.c index b2d70d38dff..25915832291 100644 --- a/kernel/user_namespace.c +++ b/kernel/user_namespace.c @@ -9,6 +9,7 @@  #include <linux/nsproxy.h>  #include <linux/slab.h>  #include <linux/user_namespace.h> +#include <linux/highuid.h>  #include <linux/cred.h>  /* @@ -82,3 +83,46 @@ void free_user_ns(struct kref *kref)  	schedule_work(&ns->destroyer);  }  EXPORT_SYMBOL(free_user_ns); + +uid_t user_ns_map_uid(struct user_namespace *to, const struct cred *cred, uid_t uid) +{ +	struct user_namespace *tmp; + +	if (likely(to == cred->user->user_ns)) +		return uid; + + +	/* Is cred->user the creator of the target user_ns +	 * or the creator of one of it's parents? +	 */ +	for ( tmp = to; tmp != &init_user_ns; +	      tmp = tmp->creator->user_ns ) { +		if (cred->user == tmp->creator) { +			return (uid_t)0; +		} +	} + +	/* No useful relationship so no mapping */ +	return overflowuid; +} + +gid_t user_ns_map_gid(struct user_namespace *to, const struct cred *cred, gid_t gid) +{ +	struct user_namespace *tmp; + +	if (likely(to == cred->user->user_ns)) +		return gid; + +	/* Is cred->user the creator of the target user_ns +	 * or the creator of one of it's parents? +	 */ +	for ( tmp = to; tmp != &init_user_ns; +	      tmp = tmp->creator->user_ns ) { +		if (cred->user == tmp->creator) { +			return (gid_t)0; +		} +	} + +	/* No useful relationship so no mapping */ +	return overflowgid; +}  |