mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-01 00:58:39 +02:00 
			
		
		
		
	fs/pipe: fix pipe buffer index use in FUSE
This was another case that Rasmus pointed out where the direct access to
the pipe head and tail pointers broke on 32-bit configurations due to
the type changes.
As with the pipe FIONREAD case, fix it by using the appropriate helper
functions that deal with the right pipe index sizing.
Reported-by: Rasmus Villemoes <ravi@prevas.dk>
Link: https://lore.kernel.org/all/878qpi5wz4.fsf@prevas.dk/
Fixes: 3d252160b8 ("fs/pipe: Read pipe->{head,tail} atomically outside pipe->mutex")Cc: Oleg >
Cc: Mateusz Guzik <mjguzik@gmail.com>
Cc: K Prateek Nayak <kprateek.nayak@amd.com>
Cc: Swapnil Sapkal <swapnil.sapkal@amd.com>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
			
			
This commit is contained in:
		
							parent
							
								
									d810d4c27b
								
							
						
					
					
						commit
						ebb0f38bb4
					
				
					 1 changed files with 6 additions and 7 deletions
				
			
		|  | @ -2107,7 +2107,7 @@ static ssize_t fuse_dev_splice_write(struct pipe_inode_info *pipe, | ||||||
| 				     struct file *out, loff_t *ppos, | 				     struct file *out, loff_t *ppos, | ||||||
| 				     size_t len, unsigned int flags) | 				     size_t len, unsigned int flags) | ||||||
| { | { | ||||||
| 	unsigned int head, tail, mask, count; | 	unsigned int head, tail, count; | ||||||
| 	unsigned nbuf; | 	unsigned nbuf; | ||||||
| 	unsigned idx; | 	unsigned idx; | ||||||
| 	struct pipe_buffer *bufs; | 	struct pipe_buffer *bufs; | ||||||
|  | @ -2124,8 +2124,7 @@ static ssize_t fuse_dev_splice_write(struct pipe_inode_info *pipe, | ||||||
| 
 | 
 | ||||||
| 	head = pipe->head; | 	head = pipe->head; | ||||||
| 	tail = pipe->tail; | 	tail = pipe->tail; | ||||||
| 	mask = pipe->ring_size - 1; | 	count = pipe_occupancy(head, tail); | ||||||
| 	count = head - tail; |  | ||||||
| 
 | 
 | ||||||
| 	bufs = kvmalloc_array(count, sizeof(struct pipe_buffer), GFP_KERNEL); | 	bufs = kvmalloc_array(count, sizeof(struct pipe_buffer), GFP_KERNEL); | ||||||
| 	if (!bufs) { | 	if (!bufs) { | ||||||
|  | @ -2135,8 +2134,8 @@ static ssize_t fuse_dev_splice_write(struct pipe_inode_info *pipe, | ||||||
| 
 | 
 | ||||||
| 	nbuf = 0; | 	nbuf = 0; | ||||||
| 	rem = 0; | 	rem = 0; | ||||||
| 	for (idx = tail; idx != head && rem < len; idx++) | 	for (idx = tail; !pipe_empty(head, idx) && rem < len; idx++) | ||||||
| 		rem += pipe->bufs[idx & mask].len; | 		rem += pipe_buf(pipe, idx)->len; | ||||||
| 
 | 
 | ||||||
| 	ret = -EINVAL; | 	ret = -EINVAL; | ||||||
| 	if (rem < len) | 	if (rem < len) | ||||||
|  | @ -2147,10 +2146,10 @@ static ssize_t fuse_dev_splice_write(struct pipe_inode_info *pipe, | ||||||
| 		struct pipe_buffer *ibuf; | 		struct pipe_buffer *ibuf; | ||||||
| 		struct pipe_buffer *obuf; | 		struct pipe_buffer *obuf; | ||||||
| 
 | 
 | ||||||
| 		if (WARN_ON(nbuf >= count || tail == head)) | 		if (WARN_ON(nbuf >= count || pipe_empty(head, tail))) | ||||||
| 			goto out_free; | 			goto out_free; | ||||||
| 
 | 
 | ||||||
| 		ibuf = &pipe->bufs[tail & mask]; | 		ibuf = pipe_buf(pipe, tail); | ||||||
| 		obuf = &bufs[nbuf]; | 		obuf = &bufs[nbuf]; | ||||||
| 
 | 
 | ||||||
| 		if (rem >= ibuf->len) { | 		if (rem >= ibuf->len) { | ||||||
|  |  | ||||||
		Loading…
	
		Reference in a new issue
	
	 Linus Torvalds
						Linus Torvalds