mirror of
				git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
				synced 2025-10-31 08:44:41 +00:00 
			
		
		
		
	Merge branch 'for-v5.14' of git://git.kernel.org/pub/scm/linux/kernel/git/ebiederm/user-namespace
Pull ucounts fix from Eric Biederman: "Fix a subtle locking versus reference counting bug in the ucount changes, found by syzbot" * 'for-v5.14' of git://git.kernel.org/pub/scm/linux/kernel/git/ebiederm/user-namespace: ucounts: Fix race condition between alloc_ucounts and put_ucounts
This commit is contained in:
		
						commit
						6209049ecf
					
				
					 1 changed files with 7 additions and 3 deletions
				
			
		|  | @ -160,6 +160,7 @@ struct ucounts *alloc_ucounts(struct user_namespace *ns, kuid_t uid) | |||
| { | ||||
| 	struct hlist_head *hashent = ucounts_hashentry(ns, uid); | ||||
| 	struct ucounts *ucounts, *new; | ||||
| 	long overflow; | ||||
| 
 | ||||
| 	spin_lock_irq(&ucounts_lock); | ||||
| 	ucounts = find_ucounts(ns, uid, hashent); | ||||
|  | @ -184,8 +185,12 @@ struct ucounts *alloc_ucounts(struct user_namespace *ns, kuid_t uid) | |||
| 			return new; | ||||
| 		} | ||||
| 	} | ||||
| 	overflow = atomic_add_negative(1, &ucounts->count); | ||||
| 	spin_unlock_irq(&ucounts_lock); | ||||
| 	ucounts = get_ucounts(ucounts); | ||||
| 	if (overflow) { | ||||
| 		put_ucounts(ucounts); | ||||
| 		return NULL; | ||||
| 	} | ||||
| 	return ucounts; | ||||
| } | ||||
| 
 | ||||
|  | @ -193,8 +198,7 @@ void put_ucounts(struct ucounts *ucounts) | |||
| { | ||||
| 	unsigned long flags; | ||||
| 
 | ||||
| 	if (atomic_dec_and_test(&ucounts->count)) { | ||||
| 		spin_lock_irqsave(&ucounts_lock, flags); | ||||
| 	if (atomic_dec_and_lock_irqsave(&ucounts->count, &ucounts_lock, flags)) { | ||||
| 		hlist_del_init(&ucounts->node); | ||||
| 		spin_unlock_irqrestore(&ucounts_lock, flags); | ||||
| 		kfree(ucounts); | ||||
|  |  | |||
		Loading…
	
	Add table
		
		Reference in a new issue
	
	 Linus Torvalds
						Linus Torvalds