Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 8eb703e4 authored by Pavel Emelyanov's avatar Pavel Emelyanov Committed by Ingo Molnar
Browse files

uids: merge multiple error paths in alloc_uid() into one



There are already 4 error paths in alloc_uid() that do incremental rollbacks.
I think it's time to merge them.  This costs us 8 lines of code :)

Maybe it would be better to merge this patch with the previous one, but I
remember that some time ago I sent a similar patch (fixing the error path and
cleaning it), but I was told to make two patches in such cases.

Signed-off-by: default avatarPavel Emelyanov <xemul@openvz.org>
Acked-by: default avatarDhaval Giani <dhaval@linux.vnet.ibm.com>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarIngo Molnar <mingo@elte.hu>
parent dc938520
Loading
Loading
Loading
Loading
+20 −27
Original line number Diff line number Diff line
@@ -319,7 +319,7 @@ void free_uid(struct user_struct *up)
struct user_struct * alloc_uid(struct user_namespace *ns, uid_t uid)
{
	struct hlist_head *hashent = uidhashentry(ns, uid);
	struct user_struct *up;
	struct user_struct *up, *new;

	/* Make uid_hash_find() + uids_user_create() + uid_hash_insert()
	 * atomic.
@@ -331,13 +331,9 @@ struct user_struct * alloc_uid(struct user_namespace *ns, uid_t uid)
	spin_unlock_irq(&uidhash_lock);

	if (!up) {
		struct user_struct *new;

		new = kmem_cache_alloc(uid_cachep, GFP_KERNEL);
		if (!new) {
			uids_mutex_unlock();
			return NULL;
		}
		if (!new)
			goto out_unlock;

		new->uid = uid;
		atomic_set(&new->__count, 1);
@@ -353,28 +349,14 @@ struct user_struct * alloc_uid(struct user_namespace *ns, uid_t uid)
#endif
		new->locked_shm = 0;

		if (alloc_uid_keyring(new, current) < 0) {
			kmem_cache_free(uid_cachep, new);
			uids_mutex_unlock();
			return NULL;
		}
		if (alloc_uid_keyring(new, current) < 0)
			goto out_free_user;

		if (sched_create_user(new) < 0) {
			key_put(new->uid_keyring);
			key_put(new->session_keyring);
			kmem_cache_free(uid_cachep, new);
			uids_mutex_unlock();
			return NULL;
		}
		if (sched_create_user(new) < 0)
			goto out_put_keys;

		if (uids_user_create(new)) {
			sched_destroy_user(new);
			key_put(new->uid_keyring);
			key_put(new->session_keyring);
			kmem_cache_free(uid_cachep, new);
			uids_mutex_unlock();
			return NULL;
		}
		if (uids_user_create(new))
			goto out_destoy_sched;

		/*
		 * Before adding this, check whether we raced
@@ -402,6 +384,17 @@ struct user_struct * alloc_uid(struct user_namespace *ns, uid_t uid)
	uids_mutex_unlock();

	return up;

out_destoy_sched:
	sched_destroy_user(new);
out_put_keys:
	key_put(new->uid_keyring);
	key_put(new->session_keyring);
out_free_user:
	kmem_cache_free(uid_cachep, new);
out_unlock:
	uids_mutex_unlock();
	return NULL;
}

void switch_uid(struct user_struct *new_user)