]> git.proxmox.com Git - mirror_iproute2.git/commitdiff
libnetlink: fix use-after-free of message buf
authorVlad Buslov <vladbu@mellanox.com>
Mon, 8 Oct 2018 20:52:26 +0000 (23:52 +0300)
committerStephen Hemminger <stephen@networkplumber.org>
Tue, 9 Oct 2018 16:41:03 +0000 (09:41 -0700)
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

index f18dceac2b5e0f7e8a13c92bcdb5b71767946ea1..a9932d423126e2c38d2a4011a2e48148b6b492b8 100644 (file)
@@ -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) {