Re: [PATCH net] ipv4: icmp: reject non-unicast input routes in icmp_route_lookup

"dongchenchen (A)" <[email protected]>
Newsgroups org.kernel.vger.netdev
Message-ID <[email protected]>
> When the forward output route cannot be used in icmp_route_lookup(),
> it enters the "reverse path" and calls ip_route_input() on fl4_dec.daddr,
> the original packet's source address.
> 
> ip_route_input() only returns an error for truly invalid packets. For
> local, broadcast, multicast and unreachable addresses it still succeeds
> and returns an input route whose dst.output is set to ip_rt_bug().  The
> existing check only rejects RTN_LOCAL routes, so the other route types
> can still be returned and later used for output, syzkaller triggering a
> WARN_ON_ONCE() in ip_rt_bug() as bellow:
> 
>   ------------[ cut here ]------------
>   WARNING: net/ipv4/route.c:1273 at ip_rt_bug+0x14/0x20
>   RIP: 0010:ip_rt_bug+0x14/0x20
>   Call Trace:
>    ip_push_pending_frames+0xfa/0x100
>    __icmp_send+0x905/0xf10
>    ip_options_compile+0xc0/0xd0
>    ip_rcv_finish_core+0x321/0xae0
>    ip_rcv+0x1de/0x260
>    __netif_receive_skb_one_core+0x11a/0x130
>    netif_receive_skb+0x7b/0x260
>    tun_get_user+0x11bf/0x1c10
>   ------------[ cut here ]------------
> 
> If the original source address is unroutable, ip_route_input() returns a
> RTN_UNREACHABLE input route with err == 0, and the ICMP reply is then sent
> through ip_rt_bug().
> 
> Only RTN_UNICAST input routes have dst.output set to ip_output() and are
> safe to use for output.  Reject any input route that is not RTN_UNICAST.
> 
> Fixes: 8b7817f3a959 ("[IPSEC]: Add ICMP host relookup support")
> Signed-off-by: Dong Chenchen <[email protected]>
> ---
>   net/ipv4/icmp.c | 12 +++++++-----
>   1 file changed, 7 insertions(+), 5 deletions(-)
> 
> diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c
> index 0caedfc7ca92..d58ac2f23f9f 100644
> --- a/net/ipv4/icmp.c
> +++ b/net/ipv4/icmp.c
> @@ -584,12 +584,14 @@ static struct rtable *icmp_route_lookup(struct net *net, struct flowi4 *fl4,
>   		 * At this point, fl4_dec.daddr should NOT be local (we
>   		 * checked fl4_dec.saddr above). However, a race condition
>   		 * may occur if the address is added to the interface
> -		 * concurrently. In that case, ip_route_input() returns a
> -		 * LOCAL route with dst.output=ip_rt_bug, which must not
> -		 * be used for output.
> +		 * concurrently, or if fl4_dec.daddr is otherwise unroutable.
> +		 * In that case, ip_route_input() returns an input route
> +		 * (RTN_LOCAL, RTN_BROADCAST, RTN_UNREACHABLE or
> +		 * RTN_MULTICAST) with dst.output set to ip_rt_bug(), which
> +		 * must not be used for output.
>   		 */
> -		if (!err && rt2 && rt2->rt_type == RTN_LOCAL) {
> -			net_warn_ratelimited("detected local route for %pI4 during ICMP sending, src %pI4\n",
> +		if (!err && rt2 && rt2->rt_type != RTN_UNICAST) {
sorry, this judgement will reject bforward packet.
broadcast and multicast rt with ip_rt_bug has been reject after
icmp_route_lookup.We only need to add a judgment for RTN_UNREACHABLE
v2 will be sent.

best regards
Dong Chenchen> +			net_warn_ratelimited("detected unusable input route 
for %pI4 during ICMP sending, src %pI4\n",
>   					     &fl4_dec.daddr, &fl4_dec.saddr);
>   			dst_release(&rt2->dst);
>   			err = -EINVAL;
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.