Re: [PATCH net v5 1/2] flow_dissector: do not dissect PPPoE PFC frames
Simon Horman <[email protected]> Tue, 14 Apr 2026 18:08:32 +0100
| Newsgroups | org.kernel.vger.linux-ppp,org.kernel.vger.linux-kernel,org.kernel.vger.netdev |
|---|---|
| Message-ID | <[email protected]> |
On Tue, Apr 14, 2026 at 10:13:48AM +0800, Qingfang Deng wrote: > RFC 2516 Section 7 states that Protocol Field Compression (PFC) is NOT > RECOMMENDED for PPPoE. In practice, pppd does not support negotiating > PFC for PPPoE sessions, and the flow dissector driver has assumed an > uncompressed frame until the blamed commit. > > During the review process of that commit [1], support for PFC is > suggested. However, having a compressed (1-byte) protocol field means > the subsequent PPP payload is shifted by one byte, causing 4-byte > misalignment for the network header and an unaligned access exception > on some architectures. > > The exception can be reproduced by sending a PPPoE PFC frame to an > ethernet interface of a MIPS board, with RPS enabled, even if no PPPoE > session is active on that interface: > > $ 0 : 00000000 80c40000 00000000 85144817 > $ 4 : 00000008 00000100 80a75758 81dc9bb8 > $ 8 : 00000010 8087ae2c 0000003d 00000000 > $12 : 000000e0 00000039 00000000 00000000 > $16 : 85043240 80a75758 81dc9bb8 00006488 > $20 : 0000002f 00000007 85144810 80a70000 > $24 : 81d1bda0 00000000 > $28 : 81dc8000 81dc9aa8 00000000 805ead08 > Hi : 00009d51 > Lo : 2163358a > epc : 805e91f0 __skb_flow_dissect+0x1b0/0x1b50 > ra : 805ead08 __skb_get_hash_net+0x74/0x12c > Status: 11000403 KERNEL EXL IE > Cause : 40800010 (ExcCode 04) > BadVA : 85144817 > PrId : 0001992f (MIPS 1004Kc) > Call Trace: > [<805e91f0>] __skb_flow_dissect+0x1b0/0x1b50 > [<805ead08>] __skb_get_hash_net+0x74/0x12c > [<805ef330>] get_rps_cpu+0x1b8/0x3fc > [<805fca70>] netif_receive_skb_list_internal+0x324/0x364 > [<805fd120>] napi_complete_done+0x68/0x2a4 > [<8058de5c>] mtk_napi_rx+0x228/0xfec > [<805fd398>] __napi_poll+0x3c/0x1c4 > [<805fd754>] napi_threaded_poll_loop+0x234/0x29c > [<805fd848>] napi_threaded_poll+0x8c/0xb0 > [<80053544>] kthread+0x104/0x12c > [<80002bd8>] ret_from_kernel_thread+0x14/0x1c > > Code: 02d51821 1060045b 00000000 <8c640000> 3084000f 2c820005 144001a2 00042080 8e220000 > > To reduce the attack surface and maintain performance, do not process > PPPoE PFC frames. > > [1] https://patch.msgid.link/[email protected] > Fixes: 46126db9c861 ("flow_dissector: Add PPPoE dissectors") > Signed-off-by: Qingfang Deng <[email protected]> > --- > Changes in v5: drop byte-swap change > Link to v4: https://lore.kernel.org/netdev/[email protected]/ > > net/core/flow_dissector.c | 10 +--------- > 1 file changed, 1 insertion(+), 9 deletions(-) > > diff --git a/net/core/flow_dissector.c b/net/core/flow_dissector.c > index 1b61bb25ba0e..f9aaba554128 100644 > --- a/net/core/flow_dissector.c > +++ b/net/core/flow_dissector.c > @@ -1374,16 +1374,8 @@ bool __skb_flow_dissect(const struct net *net, > break; > } > > - /* least significant bit of the most significant octet > - * indicates if protocol field was compressed > - */ > ppp_proto = ntohs(hdr->proto); > - if (ppp_proto & 0x0100) { > - ppp_proto = ppp_proto >> 8; > - nhoff += PPPOE_SES_HLEN - 1; > - } else { > - nhoff += PPPOE_SES_HLEN; > - } I think it would be good to add a comment around here describing how PFC is safely handled in this function. > + nhoff += PPPOE_SES_HLEN; > > if (ppp_proto == PPP_IP) { > proto = htons(ETH_P_IP); > -- > 2.43.0 >