The Linux Kernel Mailing List
 help / color / mirror / Atom feed
* [PATCH net-next v3 0/7] net: convert rawv6, ieee802154, phonet and tls getsockopt to sockopt_t
@ 2026-07-27 10:06 Breno Leitao
  2026-07-27 10:06 ` [PATCH net-next v3 1/7] ipv6: raw: drop unused level argument from do_rawv6_getsockopt Breno Leitao
                   ` (6 more replies)
  0 siblings, 7 replies; 16+ messages in thread
From: Breno Leitao @ 2026-07-27 10:06 UTC (permalink / raw)
  To: sdf, David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Simon Horman, Alexander Aring, Stefan Schmidt, Miquel Raynal,
	Remi Denis-Courmont, Rémi Denis-Courmont, John Fastabend,
	Sabrina Dubroca, Shuah Khan
  Cc: netdev, linux-kernel, linux-wpan, linux-kselftest, Breno Leitao,
	kernel-team, Joe Damato, Rémi Denis-Courmont

Now that sockopt_init_user() was already merged, builds a user-backed
sockopt_t from the __user pair. A getsockopt leaf can then take
a sockopt_t behind a thin __user wrapper: the wrapper builds it, calls
the leaf, and writes the length back to optlen. The leaf copies with
copy_to_iter() instead of copy_to_user().

Convert four more leaves the way udp and raw already were: ipv6 raw
(do_rawv6_getsockopt), ieee802154 dgram, phonet pep, and tls
(do_tls_getsockopt and its per-option helpers). 

Converting phonet surfaced a pre-existing bug: pep_getsockopt() clamps the
length it reports but writes a full int with put_user(), overrunning an
optval buffer shorter than sizeof(int). It is fixed in its own patch, with
a Fixes: tag, before the phonet conversion, so it can be backported alone.

The last patch adds getsockopt_iter selftest fixtures for rawv6,
ieee802154, phonet and tls, checking the returned length and errno across
exact, oversized and short buffers, an unknown optname and a bad level.

For full motivation about these changes, please check the initial thread
at link
https://lore.kernel.org/all/20260401-getsockopt-v2-0-611df6771aff@debian.org/#t

Signed-off-by: Breno Leitao <leitao@debian.org>
---
Changes in v3:
- min_t() -> umin() on ieee802154/rawv6 (Joe)
- Link to v2: https://patch.msgid.link/20260720-getsockopt_phase4-v2-0-8a08fcfa0d72@debian.org

Changes in v2:
- Replace min_t() by umin() (David)
- Link to v1: https://patch.msgid.link/20260716-getsockopt_phase4-v1-0-4f45cb12dce7@debian.org

---
Breno Leitao (7):
      ipv6: raw: drop unused level argument from do_rawv6_getsockopt
      ipv6: raw: convert do_rawv6_getsockopt to sockopt_t
      ieee802154: convert dgram getsockopt to sockopt_t
      phonet: pep: do not write beyond optlen in getsockopt
      phonet: pep: convert getsockopt to sockopt_t
      tls: convert getsockopt to sockopt_t
      selftests: net: getsockopt_iter: cover rawv6, ieee802154, phonet and tls

 net/ieee802154/socket.c                       |  38 ++-
 net/ipv6/raw.c                                |  29 +-
 net/phonet/pep.c                              |  36 ++-
 net/tls/tls_main.c                            |  80 +++--
 tools/testing/selftests/net/getsockopt_iter.c | 424 ++++++++++++++++++++++++++
 5 files changed, 534 insertions(+), 73 deletions(-)
---
base-commit: f6f3b36c15ed44de1fbb44e645e4fae8c4a4453e
change-id: 20260715-getsockopt_phase4-180209cfc60a

Best regards,
--  
Breno Leitao <leitao@debian.org>


^ permalink raw reply	[flat|nested] 16+ messages in thread

* [PATCH net-next v3 1/7] ipv6: raw: drop unused level argument from do_rawv6_getsockopt
  2026-07-27 10:06 [PATCH net-next v3 0/7] net: convert rawv6, ieee802154, phonet and tls getsockopt to sockopt_t Breno Leitao
@ 2026-07-27 10:06 ` Breno Leitao
  2026-07-27 15:07   ` Stanislav Fomichev
  2026-07-27 10:06 ` [PATCH net-next v3 2/7] ipv6: raw: convert do_rawv6_getsockopt to sockopt_t Breno Leitao
                   ` (5 subsequent siblings)
  6 siblings, 1 reply; 16+ messages in thread
From: Breno Leitao @ 2026-07-27 10:06 UTC (permalink / raw)
  To: sdf, David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Simon Horman, Alexander Aring, Stefan Schmidt, Miquel Raynal,
	Remi Denis-Courmont, Rémi Denis-Courmont, John Fastabend,
	Sabrina Dubroca, Shuah Khan
  Cc: netdev, linux-kernel, linux-wpan, linux-kselftest, Breno Leitao,
	kernel-team, Joe Damato

do_rawv6_getsockopt() takes a level argument but never uses it; the
level dispatch is handled by the caller, rawv6_getsockopt(). Drop it,
matching ipv4's do_raw_getsockopt().

No functional change.

Reviewed-by: Joe Damato <joe@dama.to>
Signed-off-by: Breno Leitao <leitao@debian.org>
---
 net/ipv6/raw.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c
index 3cc58698cbbd3..99eec36796fb9 100644
--- a/net/ipv6/raw.c
+++ b/net/ipv6/raw.c
@@ -1051,8 +1051,8 @@ static int rawv6_setsockopt(struct sock *sk, int level, int optname,
 	return do_rawv6_setsockopt(sk, level, optname, optval, optlen);
 }
 
-static int do_rawv6_getsockopt(struct sock *sk, int level, int optname,
-			    char __user *optval, int __user *optlen)
+static int do_rawv6_getsockopt(struct sock *sk, int optname,
+			       char __user *optval, int __user *optlen)
 {
 	struct raw6_sock *rp = raw6_sk(sk);
 	int val, len;
@@ -1109,7 +1109,7 @@ static int rawv6_getsockopt(struct sock *sk, int level, int optname,
 		return ipv6_getsockopt(sk, level, optname, optval, optlen);
 	}
 
-	return do_rawv6_getsockopt(sk, level, optname, optval, optlen);
+	return do_rawv6_getsockopt(sk, optname, optval, optlen);
 }
 
 static int rawv6_ioctl(struct sock *sk, int cmd, int *karg)

-- 
2.53.0-Meta


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH net-next v3 2/7] ipv6: raw: convert do_rawv6_getsockopt to sockopt_t
  2026-07-27 10:06 [PATCH net-next v3 0/7] net: convert rawv6, ieee802154, phonet and tls getsockopt to sockopt_t Breno Leitao
  2026-07-27 10:06 ` [PATCH net-next v3 1/7] ipv6: raw: drop unused level argument from do_rawv6_getsockopt Breno Leitao
@ 2026-07-27 10:06 ` Breno Leitao
  2026-07-27 15:24   ` Stanislav Fomichev
  2026-07-27 10:06 ` [PATCH net-next v3 3/7] ieee802154: convert dgram getsockopt " Breno Leitao
                   ` (4 subsequent siblings)
  6 siblings, 1 reply; 16+ messages in thread
From: Breno Leitao @ 2026-07-27 10:06 UTC (permalink / raw)
  To: sdf, David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Simon Horman, Alexander Aring, Stefan Schmidt, Miquel Raynal,
	Remi Denis-Courmont, Rémi Denis-Courmont, John Fastabend,
	Sabrina Dubroca, Shuah Khan
  Cc: netdev, linux-kernel, linux-wpan, linux-kselftest, Breno Leitao,
	kernel-team, Joe Damato

Convert do_rawv6_getsockopt to the new sockopt_t model, mirroring what
we have in ipv4. The overall goal is to move these callbacks gradually
from __user points to use sockopt_t, and this part touches
do_rawv6_getsockopt.

No functional change.

Reviewed-by: Joe Damato <joe@dama.to>
Signed-off-by: Breno Leitao <leitao@debian.org>
---
 net/ipv6/raw.c | 29 ++++++++++++++++++++---------
 1 file changed, 20 insertions(+), 9 deletions(-)

diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c
index 99eec36796fb9..c36152d2295b8 100644
--- a/net/ipv6/raw.c
+++ b/net/ipv6/raw.c
@@ -1051,14 +1051,12 @@ static int rawv6_setsockopt(struct sock *sk, int level, int optname,
 	return do_rawv6_setsockopt(sk, level, optname, optval, optlen);
 }
 
-static int do_rawv6_getsockopt(struct sock *sk, int optname,
-			       char __user *optval, int __user *optlen)
+static int do_rawv6_getsockopt(struct sock *sk, int optname, sockopt_t *opt)
 {
 	struct raw6_sock *rp = raw6_sk(sk);
 	int val, len;
 
-	if (get_user(len, optlen))
-		return -EFAULT;
+	len = opt->optlen;
 
 	switch (optname) {
 	case IPV6_HDRINCL:
@@ -1080,11 +1078,10 @@ static int do_rawv6_getsockopt(struct sock *sk, int optname,
 		return -ENOPROTOOPT;
 	}
 
-	len = min_t(unsigned int, sizeof(int), len);
+	len = umin(sizeof(int), len);
 
-	if (put_user(len, optlen))
-		return -EFAULT;
-	if (copy_to_user(optval, &val, len))
+	opt->optlen = len;
+	if (copy_to_iter(&val, len, &opt->iter_out) != len)
 		return -EFAULT;
 	return 0;
 }
@@ -1092,6 +1089,9 @@ static int do_rawv6_getsockopt(struct sock *sk, int optname,
 static int rawv6_getsockopt(struct sock *sk, int level, int optname,
 			  char __user *optval, int __user *optlen)
 {
+	sockopt_t opt;
+	int err;
+
 	switch (level) {
 	case SOL_RAW:
 		break;
@@ -1109,7 +1109,18 @@ static int rawv6_getsockopt(struct sock *sk, int level, int optname,
 		return ipv6_getsockopt(sk, level, optname, optval, optlen);
 	}
 
-	return do_rawv6_getsockopt(sk, optname, optval, optlen);
+	err = sockopt_init_user(&opt, optval, optlen);
+	if (err)
+		return err;
+
+	err = do_rawv6_getsockopt(sk, optname, &opt);
+	if (err)
+		return err;
+
+	if (put_user(opt.optlen, optlen))
+		return -EFAULT;
+
+	return 0;
 }
 
 static int rawv6_ioctl(struct sock *sk, int cmd, int *karg)

-- 
2.53.0-Meta


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH net-next v3 3/7] ieee802154: convert dgram getsockopt to sockopt_t
  2026-07-27 10:06 [PATCH net-next v3 0/7] net: convert rawv6, ieee802154, phonet and tls getsockopt to sockopt_t Breno Leitao
  2026-07-27 10:06 ` [PATCH net-next v3 1/7] ipv6: raw: drop unused level argument from do_rawv6_getsockopt Breno Leitao
  2026-07-27 10:06 ` [PATCH net-next v3 2/7] ipv6: raw: convert do_rawv6_getsockopt to sockopt_t Breno Leitao
@ 2026-07-27 10:06 ` Breno Leitao
  2026-07-27 15:24   ` Stanislav Fomichev
  2026-07-27 10:06 ` [PATCH net-next v3 4/7] phonet: pep: do not write beyond optlen in getsockopt Breno Leitao
                   ` (3 subsequent siblings)
  6 siblings, 1 reply; 16+ messages in thread
From: Breno Leitao @ 2026-07-27 10:06 UTC (permalink / raw)
  To: sdf, David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Simon Horman, Alexander Aring, Stefan Schmidt, Miquel Raynal,
	Remi Denis-Courmont, Rémi Denis-Courmont, John Fastabend,
	Sabrina Dubroca, Shuah Khan
  Cc: netdev, linux-kernel, linux-wpan, linux-kselftest, Breno Leitao,
	kernel-team, Joe Damato

Continue converting the proto-layer getsockopt callbacks to the sockopt_t
interface, splitting dgram_getsockopt() into a do_dgram_getsockopt() helper
that takes a sockopt_t.

No functional change.

Reviewed-by: Joe Damato <joe@dama.to>
Signed-off-by: Breno Leitao <leitao@debian.org>
---
 net/ieee802154/socket.c | 38 ++++++++++++++++++++++++++------------
 1 file changed, 26 insertions(+), 12 deletions(-)

diff --git a/net/ieee802154/socket.c b/net/ieee802154/socket.c
index 85dce296d7513..5a36e87893f64 100644
--- a/net/ieee802154/socket.c
+++ b/net/ieee802154/socket.c
@@ -831,20 +831,12 @@ static int ieee802154_dgram_deliver(struct net_device *dev, struct sk_buff *skb)
 	return ret;
 }
 
-static int dgram_getsockopt(struct sock *sk, int level, int optname,
-			    char __user *optval, int __user *optlen)
+static int do_dgram_getsockopt(struct sock *sk, int optname, sockopt_t *opt)
 {
 	struct dgram_sock *ro = dgram_sk(sk);
-
 	int val, len;
 
-	if (level != SOL_IEEE802154)
-		return -EOPNOTSUPP;
-
-	if (get_user(len, optlen))
-		return -EFAULT;
-
-	len = min_t(unsigned int, len, sizeof(int));
+	len = umin(sizeof(int), opt->optlen);
 
 	switch (optname) {
 	case WPAN_WANTACK:
@@ -871,10 +863,32 @@ static int dgram_getsockopt(struct sock *sk, int level, int optname,
 		return -ENOPROTOOPT;
 	}
 
-	if (put_user(len, optlen))
+	opt->optlen = len;
+	if (copy_to_iter(&val, len, &opt->iter_out) != len)
 		return -EFAULT;
-	if (copy_to_user(optval, &val, len))
+	return 0;
+}
+
+static int dgram_getsockopt(struct sock *sk, int level, int optname,
+			    char __user *optval, int __user *optlen)
+{
+	sockopt_t opt;
+	int err;
+
+	if (level != SOL_IEEE802154)
+		return -EOPNOTSUPP;
+
+	err = sockopt_init_user(&opt, optval, optlen);
+	if (err)
+		return err;
+
+	err = do_dgram_getsockopt(sk, optname, &opt);
+	if (err)
+		return err;
+
+	if (put_user(opt.optlen, optlen))
 		return -EFAULT;
+
 	return 0;
 }
 

-- 
2.53.0-Meta


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH net-next v3 4/7] phonet: pep: do not write beyond optlen in getsockopt
  2026-07-27 10:06 [PATCH net-next v3 0/7] net: convert rawv6, ieee802154, phonet and tls getsockopt to sockopt_t Breno Leitao
                   ` (2 preceding siblings ...)
  2026-07-27 10:06 ` [PATCH net-next v3 3/7] ieee802154: convert dgram getsockopt " Breno Leitao
@ 2026-07-27 10:06 ` Breno Leitao
  2026-07-27 15:25   ` Stanislav Fomichev
  2026-07-27 10:06 ` [PATCH net-next v3 5/7] phonet: pep: convert getsockopt to sockopt_t Breno Leitao
                   ` (2 subsequent siblings)
  6 siblings, 1 reply; 16+ messages in thread
From: Breno Leitao @ 2026-07-27 10:06 UTC (permalink / raw)
  To: sdf, David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Simon Horman, Alexander Aring, Stefan Schmidt, Miquel Raynal,
	Remi Denis-Courmont, Rémi Denis-Courmont, John Fastabend,
	Sabrina Dubroca, Shuah Khan
  Cc: netdev, linux-kernel, linux-wpan, linux-kselftest, Breno Leitao,
	kernel-team, Rémi Denis-Courmont, Joe Damato

pep_getsockopt() clamps the reported length to the caller's buffer with
min_t(), but then stores the value with put_user(val, (int __user *)
optval), which always writes sizeof(int) bytes. A getsockopt() call with
an optlen smaller than sizeof(int) thus reports the clamped length yet
writes a full int, one to three bytes past the user buffer.

Write the value with copy_to_user() bounded by len, so at most optlen
bytes are copied, matching the length reported back to userspace.

Fixes: 02a47617cdce ("Phonet: implement GPRS virtual interface over PEP socket")
Acked-by: Rémi Denis-Courmont <remi@remlab.net>
Reviewed-by: Joe Damato <joe@dama.to>
Signed-off-by: Breno Leitao <leitao@debian.org>
---
 net/phonet/pep.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/net/phonet/pep.c b/net/phonet/pep.c
index 7069271393933..60d1a5375725b 100644
--- a/net/phonet/pep.c
+++ b/net/phonet/pep.c
@@ -1115,7 +1115,7 @@ static int pep_getsockopt(struct sock *sk, int level, int optname,
 	len = min_t(unsigned int, sizeof(int), len);
 	if (put_user(len, optlen))
 		return -EFAULT;
-	if (put_user(val, (int __user *) optval))
+	if (copy_to_user(optval, &val, len))
 		return -EFAULT;
 	return 0;
 }

-- 
2.53.0-Meta


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH net-next v3 5/7] phonet: pep: convert getsockopt to sockopt_t
  2026-07-27 10:06 [PATCH net-next v3 0/7] net: convert rawv6, ieee802154, phonet and tls getsockopt to sockopt_t Breno Leitao
                   ` (3 preceding siblings ...)
  2026-07-27 10:06 ` [PATCH net-next v3 4/7] phonet: pep: do not write beyond optlen in getsockopt Breno Leitao
@ 2026-07-27 10:06 ` Breno Leitao
  2026-07-27 15:25   ` Stanislav Fomichev
  2026-07-27 10:06 ` [PATCH net-next v3 6/7] tls: " Breno Leitao
  2026-07-27 10:06 ` [PATCH net-next v3 7/7] selftests: net: getsockopt_iter: cover rawv6, ieee802154, phonet and tls Breno Leitao
  6 siblings, 1 reply; 16+ messages in thread
From: Breno Leitao @ 2026-07-27 10:06 UTC (permalink / raw)
  To: sdf, David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Simon Horman, Alexander Aring, Stefan Schmidt, Miquel Raynal,
	Remi Denis-Courmont, Rémi Denis-Courmont, John Fastabend,
	Sabrina Dubroca, Shuah Khan
  Cc: netdev, linux-kernel, linux-wpan, linux-kselftest, Breno Leitao,
	kernel-team, Rémi Denis-Courmont, Joe Damato

Continue converting the proto-layer getsockopt callbacks to the
sockopt_t interface, splitting pep_getsockopt() into a
do_pep_getsockopt() helper that takes a sockopt_t.

The thin pep_getsockopt() wrapper keeps its __user signature for now:
it builds a user-backed sockopt_t with sockopt_init_user(), calls the
helper, and writes the returned length back to optlen. The helper uses
copy_to_iter() instead of copy_to_user(). No functional change.

Acked-by: Rémi Denis-Courmont <remi@remlab.net>
Reviewed-by: Joe Damato <joe@dama.to>
Signed-off-by: Breno Leitao <leitao@debian.org>
---
 net/phonet/pep.c | 36 ++++++++++++++++++++++++++----------
 1 file changed, 26 insertions(+), 10 deletions(-)

diff --git a/net/phonet/pep.c b/net/phonet/pep.c
index 60d1a5375725b..7ef4a9a240ef8 100644
--- a/net/phonet/pep.c
+++ b/net/phonet/pep.c
@@ -1078,17 +1078,11 @@ static int pep_setsockopt(struct sock *sk, int level, int optname,
 	return err;
 }
 
-static int pep_getsockopt(struct sock *sk, int level, int optname,
-				char __user *optval, int __user *optlen)
+static int do_pep_getsockopt(struct sock *sk, int optname, sockopt_t *opt)
 {
 	struct pep_sock *pn = pep_sk(sk);
 	int len, val;
 
-	if (level != SOL_PNPIPE)
-		return -ENOPROTOOPT;
-	if (get_user(len, optlen))
-		return -EFAULT;
-
 	switch (optname) {
 	case PNPIPE_ENCAP:
 		val = pn->ifindex ? PNPIPE_ENCAP_IP : PNPIPE_ENCAP_NONE;
@@ -1112,11 +1106,33 @@ static int pep_getsockopt(struct sock *sk, int level, int optname,
 		return -ENOPROTOOPT;
 	}
 
-	len = min_t(unsigned int, sizeof(int), len);
-	if (put_user(len, optlen))
+	len = umin(sizeof(int), opt->optlen);
+	opt->optlen = len;
+	if (copy_to_iter(&val, len, &opt->iter_out) != len)
 		return -EFAULT;
-	if (copy_to_user(optval, &val, len))
+	return 0;
+}
+
+static int pep_getsockopt(struct sock *sk, int level, int optname,
+			  char __user *optval, int __user *optlen)
+{
+	sockopt_t opt;
+	int err;
+
+	if (level != SOL_PNPIPE)
+		return -ENOPROTOOPT;
+
+	err = sockopt_init_user(&opt, optval, optlen);
+	if (err)
+		return err;
+
+	err = do_pep_getsockopt(sk, optname, &opt);
+	if (err)
+		return err;
+
+	if (put_user(opt.optlen, optlen))
 		return -EFAULT;
+
 	return 0;
 }
 

-- 
2.53.0-Meta


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH net-next v3 6/7] tls: convert getsockopt to sockopt_t
  2026-07-27 10:06 [PATCH net-next v3 0/7] net: convert rawv6, ieee802154, phonet and tls getsockopt to sockopt_t Breno Leitao
                   ` (4 preceding siblings ...)
  2026-07-27 10:06 ` [PATCH net-next v3 5/7] phonet: pep: convert getsockopt to sockopt_t Breno Leitao
@ 2026-07-27 10:06 ` Breno Leitao
  2026-07-27 15:25   ` Stanislav Fomichev
  2026-07-27 10:06 ` [PATCH net-next v3 7/7] selftests: net: getsockopt_iter: cover rawv6, ieee802154, phonet and tls Breno Leitao
  6 siblings, 1 reply; 16+ messages in thread
From: Breno Leitao @ 2026-07-27 10:06 UTC (permalink / raw)
  To: sdf, David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Simon Horman, Alexander Aring, Stefan Schmidt, Miquel Raynal,
	Remi Denis-Courmont, Rémi Denis-Courmont, John Fastabend,
	Sabrina Dubroca, Shuah Khan
  Cc: netdev, linux-kernel, linux-wpan, linux-kselftest, Breno Leitao,
	kernel-team, Joe Damato

Continue converting the proto-layer getsockopt callbacks to the sockopt_t
interface, converting do_tls_getsockopt() and its per-option helpers to
take a sockopt_t.

The thin tls_getsockopt() wrapper keeps its __user signature for now: it
builds a user-backed sockopt_t with sockopt_init_user(), calls the helper,
and writes the returned length back to optlen. The helpers use
copy_to_iter() instead of copy_to_user(); the NULL optval check in the
TLS_TX/TLS_RX path is preserved by testing the iterator user buffer.

No functional change.

Reviewed-by: Sabrina Dubroca <sd@queasysnail.net>
Reviewed-by: Joe Damato <joe@dama.to>
Signed-off-by: Breno Leitao <leitao@debian.org>
---
 net/tls/tls_main.c | 80 ++++++++++++++++++++++++++----------------------------
 1 file changed, 38 insertions(+), 42 deletions(-)

diff --git a/net/tls/tls_main.c b/net/tls/tls_main.c
index 8c588cdab733d..fbb274287aa5f 100644
--- a/net/tls/tls_main.c
+++ b/net/tls/tls_main.c
@@ -424,20 +424,16 @@ static __poll_t tls_sk_poll(struct file *file, struct socket *sock,
 	return mask;
 }
 
-static int do_tls_getsockopt_conf(struct sock *sk, char __user *optval,
-				  int __user *optlen, int tx)
+static int do_tls_getsockopt_conf(struct sock *sk, sockopt_t *opt, int tx)
 {
 	int rc = 0;
 	const struct tls_cipher_desc *cipher_desc;
 	struct tls_context *ctx = tls_get_ctx(sk);
 	struct tls_crypto_info *crypto_info;
 	struct cipher_context *cctx;
-	int len;
+	int len = opt->optlen;
 
-	if (get_user(len, optlen))
-		return -EFAULT;
-
-	if (!optval || (len < sizeof(*crypto_info))) {
+	if (!opt->iter_out.ubuf || len < sizeof(*crypto_info)) {
 		rc = -EINVAL;
 		goto out;
 	}
@@ -462,7 +458,8 @@ static int do_tls_getsockopt_conf(struct sock *sk, char __user *optval,
 	}
 
 	if (len == sizeof(*crypto_info)) {
-		if (copy_to_user(optval, crypto_info, sizeof(*crypto_info)))
+		if (copy_to_iter(crypto_info, sizeof(*crypto_info),
+				 &opt->iter_out) != sizeof(*crypto_info))
 			rc = -EFAULT;
 		goto out;
 	}
@@ -478,44 +475,38 @@ static int do_tls_getsockopt_conf(struct sock *sk, char __user *optval,
 	memcpy(crypto_info_rec_seq(crypto_info, cipher_desc),
 	       cctx->rec_seq, cipher_desc->rec_seq);
 
-	if (copy_to_user(optval, crypto_info, cipher_desc->crypto_info))
+	if (copy_to_iter(crypto_info, cipher_desc->crypto_info,
+			 &opt->iter_out) != cipher_desc->crypto_info)
 		rc = -EFAULT;
 
 out:
 	return rc;
 }
 
-static int do_tls_getsockopt_tx_zc(struct sock *sk, char __user *optval,
-				   int __user *optlen)
+static int do_tls_getsockopt_tx_zc(struct sock *sk, sockopt_t *opt)
 {
 	struct tls_context *ctx = tls_get_ctx(sk);
 	unsigned int value;
-	int len;
-
-	if (get_user(len, optlen))
-		return -EFAULT;
+	int len = opt->optlen;
 
 	if (len != sizeof(value))
 		return -EINVAL;
 
 	value = ctx->zerocopy_sendfile;
-	if (copy_to_user(optval, &value, sizeof(value)))
+	if (copy_to_iter(&value, sizeof(value), &opt->iter_out) != sizeof(value))
 		return -EFAULT;
 
 	return 0;
 }
 
-static int do_tls_getsockopt_no_pad(struct sock *sk, char __user *optval,
-				    int __user *optlen)
+static int do_tls_getsockopt_no_pad(struct sock *sk, sockopt_t *opt)
 {
 	struct tls_context *ctx = tls_get_ctx(sk);
-	int value, len;
+	int value, len = opt->optlen;
 
 	if (ctx->prot_info.version != TLS_1_3_VERSION)
 		return -EINVAL;
 
-	if (get_user(len, optlen))
-		return -EFAULT;
 	if (len < sizeof(value))
 		return -EINVAL;
 
@@ -525,38 +516,31 @@ static int do_tls_getsockopt_no_pad(struct sock *sk, char __user *optval,
 	if (value < 0)
 		return value;
 
-	if (put_user(sizeof(value), optlen))
-		return -EFAULT;
-	if (copy_to_user(optval, &value, sizeof(value)))
+	opt->optlen = sizeof(value);
+	if (copy_to_iter(&value, sizeof(value), &opt->iter_out) != sizeof(value))
 		return -EFAULT;
 
 	return 0;
 }
 
-static int do_tls_getsockopt_tx_payload_len(struct sock *sk, char __user *optval,
-					    int __user *optlen)
+static int do_tls_getsockopt_tx_payload_len(struct sock *sk, sockopt_t *opt)
 {
 	struct tls_context *ctx = tls_get_ctx(sk);
 	u16 payload_len = ctx->tx_max_payload_len;
-	int len;
-
-	if (get_user(len, optlen))
-		return -EFAULT;
+	int len = opt->optlen;
 
 	if (len < sizeof(payload_len))
 		return -EINVAL;
 
-	if (put_user(sizeof(payload_len), optlen))
-		return -EFAULT;
-
-	if (copy_to_user(optval, &payload_len, sizeof(payload_len)))
+	opt->optlen = sizeof(payload_len);
+	if (copy_to_iter(&payload_len, sizeof(payload_len),
+			 &opt->iter_out) != sizeof(payload_len))
 		return -EFAULT;
 
 	return 0;
 }
 
-static int do_tls_getsockopt(struct sock *sk, int optname,
-			     char __user *optval, int __user *optlen)
+static int do_tls_getsockopt(struct sock *sk, int optname, sockopt_t *opt)
 {
 	int rc = 0;
 
@@ -565,17 +549,16 @@ static int do_tls_getsockopt(struct sock *sk, int optname,
 	switch (optname) {
 	case TLS_TX:
 	case TLS_RX:
-		rc = do_tls_getsockopt_conf(sk, optval, optlen,
-					    optname == TLS_TX);
+		rc = do_tls_getsockopt_conf(sk, opt, optname == TLS_TX);
 		break;
 	case TLS_TX_ZEROCOPY_RO:
-		rc = do_tls_getsockopt_tx_zc(sk, optval, optlen);
+		rc = do_tls_getsockopt_tx_zc(sk, opt);
 		break;
 	case TLS_RX_EXPECT_NO_PAD:
-		rc = do_tls_getsockopt_no_pad(sk, optval, optlen);
+		rc = do_tls_getsockopt_no_pad(sk, opt);
 		break;
 	case TLS_TX_MAX_PAYLOAD_LEN:
-		rc = do_tls_getsockopt_tx_payload_len(sk, optval, optlen);
+		rc = do_tls_getsockopt_tx_payload_len(sk, opt);
 		break;
 	default:
 		rc = -ENOPROTOOPT;
@@ -591,12 +574,25 @@ static int tls_getsockopt(struct sock *sk, int level, int optname,
 			  char __user *optval, int __user *optlen)
 {
 	struct tls_context *ctx = tls_get_ctx(sk);
+	sockopt_t opt;
+	int err;
 
 	if (level != SOL_TLS)
 		return ctx->sk_proto->getsockopt(sk, level,
 						 optname, optval, optlen);
 
-	return do_tls_getsockopt(sk, optname, optval, optlen);
+	err = sockopt_init_user(&opt, optval, optlen);
+	if (err)
+		return err;
+
+	err = do_tls_getsockopt(sk, optname, &opt);
+	if (err)
+		return err;
+
+	if (put_user(opt.optlen, optlen))
+		return -EFAULT;
+
+	return 0;
 }
 
 static int validate_crypto_info(const struct tls_crypto_info *crypto_info,

-- 
2.53.0-Meta


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH net-next v3 7/7] selftests: net: getsockopt_iter: cover rawv6, ieee802154, phonet and tls
  2026-07-27 10:06 [PATCH net-next v3 0/7] net: convert rawv6, ieee802154, phonet and tls getsockopt to sockopt_t Breno Leitao
                   ` (5 preceding siblings ...)
  2026-07-27 10:06 ` [PATCH net-next v3 6/7] tls: " Breno Leitao
@ 2026-07-27 10:06 ` Breno Leitao
  2026-07-27 15:26   ` Stanislav Fomichev
  2026-07-27 23:16   ` Jakub Kicinski
  6 siblings, 2 replies; 16+ messages in thread
From: Breno Leitao @ 2026-07-27 10:06 UTC (permalink / raw)
  To: sdf, David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Simon Horman, Alexander Aring, Stefan Schmidt, Miquel Raynal,
	Remi Denis-Courmont, Rémi Denis-Courmont, John Fastabend,
	Sabrina Dubroca, Shuah Khan
  Cc: netdev, linux-kernel, linux-wpan, linux-kselftest, Breno Leitao,
	kernel-team, Rémi Denis-Courmont, Joe Damato

Add fixtures for the newly converted getsockopt leaves:

  - rawv6:      IPV6_HDRINCL / IPV6_CHECKSUM int paths + a SOL_RAW
                unknown-optname case that reaches do_rawv6_getsockopt().
  - ieee802154: WPAN_WANTACK dgram int path + non-SOL_IEEE802154 level
                rejection.
  - phonet:     PNPIPE_ENCAP pep int path + non-SOL_PNPIPE level
                rejection.
  - tls:        TLS_TX_ZEROCOPY_RO, the TLS_TX crypto_info round-trip at
                the base and full cipher sizes, the NULL-optval and short
                buffer EINVAL paths, and an unknown optname. It skips when
                the kernel lacks TLS or AES-GCM.

Each fixture pins the returned-length / errno semantics across exact,
oversized and short buffers, an unknown optname and a bogus level. The
semantics are unchanged by the sockopt_t conversion, so the tests pass
both before and after the leaf conversions.

Acked-by: Rémi Denis-Courmont <remi@remlab.net>
Reviewed-by: Sabrina Dubroca <sd@queasysnail.net>
Reviewed-by: Joe Damato <joe@dama.to>
Signed-off-by: Breno Leitao <leitao@debian.org>
---
 tools/testing/selftests/net/getsockopt_iter.c | 424 ++++++++++++++++++++++++++
 1 file changed, 424 insertions(+)

diff --git a/tools/testing/selftests/net/getsockopt_iter.c b/tools/testing/selftests/net/getsockopt_iter.c
index fe5a5268bc34e..974065a23fa82 100644
--- a/tools/testing/selftests/net/getsockopt_iter.c
+++ b/tools/testing/selftests/net/getsockopt_iter.c
@@ -28,7 +28,10 @@
 #include <linux/vm_sockets.h>
 #include <linux/icmp.h>
 #include <netinet/in.h>
+#include <netinet/tcp.h>
+#include <arpa/inet.h>
 #include <sys/socket.h>
+#include <linux/tls.h>
 #include "kselftest_harness.h"
 
 #ifndef AF_VSOCK
@@ -40,6 +43,45 @@
 #ifndef ICMP_FILTER
 #define ICMP_FILTER 1
 #endif
+#ifndef IPV6_HDRINCL
+#define IPV6_HDRINCL 36
+#endif
+#ifndef IPV6_CHECKSUM
+#define IPV6_CHECKSUM 7
+#endif
+#ifndef AF_IEEE802154
+#define AF_IEEE802154 36
+#endif
+#ifndef SOL_IEEE802154
+#define SOL_IEEE802154 0
+#endif
+#ifndef WPAN_WANTACK
+#define WPAN_WANTACK 0
+#endif
+#ifndef AF_PHONET
+#define AF_PHONET 35
+#endif
+#ifndef SOL_PNPIPE
+#define SOL_PNPIPE 275
+#endif
+#ifndef PN_PROTO_PIPE
+#define PN_PROTO_PIPE 2
+#endif
+#ifndef PNPIPE_ENCAP
+#define PNPIPE_ENCAP 1
+#endif
+#ifndef PNPIPE_ENCAP_NONE
+#define PNPIPE_ENCAP_NONE 0
+#endif
+#ifndef PNPIPE_ENCAP_IP
+#define PNPIPE_ENCAP_IP 1
+#endif
+#ifndef SOL_TLS
+#define SOL_TLS 282
+#endif
+#ifndef TCP_ULP
+#define TCP_ULP 31
+#endif
 
 /* ---------- netlink ---------- */
 
@@ -394,4 +436,386 @@ TEST_F(raw, bad_optname)
 	ASSERT_EQ(sizeof(val), optlen);
 }
 
+/* ---------- raw (ipv6) ---------- */
+
+FIXTURE(rawv6)
+{
+	int fd;
+};
+
+FIXTURE_SETUP(rawv6)
+{
+	self->fd = socket(AF_INET6, SOCK_RAW, IPPROTO_UDP);
+	if (self->fd < 0)
+		SKIP(return, "SOCK_RAW/IPv6 socket: %s", strerror(errno));
+}
+
+FIXTURE_TEARDOWN(rawv6)
+{
+	if (self->fd >= 0)
+		close(self->fd);
+}
+
+TEST_F(rawv6, hdrincl_exact)
+{
+	socklen_t optlen;
+	int val = -1;
+
+	optlen = sizeof(val);
+
+	ASSERT_EQ(0, getsockopt(self->fd, IPPROTO_IPV6, IPV6_HDRINCL,
+				&val, &optlen));
+	ASSERT_EQ(sizeof(int), optlen);
+	ASSERT_TRUE(val == 0 || val == 1);
+}
+
+TEST_F(rawv6, hdrincl_oversize_clamped)
+{
+	char buf[16] = {};
+	socklen_t optlen = sizeof(buf);
+
+	ASSERT_EQ(0, getsockopt(self->fd, IPPROTO_IPV6, IPV6_HDRINCL,
+				buf, &optlen));
+	ASSERT_EQ(sizeof(int), optlen);
+}
+
+/* Raw int options clamp the reported length down to the user buffer
+ * instead of returning EINVAL on a short buffer.
+ */
+TEST_F(rawv6, hdrincl_undersize_clamped)
+{
+	socklen_t optlen = 2;
+	int val = 0;
+
+	ASSERT_EQ(0, getsockopt(self->fd, IPPROTO_IPV6, IPV6_HDRINCL,
+				&val, &optlen));
+	ASSERT_EQ(2, optlen);
+}
+
+TEST_F(rawv6, checksum_default)
+{
+	socklen_t optlen;
+	int val = 0;
+
+	optlen = sizeof(val);
+
+	/* A non-ICMPv6 raw socket has the checksum disabled, reported as -1. */
+	ASSERT_EQ(0, getsockopt(self->fd, IPPROTO_IPV6, IPV6_CHECKSUM,
+				&val, &optlen));
+	ASSERT_EQ(sizeof(int), optlen);
+	ASSERT_EQ(-1, val);
+}
+
+TEST_F(rawv6, bad_optname)
+{
+	socklen_t optlen;
+	int val;
+
+	optlen = sizeof(val);
+
+	/* SOL_RAW reaches do_rawv6_getsockopt() directly. */
+	ASSERT_EQ(-1, getsockopt(self->fd, SOL_RAW, 0x7fff, &val, &optlen));
+	ASSERT_EQ(ENOPROTOOPT, errno);
+	ASSERT_EQ(sizeof(val), optlen);
+}
+
+/* ---------- ieee802154 (dgram) ---------- */
+
+FIXTURE(ieee802154)
+{
+	int fd;
+};
+
+FIXTURE_SETUP(ieee802154)
+{
+	self->fd = socket(AF_IEEE802154, SOCK_DGRAM, 0);
+	if (self->fd < 0)
+		SKIP(return, "AF_IEEE802154 dgram socket: %s", strerror(errno));
+}
+
+FIXTURE_TEARDOWN(ieee802154)
+{
+	if (self->fd >= 0)
+		close(self->fd);
+}
+
+TEST_F(ieee802154, wantack_exact)
+{
+	socklen_t optlen;
+	int val = -1;
+
+	optlen = sizeof(val);
+
+	ASSERT_EQ(0, getsockopt(self->fd, SOL_IEEE802154, WPAN_WANTACK,
+				&val, &optlen));
+	ASSERT_EQ(sizeof(int), optlen);
+	ASSERT_TRUE(val == 0 || val == 1);
+}
+
+TEST_F(ieee802154, wantack_oversize_clamped)
+{
+	char buf[16] = {};
+	socklen_t optlen = sizeof(buf);
+
+	ASSERT_EQ(0, getsockopt(self->fd, SOL_IEEE802154, WPAN_WANTACK,
+				buf, &optlen));
+	ASSERT_EQ(sizeof(int), optlen);
+}
+
+TEST_F(ieee802154, wantack_undersize_clamped)
+{
+	socklen_t optlen = 2;
+	int val = 0;
+
+	ASSERT_EQ(0, getsockopt(self->fd, SOL_IEEE802154, WPAN_WANTACK,
+				&val, &optlen));
+	ASSERT_EQ(2, optlen);
+}
+
+TEST_F(ieee802154, bad_optname)
+{
+	socklen_t optlen;
+	int val;
+
+	optlen = sizeof(val);
+
+	ASSERT_EQ(-1, getsockopt(self->fd, SOL_IEEE802154, 0x7fff,
+				 &val, &optlen));
+	ASSERT_EQ(ENOPROTOOPT, errno);
+	ASSERT_EQ(sizeof(val), optlen);
+}
+
+/* dgram_getsockopt() rejects any level other than SOL_IEEE802154. */
+TEST_F(ieee802154, bad_level)
+{
+	socklen_t optlen;
+	int val;
+
+	optlen = sizeof(val);
+
+	ASSERT_EQ(-1, getsockopt(self->fd, SOL_RAW, WPAN_WANTACK,
+				 &val, &optlen));
+	ASSERT_EQ(EOPNOTSUPP, errno);
+	ASSERT_EQ(sizeof(val), optlen);
+}
+
+/* ---------- phonet (pep) ---------- */
+
+FIXTURE(phonet)
+{
+	int fd;
+};
+
+FIXTURE_SETUP(phonet)
+{
+	self->fd = socket(AF_PHONET, SOCK_SEQPACKET, PN_PROTO_PIPE);
+	if (self->fd < 0)
+		SKIP(return, "AF_PHONET pipe socket: %s", strerror(errno));
+}
+
+FIXTURE_TEARDOWN(phonet)
+{
+	if (self->fd >= 0)
+		close(self->fd);
+}
+
+TEST_F(phonet, encap_exact)
+{
+	socklen_t optlen;
+	int val = -1;
+
+	optlen = sizeof(val);
+
+	ASSERT_EQ(0, getsockopt(self->fd, SOL_PNPIPE, PNPIPE_ENCAP,
+				&val, &optlen));
+	ASSERT_EQ(sizeof(int), optlen);
+	ASSERT_TRUE(val == PNPIPE_ENCAP_NONE || val == PNPIPE_ENCAP_IP);
+}
+
+TEST_F(phonet, encap_oversize_clamped)
+{
+	char buf[16] = {};
+	socklen_t optlen = sizeof(buf);
+
+	ASSERT_EQ(0, getsockopt(self->fd, SOL_PNPIPE, PNPIPE_ENCAP,
+				buf, &optlen));
+	ASSERT_EQ(sizeof(int), optlen);
+}
+
+/* pep clamps the reported length down to the user buffer. Use an
+ * int-sized backing buffer with a short optlen so the baseline kernel,
+ * which writes a full int via put_user(), does not scribble past it.
+ */
+TEST_F(phonet, encap_undersize_clamped)
+{
+	socklen_t optlen = 2;
+	int val = 0;
+
+	ASSERT_EQ(0, getsockopt(self->fd, SOL_PNPIPE, PNPIPE_ENCAP,
+				&val, &optlen));
+	ASSERT_EQ(2, optlen);
+}
+
+TEST_F(phonet, bad_optname)
+{
+	socklen_t optlen;
+	int val;
+
+	optlen = sizeof(val);
+
+	ASSERT_EQ(-1, getsockopt(self->fd, SOL_PNPIPE, 0x7fff, &val, &optlen));
+	ASSERT_EQ(ENOPROTOOPT, errno);
+	ASSERT_EQ(sizeof(val), optlen);
+}
+
+/* pep_getsockopt() rejects any level other than SOL_PNPIPE. */
+TEST_F(phonet, bad_level)
+{
+	socklen_t optlen;
+	int val;
+
+	optlen = sizeof(val);
+
+	ASSERT_EQ(-1, getsockopt(self->fd, SOL_RAW, PNPIPE_ENCAP, &val, &optlen));
+	ASSERT_EQ(ENOPROTOOPT, errno);
+	ASSERT_EQ(sizeof(val), optlen);
+}
+
+/* ---------- tls ---------- */
+
+FIXTURE(tls)
+{
+	int fd;
+	int sfd;
+};
+
+FIXTURE_SETUP(tls)
+{
+	struct sockaddr_in a = {
+		.sin_family = AF_INET,
+		.sin_addr.s_addr = htonl(INADDR_LOOPBACK),
+	};
+	socklen_t alen = sizeof(a);
+	int lfd;
+
+	self->fd = -1;
+	self->sfd = -1;
+
+	lfd = socket(AF_INET, SOCK_STREAM, 0);
+	if (lfd < 0)
+		SKIP(return, "TCP socket: %s", strerror(errno));
+	if (bind(lfd, (struct sockaddr *)&a, sizeof(a)) || listen(lfd, 1) ||
+	    getsockname(lfd, (struct sockaddr *)&a, &alen)) {
+		close(lfd);
+		SKIP(return, "listener setup: %s", strerror(errno));
+	}
+	self->fd = socket(AF_INET, SOCK_STREAM, 0);
+	if (connect(self->fd, (struct sockaddr *)&a, sizeof(a))) {
+		close(lfd);
+		SKIP(return, "connect: %s", strerror(errno));
+	}
+	self->sfd = accept(lfd, NULL, NULL);
+	close(lfd);
+	if (setsockopt(self->fd, IPPROTO_TCP, TCP_ULP, "tls", sizeof("tls")))
+		SKIP(return, "TCP_ULP=tls: %s (built without TLS?)",
+		     strerror(errno));
+}
+
+FIXTURE_TEARDOWN(tls)
+{
+	if (self->fd >= 0)
+		close(self->fd);
+	if (self->sfd >= 0)
+		close(self->sfd);
+}
+
+/* do_tls_getsockopt_tx_zc(): fixed-size int, exact length required. */
+TEST_F(tls, tx_zerocopy_exact)
+{
+	socklen_t optlen = sizeof(int);
+	int val = -1;
+
+	ASSERT_EQ(0, getsockopt(self->fd, SOL_TLS, TLS_TX_ZEROCOPY_RO,
+				&val, &optlen));
+	ASSERT_EQ(sizeof(int), optlen);
+	ASSERT_TRUE(val == 0 || val == 1);
+}
+
+TEST_F(tls, tx_zerocopy_wrong_len)
+{
+	socklen_t optlen = 2;
+	int val;
+
+	ASSERT_EQ(-1, getsockopt(self->fd, SOL_TLS, TLS_TX_ZEROCOPY_RO,
+				 &val, &optlen));
+	ASSERT_EQ(EINVAL, errno);
+}
+
+/* do_tls_getsockopt_conf(): NULL optval still yields EINVAL -- the
+ * converted code tests opt->iter_out.ubuf in place of optval.
+ */
+TEST_F(tls, conf_null_optval)
+{
+	socklen_t optlen = 64;
+
+	ASSERT_EQ(-1, getsockopt(self->fd, SOL_TLS, TLS_TX, NULL, &optlen));
+	ASSERT_EQ(EINVAL, errno);
+}
+
+TEST_F(tls, conf_short)
+{
+	socklen_t optlen = 2;
+	char buf[2];
+
+	ASSERT_EQ(-1, getsockopt(self->fd, SOL_TLS, TLS_TX, buf, &optlen));
+	ASSERT_EQ(EINVAL, errno);
+}
+
+/* TLS_TX before crypto is set reports not-ready. */
+TEST_F(tls, conf_not_ready)
+{
+	struct tls_crypto_info info;
+	socklen_t optlen = sizeof(info);
+
+	ASSERT_EQ(-1, getsockopt(self->fd, SOL_TLS, TLS_TX, &info, &optlen));
+	ASSERT_EQ(EBUSY, errno);
+}
+
+/* Set TX crypto, then read it back at the base and full sizes, exercising
+ * both copy_to_iter() branches. SKIP if AES-GCM is unavailable.
+ */
+TEST_F(tls, conf_crypto_roundtrip)
+{
+	struct tls12_crypto_info_aes_gcm_128 tx = {
+		.info.version = TLS_1_2_VERSION,
+		.info.cipher_type = TLS_CIPHER_AES_GCM_128,
+	};
+	struct tls12_crypto_info_aes_gcm_128 full;
+	struct tls_crypto_info base;
+	socklen_t optlen;
+
+	if (setsockopt(self->fd, SOL_TLS, TLS_TX, &tx, sizeof(tx)))
+		SKIP(return, "set TLS_TX aes_gcm_128: %s", strerror(errno));
+
+	optlen = sizeof(base);
+	ASSERT_EQ(0, getsockopt(self->fd, SOL_TLS, TLS_TX, &base, &optlen));
+	ASSERT_EQ(sizeof(base), optlen);
+	ASSERT_EQ(TLS_1_2_VERSION, base.version);
+	ASSERT_EQ(TLS_CIPHER_AES_GCM_128, base.cipher_type);
+
+	optlen = sizeof(full);
+	ASSERT_EQ(0, getsockopt(self->fd, SOL_TLS, TLS_TX, &full, &optlen));
+	ASSERT_EQ(sizeof(full), optlen);
+	ASSERT_EQ(TLS_CIPHER_AES_GCM_128, full.info.cipher_type);
+}
+
+TEST_F(tls, bad_optname)
+{
+	socklen_t optlen = sizeof(int);
+	int val;
+
+	ASSERT_EQ(-1, getsockopt(self->fd, SOL_TLS, 0x7fff, &val, &optlen));
+	ASSERT_EQ(ENOPROTOOPT, errno);
+}
+
 TEST_HARNESS_MAIN

-- 
2.53.0-Meta


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* Re: [PATCH net-next v3 1/7] ipv6: raw: drop unused level argument from do_rawv6_getsockopt
  2026-07-27 10:06 ` [PATCH net-next v3 1/7] ipv6: raw: drop unused level argument from do_rawv6_getsockopt Breno Leitao
@ 2026-07-27 15:07   ` Stanislav Fomichev
  0 siblings, 0 replies; 16+ messages in thread
From: Stanislav Fomichev @ 2026-07-27 15:07 UTC (permalink / raw)
  To: Breno Leitao
  Cc: sdf, David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Simon Horman, Alexander Aring, Stefan Schmidt, Miquel Raynal,
	Remi Denis-Courmont, Rémi Denis-Courmont, John Fastabend,
	Sabrina Dubroca, Shuah Khan, netdev, linux-kernel, linux-wpan,
	linux-kselftest, kernel-team, Joe Damato

On 07/27, Breno Leitao wrote:
> do_rawv6_getsockopt() takes a level argument but never uses it; the
> level dispatch is handled by the caller, rawv6_getsockopt(). Drop it,
> matching ipv4's do_raw_getsockopt().
> 
> No functional change.
> 
> Reviewed-by: Joe Damato <joe@dama.to>
> Signed-off-by: Breno Leitao <leitao@debian.org>

Acked-by: Stanislav Fomichev <sdf@fomichev.me>

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH net-next v3 2/7] ipv6: raw: convert do_rawv6_getsockopt to sockopt_t
  2026-07-27 10:06 ` [PATCH net-next v3 2/7] ipv6: raw: convert do_rawv6_getsockopt to sockopt_t Breno Leitao
@ 2026-07-27 15:24   ` Stanislav Fomichev
  0 siblings, 0 replies; 16+ messages in thread
From: Stanislav Fomichev @ 2026-07-27 15:24 UTC (permalink / raw)
  To: Breno Leitao
  Cc: sdf, David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Simon Horman, Alexander Aring, Stefan Schmidt, Miquel Raynal,
	Remi Denis-Courmont, Rémi Denis-Courmont, John Fastabend,
	Sabrina Dubroca, Shuah Khan, netdev, linux-kernel, linux-wpan,
	linux-kselftest, kernel-team, Joe Damato

On 07/27, Breno Leitao wrote:
> Convert do_rawv6_getsockopt to the new sockopt_t model, mirroring what
> we have in ipv4. The overall goal is to move these callbacks gradually
> from __user points to use sockopt_t, and this part touches
> do_rawv6_getsockopt.
> 
> No functional change.
> 
> Reviewed-by: Joe Damato <joe@dama.to>
> Signed-off-by: Breno Leitao <leitao@debian.org>

Acked-by: Stanislav Fomichev <sdf@fomichev.me>

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH net-next v3 3/7] ieee802154: convert dgram getsockopt to sockopt_t
  2026-07-27 10:06 ` [PATCH net-next v3 3/7] ieee802154: convert dgram getsockopt " Breno Leitao
@ 2026-07-27 15:24   ` Stanislav Fomichev
  0 siblings, 0 replies; 16+ messages in thread
From: Stanislav Fomichev @ 2026-07-27 15:24 UTC (permalink / raw)
  To: Breno Leitao
  Cc: sdf, David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Simon Horman, Alexander Aring, Stefan Schmidt, Miquel Raynal,
	Remi Denis-Courmont, Rémi Denis-Courmont, John Fastabend,
	Sabrina Dubroca, Shuah Khan, netdev, linux-kernel, linux-wpan,
	linux-kselftest, kernel-team, Joe Damato

On 07/27, Breno Leitao wrote:
> Continue converting the proto-layer getsockopt callbacks to the sockopt_t
> interface, splitting dgram_getsockopt() into a do_dgram_getsockopt() helper
> that takes a sockopt_t.
> 
> No functional change.
> 
> Reviewed-by: Joe Damato <joe@dama.to>
> Signed-off-by: Breno Leitao <leitao@debian.org>

Acked-by: Stanislav Fomichev <sdf@fomichev.me>

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH net-next v3 4/7] phonet: pep: do not write beyond optlen in getsockopt
  2026-07-27 10:06 ` [PATCH net-next v3 4/7] phonet: pep: do not write beyond optlen in getsockopt Breno Leitao
@ 2026-07-27 15:25   ` Stanislav Fomichev
  0 siblings, 0 replies; 16+ messages in thread
From: Stanislav Fomichev @ 2026-07-27 15:25 UTC (permalink / raw)
  To: Breno Leitao
  Cc: sdf, David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Simon Horman, Alexander Aring, Stefan Schmidt, Miquel Raynal,
	Remi Denis-Courmont, Rémi Denis-Courmont, John Fastabend,
	Sabrina Dubroca, Shuah Khan, netdev, linux-kernel, linux-wpan,
	linux-kselftest, kernel-team, Rémi Denis-Courmont,
	Joe Damato

On 07/27, Breno Leitao wrote:
> pep_getsockopt() clamps the reported length to the caller's buffer with
> min_t(), but then stores the value with put_user(val, (int __user *)
> optval), which always writes sizeof(int) bytes. A getsockopt() call with
> an optlen smaller than sizeof(int) thus reports the clamped length yet
> writes a full int, one to three bytes past the user buffer.
> 
> Write the value with copy_to_user() bounded by len, so at most optlen
> bytes are copied, matching the length reported back to userspace.
> 
> Fixes: 02a47617cdce ("Phonet: implement GPRS virtual interface over PEP socket")
> Acked-by: Rémi Denis-Courmont <remi@remlab.net>
> Reviewed-by: Joe Damato <joe@dama.to>
> Signed-off-by: Breno Leitao <leitao@debian.org>

Acked-by: Stanislav Fomichev <sdf@fomichev.me>

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH net-next v3 5/7] phonet: pep: convert getsockopt to sockopt_t
  2026-07-27 10:06 ` [PATCH net-next v3 5/7] phonet: pep: convert getsockopt to sockopt_t Breno Leitao
@ 2026-07-27 15:25   ` Stanislav Fomichev
  0 siblings, 0 replies; 16+ messages in thread
From: Stanislav Fomichev @ 2026-07-27 15:25 UTC (permalink / raw)
  To: Breno Leitao
  Cc: sdf, David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Simon Horman, Alexander Aring, Stefan Schmidt, Miquel Raynal,
	Remi Denis-Courmont, Rémi Denis-Courmont, John Fastabend,
	Sabrina Dubroca, Shuah Khan, netdev, linux-kernel, linux-wpan,
	linux-kselftest, kernel-team, Rémi Denis-Courmont,
	Joe Damato

On 07/27, Breno Leitao wrote:
> Continue converting the proto-layer getsockopt callbacks to the
> sockopt_t interface, splitting pep_getsockopt() into a
> do_pep_getsockopt() helper that takes a sockopt_t.
> 
> The thin pep_getsockopt() wrapper keeps its __user signature for now:
> it builds a user-backed sockopt_t with sockopt_init_user(), calls the
> helper, and writes the returned length back to optlen. The helper uses
> copy_to_iter() instead of copy_to_user(). No functional change.
> 
> Acked-by: Rémi Denis-Courmont <remi@remlab.net>
> Reviewed-by: Joe Damato <joe@dama.to>
> Signed-off-by: Breno Leitao <leitao@debian.org>

Acked-by: Stanislav Fomichev <sdf@fomichev.me>

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH net-next v3 6/7] tls: convert getsockopt to sockopt_t
  2026-07-27 10:06 ` [PATCH net-next v3 6/7] tls: " Breno Leitao
@ 2026-07-27 15:25   ` Stanislav Fomichev
  0 siblings, 0 replies; 16+ messages in thread
From: Stanislav Fomichev @ 2026-07-27 15:25 UTC (permalink / raw)
  To: Breno Leitao
  Cc: sdf, David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Simon Horman, Alexander Aring, Stefan Schmidt, Miquel Raynal,
	Remi Denis-Courmont, Rémi Denis-Courmont, John Fastabend,
	Sabrina Dubroca, Shuah Khan, netdev, linux-kernel, linux-wpan,
	linux-kselftest, kernel-team, Joe Damato

On 07/27, Breno Leitao wrote:
> Continue converting the proto-layer getsockopt callbacks to the sockopt_t
> interface, converting do_tls_getsockopt() and its per-option helpers to
> take a sockopt_t.
> 
> The thin tls_getsockopt() wrapper keeps its __user signature for now: it
> builds a user-backed sockopt_t with sockopt_init_user(), calls the helper,
> and writes the returned length back to optlen. The helpers use
> copy_to_iter() instead of copy_to_user(); the NULL optval check in the
> TLS_TX/TLS_RX path is preserved by testing the iterator user buffer.
> 
> No functional change.
> 
> Reviewed-by: Sabrina Dubroca <sd@queasysnail.net>
> Reviewed-by: Joe Damato <joe@dama.to>
> Signed-off-by: Breno Leitao <leitao@debian.org>

Acked-by: Stanislav Fomichev <sdf@fomichev.me>

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH net-next v3 7/7] selftests: net: getsockopt_iter: cover rawv6, ieee802154, phonet and tls
  2026-07-27 10:06 ` [PATCH net-next v3 7/7] selftests: net: getsockopt_iter: cover rawv6, ieee802154, phonet and tls Breno Leitao
@ 2026-07-27 15:26   ` Stanislav Fomichev
  2026-07-27 23:16   ` Jakub Kicinski
  1 sibling, 0 replies; 16+ messages in thread
From: Stanislav Fomichev @ 2026-07-27 15:26 UTC (permalink / raw)
  To: Breno Leitao
  Cc: sdf, David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Simon Horman, Alexander Aring, Stefan Schmidt, Miquel Raynal,
	Remi Denis-Courmont, Rémi Denis-Courmont, John Fastabend,
	Sabrina Dubroca, Shuah Khan, netdev, linux-kernel, linux-wpan,
	linux-kselftest, kernel-team, Rémi Denis-Courmont,
	Joe Damato

On 07/27, Breno Leitao wrote:
> Add fixtures for the newly converted getsockopt leaves:
> 
>   - rawv6:      IPV6_HDRINCL / IPV6_CHECKSUM int paths + a SOL_RAW
>                 unknown-optname case that reaches do_rawv6_getsockopt().
>   - ieee802154: WPAN_WANTACK dgram int path + non-SOL_IEEE802154 level
>                 rejection.
>   - phonet:     PNPIPE_ENCAP pep int path + non-SOL_PNPIPE level
>                 rejection.
>   - tls:        TLS_TX_ZEROCOPY_RO, the TLS_TX crypto_info round-trip at
>                 the base and full cipher sizes, the NULL-optval and short
>                 buffer EINVAL paths, and an unknown optname. It skips when
>                 the kernel lacks TLS or AES-GCM.
> 
> Each fixture pins the returned-length / errno semantics across exact,
> oversized and short buffers, an unknown optname and a bogus level. The
> semantics are unchanged by the sockopt_t conversion, so the tests pass
> both before and after the leaf conversions.
> 
> Acked-by: Rémi Denis-Courmont <remi@remlab.net>
> Reviewed-by: Sabrina Dubroca <sd@queasysnail.net>
> Reviewed-by: Joe Damato <joe@dama.to>
> Signed-off-by: Breno Leitao <leitao@debian.org>

Acked-by: Stanislav Fomichev <sdf@fomichev.me>

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH net-next v3 7/7] selftests: net: getsockopt_iter: cover rawv6, ieee802154, phonet and tls
  2026-07-27 10:06 ` [PATCH net-next v3 7/7] selftests: net: getsockopt_iter: cover rawv6, ieee802154, phonet and tls Breno Leitao
  2026-07-27 15:26   ` Stanislav Fomichev
@ 2026-07-27 23:16   ` Jakub Kicinski
  1 sibling, 0 replies; 16+ messages in thread
From: Jakub Kicinski @ 2026-07-27 23:16 UTC (permalink / raw)
  To: Breno Leitao
  Cc: sdf, David S. Miller, Eric Dumazet, Paolo Abeni, Simon Horman,
	Alexander Aring, Stefan Schmidt, Miquel Raynal,
	Remi Denis-Courmont, Rémi Denis-Courmont, John Fastabend,
	Sabrina Dubroca, Shuah Khan, netdev, linux-kernel, linux-wpan,
	linux-kselftest, kernel-team, Rémi Denis-Courmont,
	Joe Damato

On Mon, 27 Jul 2026 03:06:41 -0700 Breno Leitao wrote:
>   - ieee802154: WPAN_WANTACK dgram int path + non-SOL_IEEE802154 level
>                 rejection.
>   - phonet:     PNPIPE_ENCAP pep int path + non-SOL_PNPIPE level
>                 rejection.

The config options for these are not enabled in the config for net
selftest target. Doesn't look like we're testing anything particularly
meaningful here, so maybe just drop the cases for these?

^ permalink raw reply	[flat|nested] 16+ messages in thread

end of thread, other threads:[~2026-07-27 23:16 UTC | newest]

Thread overview: 16+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-07-27 10:06 [PATCH net-next v3 0/7] net: convert rawv6, ieee802154, phonet and tls getsockopt to sockopt_t Breno Leitao
2026-07-27 10:06 ` [PATCH net-next v3 1/7] ipv6: raw: drop unused level argument from do_rawv6_getsockopt Breno Leitao
2026-07-27 15:07   ` Stanislav Fomichev
2026-07-27 10:06 ` [PATCH net-next v3 2/7] ipv6: raw: convert do_rawv6_getsockopt to sockopt_t Breno Leitao
2026-07-27 15:24   ` Stanislav Fomichev
2026-07-27 10:06 ` [PATCH net-next v3 3/7] ieee802154: convert dgram getsockopt " Breno Leitao
2026-07-27 15:24   ` Stanislav Fomichev
2026-07-27 10:06 ` [PATCH net-next v3 4/7] phonet: pep: do not write beyond optlen in getsockopt Breno Leitao
2026-07-27 15:25   ` Stanislav Fomichev
2026-07-27 10:06 ` [PATCH net-next v3 5/7] phonet: pep: convert getsockopt to sockopt_t Breno Leitao
2026-07-27 15:25   ` Stanislav Fomichev
2026-07-27 10:06 ` [PATCH net-next v3 6/7] tls: " Breno Leitao
2026-07-27 15:25   ` Stanislav Fomichev
2026-07-27 10:06 ` [PATCH net-next v3 7/7] selftests: net: getsockopt_iter: cover rawv6, ieee802154, phonet and tls Breno Leitao
2026-07-27 15:26   ` Stanislav Fomichev
2026-07-27 23:16   ` Jakub Kicinski

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox