forked from mirrors/linux
		
	net: Fix use after free in the recvmmsg exit path
The syzkaller fuzzer hit the following use-after-free:
  Call Trace:
   [<ffffffff8175ea0e>] __asan_report_load8_noabort+0x3e/0x40 mm/kasan/report.c:295
   [<ffffffff851cc31a>] __sys_recvmmsg+0x6fa/0x7f0 net/socket.c:2261
   [<     inline     >] SYSC_recvmmsg net/socket.c:2281
   [<ffffffff851cc57f>] SyS_recvmmsg+0x16f/0x180 net/socket.c:2270
   [<ffffffff86332bb6>] entry_SYSCALL_64_fastpath+0x16/0x7a
  arch/x86/entry/entry_64.S:185
And, as Dmitry rightly assessed, that is because we can drop the
reference and then touch it when the underlying recvmsg calls return
some packets and then hit an error, which will make recvmmsg to set
sock->sk->sk_err, oops, fix it.
Reported-and-Tested-by: Dmitry Vyukov <dvyukov@google.com>
Cc: Alexander Potapenko <glider@google.com>
Cc: Eric Dumazet <edumazet@google.com>
Cc: Kostya Serebryany <kcc@google.com>
Cc: Sasha Levin <sasha.levin@oracle.com>
Fixes: a2e2725541 ("net: Introduce recvmmsg socket syscall")
http://lkml.kernel.org/r/20160122211644.GC2470@redhat.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
			
			
This commit is contained in:
		
							parent
							
								
									b6e4038262
								
							
						
					
					
						commit
						34b88a68f2
					
				
					 1 changed files with 22 additions and 22 deletions
				
			
		
							
								
								
									
										16
									
								
								net/socket.c
									
									
									
									
									
								
							
							
						
						
									
										16
									
								
								net/socket.c
									
									
									
									
									
								
							|  | @ -2244,13 +2244,14 @@ int __sys_recvmmsg(int fd, struct mmsghdr __user *mmsg, unsigned int vlen, | |||
| 		cond_resched(); | ||||
| 	} | ||||
| 
 | ||||
| out_put: | ||||
| 	fput_light(sock->file, fput_needed); | ||||
| 
 | ||||
| 	if (err == 0) | ||||
| 		return datagrams; | ||||
| 		goto out_put; | ||||
| 
 | ||||
| 	if (datagrams == 0) { | ||||
| 		datagrams = err; | ||||
| 		goto out_put; | ||||
| 	} | ||||
| 
 | ||||
| 	if (datagrams != 0) { | ||||
| 	/*
 | ||||
| 	 * We may return less entries than requested (vlen) if the | ||||
| 	 * sock is non block and there aren't enough datagrams... | ||||
|  | @ -2264,13 +2265,12 @@ int __sys_recvmmsg(int fd, struct mmsghdr __user *mmsg, unsigned int vlen, | |||
| 		 */ | ||||
| 		sock->sk->sk_err = -err; | ||||
| 	} | ||||
| out_put: | ||||
| 	fput_light(sock->file, fput_needed); | ||||
| 
 | ||||
| 	return datagrams; | ||||
| } | ||||
| 
 | ||||
| 	return err; | ||||
| } | ||||
| 
 | ||||
| SYSCALL_DEFINE5(recvmmsg, int, fd, struct mmsghdr __user *, mmsg, | ||||
| 		unsigned int, vlen, unsigned int, flags, | ||||
| 		struct timespec __user *, timeout) | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue
	
	 Arnaldo Carvalho de Melo
						Arnaldo Carvalho de Melo