Subject: [PATCH net 3/7] net: tls: fix page pin leak on sendpage_ok() failure

From: Jakub Kicinski <[email-masked]>
Date: Wed, 29 Apr 2026 15:29:40 -0700

When iov_iter_extract_pages() is called on a user-backed iterator, it
pins the extracted pages via pin_user_pages_fast(). If the subsequent
sendpage_ok() check fails, both tls_sw_sendmsg_splice() and
tls_push_data() (device offload path) call iov_iter_revert() to unwind
the iterator position, but iov_iter_revert() only adjusts the cursor -
it does not release the page pin taken by the extract.

Fixes: 45e5be844ab6 ("tls/sw: Convert tls_sw_sendpage() to use MSG_SPLICE_PAGES")
Fixes: 24763c9c0980 ("tls/device: Support MSG_SPLICE_PAGES")
Signed-off-by: Jakub Kicinski <[email-masked]>
---
CC: [email-masked]
CC: [email-masked]
CC: [email-masked]
---
 net/tls/tls_device.c | 2 ++
 net/tls/tls_sw.c     | 2 ++
 2 files changed, 4 insertions(+)

diff --git a/net/tls/tls_device.c b/net/tls/tls_device.c
index 741aef09bfd3..6aae8d04f976 100644
--- a/net/tls/tls_device.c
+++ b/net/tls/tls_device.c
@@ -508,6 +508,8 @@ static int tls_push_data(struct sock *sk,
 			copy = rc;
 
 			if (WARN_ON_ONCE(!sendpage_ok(zc_pfrag.page))) {
+				if (iov_iter_extract_will_pin(iter))
+					unpin_user_page(zc_pfrag.page);
 				iov_iter_revert(iter, copy);
 				rc = -EIO;
 				goto handle_error;
diff --git a/net/tls/tls_sw.c b/net/tls/tls_sw.c
index 2590e855f6a5..906a1998c630 100644
--- a/net/tls/tls_sw.c
+++ b/net/tls/tls_sw.c
@@ -1018,6 +1018,8 @@ static int tls_sw_sendmsg_splice(struct sock *sk, struct msghdr *msg,
 			return part ?: -EIO;
 
 		if (WARN_ON_ONCE(!sendpage_ok(page))) {
+			if (iov_iter_extract_will_pin(&msg->msg_iter))
+				unpin_user_page(page);
 			iov_iter_revert(&msg->msg_iter, part);
 			return -EIO;
 		}
-- 
2.54.0