All of lore.kernel.org
 help / color / mirror / Atom feed
* ip_queue_xmit() used illegally
@ 2011-05-06 19:26 David Miller
  2011-05-06 20:21 ` David Miller
  0 siblings, 1 reply; 4+ messages in thread
From: David Miller @ 2011-05-06 19:26 UTC (permalink / raw)
  To: netdev; +Cc: vladislav.yasevich, yjwei, jchapman


Several users of ip_queue_xmit() use it illegally.

I've only audited L2TP and SCTP so far, and they both cannot use
ip_queue_xmit() with the way they operate currently.

The issue surrounds how the socket binding is maintained in
inet->inet_daddr, inet->inet_saddr etc.

TCP does things right, in that ip_queue_xmit() is only invoked with
inet->inet_daddr and inet->inet_saddr having fully resolved, final,
fully connected values.

This is an absolute requirement because if the socket's route
invalidates (which happens completely asynchronously) it's going to
lookup a new route using whatever is stored in
inet->inet_{daddr,saddr} and then use those addresses to build the
packet.  Even if ->inet_{saddr,daddr} are both zero this will still
emit a packet (bonus points if you know what addresses will be picked,
no peeking at route.c :-).

SCTP stores it's binding information using transports and assosciations
and does not fill in the ->inet_{daddr,saddr} values.

It tries to work around this route issue by checking dst->obsolete
directly in sctp_packet_transmit(), which just makes the race smaller
and does not eliminate it.  ip_queue_xmit() can still end up with
__sk_dst_check() returning NULL and then we end up emitting a
potentially bogus packet.

L2TP supports more of a datagram type socket semantic than a stream
one, it allows unconnected modes of operation.  And for this reason
it also cannot use ip_queue_xmit() legally.

After a quick cursory scan it seem like DCCP is OK.

I think SCTP could potentially be fixed by simply filling in the
inet->inet_{daddr,saddr} values when it makes an internal binding
of the transport via sctp_transport_route().

L2TP on the other hand will need to use another interface to send ipv4
packets because it allows disconnected operation.

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: ip_queue_xmit() used illegally
  2011-05-06 19:26 ip_queue_xmit() used illegally David Miller
@ 2011-05-06 20:21 ` David Miller
  2011-05-06 21:10   ` Vladislav Yasevich
  0 siblings, 1 reply; 4+ messages in thread
From: David Miller @ 2011-05-06 20:21 UTC (permalink / raw)
  To: netdev; +Cc: vladislav.yasevich, yjwei, jchapman

From: David Miller <davem@davemloft.net>
Date: Fri, 06 May 2011 12:26:56 -0700 (PDT)

> SCTP stores it's binding information using transports and assosciations
> and does not fill in the ->inet_{daddr,saddr} values.
> 
> It tries to work around this route issue by checking dst->obsolete
> directly in sctp_packet_transmit(), which just makes the race smaller
> and does not eliminate it.  ip_queue_xmit() can still end up with
> __sk_dst_check() returning NULL and then we end up emitting a
> potentially bogus packet.

I take this back, we added this hack where things like SCTP can
pre-route the packet by hooking up the route to the SKB before
calling ->queue_xmit.

And L2TP does something similar.

So false alarm, nothing to see here :-)

I still want to clean this up so that this kind of stuff can be
handled generically inside of ->queue_xmit() by passing in the correct
addressing information.

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: ip_queue_xmit() used illegally
  2011-05-06 20:21 ` David Miller
@ 2011-05-06 21:10   ` Vladislav Yasevich
  2011-05-06 21:28     ` David Miller
  0 siblings, 1 reply; 4+ messages in thread
From: Vladislav Yasevich @ 2011-05-06 21:10 UTC (permalink / raw)
  To: David Miller; +Cc: netdev, yjwei, jchapman

On 05/06/2011 04:21 PM, David Miller wrote:
> From: David Miller <davem@davemloft.net>
> Date: Fri, 06 May 2011 12:26:56 -0700 (PDT)
> 
>> SCTP stores it's binding information using transports and assosciations
>> and does not fill in the ->inet_{daddr,saddr} values.
>>
>> It tries to work around this route issue by checking dst->obsolete
>> directly in sctp_packet_transmit(), which just makes the race smaller
>> and does not eliminate it.  ip_queue_xmit() can still end up with
>> __sk_dst_check() returning NULL and then we end up emitting a
>> potentially bogus packet.
> 
> I take this back, we added this hack where things like SCTP can
> pre-route the packet by hooking up the route to the SKB before
> calling ->queue_xmit.
> 
> And L2TP does something similar.
> 
> So false alarm, nothing to see here :-)
> 
> I still want to clean this up so that this kind of stuff can be
> handled generically inside of ->queue_xmit() by passing in the correct
> addressing information.
> 

Wow, You had me scrambling there for a while.  I was just about to send note
about the pre-hooked route, but you beat me to it.

The reason why sctp doesn't change the inet_addr, is because that address can theoretically
change on ever packet transmit due to multi-homing nature of SCTP.

I'll take a look at ->queue_xmit() to see if SCTP can convert to using that.

-vlad

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: ip_queue_xmit() used illegally
  2011-05-06 21:10   ` Vladislav Yasevich
@ 2011-05-06 21:28     ` David Miller
  0 siblings, 0 replies; 4+ messages in thread
From: David Miller @ 2011-05-06 21:28 UTC (permalink / raw)
  To: vladislav.yasevich; +Cc: netdev, yjwei, jchapman

From: Vladislav Yasevich <vladislav.yasevich@hp.com>
Date: Fri, 06 May 2011 17:10:31 -0400

> I'll take a look at ->queue_xmit() to see if SCTP can convert to using that.

It already does via sctp_v4_queue_xmit() --> ip_queue_xmit().

I have a plan which I'm working on already, it will involve putting
a "struct flowi" into the sctp_transport.

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2011-05-06 21:29 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-05-06 19:26 ip_queue_xmit() used illegally David Miller
2011-05-06 20:21 ` David Miller
2011-05-06 21:10   ` Vladislav Yasevich
2011-05-06 21:28     ` David Miller

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.