From 09e0528cf977150fcf6b849671091501b0958fdb Mon Sep 17 00:00:00 2001 From: Nikolay Aleksandrov Date: Fri, 26 Apr 2019 13:54:21 +0300 Subject: [PATCH 1/4] ip: mroute: add fflush to print_mroute Similar to other print functions we need to flush buffered data in order to work with pipes and output redirects. After this patch ip monitor mroute &>log works properly. Signed-off-by: Nikolay Aleksandrov Signed-off-by: Stephen Hemminger --- ip/ipmroute.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ip/ipmroute.c b/ip/ipmroute.c index b29c78e4..6cf91fe9 100644 --- a/ip/ipmroute.c +++ b/ip/ipmroute.c @@ -57,6 +57,7 @@ int print_mroute(struct nlmsghdr *n, void *arg) struct rtmsg *r = NLMSG_DATA(n); int len = n->nlmsg_len; struct rtattr *tb[RTA_MAX+1]; + FILE *fp = arg; const char *src, *dst; SPRINT_BUF(b1); SPRINT_BUF(b2); @@ -209,6 +210,7 @@ int print_mroute(struct nlmsghdr *n, void *arg) print_string(PRINT_FP, NULL, "\n", NULL); close_json_object(); + fflush(fp); return 0; } From e73306048f798ec6f6265cb6e6fcaf4543cddba6 Mon Sep 17 00:00:00 2001 From: Ido Schimmel Date: Sun, 5 May 2019 17:12:43 +0300 Subject: [PATCH 2/4] devlink: Fix monitor command The command is supposed to allow users to filter events related to certain objects, but returns an error when an object is specified: # devlink mon dev Command "dev" not found Fix this by allowing the command to process the specified objects. Example: # devlink/devlink mon dev & # echo "10 1" > /sys/bus/netdevsim/new_device [dev,new] netdevsim/netdevsim10 # devlink/devlink mon port & # echo "11 1" > /sys/bus/netdevsim/new_device [port,new] netdevsim/netdevsim11/0: type notset flavour physical [port,new] netdevsim/netdevsim11/0: type eth netdev eth1 flavour physical # devlink/devlink mon & # echo "12 1" > /sys/bus/netdevsim/new_device [dev,new] netdevsim/netdevsim12 [port,new] netdevsim/netdevsim12/0: type notset flavour physical [port,new] netdevsim/netdevsim12/0: type eth netdev eth2 flavour physical Fixes: a3c4b484a1ed ("add devlink tool") Signed-off-by: Ido Schimmel Acked-by: Jiri Pirko Signed-off-by: Stephen Hemminger --- devlink/devlink.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/devlink/devlink.c b/devlink/devlink.c index dc6e73fe..6a4ce58b 100644 --- a/devlink/devlink.c +++ b/devlink/devlink.c @@ -3858,12 +3858,8 @@ static int cmd_mon(struct dl *dl) if (dl_argv_match(dl, "help")) { cmd_mon_help(); return 0; - } else if (dl_no_arg(dl)) { - dl_arg_inc(dl); - return cmd_mon_show(dl); } - pr_err("Command \"%s\" not found\n", dl_argv(dl)); - return -ENOENT; + return cmd_mon_show(dl); } struct dpipe_field { From 9bf2c538a0eb10d66e2365a655bf6c52f5ba3d10 Mon Sep 17 00:00:00 2001 From: Zhiqiang Liu Date: Sun, 5 May 2019 09:59:51 +0800 Subject: [PATCH 3/4] 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: 86bf43c7c2f ("lib/libnetlink: update rtnl_talk to support malloc buff at run time") Reported-by: Huiying Kou Signed-off-by: Zhiqiang Liu Acked-by: Phil Sutter Signed-off-by: Stephen Hemminger --- ip/ipnetns.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/ip/ipnetns.c b/ip/ipnetns.c index 430d8844..52aefacf 100644 --- a/ip/ipnetns.c +++ b/ip/ipnetns.c @@ -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 { From cd21ae40130b4d1ddb3ef500800840e35e7bfad1 Mon Sep 17 00:00:00 2001 From: Phil Sutter Date: Mon, 6 May 2019 19:09:56 +0200 Subject: [PATCH 4/4] ip-xfrm: Respect family in deleteall and list commands Allow to limit 'ip xfrm {state|policy} list' output to a certain address family and to delete all states/policies by family. Although preferred_family was already set in filters, the filter function ignored it. To enable filtering despite the lack of other selectors, filter.use has to be set if family is not AF_UNSPEC. Signed-off-by: Phil Sutter Signed-off-by: Stephen Hemminger --- ip/xfrm_policy.c | 6 +++++- ip/xfrm_state.c | 6 +++++- man/man8/ip-xfrm.8 | 6 +++--- 3 files changed, 13 insertions(+), 5 deletions(-) diff --git a/ip/xfrm_policy.c b/ip/xfrm_policy.c index 4a63e9ab..98984350 100644 --- a/ip/xfrm_policy.c +++ b/ip/xfrm_policy.c @@ -410,6 +410,10 @@ static int xfrm_policy_filter_match(struct xfrm_userpolicy_info *xpinfo, if (!filter.use) return 1; + if (filter.xpinfo.sel.family != AF_UNSPEC && + filter.xpinfo.sel.family != xpinfo->sel.family) + return 0; + if ((xpinfo->dir^filter.xpinfo.dir)&filter.dir_mask) return 0; @@ -780,7 +784,7 @@ static int xfrm_policy_list_or_deleteall(int argc, char **argv, int deleteall) char *selp = NULL; struct rtnl_handle rth; - if (argc > 0) + if (argc > 0 || preferred_family != AF_UNSPEC) filter.use = 1; filter.xpinfo.sel.family = preferred_family; diff --git a/ip/xfrm_state.c b/ip/xfrm_state.c index 93601437..f2727070 100644 --- a/ip/xfrm_state.c +++ b/ip/xfrm_state.c @@ -898,6 +898,10 @@ static int xfrm_state_filter_match(struct xfrm_usersa_info *xsinfo) if (!filter.use) return 1; + if (filter.xsinfo.family != AF_UNSPEC && + filter.xsinfo.family != xsinfo->family) + return 0; + if (filter.id_src_mask) if (xfrm_addr_match(&xsinfo->saddr, &filter.xsinfo.saddr, filter.id_src_mask)) @@ -1170,7 +1174,7 @@ static int xfrm_state_list_or_deleteall(int argc, char **argv, int deleteall) struct rtnl_handle rth; bool nokeys = false; - if (argc > 0) + if (argc > 0 || preferred_family != AF_UNSPEC) filter.use = 1; filter.xsinfo.family = preferred_family; diff --git a/man/man8/ip-xfrm.8 b/man/man8/ip-xfrm.8 index 95478085..cfce1e40 100644 --- a/man/man8/ip-xfrm.8 +++ b/man/man8/ip-xfrm.8 @@ -89,7 +89,7 @@ ip-xfrm \- transform configuration .IR MASK " ] ]" .ti -8 -.BR "ip xfrm state " deleteall " [" +.BR ip " [ " -4 " | " -6 " ] " "xfrm state deleteall" " [" .IR ID " ]" .RB "[ " mode .IR MODE " ]" @@ -99,7 +99,7 @@ ip-xfrm \- transform configuration .IR FLAG-LIST " ]" .ti -8 -.BR "ip xfrm state " list " [" +.BR ip " [ " -4 " | " -6 " ] " "xfrm state list" " [" .IR ID " ]" .RB "[ " nokeys " ]" .RB "[ " mode @@ -257,7 +257,7 @@ ip-xfrm \- transform configuration .IR PTYPE " ]" .ti -8 -.BR "ip xfrm policy" " { " deleteall " | " list " }" +.BR ip " [ " -4 " | " -6 " ] " "xfrm policy" " { " deleteall " | " list " }" .RB "[ " nosock " ]" .RI "[ " SELECTOR " ]" .RB "[ " dir