rxrpc: Also unshare DATA/RESPONSE packets when paged frags are present
Subsystems (4)
PATCH v2 1/1 rxrpc: Also unshare DATA/RESPONSE packets when paged frags are present
The DATA-packet handler in rxrpc_input_call_event() and the RESPONSE handler in rxrpc_verify_response() copy the skb to a linear one before calling into the security ops only when skb_cloned() is true. An skb that is not cloned but still carries paged fragments (skb->data_len != 0) falls through to the in-place decryption path, which binds the frag pages directly into the AEAD/skcipher SGL via skb_to_sgvec().
Extend the gate so that any skb with non-linear data is also copied, ensuring the security handler always operates on a fully linear skb. The OOM/trace handling already in place is reused.
---
Changes in v2:
- Use skb_is_nonlinear() instead of skb->data_len
- v1: https://lore.kernel.org/all/afKV2zGR6rrelPC7@v4bel/
--- net/rxrpc/call_event.c | 2 +- net/rxrpc/conn_event.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-)
net/rxrpc/call_event.c +1 -1
@@ -334,7 +334,7 @@ bool rxrpc_input_call_event(struct rxrpc_call *call)if (sp->hdr.type ==RXRPC_PACKET_TYPE_DATA && sp->hdr.securityIndex !=0 && -skb_cloned (skb)) { + (skb_cloned (skb) ||skb_is_nonlinear (skb))) {/* Unshare the packet so that it can be * modified by in-place decryption. */
net/rxrpc/conn_event.c +1 -1
@@ -245,7 +245,7 @@ static int rxrpc_verify_response(struct rxrpc_connection *conn, {int ret; -if (skb_cloned (skb)) { +if (skb_cloned (skb) ||skb_is_nonlinear (skb)) {/* Copy the packet if shared so that we can do in-place * decryption. */
Signature · 1 line
2.43.0
Quoted 41 lines · Hyunwoo Kim
The DATA-packet handler in
rxrpc_input_call_event()and the RESPONSE handler inrxrpc_verify_response()copy the skb to a linear one before calling into the security ops only whenskb_cloned()is true. An skb that is not cloned but still carries paged fragments (skb->data_len!= 0) falls through to the in-place decryption path, which binds the frag pages directly into the AEAD/skcipher SGL viaskb_to_sgvec().Extend the gate so that any skb with non-linear data is also copied, ensuring the security handler always operates on a fully linear skb. The OOM/trace handling already in place is reused.
Fixes d0d5c0cd1e71 ("rxrpc: Use skb_unshare() rather than skb_cow_data()")Signed-off-by Hyunwoo Kim <[email protected]>---
Changes in v2:
- Useskb_is_nonlinear()instead ofskb->data_len
- v1: https://lore.kernel.org/all/afKV2zGR6rrelPC7@v4bel/--- net/rxrpc/call_event.c | 2 +- net/rxrpc/conn_event.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-)net/rxrpc/call_event.c +1
-1@@ -334,7 +334,7 @@ bool rxrpc_input_call_event(struct rxrpc_call *call)if (sp->hdr.type ==RXRPC_PACKET_TYPE_DATA && sp->hdr.securityIndex !=0 && -skb_cloned (skb)) { + (skb_cloned (skb) ||skb_is_nonlinear (skb))) {/* Unshare the packet so that it can be * modified by in-place decryption. */ net/rxrpc/conn_event.c +0
-0
net/rxrpc/conn_event.c static int rxrpc_verify_response(struct rxrpc_connection *conn, · line 251
Quoted 8 lines
net/rxrpc/conn_event.c +1
-1@@ -245,7 +245,7 @@ static int rxrpc_verify_response(struct rxrpc_connection *conn, {int ret; -if (skb_cloned (skb)) { +if (skb_cloned (skb) ||skb_is_nonlinear (skb)) {/* Copy the packet if shared so that we can do in-place * decryption. */
Why not adopt the same gate as the ESP fix:
skb_cloned(skb) || skb_has_frag_list(skb) || skb_has_shared_frag(skb)
so NIC page_pool RX keeps its zero-copy path while still catching the splice-loopback vector?
Quoted 54 lines · Jiayuan Chen
Quoted 40 lines · Hyunwoo Kim
The DATA-packet handler in
rxrpc_input_call_event()and the RESPONSE handler inrxrpc_verify_response()copy the skb to a linear one before calling into the security ops only whenskb_cloned()is true. An skb that is not cloned but still carries paged fragments (skb->data_len!= 0) falls through to the in-place decryption path, which binds the frag pages directly into the AEAD/skcipher SGL viaskb_to_sgvec().Extend the gate so that any skb with non-linear data is also copied, ensuring the security handler always operates on a fully linear skb. The OOM/trace handling already in place is reused.
Fixes d0d5c0cd1e71 ("rxrpc: Use skb_unshare() rather than skb_cow_data()")Signed-off-by Hyunwoo Kim <[email protected]>---
Changes in v2:
- Useskb_is_nonlinear()instead ofskb->data_len
- v1: https://lore.kernel.org/all/afKV2zGR6rrelPC7@v4bel/--- net/rxrpc/call_event.c | 2 +- net/rxrpc/conn_event.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-)net/rxrpc/call_event.c +1
-1@@ -334,7 +334,7 @@ bool rxrpc_input_call_event(struct rxrpc_call *call)if (sp->hdr.type ==RXRPC_PACKET_TYPE_DATA && sp->hdr.securityIndex !=0 && -skb_cloned (skb)) { + (skb_cloned (skb) ||skb_is_nonlinear (skb))) {/* Unshare the packet so that it can be * modified by in-place decryption. */ net/rxrpc/conn_event.c +0
-0net/rxrpc/conn_event.c static int rxrpc_verify_response(struct rxrpc_connection *conn, · line 250
Quoted 7 lines
net/rxrpc/conn_event.c +1
-1@@ -245,7 +245,7 @@ static int rxrpc_verify_response(struct rxrpc_connection *conn, {int ret; -if (skb_cloned (skb)) { +if (skb_cloned (skb) ||skb_is_nonlinear (skb)) {/* Copy the packet if shared so that we can do in-place * decryption. */ Why not adopt the same gate as the ESP fix:
Quoted 5 lines
skb_cloned(skb)||skb_has_frag_list(skb)||skb_has_shared_frag(skb)so NIC
page_poolRX keeps its zero-copy path while still catching the splice-loopback vector?
Yeah, that approach preserves the fast path. I'll test and submit v3.
Best regards,
Hyunwoo Kim