|
@@ -14,20 +14,19 @@
|
|
|
#include <linux/bitops.h>
|
|
|
#include <linux/key.h>
|
|
|
#include <linux/interrupt.h>
|
|
|
+#include <linux/module.h>
|
|
|
+#include <linux/user_namespace.h>
|
|
|
|
|
|
/*
|
|
|
* UID task count cache, to get fast user lookup in "alloc_uid"
|
|
|
* when changing user ID's (ie setuid() and friends).
|
|
|
*/
|
|
|
|
|
|
-#define UIDHASH_BITS (CONFIG_BASE_SMALL ? 3 : 8)
|
|
|
-#define UIDHASH_SZ (1 << UIDHASH_BITS)
|
|
|
#define UIDHASH_MASK (UIDHASH_SZ - 1)
|
|
|
#define __uidhashfn(uid) (((uid >> UIDHASH_BITS) + uid) & UIDHASH_MASK)
|
|
|
-#define uidhashentry(uid) (uidhash_table + __uidhashfn((uid)))
|
|
|
+#define uidhashentry(ns, uid) ((ns)->uidhash_table + __uidhashfn((uid)))
|
|
|
|
|
|
static struct kmem_cache *uid_cachep;
|
|
|
-static struct list_head uidhash_table[UIDHASH_SZ];
|
|
|
|
|
|
/*
|
|
|
* The uidhash_lock is mostly taken from process context, but it is
|
|
@@ -94,9 +93,10 @@ struct user_struct *find_user(uid_t uid)
|
|
|
{
|
|
|
struct user_struct *ret;
|
|
|
unsigned long flags;
|
|
|
+ struct user_namespace *ns = current->nsproxy->user_ns;
|
|
|
|
|
|
spin_lock_irqsave(&uidhash_lock, flags);
|
|
|
- ret = uid_hash_find(uid, uidhashentry(uid));
|
|
|
+ ret = uid_hash_find(uid, uidhashentry(ns, uid));
|
|
|
spin_unlock_irqrestore(&uidhash_lock, flags);
|
|
|
return ret;
|
|
|
}
|
|
@@ -120,9 +120,9 @@ void free_uid(struct user_struct *up)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-struct user_struct * alloc_uid(uid_t uid)
|
|
|
+struct user_struct * alloc_uid(struct user_namespace *ns, uid_t uid)
|
|
|
{
|
|
|
- struct list_head *hashent = uidhashentry(uid);
|
|
|
+ struct list_head *hashent = uidhashentry(ns, uid);
|
|
|
struct user_struct *up;
|
|
|
|
|
|
spin_lock_irq(&uidhash_lock);
|
|
@@ -211,11 +211,11 @@ static int __init uid_cache_init(void)
|
|
|
0, SLAB_HWCACHE_ALIGN|SLAB_PANIC, NULL, NULL);
|
|
|
|
|
|
for(n = 0; n < UIDHASH_SZ; ++n)
|
|
|
- INIT_LIST_HEAD(uidhash_table + n);
|
|
|
+ INIT_LIST_HEAD(init_user_ns.uidhash_table + n);
|
|
|
|
|
|
/* Insert the root user immediately (init already runs as root) */
|
|
|
spin_lock_irq(&uidhash_lock);
|
|
|
- uid_hash_insert(&root_user, uidhashentry(0));
|
|
|
+ uid_hash_insert(&root_user, uidhashentry(&init_user_ns, 0));
|
|
|
spin_unlock_irq(&uidhash_lock);
|
|
|
|
|
|
return 0;
|