Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

net: mctp: defer creation of dst after source-address check

Sashiko reports:

> mctp_dst_from_route() increments the device reference count by calling
> mctp_dev_hold(). When a valid route is found and dst is NULL, the
> structure copy is bypassed and rc is set to 0.

Instead of optimistically creating a dst from the final route (then
releasing it if the saddr is invalid), perform the saddr check first.

This means we don't have an unuecessary hold/release on the dev, which
could leak if the dst pointer is NULL. No caller passes a NULL dst at
present though (so the leak is not possible), but this is an intended
use of mctp_dst_from_route().

Signed-off-by: Jeremy Kerr <jk@codeconstruct.com.au>
Reviewed-by: Simon Horman <horms@kernel.org>
Link: https://patch.msgid.link/20260403-dev-mctp-dst-defer-v1-1-9c2c55faf9e9@codeconstruct.com.au
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

authored by

Jeremy Kerr and committed by
Jakub Kicinski
f32ba096 70e32aad

+11 -11
+11 -11
net/mctp/route.c
··· 897 897 898 898 /* must only be called on a direct route, as the final output hop */ 899 899 static void mctp_dst_from_route(struct mctp_dst *dst, mctp_eid_t eid, 900 - unsigned int mtu, struct mctp_route *route) 900 + mctp_eid_t saddr, unsigned int mtu, 901 + struct mctp_route *route) 901 902 { 902 903 mctp_dev_hold(route->dev); 903 904 dst->nexthop = eid; ··· 908 907 dst->mtu = min(dst->mtu, mtu); 909 908 dst->halen = 0; 910 909 dst->output = route->output; 911 - dst->saddr = mctp_dev_saddr(route->dev); 910 + dst->saddr = saddr; 912 911 } 913 912 914 913 int mctp_dst_from_extaddr(struct mctp_dst *dst, struct net *net, int ifindex, ··· 976 975 { 977 976 const unsigned int max_depth = 32; 978 977 unsigned int depth, mtu = 0; 979 - struct mctp_dst dst_tmp; 980 978 int rc = -EHOSTUNREACH; 981 979 982 980 rcu_read_lock(); ··· 996 996 mtu = mtu ?: rt->mtu; 997 997 998 998 if (rt->dst_type == MCTP_ROUTE_DIRECT) { 999 - mctp_dst_from_route(&dst_tmp, daddr, mtu, rt); 999 + mctp_eid_t saddr = mctp_dev_saddr(rt->dev); 1000 + 1000 1001 /* cannot do gateway-ed routes without a src */ 1001 - if (dst_tmp.saddr == MCTP_ADDR_NULL && depth != 0) { 1002 - mctp_dst_release(&dst_tmp); 1003 - } else { 1004 - if (dst) 1005 - *dst = dst_tmp; 1006 - rc = 0; 1007 - } 1002 + if (saddr == MCTP_ADDR_NULL && depth != 0) 1003 + break; 1004 + 1005 + if (dst) 1006 + mctp_dst_from_route(dst, daddr, saddr, mtu, rt); 1007 + rc = 0; 1008 1008 break; 1009 1009 1010 1010 } else if (rt->dst_type == MCTP_ROUTE_GATEWAY) {