From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
To: linux-kernel@vger.kernel.org
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
stable@vger.kernel.org, Jose Alonso <joalonsof@gmail.com>,
Paolo Abeni <pabeni@redhat.com>
Subject: [PATCH 5.10 13/84] net: usb: ax88179_178a: Fix packet receiving
Date: Tue, 5 Jul 2022 13:57:36 +0200 [thread overview]
Message-ID: <20220705115615.714867674@linuxfoundation.org> (raw)
In-Reply-To: <20220705115615.323395630@linuxfoundation.org>
From: Jose Alonso <joalonsof@gmail.com>
commit f8ebb3ac881b17712e1d5967c97ab1806b16d3d6 upstream.
This patch corrects packet receiving in ax88179_rx_fixup.
- problem observed:
ifconfig shows allways a lot of 'RX Errors' while packets
are received normally.
This occurs because ax88179_rx_fixup does not recognise properly
the usb urb received.
The packets are normally processed and at the end, the code exits
with 'return 0', generating RX Errors.
(pkt_cnt==-2 and ptk_hdr over field rx_hdr trying to identify
another packet there)
This is a usb urb received by "tcpdump -i usbmon2 -X" on a
little-endian CPU:
0x0000: eeee f8e3 3b19 87a0 94de 80e3 daac 0800
^ packet 1 start (pkt_len = 0x05ec)
^^^^ IP alignment pseudo header
^ ethernet packet start
last byte ethernet packet v
padding (8-bytes aligned) vvvv vvvv
0x05e0: c92d d444 1420 8a69 83dd 272f e82b 9811
0x05f0: eeee f8e3 3b19 87a0 94de 80e3 daac 0800
... ^ packet 2
0x0be0: eeee f8e3 3b19 87a0 94de 80e3 daac 0800
...
0x1130: 9d41 9171 8a38 0ec5 eeee f8e3 3b19 87a0
...
0x1720: 8cfc 15ff 5e4c e85c eeee f8e3 3b19 87a0
...
0x1d10: ecfa 2a3a 19ab c78c eeee f8e3 3b19 87a0
...
0x2070: eeee f8e3 3b19 87a0 94de 80e3 daac 0800
... ^ packet 7
0x2120: 7c88 4ca5 5c57 7dcc 0d34 7577 f778 7e0a
0x2130: f032 e093 7489 0740 3008 ec05 0000 0080
====1==== ====2====
hdr_off ^
pkt_len = 0x05ec ^^^^
AX_RXHDR_*=0x00830 ^^^^ ^
pkt_len = 0 ^^^^
AX_RXHDR_DROP_ERR=0x80000000 ^^^^ ^
0x2140: 3008 ec05 0000 0080 3008 5805 0000 0080
0x2150: 3008 ec05 0000 0080 3008 ec05 0000 0080
0x2160: 3008 5803 0000 0080 3008 c800 0000 0080
===11==== ===12==== ===13==== ===14====
0x2170: 0000 0000 0e00 3821
^^^^ ^^^^ rx_hdr
^^^^ pkt_cnt=14
^^^^ hdr_off=0x2138
^^^^ ^^^^ padding
The dump shows that pkt_cnt is the number of entrys in the
per-packet metadata. It is "2 * packet count".
Each packet have two entrys. The first have a valid
value (pkt_len and AX_RXHDR_*) and the second have a
dummy-header 0x80000000 (pkt_len=0 with AX_RXHDR_DROP_ERR).
Why exists dummy-header for each packet?!?
My guess is that this was done probably to align the
entry for each packet to 64-bits and maintain compatibility
with old firmware.
There is also a padding (0x00000000) before the rx_hdr to
align the end of rx_hdr to 64-bit.
Note that packets have a alignment of 64-bits (8-bytes).
This patch assumes that the dummy-header and the last
padding are optional. So it preserves semantics and
recognises the same valid packets as the current code.
This patch was made using only the dumpfile information and
tested with only one device:
0b95:1790 ASIX Electronics Corp. AX88179 Gigabit Ethernet
Fixes: 57bc3d3ae8c1 ("net: usb: ax88179_178a: Fix out-of-bounds accesses in RX fixup")
Fixes: e2ca90c276e1 ("ax88179_178a: ASIX AX88179_178A USB 3.0/2.0 to gigabit ethernet adapter driver")
Signed-off-by: Jose Alonso <joalonsof@gmail.com>
Acked-by: Paolo Abeni <pabeni@redhat.com>
Link: https://lore.kernel.org/r/d6970bb04bf67598af4d316eaeb1792040b18cfd.camel@gmail.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/net/usb/ax88179_178a.c | 101 ++++++++++++++++++++++++++++++-----------
1 file changed, 76 insertions(+), 25 deletions(-)
--- a/drivers/net/usb/ax88179_178a.c
+++ b/drivers/net/usb/ax88179_178a.c
@@ -1471,6 +1471,42 @@ static int ax88179_rx_fixup(struct usbne
* are bundled into this buffer and where we can find an array of
* per-packet metadata (which contains elements encoded into u16).
*/
+
+ /* SKB contents for current firmware:
+ * <packet 1> <padding>
+ * ...
+ * <packet N> <padding>
+ * <per-packet metadata entry 1> <dummy header>
+ * ...
+ * <per-packet metadata entry N> <dummy header>
+ * <padding2> <rx_hdr>
+ *
+ * where:
+ * <packet N> contains pkt_len bytes:
+ * 2 bytes of IP alignment pseudo header
+ * packet received
+ * <per-packet metadata entry N> contains 4 bytes:
+ * pkt_len and fields AX_RXHDR_*
+ * <padding> 0-7 bytes to terminate at
+ * 8 bytes boundary (64-bit).
+ * <padding2> 4 bytes to make rx_hdr terminate at
+ * 8 bytes boundary (64-bit)
+ * <dummy-header> contains 4 bytes:
+ * pkt_len=0 and AX_RXHDR_DROP_ERR
+ * <rx-hdr> contains 4 bytes:
+ * pkt_cnt and hdr_off (offset of
+ * <per-packet metadata entry 1>)
+ *
+ * pkt_cnt is number of entrys in the per-packet metadata.
+ * In current firmware there is 2 entrys per packet.
+ * The first points to the packet and the
+ * second is a dummy header.
+ * This was done probably to align fields in 64-bit and
+ * maintain compatibility with old firmware.
+ * This code assumes that <dummy header> and <padding2> are
+ * optional.
+ */
+
if (skb->len < 4)
return 0;
skb_trim(skb, skb->len - 4);
@@ -1484,51 +1520,66 @@ static int ax88179_rx_fixup(struct usbne
/* Make sure that the bounds of the metadata array are inside the SKB
* (and in front of the counter at the end).
*/
- if (pkt_cnt * 2 + hdr_off > skb->len)
+ if (pkt_cnt * 4 + hdr_off > skb->len)
return 0;
pkt_hdr = (u32 *)(skb->data + hdr_off);
/* Packets must not overlap the metadata array */
skb_trim(skb, hdr_off);
- for (; ; pkt_cnt--, pkt_hdr++) {
+ for (; pkt_cnt > 0; pkt_cnt--, pkt_hdr++) {
+ u16 pkt_len_plus_padd;
u16 pkt_len;
le32_to_cpus(pkt_hdr);
pkt_len = (*pkt_hdr >> 16) & 0x1fff;
+ pkt_len_plus_padd = (pkt_len + 7) & 0xfff8;
- if (pkt_len > skb->len)
+ /* Skip dummy header used for alignment
+ */
+ if (pkt_len == 0)
+ continue;
+
+ if (pkt_len_plus_padd > skb->len)
return 0;
/* Check CRC or runt packet */
- if (((*pkt_hdr & (AX_RXHDR_CRC_ERR | AX_RXHDR_DROP_ERR)) == 0) &&
- pkt_len >= 2 + ETH_HLEN) {
- bool last = (pkt_cnt == 0);
-
- if (last) {
- ax_skb = skb;
- } else {
- ax_skb = skb_clone(skb, GFP_ATOMIC);
- if (!ax_skb)
- return 0;
- }
- ax_skb->len = pkt_len;
- /* Skip IP alignment pseudo header */
- skb_pull(ax_skb, 2);
- skb_set_tail_pointer(ax_skb, ax_skb->len);
- ax_skb->truesize = pkt_len + sizeof(struct sk_buff);
- ax88179_rx_checksum(ax_skb, pkt_hdr);
+ if ((*pkt_hdr & (AX_RXHDR_CRC_ERR | AX_RXHDR_DROP_ERR)) ||
+ pkt_len < 2 + ETH_HLEN) {
+ dev->net->stats.rx_errors++;
+ skb_pull(skb, pkt_len_plus_padd);
+ continue;
+ }
- if (last)
- return 1;
+ /* last packet */
+ if (pkt_len_plus_padd == skb->len) {
+ skb_trim(skb, pkt_len);
- usbnet_skb_return(dev, ax_skb);
+ /* Skip IP alignment pseudo header */
+ skb_pull(skb, 2);
+
+ skb->truesize = SKB_TRUESIZE(pkt_len_plus_padd);
+ ax88179_rx_checksum(skb, pkt_hdr);
+ return 1;
}
- /* Trim this packet away from the SKB */
- if (!skb_pull(skb, (pkt_len + 7) & 0xFFF8))
+ ax_skb = skb_clone(skb, GFP_ATOMIC);
+ if (!ax_skb)
return 0;
+ skb_trim(ax_skb, pkt_len);
+
+ /* Skip IP alignment pseudo header */
+ skb_pull(ax_skb, 2);
+
+ skb->truesize = pkt_len_plus_padd +
+ SKB_DATA_ALIGN(sizeof(struct sk_buff));
+ ax88179_rx_checksum(ax_skb, pkt_hdr);
+ usbnet_skb_return(dev, ax_skb);
+
+ skb_pull(skb, pkt_len_plus_padd);
}
+
+ return 0;
}
static struct sk_buff *
next prev parent reply other threads:[~2022-07-05 12:13 UTC|newest]
Thread overview: 95+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-07-05 11:57 [PATCH 5.10 00/84] 5.10.129-rc1 review Greg Kroah-Hartman
2022-07-05 11:57 ` [PATCH 5.10 01/84] drm/amdgpu: To flush tlb for MMHUB of RAVEN series Greg Kroah-Hartman
2022-07-05 11:57 ` [PATCH 5.10 02/84] ipv6: take care of disable_policy when restoring routes Greg Kroah-Hartman
2022-07-05 11:57 ` [PATCH 5.10 03/84] nvme-pci: add NVME_QUIRK_BOGUS_NID for ADATA XPG SX6000LNP (AKA SPECTRIX S40G) Greg Kroah-Hartman
2022-07-05 11:57 ` [PATCH 5.10 04/84] nvdimm: Fix badblocks clear off-by-one error Greg Kroah-Hartman
2022-07-05 11:57 ` [PATCH 5.10 05/84] powerpc/prom_init: Fix kernel config grep Greg Kroah-Hartman
2022-07-05 11:57 ` [PATCH 5.10 06/84] powerpc/book3e: Fix PUD allocation size in map_kernel_page() Greg Kroah-Hartman
2022-07-05 11:57 ` [PATCH 5.10 07/84] powerpc/bpf: Fix use of user_pt_regs in uapi Greg Kroah-Hartman
2022-07-05 11:57 ` [PATCH 5.10 08/84] dm raid: fix accesses beyond end of raid member array Greg Kroah-Hartman
2022-07-05 11:57 ` [PATCH 5.10 09/84] dm raid: fix KASAN warning in raid5_add_disks Greg Kroah-Hartman
2022-07-05 11:57 ` [PATCH 5.10 10/84] s390/archrandom: simplify back to earlier design and initialize earlier Greg Kroah-Hartman
2022-07-05 11:57 ` [PATCH 5.10 11/84] SUNRPC: Fix READ_PLUS crasher Greg Kroah-Hartman
2022-07-05 11:57 ` [PATCH 5.10 12/84] net: rose: fix UAF bugs caused by timer handler Greg Kroah-Hartman
2022-07-05 11:57 ` Greg Kroah-Hartman [this message]
2022-07-05 11:57 ` [PATCH 5.10 14/84] virtio-net: fix race between ndo_open() and virtio_device_ready() Greg Kroah-Hartman
2022-07-05 11:57 ` [PATCH 5.10 15/84] selftests/net: pass ipv6_args to udpgso_benchs IPv6 TCP test Greg Kroah-Hartman
2022-07-05 11:57 ` [PATCH 5.10 16/84] net: dsa: bcm_sf2: force pause link settings Greg Kroah-Hartman
2022-07-05 11:57 ` [PATCH 5.10 17/84] net: tun: unlink NAPI from device on destruction Greg Kroah-Hartman
2022-07-05 11:57 ` [PATCH 5.10 18/84] net: tun: stop NAPI when detaching queues Greg Kroah-Hartman
2022-07-05 11:57 ` [PATCH 5.10 19/84] net: dp83822: disable false carrier interrupt Greg Kroah-Hartman
2022-07-05 11:57 ` [PATCH 5.10 20/84] net: dp83822: disable rx error interrupt Greg Kroah-Hartman
2022-07-05 11:57 ` [PATCH 5.10 21/84] RDMA/qedr: Fix reporting QP timeout attribute Greg Kroah-Hartman
2022-07-05 11:57 ` [PATCH 5.10 22/84] RDMA/cm: Fix memory leak in ib_cm_insert_listen Greg Kroah-Hartman
2022-07-05 11:57 ` [PATCH 5.10 23/84] linux/dim: Fix divide by 0 in RDMA DIM Greg Kroah-Hartman
2022-07-05 11:57 ` [PATCH 5.10 24/84] usbnet: fix memory allocation in helpers Greg Kroah-Hartman
2022-07-05 11:57 ` [PATCH 5.10 25/84] net: ipv6: unexport __init-annotated seg6_hmac_net_init() Greg Kroah-Hartman
2022-07-05 11:57 ` [PATCH 5.10 26/84] NFSD: restore EINVAL error translation in nfsd_commit() Greg Kroah-Hartman
2022-07-05 11:57 ` [PATCH 5.10 27/84] caif_virtio: fix race between virtio_device_ready() and ndo_open() Greg Kroah-Hartman
2022-07-05 11:57 ` [PATCH 5.10 28/84] PM / devfreq: exynos-ppmu: Fix refcount leak in of_get_devfreq_events Greg Kroah-Hartman
2022-07-05 11:57 ` [PATCH 5.10 29/84] s390: remove unneeded select BUILD_BIN2C Greg Kroah-Hartman
2022-07-05 11:57 ` [PATCH 5.10 30/84] netfilter: nft_dynset: restore set element counter when failing to update Greg Kroah-Hartman
2022-07-05 11:57 ` [PATCH 5.10 31/84] net/sched: act_api: Notify user space if any actions were flushed before error Greg Kroah-Hartman
2022-07-05 11:57 ` [PATCH 5.10 32/84] net: bonding: fix possible NULL deref in rlb code Greg Kroah-Hartman
2022-07-05 11:57 ` [PATCH 5.10 33/84] net: bonding: fix use-after-free after 802.3ad slave unbind Greg Kroah-Hartman
2022-07-05 11:57 ` [PATCH 5.10 34/84] nfc: nfcmrvl: Fix irq_of_parse_and_map() return value Greg Kroah-Hartman
2022-07-05 11:57 ` [PATCH 5.10 35/84] NFC: nxp-nci: Dont issue a zero length i2c_master_read() Greg Kroah-Hartman
2022-07-05 11:57 ` [PATCH 5.10 36/84] tipc: move bc link creation back to tipc_node_create Greg Kroah-Hartman
2022-07-05 11:58 ` [PATCH 5.10 37/84] epic100: fix use after free on rmmod Greg Kroah-Hartman
2022-07-05 11:58 ` [PATCH 5.10 38/84] io_uring: ensure that send/sendmsg and recv/recvmsg check sqe->ioprio Greg Kroah-Hartman
2022-07-05 11:58 ` [PATCH 5.10 39/84] tunnels: do not assume mac header is set in skb_tunnel_check_pmtu() Greg Kroah-Hartman
2022-07-05 11:58 ` [PATCH 5.10 40/84] net: tun: avoid disabling NAPI twice Greg Kroah-Hartman
2022-07-05 11:58 ` [PATCH 5.10 41/84] xfs: use current->journal_info for detecting transaction recursion Greg Kroah-Hartman
2022-07-05 11:58 ` [PATCH 5.10 42/84] xfs: rename variable mp to parsing_mp Greg Kroah-Hartman
2022-07-05 11:58 ` [PATCH 5.10 43/84] xfs: Skip repetitive warnings about mount options Greg Kroah-Hartman
2022-07-05 11:58 ` [PATCH 5.10 44/84] xfs: ensure xfs_errortag_random_default matches XFS_ERRTAG_MAX Greg Kroah-Hartman
2022-07-05 11:58 ` [PATCH 5.10 45/84] xfs: fix xfs_trans slab cache name Greg Kroah-Hartman
2022-07-05 11:58 ` [PATCH 5.10 46/84] xfs: update superblock counters correctly for !lazysbcount Greg Kroah-Hartman
2022-07-05 11:58 ` [PATCH 5.10 47/84] xfs: fix xfs_reflink_unshare usage of filemap_write_and_wait_range Greg Kroah-Hartman
2022-07-05 11:58 ` [PATCH 5.10 48/84] tcp: add a missing nf_reset_ct() in 3WHS handling Greg Kroah-Hartman
2022-07-05 11:58 ` [PATCH 5.10 49/84] xen/gntdev: Avoid blocking in unmap_grant_pages() Greg Kroah-Hartman
2022-07-05 11:58 ` [PATCH 5.10 50/84] drivers: cpufreq: Add missing of_node_put() in qoriq-cpufreq.c Greg Kroah-Hartman
2022-07-05 11:58 ` [PATCH 5.10 51/84] selftests: mptcp: add ADD_ADDR timeout test case Greg Kroah-Hartman
2022-07-05 15:59 ` Matthieu Baerts
2022-07-05 16:31 ` Greg Kroah-Hartman
2022-07-05 18:54 ` Mat Martineau
2022-07-06 8:51 ` Matthieu Baerts
2022-07-05 11:58 ` [PATCH 5.10 52/84] selftests: mptcp: add link failure " Greg Kroah-Hartman
2022-07-05 11:58 ` [PATCH 5.10 53/84] selftests: mptcp: add ADD_ADDR IPv6 test cases Greg Kroah-Hartman
2022-07-05 11:58 ` [PATCH 5.10 54/84] selftests: mptcp: launch mptcp_connect with timeout Greg Kroah-Hartman
2022-07-05 11:58 ` [PATCH 5.10 55/84] selftests: mptcp: fix diag instability Greg Kroah-Hartman
2022-07-05 11:58 ` [PATCH 5.10 56/84] selftests: mptcp: more stable diag tests Greg Kroah-Hartman
2022-07-05 11:58 ` [PATCH 5.10 57/84] sit: use min Greg Kroah-Hartman
2022-07-05 11:58 ` [PATCH 5.10 58/84] ipv6/sit: fix ipip6_tunnel_get_prl return value Greg Kroah-Hartman
2022-07-05 11:58 ` [PATCH 5.10 59/84] hwmon: (ibmaem) dont call platform_device_del() if platform_device_add() fails Greg Kroah-Hartman
2022-07-05 11:58 ` [PATCH 5.10 60/84] selftests/rseq: remove ARRAY_SIZE define from individual tests Greg Kroah-Hartman
2022-07-05 11:58 ` [PATCH 5.10 61/84] selftests/rseq: introduce own copy of rseq uapi header Greg Kroah-Hartman
2022-07-05 11:58 ` [PATCH 5.10 62/84] selftests/rseq: Remove useless assignment to cpu variable Greg Kroah-Hartman
2022-07-05 11:58 ` [PATCH 5.10 63/84] selftests/rseq: Remove volatile from __rseq_abi Greg Kroah-Hartman
2022-07-05 11:58 ` [PATCH 5.10 64/84] selftests/rseq: Introduce rseq_get_abi() helper Greg Kroah-Hartman
2022-07-05 11:58 ` [PATCH 5.10 65/84] selftests/rseq: Introduce thread pointer getters Greg Kroah-Hartman
2022-07-05 11:58 ` [PATCH 5.10 66/84] selftests/rseq: Uplift rseq selftests for compatibility with glibc-2.35 Greg Kroah-Hartman
2022-07-05 11:58 ` [PATCH 5.10 67/84] selftests/rseq: Fix ppc32: wrong rseq_cs 32-bit field pointer on big endian Greg Kroah-Hartman
2022-07-05 11:58 ` [PATCH 5.10 68/84] selftests/rseq: Fix ppc32 missing instruction selection "u" and "x" for load/store Greg Kroah-Hartman
2022-07-05 11:58 ` [PATCH 5.10 69/84] selftests/rseq: Fix ppc32 offsets by using long rather than off_t Greg Kroah-Hartman
2022-07-05 11:58 ` [PATCH 5.10 70/84] selftests/rseq: Fix warnings about #if checks of undefined tokens Greg Kroah-Hartman
2022-07-05 11:58 ` [PATCH 5.10 71/84] selftests/rseq: Remove arm/mips asm goto compiler work-around Greg Kroah-Hartman
2022-07-05 11:58 ` [PATCH 5.10 72/84] selftests/rseq: Fix: work-around asm goto compiler bugs Greg Kroah-Hartman
2022-07-05 11:58 ` [PATCH 5.10 73/84] selftests/rseq: x86-64: use %fs segment selector for accessing rseq thread area Greg Kroah-Hartman
2022-07-05 11:58 ` [PATCH 5.10 74/84] selftests/rseq: x86-32: use %gs " Greg Kroah-Hartman
2022-07-05 11:58 ` [PATCH 5.10 75/84] selftests/rseq: Change type of rseq_offset to ptrdiff_t Greg Kroah-Hartman
2022-07-05 11:58 ` [PATCH 5.10 76/84] xen/blkfront: fix leaking data in shared pages Greg Kroah-Hartman
2022-07-05 11:58 ` [PATCH 5.10 77/84] xen/netfront: " Greg Kroah-Hartman
2022-07-05 11:58 ` [PATCH 5.10 78/84] xen/netfront: force data bouncing when backend is untrusted Greg Kroah-Hartman
2022-07-05 11:58 ` [PATCH 5.10 79/84] xen/blkfront: " Greg Kroah-Hartman
2022-07-05 11:58 ` [PATCH 5.10 80/84] xen-netfront: restore __skb_queue_tail() positioning in xennet_get_responses() Greg Kroah-Hartman
2022-07-05 11:58 ` [PATCH 5.10 81/84] xen/arm: Fix race in RB-tree based P2M accounting Greg Kroah-Hartman
2022-07-05 11:58 ` [PATCH 5.10 82/84] net: usb: qmi_wwan: add Telit 0x1060 composition Greg Kroah-Hartman
2022-07-05 11:58 ` [PATCH 5.10 83/84] net: usb: qmi_wwan: add Telit 0x1070 composition Greg Kroah-Hartman
2022-07-05 11:58 ` [PATCH 5.10 84/84] clocksource/drivers/ixp4xx: remove EXPORT_SYMBOL_GPL from ixp4xx_timer_setup() Greg Kroah-Hartman
2022-07-05 18:04 ` [PATCH 5.10 00/84] 5.10.129-rc1 review Florian Fainelli
2022-07-06 6:49 ` Naresh Kamboju
2022-07-06 10:18 ` Sudip Mukherjee (Codethink)
2022-07-06 13:44 ` Guenter Roeck
2022-07-06 23:57 ` Shuah Khan
2022-07-07 0:53 ` Samuel Zou
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20220705115615.714867674@linuxfoundation.org \
--to=gregkh@linuxfoundation.org \
--cc=joalonsof@gmail.com \
--cc=linux-kernel@vger.kernel.org \
--cc=pabeni@redhat.com \
--cc=stable@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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).