user_ns: Introduce user_nsmap_uid and user_ns_map_gid.
Define what happens when a we view a uid from one user_namespace in another user_namepece. - If the user namespaces are the same no mapping is necessary. - For most cases of difference use overflowuid and overflowgid, the uid and gid currently used for 16bit apis when we have a 32bit uid that does fit in 16bits. Effectively the situation is the same, we want to return a uid or gid that is not assigned to any user. - For the case when we happen to be mapping the uid or gid of the creator of the target user namespace use uid 0 and gid as confusing that user with root is not a problem. Signed-off-by: Eric W. Biederman <ebiederm@xmission.com> Acked-by: Serge E. Hallyn <serue@us.ibm.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Родитель
812e876e84
Коммит
5c1469de75
|
@ -36,6 +36,9 @@ static inline void put_user_ns(struct user_namespace *ns)
|
|||
kref_put(&ns->kref, free_user_ns);
|
||||
}
|
||||
|
||||
uid_t user_ns_map_uid(struct user_namespace *to, const struct cred *cred, uid_t uid);
|
||||
gid_t user_ns_map_gid(struct user_namespace *to, const struct cred *cred, gid_t gid);
|
||||
|
||||
#else
|
||||
|
||||
static inline struct user_namespace *get_user_ns(struct user_namespace *ns)
|
||||
|
@ -52,6 +55,17 @@ static inline void put_user_ns(struct user_namespace *ns)
|
|||
{
|
||||
}
|
||||
|
||||
static inline uid_t user_ns_map_uid(struct user_namespace *to,
|
||||
const struct cred *cred, uid_t uid)
|
||||
{
|
||||
return uid;
|
||||
}
|
||||
static inline gid_t user_ns_map_gid(struct user_namespace *to,
|
||||
const struct cred *cred, gid_t gid)
|
||||
{
|
||||
return gid;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* _LINUX_USER_H */
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче