Skip to contentSkip to conversation

rxrpc: Also unshare DATA/RESPONSE packets when paged frags are present

PATCH Superseded Hyunwoo Kim 2 participants 3 messages May 8

Subsystems (4)

v2 of 3 Superseded Latest is v3 →

lore
Share & tools
lore
#0 lore raw

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.

Fixes d0d5c0cd1e71 ("rxrpc: Use skb_unshare() rather than skb_cow_data()")

---
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
index fdd683261226..a6ad5ff6ec5f 100644
@@ -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
index a2130d25aaa9..632cbeff1f5d 100644
@@ -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
#1 lore raw
Quoted 41 lines · Hyunwoo Kim

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.

Fixes d0d5c0cd1e71 ("rxrpc: Use skb_unshare() rather than skb_cow_data()")

---
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
index fdd683261226..a6ad5ff6ec5f 100644
@@ -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
index a2130d25aaa9..632cbeff1f5d 100644

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?

#2 lore raw
Quoted 54 lines · Jiayuan Chen
Quoted 40 lines · Hyunwoo Kim

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.

Fixes d0d5c0cd1e71 ("rxrpc: Use skb_unshare() rather than skb_cow_data()")

---
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
index fdd683261226..a6ad5ff6ec5f 100644
@@ -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
index a2130d25aaa9..632cbeff1f5d 100644

net/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_pool RX 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