82 lines
		
	
	
		
			2.2 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
			
		
		
	
	
			82 lines
		
	
	
		
			2.2 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
| From 3ec32595e21849de3165d52e1af48ca3bdf51fab Mon Sep 17 00:00:00 2001
 | |
| From: Phil Sutter <psutter@redhat.com>
 | |
| Date: Thu, 25 Oct 2018 12:24:30 +0200
 | |
| Subject: [PATCH] libnetlink: fix leak and using unused memory on error
 | |
| 
 | |
| Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1602555
 | |
| Upstream Status: iproute2.git commit c60389e4f9ea8
 | |
| 
 | |
| commit c60389e4f9ea88d7246dbb148d28791d577fe5b4
 | |
| Author: Stephen Hemminger <stephen@networkplumber.org>
 | |
| Date:   Thu Sep 13 12:33:38 2018 -0700
 | |
| 
 | |
|     libnetlink: fix leak and using unused memory on error
 | |
| 
 | |
|     If an error happens in multi-segment message (tc only)
 | |
|     then report the error and stop processing further responses.
 | |
|     This also fixes refering to the buffer after free.
 | |
| 
 | |
|     The sequence check is not necessary here because the
 | |
|     response message has already been validated to be in
 | |
|     the window of the sequence number of the iov.
 | |
| 
 | |
|     Reported-by: Mahesh Bandewar <mahesh@bandewar.net>
 | |
|     Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
 | |
|     Acked-by: Mahesh Bandewar <maheshb@google.com>
 | |
| ---
 | |
|  lib/libnetlink.c | 23 +++++++++--------------
 | |
|  1 file changed, 9 insertions(+), 14 deletions(-)
 | |
| 
 | |
| diff --git a/lib/libnetlink.c b/lib/libnetlink.c
 | |
| index 928de1d..5868092 100644
 | |
| --- a/lib/libnetlink.c
 | |
| +++ b/lib/libnetlink.c
 | |
| @@ -617,7 +617,6 @@ static int __rtnl_talk_iov(struct rtnl_handle *rtnl, struct iovec *iov,
 | |
|  	msg.msg_iovlen = 1;
 | |
|  	i = 0;
 | |
|  	while (1) {
 | |
| -next:
 | |
|  		status = rtnl_recvmsg(rtnl->fd, &msg, &buf);
 | |
|  		++i;
 | |
|  
 | |
| @@ -660,27 +659,23 @@ next:
 | |
|  
 | |
|  				if (l < sizeof(struct nlmsgerr)) {
 | |
|  					fprintf(stderr, "ERROR truncated\n");
 | |
| -				} else if (!err->error) {
 | |
| +					free(buf);
 | |
| +					return -1;
 | |
| +				}
 | |
| +
 | |
| +				if (!err->error)
 | |
|  					/* check messages from kernel */
 | |
|  					nl_dump_ext_ack(h, errfn);
 | |
|  
 | |
| -					if (answer)
 | |
| -						*answer = (struct nlmsghdr *)buf;
 | |
| -					else
 | |
| -						free(buf);
 | |
| -					if (h->nlmsg_seq == seq)
 | |
| -						return 0;
 | |
| -					else if (i < iovlen)
 | |
| -						goto next;
 | |
| -					return 0;
 | |
| -				}
 | |
| -
 | |
|  				if (rtnl->proto != NETLINK_SOCK_DIAG &&
 | |
|  				    show_rtnl_err)
 | |
|  					rtnl_talk_error(h, err, errfn);
 | |
|  
 | |
|  				errno = -err->error;
 | |
| -				free(buf);
 | |
| +				if (answer)
 | |
| +					*answer = (struct nlmsghdr *)buf;
 | |
| +				else
 | |
| +					free(buf);
 | |
|  				return -i;
 | |
|  			}
 | |
|  
 | |
| -- 
 | |
| 1.8.3.1
 | |
| 
 |