ipnetns: use-after-free problem in get_netnsid_from_name func

Follow the following steps:
 # ip netns add net1
 # export MALLOC_MMAP_THRESHOLD_=0
 # ip netns list
then Segmentation fault (core dumped) will occur.

In get_netnsid_from_name func, answer is freed before
rta_getattr_u32(tb[NETNSA_NSID]), where tb[] refers to answer`s
content. If we set MALLOC_MMAP_THRESHOLD_=0, mmap will be adoped to
malloc memory, which will be freed immediately after calling free
func.  So reading tb[NETNSA_NSID] will access the released memory
after free(answer).

Here, we will call get_netnsid_from_name(tb[NETNSA_NSID]) before free(answer).

Fixes: 86bf43c7c2 ("lib/libnetlink: update rtnl_talk to support malloc buff at run time")
Reported-by: Huiying Kou <kouhuiying@huawei.com>
Signed-off-by: Zhiqiang Liu <liuzhiqiang26@huawei.com>
Acked-by: Phil Sutter <phil@nwl.cc>
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
This commit is contained in:
Zhiqiang Liu 2019-05-05 09:59:51 +08:00 committed by Stephen Hemminger
parent e73306048f
commit 9bf2c538a0

View File

@ -107,7 +107,7 @@ int get_netnsid_from_name(const char *name)
struct nlmsghdr *answer;
struct rtattr *tb[NETNSA_MAX + 1];
struct rtgenmsg *rthdr;
int len, fd;
int len, fd, ret = -1;
netns_nsid_socket_init();
@ -124,23 +124,22 @@ int get_netnsid_from_name(const char *name)
/* Validate message and parse attributes */
if (answer->nlmsg_type == NLMSG_ERROR)
goto err_out;
goto out;
rthdr = NLMSG_DATA(answer);
len = answer->nlmsg_len - NLMSG_SPACE(sizeof(*rthdr));
if (len < 0)
goto err_out;
goto out;
parse_rtattr(tb, NETNSA_MAX, NETNS_RTA(rthdr), len);
if (tb[NETNSA_NSID]) {
free(answer);
return rta_getattr_u32(tb[NETNSA_NSID]);
ret = rta_getattr_u32(tb[NETNSA_NSID]);
}
err_out:
out:
free(answer);
return -1;
return ret;
}
struct nsid_cache {