From mboxrd@z Thu Jan 1 00:00:00 1970 From: Stephen Hemminger Subject: [PATCH iproute2] libnetlink: fix leak and using unused memory on error Date: Thu, 13 Sep 2018 12:33:38 -0700 Message-ID: <20180913193338.20233-1-stephen@networkplumber.org> Cc: netdev@vger.kernel.org, Stephen Hemminger To: Mahesh Bandewar Return-path: Received: from mail-pl1-f193.google.com ([209.85.214.193]:45686 "EHLO mail-pl1-f193.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727051AbeINAof (ORCPT ); Thu, 13 Sep 2018 20:44:35 -0400 Received: by mail-pl1-f193.google.com with SMTP id j8-v6so3035695pll.12 for ; Thu, 13 Sep 2018 12:33:41 -0700 (PDT) Sender: netdev-owner@vger.kernel.org List-ID: 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 Fixes: 7b2ee50c0cd5 ("hv_netvsc: common detach logic") Signed-off-by: Stephen Hemminger --- lib/libnetlink.c | 23 +++++++++-------------- 1 file changed, 9 insertions(+), 14 deletions(-) diff --git a/lib/libnetlink.c b/lib/libnetlink.c index 928de1dd16d8..586809292594 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; } -- 2.18.0