2020-11-19 17:30:07

by Yves-Alexis Perez

[permalink] [raw]
Subject: [PATCH] usbnet: ipheth: fix connectivity with iOS 14

Starting with iOS 14 released in September 2020, connectivity using the
personal hotspot USB tethering function of iOS devices is broken.

Communication between the host and the device (for example ICMP traffic
or DNS resolution using the DNS service running in the device itself)
works fine, but communication to endpoints further away doesn't work.

Investigation on the matter shows that UDP and ICMP traffic from the
tethered host is reaching the Internet at all. For TCP traffic there are
exchanges between tethered host and server but packets are modified in
transit leading to impossible communication.

After some trials Matti Vuorela discovered that reducing the URB buffer
size by two bytes restored the previous behavior. While a better
solution might exist to fix the issue, since the protocol is not
publicly documented and considering the small size of the fix, let's do
that.

Tested-by: Matti Vuorela <[email protected]>
Signed-off-by: Yves-Alexis Perez <[email protected]>
Link: https://lore.kernel.org/linux-usb/CAAn0qaXmysJ9vx3ZEMkViv_B19ju-_ExN8Yn_uSefxpjS6g4Lw@mail.gmail.com/
Link: https://github.com/libimobiledevice/libimobiledevice/issues/1038
Cc: [email protected]
---
drivers/net/usb/ipheth.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/usb/ipheth.c b/drivers/net/usb/ipheth.c
index b09b45382faf..207e59e74935 100644
--- a/drivers/net/usb/ipheth.c
+++ b/drivers/net/usb/ipheth.c
@@ -59,7 +59,7 @@
#define IPHETH_USBINTF_SUBCLASS 253
#define IPHETH_USBINTF_PROTO 1

-#define IPHETH_BUF_SIZE 1516
+#define IPHETH_BUF_SIZE 1514
#define IPHETH_IP_ALIGN 2 /* padding at front of URB */
#define IPHETH_TX_TIMEOUT (5 * HZ)

--
2.29.2


2020-11-20 09:19:46

by Sergei Shtylyov

[permalink] [raw]
Subject: Re: [PATCH] usbnet: ipheth: fix connectivity with iOS 14

Hello!

On 19.11.2020 20:24, Yves-Alexis Perez wrote:

> Starting with iOS 14 released in September 2020, connectivity using the
> personal hotspot USB tethering function of iOS devices is broken.
>
> Communication between the host and the device (for example ICMP traffic
> or DNS resolution using the DNS service running in the device itself)
> works fine, but communication to endpoints further away doesn't work.
>
> Investigation on the matter shows that UDP and ICMP traffic from the
^ "no" missing?

> tethered host is reaching the Internet at all. For TCP traffic there are
> exchanges between tethered host and server but packets are modified in
> transit leading to impossible communication.
>
> After some trials Matti Vuorela discovered that reducing the URB buffer
> size by two bytes restored the previous behavior. While a better
> solution might exist to fix the issue, since the protocol is not
> publicly documented and considering the small size of the fix, let's do
> that.
>
> Tested-by: Matti Vuorela <[email protected]>
> Signed-off-by: Yves-Alexis Perez <[email protected]>
> Link: https://lore.kernel.org/linux-usb/CAAn0qaXmysJ9vx3ZEMkViv_B19ju-_ExN8Yn_uSefxpjS6g4Lw@mail.gmail.com/
> Link: https://github.com/libimobiledevice/libimobiledevice/issues/1038
> Cc: [email protected]
[...]

MBR, Sergei

2020-11-20 17:02:41

by Yves-Alexis Perez

[permalink] [raw]
Subject: Re: [PATCH] usbnet: ipheth: fix connectivity with iOS 14

On Fri, 2020-11-20 at 12:15 +0300, Sergei Shtylyov wrote:
> > Investigation on the matter shows that UDP and ICMP traffic from the
>                                          ^ "no" missing?
Yes indeed. Thanks and sorry for the typo.

Regards,
--
Yves-Alexis

2020-11-21 22:06:28

by Jakub Kicinski

[permalink] [raw]
Subject: Re: [PATCH] usbnet: ipheth: fix connectivity with iOS 14

On Thu, 19 Nov 2020 18:24:39 +0100 Yves-Alexis Perez wrote:
> Starting with iOS 14 released in September 2020, connectivity using the
> personal hotspot USB tethering function of iOS devices is broken.
>
> Communication between the host and the device (for example ICMP traffic
> or DNS resolution using the DNS service running in the device itself)
> works fine, but communication to endpoints further away doesn't work.
>
> Investigation on the matter shows that UDP and ICMP traffic from the
> tethered host is reaching the Internet at all. For TCP traffic there are
> exchanges between tethered host and server but packets are modified in
> transit leading to impossible communication.
>
> After some trials Matti Vuorela discovered that reducing the URB buffer
> size by two bytes restored the previous behavior. While a better
> solution might exist to fix the issue, since the protocol is not
> publicly documented and considering the small size of the fix, let's do
> that.
>
> Tested-by: Matti Vuorela <[email protected]>
> Signed-off-by: Yves-Alexis Perez <[email protected]>
> Link: https://lore.kernel.org/linux-usb/CAAn0qaXmysJ9vx3ZEMkViv_B19ju-_ExN8Yn_uSefxpjS6g4Lw@mail.gmail.com/
> Link: https://github.com/libimobiledevice/libimobiledevice/issues/1038

Applied to net with the typo fixed, thanks!

2020-11-24 16:43:40

by Jakub Kicinski

[permalink] [raw]
Subject: Re: [PATCH] usbnet: ipheth: fix connectivity with iOS 14

On Tue, 24 Nov 2020 11:41:40 +0100 Yves-Alexis Perez wrote:
> On Sat, 2020-11-21 at 14:03 -0800, Jakub Kicinski wrote:
> > Applied to net with the typo fixed, thanks!
>
> Thanks!
>
> Is there any chance it'll be in 5.10 or will it have to wait for the 5.11
> merge window?

It'll be in 5.10-rc6.

> Also it should be applied to all supported/stable kernels. I guess that'll
> have to wait until it's in Linus tree according [1] to but I'm unsure if I
> need to trigger the action myself or if Greg (or Dave, according to [2]) will
> do it.

Dave (or someone helping him, like myself) will do it, probably around
the time 5.10-rc6 is released.

> I looked at [3] and it seems that adding the CC: stable in my commit message
> maybe was an error because it's marked as a Failure, so if there's anything
> needed from me here, don't hesitate to ask.

No worries, I stripped the CC and put the patch in Dave's stable queue.

2020-11-24 21:08:02

by Yves-Alexis Perez

[permalink] [raw]
Subject: Re: [PATCH] usbnet: ipheth: fix connectivity with iOS 14

On Sat, 2020-11-21 at 14:03 -0800, Jakub Kicinski wrote:
> Applied to net with the typo fixed, thanks!

Thanks!

Is there any chance it'll be in 5.10 or will it have to wait for the 5.11
merge window?

Also it should be applied to all supported/stable kernels. I guess that'll
have to wait until it's in Linus tree according [1] to but I'm unsure if I
need to trigger the action myself or if Greg (or Dave, according to [2]) will
do it.

I looked at [3] and it seems that adding the CC: stable in my commit message
maybe was an error because it's marked as a Failure, so if there's anything
needed from me here, don't hesitate to ask.

[1] https://www.kernel.org/doc/html/latest/process/stable-kernel-rules.html
[2]
https://www.kernel.org/doc/html/latest/networking/netdev-FAQ.html#q-how-can-i-tell-what-patches-are-queued-up-for-backporting-to-the-various-stable-releases
[3] https://patchwork.kernel.org/bundle/netdev/stable/?state=*

Regards,
--
Yves-Alexis

2021-02-21 11:04:27

by Sam Bingner

[permalink] [raw]
Subject: Re: [PATCH] usbnet: ipheth: fix connectivity with iOS 14

There seems to be a problem with this patch:

Whenever the iPhone sends a packet to the tethered device that is 1500 bytes long, it gets the error "ipheth 1-1:4.2: ipheth_rcvbulk_callback: urb status: -79" on the connected device and stops passing traffic. I am able to bring it back up by shutting and unshutting the interface, but the same thing happens very quickly. I noticed that this patch dropped the max USB packet size from 1516 to 1514 bytes, so I decided to try lowering the MTU to 1498; this made the connection reliable and no more errors occurred.

It appears to me that the iPhone is still sending out 1516 bytes over USB for a 1500 byte packet and this patch makes USB abort when that happens? I could duplicate reliably by sending a ping from the iphone (ping -s 1472) to the connected device, or vice versa as the reply would then break it.

I apologize if this reply doesn't end up where it should - I tried to reply to the last message in this thread but I wasn't actually *on* the thread so I had to just build it as much as possible myself.

Sam

2021-02-22 12:11:57

by Oliver Neukum

[permalink] [raw]
Subject: Re: [PATCH] usbnet: ipheth: fix connectivity with iOS 14

Am Sonntag, den 21.02.2021, 10:42 +0000 schrieb Sam Bingner:
> There seems to be a problem with this patch:
>
> Whenever the iPhone sends a packet to the tethered device that is 1500 bytes long, it gets the error "ipheth 1-1:4.2: ipheth_rcvbulk_callback: urb status: -79" on the connected device and stops passing traffic. I am able to bring it back up by shutting and unshutting the interface, but the same thing happens very quickly. I noticed that this patch dropped the max USB packet size from 1516 to 1514 bytes, so I decided to try lowering the MTU to 1498; this made the connection reliable and no more errors occurred.
>
> It appears to me that the iPhone is still sending out 1516 bytes over USB for a 1500 byte packet and this patch makes USB abort when that happens? I could duplicate reliably by sending a ping from the iphone (ping -s 1472) to the connected device, or vice versa as the reply would then break it.
>
> I apologize if this reply doesn't end up where it should - I tried to reply to the last message in this thread but I wasn't actually *on* the thread so I had to just build it as much as possible myself.

Is this a regression? Does it work after reverting the patch? Which
version of iOS?

Regards
Oliver


2021-09-22 20:30:31

by Sam Bingner

[permalink] [raw]
Subject: RE: [PATCH] usbnet: ipheth: fix connectivity with iOS 14

Sorry I didn't have time to research this further to prove it was a regression - but there is now somebody else who has done so and created a patch. I thought it might be good to give a link to it to you guys. It caused problems on all iOS versions AFAIK. The patch and discussion is available at:

https://github.com/openwrt/openwrt/pull/4084

Sam

-----Original Message-----
From: Oliver Neukum <[email protected]>
Sent: Monday, February 22, 2021 2:10 AM
To: Sam Bingner <[email protected]>; [email protected]
Cc: David S. Miller <[email protected]>; Martin Habets <[email protected]>; Luc Van Oostenryck <[email protected]>; Shannon Nelson <[email protected]>; Michael S. Tsirkin <[email protected]>; [email protected]; [email protected]; Matti Vuorela <[email protected]>; Jakub Kicinski <[email protected]>; Yves-Alexis Perez <[email protected]>
Subject: Re: [PATCH] usbnet: ipheth: fix connectivity with iOS 14

Am Sonntag, den 21.02.2021, 10:42 +0000 schrieb Sam Bingner:
> There seems to be a problem with this patch:
>
> Whenever the iPhone sends a packet to the tethered device that is 1500 bytes long, it gets the error "ipheth 1-1:4.2: ipheth_rcvbulk_callback: urb status: -79" on the connected device and stops passing traffic. I am able to bring it back up by shutting and unshutting the interface, but the same thing happens very quickly. I noticed that this patch dropped the max USB packet size from 1516 to 1514 bytes, so I decided to try lowering the MTU to 1498; this made the connection reliable and no more errors occurred.
>
> It appears to me that the iPhone is still sending out 1516 bytes over USB for a 1500 byte packet and this patch makes USB abort when that happens? I could duplicate reliably by sending a ping from the iphone (ping -s 1472) to the connected device, or vice versa as the reply would then break it.
>
> I apologize if this reply doesn't end up where it should - I tried to reply to the last message in this thread but I wasn't actually *on* the thread so I had to just build it as much as possible myself.

Is this a regression? Does it work after reverting the patch? Which version of iOS?

Regards
Oliver


2021-09-27 15:14:51

by Yves-Alexis Perez

[permalink] [raw]
Subject: Re: [PATCH] usbnet: ipheth: fix connectivity with iOS 14

On Wed, 2021-09-22 at 20:11 +0000, Sam Bingner wrote:
> Sorry I didn't have time to research this further to prove it was a
> regression - but there is now somebody else who has done so and created a
> patch.  I thought it might be good to give a link to it to you guys.  It
> caused problems on all iOS versions AFAIK.  The patch and discussion is
> available at:
>
> https://github.com/openwrt/openwrt/pull/4084

Hi Sam, sorry for the delay.

I've read the thread above and the patch. Unfortunately we don't have
documentation on how the driver is supposed to work and how the iPhone part
behave, everything was reverse engineered at the time and the people who did
it seem long gone.

As far as I understand it, when we experienced the “first” bug, it was noted
that reducing the (TX) buffer size by 2 helped, and thus the patch changing
IPHETH_BUF_SIZE to 1514 was committed, reducing both RX and TX buffer size.

During my testings I never experienced the subsequent bug (the
ipheth_rcvbulk_callback: urb status: -75) but maybe I never received 1500b
packets (it's a bit strange but maybe).

Maybe the right fix would be to split IPHETH_BUF_SIZE to
IPHETH_{RX,TX}_BUF_SIZE? Something like:

diff --git a/drivers/net/usb/ipheth.c b/drivers/net/usb/ipheth.c
index 57d94b18ef33..005d2e31d97c 100644
--- a/drivers/net/usb/ipheth.c
+++ b/drivers/net/usb/ipheth.c
@@ -60,7 +60,9 @@
#define IPHETH_USBINTF_PROTO 1

#define IPHETH_BUF_SIZE 1514
-#define IPHETH_IP_ALIGN 2 /* padding at front of URB */
+#define IPHETH_IP_ALIGN 2 /* padding at front of URB on
RX path */
+#define IPHETH_TX_BUF_SIZE IPHETH_BUF_SIZE
+#define IPHETH_RX_BUF_SIZE IPHETH_BUF_SIZE + IPHETH_IP_ALIGN
#define IPHETH_TX_TIMEOUT (5 * HZ)

#define IPHETH_INTFNUM 2
@@ -116,12 +118,12 @@ static int ipheth_alloc_urbs(struct ipheth_device
*iphone)
if (rx_urb == NULL)
goto free_tx_urb;

- tx_buf = usb_alloc_coherent(iphone->udev, IPHETH_BUF_SIZE,
+ tx_buf = usb_alloc_coherent(iphone->udev, IPHETH_TX_BUF_SIZE,
GFP_KERNEL, &tx_urb->transfer_dma);
if (tx_buf == NULL)
goto free_rx_urb;

- rx_buf = usb_alloc_coherent(iphone->udev, IPHETH_BUF_SIZE,
+ rx_buf = usb_alloc_coherent(iphone->udev, IPHETH_RX_BUF_SIZE,
GFP_KERNEL, &rx_urb->transfer_dma);
if (rx_buf == NULL)
goto free_tx_buf;
@@ -134,7 +136,7 @@ static int ipheth_alloc_urbs(struct ipheth_device *iphone)
return 0;

free_tx_buf:
- usb_free_coherent(iphone->udev, IPHETH_BUF_SIZE, tx_buf,
+ usb_free_coherent(iphone->udev, IPHETH_TX_BUF_SIZE, tx_buf,
tx_urb->transfer_dma);
free_rx_urb:
usb_free_urb(rx_urb);
@@ -146,9 +148,9 @@ static int ipheth_alloc_urbs(struct ipheth_device *iphone)

static void ipheth_free_urbs(struct ipheth_device *iphone)
{
- usb_free_coherent(iphone->udev, IPHETH_BUF_SIZE, iphone->rx_buf,
+ usb_free_coherent(iphone->udev, IPHETH_RX_BUF_SIZE, iphone->rx_buf,
iphone->rx_urb->transfer_dma);
- usb_free_coherent(iphone->udev, IPHETH_BUF_SIZE, iphone->tx_buf,
+ usb_free_coherent(iphone->udev, IPHETH_TX_BUF_SIZE, iphone->tx_buf,
iphone->tx_urb->transfer_dma);
usb_free_urb(iphone->rx_urb);
usb_free_urb(iphone->tx_urb);
@@ -317,7 +319,7 @@ static int ipheth_rx_submit(struct ipheth_device *dev,
gfp_t mem_flags)

usb_fill_bulk_urb(dev->rx_urb, udev,
usb_rcvbulkpipe(udev, dev->bulk_in),
- dev->rx_buf, IPHETH_BUF_SIZE,
+ dev->rx_buf, IPHETH_RX_BUF_SIZE,
ipheth_rcvbulk_callback,
dev);
dev->rx_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
@@ -381,7 +383,7 @@ static netdev_tx_t ipheth_tx(struct sk_buff *skb, struct
net_device *net)
int retval;

/* Paranoid */
- if (skb->len > IPHETH_BUF_SIZE) {
+ if (skb->len > IPHETH_TX_BUF_SIZE) {
WARN(1, "%s: skb too large: %d bytes\n", __func__, skb->len);
dev->net->stats.tx_dropped++;
dev_kfree_skb_any(skb);
@@ -389,12 +391,12 @@ static netdev_tx_t ipheth_tx(struct sk_buff *skb, struct
net_device *net)
}

memcpy(dev->tx_buf, skb->data, skb->len);
- if (skb->len < IPHETH_BUF_SIZE)
- memset(dev->tx_buf + skb->len, 0, IPHETH_BUF_SIZE - skb-
>len);
+ if (skb->len < IPHETH_TX_BUF_SIZE)
+ memset(dev->tx_buf + skb->len, 0, IPHETH_TX_BUF_SIZE - skb-
>len);

usb_fill_bulk_urb(dev->tx_urb, udev,
usb_sndbulkpipe(udev, dev->bulk_out),
- dev->tx_buf, IPHETH_BUF_SIZE,
+ dev->tx_buf, IPHETH_TX_BUF_SIZE,
ipheth_sndbulk_callback,
dev);
dev->tx_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;

--
Yves-Alexis