mirror of
				https://github.com/torvalds/linux.git
				synced 2025-10-31 08:38:45 +02:00 
			
		
		
		
	ALSA: seq: Fix racy pool initializations
ALSA sequencer core initializes the event pool on demand by invoking snd_seq_pool_init() when the first write happens and the pool is empty. Meanwhile user can reset the pool size manually via ioctl concurrently, and this may lead to UAF or out-of-bound accesses since the function tries to vmalloc / vfree the buffer. A simple fix is to just wrap the snd_seq_pool_init() call with the recently introduced client->ioctl_mutex; as the calls for snd_seq_pool_init() from other side are always protected with this mutex, we can avoid the race. Reported-by: 范龙飞 <long7573@126.com> Cc: <stable@vger.kernel.org> Signed-off-by: Takashi Iwai <tiwai@suse.de>
This commit is contained in:
		
							parent
							
								
									1dcb1859dd
								
							
						
					
					
						commit
						d15d662e89
					
				
					 1 changed files with 6 additions and 2 deletions
				
			
		|  | @ -1003,7 +1003,7 @@ static ssize_t snd_seq_write(struct file *file, const char __user *buf, | ||||||
| { | { | ||||||
| 	struct snd_seq_client *client = file->private_data; | 	struct snd_seq_client *client = file->private_data; | ||||||
| 	int written = 0, len; | 	int written = 0, len; | ||||||
| 	int err = -EINVAL; | 	int err; | ||||||
| 	struct snd_seq_event event; | 	struct snd_seq_event event; | ||||||
| 
 | 
 | ||||||
| 	if (!(snd_seq_file_flags(file) & SNDRV_SEQ_LFLG_OUTPUT)) | 	if (!(snd_seq_file_flags(file) & SNDRV_SEQ_LFLG_OUTPUT)) | ||||||
|  | @ -1018,11 +1018,15 @@ static ssize_t snd_seq_write(struct file *file, const char __user *buf, | ||||||
| 
 | 
 | ||||||
| 	/* allocate the pool now if the pool is not allocated yet */  | 	/* allocate the pool now if the pool is not allocated yet */  | ||||||
| 	if (client->pool->size > 0 && !snd_seq_write_pool_allocated(client)) { | 	if (client->pool->size > 0 && !snd_seq_write_pool_allocated(client)) { | ||||||
| 		if (snd_seq_pool_init(client->pool) < 0) | 		mutex_lock(&client->ioctl_mutex); | ||||||
|  | 		err = snd_seq_pool_init(client->pool); | ||||||
|  | 		mutex_unlock(&client->ioctl_mutex); | ||||||
|  | 		if (err < 0) | ||||||
| 			return -ENOMEM; | 			return -ENOMEM; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	/* only process whole events */ | 	/* only process whole events */ | ||||||
|  | 	err = -EINVAL; | ||||||
| 	while (count >= sizeof(struct snd_seq_event)) { | 	while (count >= sizeof(struct snd_seq_event)) { | ||||||
| 		/* Read in the event header from the user */ | 		/* Read in the event header from the user */ | ||||||
| 		len = sizeof(event); | 		len = sizeof(event); | ||||||
|  |  | ||||||
		Loading…
	
		Reference in a new issue
	
	 Takashi Iwai
						Takashi Iwai