linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH net] net: lapb: Copy the skb before sending a packet
@ 2021-02-01  5:57 Xie He
  2021-02-01 10:05 ` Martin Schiller
                   ` (2 more replies)
  0 siblings, 3 replies; 11+ messages in thread
From: Xie He @ 2021-02-01  5:57 UTC (permalink / raw)
  To: David S. Miller, Jakub Kicinski, linux-x25, netdev, linux-kernel,
	Martin Schiller
  Cc: Xie He

When sending a packet, we will prepend it with an LAPB header.
This modifies the shared parts of a cloned skb, so we should copy the
skb rather than just clone it, before we prepend the header.

In "Documentation/networking/driver.rst" (the 2nd point), it states
that drivers shouldn't modify the shared parts of a cloned skb when
transmitting.

The "dev_queue_xmit_nit" function in "net/core/dev.c", which is called
when an skb is being sent, clones the skb and sents the clone to
AF_PACKET sockets. Because the LAPB drivers first remove a 1-byte
pseudo-header before handing over the skb to us, if we don't copy the
skb before prepending the LAPB header, the first byte of the packets
received on AF_PACKET sockets can be corrupted.

Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Cc: Martin Schiller <ms@dev.tdt.de>
Signed-off-by: Xie He <xie.he.0141@gmail.com>
---
 net/lapb/lapb_out.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/net/lapb/lapb_out.c b/net/lapb/lapb_out.c
index 7a4d0715d1c3..a966d29c772d 100644
--- a/net/lapb/lapb_out.c
+++ b/net/lapb/lapb_out.c
@@ -82,7 +82,8 @@ void lapb_kick(struct lapb_cb *lapb)
 		skb = skb_dequeue(&lapb->write_queue);
 
 		do {
-			if ((skbn = skb_clone(skb, GFP_ATOMIC)) == NULL) {
+			skbn = skb_copy(skb, GFP_ATOMIC);
+			if (!skbn) {
 				skb_queue_head(&lapb->write_queue, skb);
 				break;
 			}
-- 
2.27.0


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

* Re: [PATCH net] net: lapb: Copy the skb before sending a packet
  2021-02-01  5:57 [PATCH net] net: lapb: Copy the skb before sending a packet Xie He
@ 2021-02-01 10:05 ` Martin Schiller
  2021-02-01 10:49   ` Xie He
  2021-02-01 14:10 ` Julian Wiedmann
  2021-02-02 16:50 ` patchwork-bot+netdevbpf
  2 siblings, 1 reply; 11+ messages in thread
From: Martin Schiller @ 2021-02-01 10:05 UTC (permalink / raw)
  To: Xie He; +Cc: David S. Miller, Jakub Kicinski, linux-x25, netdev, linux-kernel

On 2021-02-01 06:57, Xie He wrote:
> When sending a packet, we will prepend it with an LAPB header.
> This modifies the shared parts of a cloned skb, so we should copy the
> skb rather than just clone it, before we prepend the header.
> 
> In "Documentation/networking/driver.rst" (the 2nd point), it states
> that drivers shouldn't modify the shared parts of a cloned skb when
> transmitting.
> 
> The "dev_queue_xmit_nit" function in "net/core/dev.c", which is called
> when an skb is being sent, clones the skb and sents the clone to
> AF_PACKET sockets. Because the LAPB drivers first remove a 1-byte
> pseudo-header before handing over the skb to us, if we don't copy the
> skb before prepending the LAPB header, the first byte of the packets
> received on AF_PACKET sockets can be corrupted.

What kind of packages do you mean are corrupted?
ETH_P_X25 or ETH_P_HDLC?

I have also sent a patch here in the past that addressed corrupted
ETH_P_X25 frames on an AF_PACKET socket:

https://lkml.org/lkml/2020/1/13/388

Unfortunately I could not track and describe exactly where the problem
was.

I just wonder when/where is the logically correct place to copy the skb.
Shouldn't it be copied before removing the pseudo header (as I did in my
patch)?

> 
> Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
> Cc: Martin Schiller <ms@dev.tdt.de>
> Signed-off-by: Xie He <xie.he.0141@gmail.com>
> ---
>  net/lapb/lapb_out.c | 3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)
> 
> diff --git a/net/lapb/lapb_out.c b/net/lapb/lapb_out.c
> index 7a4d0715d1c3..a966d29c772d 100644
> --- a/net/lapb/lapb_out.c
> +++ b/net/lapb/lapb_out.c
> @@ -82,7 +82,8 @@ void lapb_kick(struct lapb_cb *lapb)
>  		skb = skb_dequeue(&lapb->write_queue);
> 
>  		do {
> -			if ((skbn = skb_clone(skb, GFP_ATOMIC)) == NULL) {
> +			skbn = skb_copy(skb, GFP_ATOMIC);
> +			if (!skbn) {
>  				skb_queue_head(&lapb->write_queue, skb);
>  				break;
>  			}

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

* Re: [PATCH net] net: lapb: Copy the skb before sending a packet
  2021-02-01 10:05 ` Martin Schiller
@ 2021-02-01 10:49   ` Xie He
  2021-02-01 12:47     ` Martin Schiller
  0 siblings, 1 reply; 11+ messages in thread
From: Xie He @ 2021-02-01 10:49 UTC (permalink / raw)
  To: Martin Schiller
  Cc: David S. Miller, Jakub Kicinski, Linux X25,
	Linux Kernel Network Developers, LKML

On Mon, Feb 1, 2021 at 2:05 AM Martin Schiller <ms@dev.tdt.de> wrote:
>
> What kind of packages do you mean are corrupted?
> ETH_P_X25 or ETH_P_HDLC?

I mean ETH_P_X25. I was using "lapbether.c" to test so there was no ETH_P_HDLC.

> I have also sent a patch here in the past that addressed corrupted
> ETH_P_X25 frames on an AF_PACKET socket:
>
> https://lkml.org/lkml/2020/1/13/388
>
> Unfortunately I could not track and describe exactly where the problem
> was.

Ah... Looks like we had the same problem.

> I just wonder when/where is the logically correct place to copy the skb.
> Shouldn't it be copied before removing the pseudo header (as I did in my
> patch)?

I think it's not necessary to copy it before removing the pseudo
header, because "skb_pull" will not change any data in the data
buffer. "skb_pull" will only change the values of "skb->data" and
"skb->len". These values are not shared between clones of skbs, so
it's safe to change them without affecting other clones of the skb.

I also choose to copy the skb in the LAPB module (rather than in the
drivers) because I see all drivers have this problem (including the
recently deleted x25_asy.c driver), so it'd be better to fix this
issue in the LAPB module, for all drivers.

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

* Re: [PATCH net] net: lapb: Copy the skb before sending a packet
  2021-02-01 10:49   ` Xie He
@ 2021-02-01 12:47     ` Martin Schiller
  0 siblings, 0 replies; 11+ messages in thread
From: Martin Schiller @ 2021-02-01 12:47 UTC (permalink / raw)
  To: Xie He
  Cc: David S. Miller, Jakub Kicinski, Linux X25,
	Linux Kernel Network Developers, LKML

On 2021-02-01 11:49, Xie He wrote:
> On Mon, Feb 1, 2021 at 2:05 AM Martin Schiller <ms@dev.tdt.de> wrote:
>> 
>> What kind of packages do you mean are corrupted?
>> ETH_P_X25 or ETH_P_HDLC?
> 
> I mean ETH_P_X25. I was using "lapbether.c" to test so there was no 
> ETH_P_HDLC.
> 
>> I have also sent a patch here in the past that addressed corrupted
>> ETH_P_X25 frames on an AF_PACKET socket:
>> 
>> https://lkml.org/lkml/2020/1/13/388
>> 
>> Unfortunately I could not track and describe exactly where the problem
>> was.
> 
> Ah... Looks like we had the same problem.
> 
>> I just wonder when/where is the logically correct place to copy the 
>> skb.
>> Shouldn't it be copied before removing the pseudo header (as I did in 
>> my
>> patch)?
> 
> I think it's not necessary to copy it before removing the pseudo
> header, because "skb_pull" will not change any data in the data
> buffer. "skb_pull" will only change the values of "skb->data" and
> "skb->len". These values are not shared between clones of skbs, so
> it's safe to change them without affecting other clones of the skb.
> 
> I also choose to copy the skb in the LAPB module (rather than in the
> drivers) because I see all drivers have this problem (including the
> recently deleted x25_asy.c driver), so it'd be better to fix this
> issue in the LAPB module, for all drivers.

OK.

Acked-by: Martin Schiller <ms@dev.tdt.de>


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

* Re: [PATCH net] net: lapb: Copy the skb before sending a packet
  2021-02-01  5:57 [PATCH net] net: lapb: Copy the skb before sending a packet Xie He
  2021-02-01 10:05 ` Martin Schiller
@ 2021-02-01 14:10 ` Julian Wiedmann
  2021-02-01 16:14   ` Xie He
  2021-02-02 16:50 ` patchwork-bot+netdevbpf
  2 siblings, 1 reply; 11+ messages in thread
From: Julian Wiedmann @ 2021-02-01 14:10 UTC (permalink / raw)
  To: Xie He, David S. Miller, Jakub Kicinski, linux-x25, netdev,
	linux-kernel, Martin Schiller

On 01.02.21 06:57, Xie He wrote:
> When sending a packet, we will prepend it with an LAPB header.
> This modifies the shared parts of a cloned skb, so we should copy the
> skb rather than just clone it, before we prepend the header.
> 
> In "Documentation/networking/driver.rst" (the 2nd point), it states
> that drivers shouldn't modify the shared parts of a cloned skb when
> transmitting.
> 

This sounds a bit like you want skb_cow_head() ... ?

> The "dev_queue_xmit_nit" function in "net/core/dev.c", which is called
> when an skb is being sent, clones the skb and sents the clone to
> AF_PACKET sockets. Because the LAPB drivers first remove a 1-byte
> pseudo-header before handing over the skb to us, if we don't copy the
> skb before prepending the LAPB header, the first byte of the packets
> received on AF_PACKET sockets can be corrupted.
> 
> Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
> Cc: Martin Schiller <ms@dev.tdt.de>
> Signed-off-by: Xie He <xie.he.0141@gmail.com>
> ---
>  net/lapb/lapb_out.c | 3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)
> 
> diff --git a/net/lapb/lapb_out.c b/net/lapb/lapb_out.c
> index 7a4d0715d1c3..a966d29c772d 100644
> --- a/net/lapb/lapb_out.c
> +++ b/net/lapb/lapb_out.c
> @@ -82,7 +82,8 @@ void lapb_kick(struct lapb_cb *lapb)
>  		skb = skb_dequeue(&lapb->write_queue);
>  
>  		do {
> -			if ((skbn = skb_clone(skb, GFP_ATOMIC)) == NULL) {
> +			skbn = skb_copy(skb, GFP_ATOMIC);
> +			if (!skbn) {
>  				skb_queue_head(&lapb->write_queue, skb);
>  				break;
>  			}
> 


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

* Re: [PATCH net] net: lapb: Copy the skb before sending a packet
  2021-02-01 14:10 ` Julian Wiedmann
@ 2021-02-01 16:14   ` Xie He
  2021-02-02  4:42     ` Jakub Kicinski
  2021-02-02  9:04     ` David Laight
  0 siblings, 2 replies; 11+ messages in thread
From: Xie He @ 2021-02-01 16:14 UTC (permalink / raw)
  To: Julian Wiedmann
  Cc: David S. Miller, Jakub Kicinski, Linux X25,
	Linux Kernel Network Developers, LKML, Martin Schiller

On Mon, Feb 1, 2021 at 6:10 AM Julian Wiedmann <jwi@linux.ibm.com> wrote:
>
> This sounds a bit like you want skb_cow_head() ... ?

Calling "skb_cow_head" before we call "skb_clone" would indeed solve
the problem of writes to our clones affecting clones in other parts of
the system. But since we are still writing to the skb after
"skb_clone", it'd still be better to replace "skb_clone" with
"skb_copy" to avoid interference between our own clones.

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

* Re: [PATCH net] net: lapb: Copy the skb before sending a packet
  2021-02-01 16:14   ` Xie He
@ 2021-02-02  4:42     ` Jakub Kicinski
  2021-02-02  6:25       ` Xie He
  2021-02-02  9:04     ` David Laight
  1 sibling, 1 reply; 11+ messages in thread
From: Jakub Kicinski @ 2021-02-02  4:42 UTC (permalink / raw)
  To: Xie He
  Cc: Julian Wiedmann, David S. Miller, Linux X25,
	Linux Kernel Network Developers, LKML, Martin Schiller

On Mon, 1 Feb 2021 08:14:31 -0800 Xie He wrote:
> On Mon, Feb 1, 2021 at 6:10 AM Julian Wiedmann <jwi@linux.ibm.com> wrote:
> > This sounds a bit like you want skb_cow_head() ... ?  
> 
> Calling "skb_cow_head" before we call "skb_clone" would indeed solve
> the problem of writes to our clones affecting clones in other parts of
> the system. But since we are still writing to the skb after
> "skb_clone", it'd still be better to replace "skb_clone" with
> "skb_copy" to avoid interference between our own clones.

Why call skb_cow_head() before skb_clone()? skb_cow_head should be
called before the data in skb head is modified. I'm assuming you're only
modifying "front" of the frame, right? skb_cow_head() should do nicely
in that case.

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

* Re: [PATCH net] net: lapb: Copy the skb before sending a packet
  2021-02-02  4:42     ` Jakub Kicinski
@ 2021-02-02  6:25       ` Xie He
  2021-02-02 16:41         ` Jakub Kicinski
  0 siblings, 1 reply; 11+ messages in thread
From: Xie He @ 2021-02-02  6:25 UTC (permalink / raw)
  To: Jakub Kicinski
  Cc: Julian Wiedmann, David S. Miller, Linux X25,
	Linux Kernel Network Developers, LKML, Martin Schiller

On Mon, Feb 1, 2021 at 8:42 PM Jakub Kicinski <kuba@kernel.org> wrote:
>
> On Mon, 1 Feb 2021 08:14:31 -0800 Xie He wrote:
> > On Mon, Feb 1, 2021 at 6:10 AM Julian Wiedmann <jwi@linux.ibm.com> wrote:
> > > This sounds a bit like you want skb_cow_head() ... ?
> >
> > Calling "skb_cow_head" before we call "skb_clone" would indeed solve
> > the problem of writes to our clones affecting clones in other parts of
> > the system. But since we are still writing to the skb after
> > "skb_clone", it'd still be better to replace "skb_clone" with
> > "skb_copy" to avoid interference between our own clones.
>
> Why call skb_cow_head() before skb_clone()? skb_cow_head should be
> called before the data in skb head is modified. I'm assuming you're only
> modifying "front" of the frame, right? skb_cow_head() should do nicely
> in that case.

The modification happens after skb_clone. If we call skb_cow_head
after skb_clone (before the modification), then skb_cow_head would
always see that the skb is a clone and would always copy it. Therefore
skb_clone + skb_cow_head is equivalent to skb_copy.

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

* RE: [PATCH net] net: lapb: Copy the skb before sending a packet
  2021-02-01 16:14   ` Xie He
  2021-02-02  4:42     ` Jakub Kicinski
@ 2021-02-02  9:04     ` David Laight
  1 sibling, 0 replies; 11+ messages in thread
From: David Laight @ 2021-02-02  9:04 UTC (permalink / raw)
  To: 'Xie He', Julian Wiedmann
  Cc: David S. Miller, Jakub Kicinski, Linux X25,
	Linux Kernel Network Developers, LKML, Martin Schiller

From: Xie He
> Sent: 01 February 2021 16:15
> 
> On Mon, Feb 1, 2021 at 6:10 AM Julian Wiedmann <jwi@linux.ibm.com> wrote:
> >
> > This sounds a bit like you want skb_cow_head() ... ?
> 
> Calling "skb_cow_head" before we call "skb_clone" would indeed solve
> the problem of writes to our clones affecting clones in other parts of
> the system. But since we are still writing to the skb after
> "skb_clone", it'd still be better to replace "skb_clone" with
> "skb_copy" to avoid interference between our own clones.

What is the fastest link lapb is actually used on these days?
64k used to be 'fast' - so copying the skb isn't going to have
a noticeable effect on system performance.

We did once get a 'free' upgrade of our X.25 link from 2400 to 9600.
Probably due to the power consumption and rack space needed for
the older modem.

	David

-
Registered Address Lakeside, Bramley Road, Mount Farm, Milton Keynes, MK1 1PT, UK
Registration No: 1397386 (Wales)

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

* Re: [PATCH net] net: lapb: Copy the skb before sending a packet
  2021-02-02  6:25       ` Xie He
@ 2021-02-02 16:41         ` Jakub Kicinski
  0 siblings, 0 replies; 11+ messages in thread
From: Jakub Kicinski @ 2021-02-02 16:41 UTC (permalink / raw)
  To: Xie He
  Cc: Julian Wiedmann, David S. Miller, Linux X25,
	Linux Kernel Network Developers, LKML, Martin Schiller

On Mon, 1 Feb 2021 22:25:17 -0800 Xie He wrote:
> On Mon, Feb 1, 2021 at 8:42 PM Jakub Kicinski <kuba@kernel.org> wrote:
> >
> > On Mon, 1 Feb 2021 08:14:31 -0800 Xie He wrote:  
> > > On Mon, Feb 1, 2021 at 6:10 AM Julian Wiedmann <jwi@linux.ibm.com> wrote:  
>  [...]  
> > >
> > > Calling "skb_cow_head" before we call "skb_clone" would indeed solve
> > > the problem of writes to our clones affecting clones in other parts of
> > > the system. But since we are still writing to the skb after
> > > "skb_clone", it'd still be better to replace "skb_clone" with
> > > "skb_copy" to avoid interference between our own clones.  
> >
> > Why call skb_cow_head() before skb_clone()? skb_cow_head should be
> > called before the data in skb head is modified. I'm assuming you're only
> > modifying "front" of the frame, right? skb_cow_head() should do nicely
> > in that case.  
> 
> The modification happens after skb_clone. If we call skb_cow_head
> after skb_clone (before the modification), then skb_cow_head would
> always see that the skb is a clone and would always copy it. Therefore
> skb_clone + skb_cow_head is equivalent to skb_copy.

You're right. I thought cow_head is a little more clever.

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

* Re: [PATCH net] net: lapb: Copy the skb before sending a packet
  2021-02-01  5:57 [PATCH net] net: lapb: Copy the skb before sending a packet Xie He
  2021-02-01 10:05 ` Martin Schiller
  2021-02-01 14:10 ` Julian Wiedmann
@ 2021-02-02 16:50 ` patchwork-bot+netdevbpf
  2 siblings, 0 replies; 11+ messages in thread
From: patchwork-bot+netdevbpf @ 2021-02-02 16:50 UTC (permalink / raw)
  To: Xie He; +Cc: davem, kuba, linux-x25, netdev, linux-kernel, ms

Hello:

This patch was applied to netdev/net.git (refs/heads/master):

On Sun, 31 Jan 2021 21:57:06 -0800 you wrote:
> When sending a packet, we will prepend it with an LAPB header.
> This modifies the shared parts of a cloned skb, so we should copy the
> skb rather than just clone it, before we prepend the header.
> 
> In "Documentation/networking/driver.rst" (the 2nd point), it states
> that drivers shouldn't modify the shared parts of a cloned skb when
> transmitting.
> 
> [...]

Here is the summary with links:
  - [net] net: lapb: Copy the skb before sending a packet
    https://git.kernel.org/netdev/net/c/88c7a9fd9bdd

You are awesome, thank you!
--
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html



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

end of thread, other threads:[~2021-02-02 16:55 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-02-01  5:57 [PATCH net] net: lapb: Copy the skb before sending a packet Xie He
2021-02-01 10:05 ` Martin Schiller
2021-02-01 10:49   ` Xie He
2021-02-01 12:47     ` Martin Schiller
2021-02-01 14:10 ` Julian Wiedmann
2021-02-01 16:14   ` Xie He
2021-02-02  4:42     ` Jakub Kicinski
2021-02-02  6:25       ` Xie He
2021-02-02 16:41         ` Jakub Kicinski
2021-02-02  9:04     ` David Laight
2021-02-02 16:50 ` patchwork-bot+netdevbpf

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).