Blob Blame History Raw
From e7c11266309ffa65143455ceefc17fe92d93511c 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 use-after-free of message buf

Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1602555
Upstream Status: iproute2.git commit 8c50b728b226f

commit 8c50b728b226f6254251282697ce38a72639a6fc
Author: Vlad Buslov <vladbu@mellanox.com>
Date:   Mon Oct 8 23:52:26 2018 +0300

    libnetlink: fix use-after-free of message buf

    In __rtnl_talk_iov() main loop, err is a pointer to memory in dynamically
    allocated 'buf' that is used to store netlink messages. If netlink message
    is an error message, buf is deallocated before returning with error code.
    However, on return err->error code is checked one more time to generate
    return value, after memory which err points to has already been
    freed. Save error code in temporary variable and use the variable to
    generate return value.

    Fixes: c60389e4f9ea ("libnetlink: fix leak and using unused memory on error")
    Signed-off-by: Vlad Buslov <vladbu@mellanox.com>
    Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
 lib/libnetlink.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/lib/libnetlink.c b/lib/libnetlink.c
index f18dcea..a9932d4 100644
--- a/lib/libnetlink.c
+++ b/lib/libnetlink.c
@@ -656,6 +656,7 @@ static int __rtnl_talk_iov(struct rtnl_handle *rtnl, struct iovec *iov,
 
 			if (h->nlmsg_type == NLMSG_ERROR) {
 				struct nlmsgerr *err = (struct nlmsgerr *)NLMSG_DATA(h);
+				int error = err->error;
 
 				if (l < sizeof(struct nlmsgerr)) {
 					fprintf(stderr, "ERROR truncated\n");
@@ -679,7 +680,7 @@ static int __rtnl_talk_iov(struct rtnl_handle *rtnl, struct iovec *iov,
 				else
 					free(buf);
 
-				return err->error ? -i : 0;
+				return error ? -i : 0;
 			}
 
 			if (answer) {
-- 
1.8.3.1