* [PATCH net-next v2 1/7] af_iucv: take socket lock around SO_MSGSIZE getsockopt
2026-05-15 8:32 [PATCH net-next v2 0/7] net: convert atm/xdp/af_iucv/l2tp_ppp/rxrpc/tipc to getsockopt_iter Breno Leitao
@ 2026-05-15 8:32 ` Breno Leitao
2026-05-15 8:32 ` [PATCH net-next v2 2/7] af_iucv: convert to getsockopt_iter Breno Leitao
` (5 subsequent siblings)
6 siblings, 0 replies; 8+ messages in thread
From: Breno Leitao @ 2026-05-15 8:32 UTC (permalink / raw)
To: Chas Williams, David S. Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni, Simon Horman, Magnus Karlsson, Maciej Fijalkowski,
Stanislav Fomichev, Alexei Starovoitov, Daniel Borkmann,
Jesper Dangaard Brouer, John Fastabend, Jon Maloy,
Alexandra Winter, Thorsten Winkler, James Chapman, David Howells,
Marc Dionne, David Heidelberg, Samuel Ortiz
Cc: linux-atm-general, netdev, linux-kernel, bpf, tipc-discussion,
linux-s390, linux-afs, oe-linux-nfc, Breno Leitao, kernel-team
Mirror the locking used by the SO_MSGLIMIT case directly above: take
lock_sock() before reading iucv->hs_dev and dereferencing hs_dev->mtu,
and release it afterwards. This keeps the two adjacent getsockopt arms
consistent and matches the lock held by iucv_sock_close() when it
clears hs_dev.
This is not an exploitable bug. iucv_sock_close() is the only writer
of iucv->hs_dev and only runs from the protocol release callback,
which the socket layer invokes after the last file reference drops.
The getsockopt() syscall holds an fd reference for its entire
duration via fdget()/fdput(), so iucv_sock_close() cannot run
concurrently with the SO_MSGSIZE read on the same socket. There is
no other writer of hs_dev, and the aligned pointer load cannot tear
on any architecture Linux supports, so the existing code cannot
observe a NULL dereference or use-after-free in practice.
The change is purely defensive: making the locking pattern uniform
across the function avoids surprising the next reader and removes a
foot-gun should the close path ever grow a new caller that does not
hold the fd reference.
Note: For the reason above, it doesn't contain a "Fixes" tag, and is
aiming at net-next instead of net.
Signed-off-by: Breno Leitao <leitao@debian.org>
---
net/iucv/af_iucv.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/net/iucv/af_iucv.c b/net/iucv/af_iucv.c
index 72dfccd4e3d58..3dd11d7a967c8 100644
--- a/net/iucv/af_iucv.c
+++ b/net/iucv/af_iucv.c
@@ -1566,9 +1566,11 @@ static int iucv_sock_getsockopt(struct socket *sock, int level, int optname,
case SO_MSGSIZE:
if (sk->sk_state == IUCV_OPEN)
return -EBADFD;
+ lock_sock(sk);
val = (iucv->hs_dev) ? iucv->hs_dev->mtu -
sizeof(struct af_iucv_trans_hdr) - ETH_HLEN :
0x7fffffff;
+ release_sock(sk);
break;
default:
return -ENOPROTOOPT;
--
2.53.0-Meta
^ permalink raw reply related [flat|nested] 8+ messages in thread* [PATCH net-next v2 2/7] af_iucv: convert to getsockopt_iter
2026-05-15 8:32 [PATCH net-next v2 0/7] net: convert atm/xdp/af_iucv/l2tp_ppp/rxrpc/tipc to getsockopt_iter Breno Leitao
2026-05-15 8:32 ` [PATCH net-next v2 1/7] af_iucv: take socket lock around SO_MSGSIZE getsockopt Breno Leitao
@ 2026-05-15 8:32 ` Breno Leitao
2026-05-15 8:32 ` [PATCH net-next v2 3/7] atm: " Breno Leitao
` (4 subsequent siblings)
6 siblings, 0 replies; 8+ messages in thread
From: Breno Leitao @ 2026-05-15 8:32 UTC (permalink / raw)
To: Chas Williams, David S. Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni, Simon Horman, Magnus Karlsson, Maciej Fijalkowski,
Stanislav Fomichev, Alexei Starovoitov, Daniel Borkmann,
Jesper Dangaard Brouer, John Fastabend, Jon Maloy,
Alexandra Winter, Thorsten Winkler, James Chapman, David Howells,
Marc Dionne, David Heidelberg, Samuel Ortiz
Cc: linux-atm-general, netdev, linux-kernel, bpf, tipc-discussion,
linux-s390, linux-afs, oe-linux-nfc, Breno Leitao, kernel-team
Convert IUCV socket's getsockopt implementation to use the new
getsockopt_iter callback with sockopt_t.
Key changes:
- Replace (char __user *optval, int __user *optlen) with sockopt_t *opt
- Use opt->optlen for buffer length (input) and returned size (output)
- Use copy_to_iter() instead of put_user()/copy_to_user()
Acked-by: Stanislav Fomichev <sdf@fomichev.me>
Signed-off-by: Breno Leitao <leitao@debian.org>
---
net/iucv/af_iucv.c | 14 ++++++--------
1 file changed, 6 insertions(+), 8 deletions(-)
diff --git a/net/iucv/af_iucv.c b/net/iucv/af_iucv.c
index 3dd11d7a967c8..c0faf06d4afc0 100644
--- a/net/iucv/af_iucv.c
+++ b/net/iucv/af_iucv.c
@@ -26,6 +26,7 @@
#include <linux/init.h>
#include <linux/poll.h>
#include <linux/security.h>
+#include <linux/uio.h>
#include <net/sock.h>
#include <asm/machine.h>
#include <asm/ebcdic.h>
@@ -1535,7 +1536,7 @@ static int iucv_sock_setsockopt(struct socket *sock, int level, int optname,
}
static int iucv_sock_getsockopt(struct socket *sock, int level, int optname,
- char __user *optval, int __user *optlen)
+ sockopt_t *opt)
{
struct sock *sk = sock->sk;
struct iucv_sock *iucv = iucv_sk(sk);
@@ -1545,9 +1546,7 @@ static int iucv_sock_getsockopt(struct socket *sock, int level, int optname,
if (level != SOL_IUCV)
return -ENOPROTOOPT;
- if (get_user(len, optlen))
- return -EFAULT;
-
+ len = opt->optlen;
if (len < 0)
return -EINVAL;
@@ -1576,9 +1575,8 @@ static int iucv_sock_getsockopt(struct socket *sock, int level, int optname,
return -ENOPROTOOPT;
}
- 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;
@@ -2230,7 +2228,7 @@ static const struct proto_ops iucv_sock_ops = {
.socketpair = sock_no_socketpair,
.shutdown = iucv_sock_shutdown,
.setsockopt = iucv_sock_setsockopt,
- .getsockopt = iucv_sock_getsockopt,
+ .getsockopt_iter = iucv_sock_getsockopt,
};
static int iucv_sock_create(struct net *net, struct socket *sock, int protocol,
--
2.53.0-Meta
^ permalink raw reply related [flat|nested] 8+ messages in thread* [PATCH net-next v2 3/7] atm: convert to getsockopt_iter
2026-05-15 8:32 [PATCH net-next v2 0/7] net: convert atm/xdp/af_iucv/l2tp_ppp/rxrpc/tipc to getsockopt_iter Breno Leitao
2026-05-15 8:32 ` [PATCH net-next v2 1/7] af_iucv: take socket lock around SO_MSGSIZE getsockopt Breno Leitao
2026-05-15 8:32 ` [PATCH net-next v2 2/7] af_iucv: convert to getsockopt_iter Breno Leitao
@ 2026-05-15 8:32 ` Breno Leitao
2026-05-15 8:32 ` [PATCH net-next v2 4/7] xdp: " Breno Leitao
` (3 subsequent siblings)
6 siblings, 0 replies; 8+ messages in thread
From: Breno Leitao @ 2026-05-15 8:32 UTC (permalink / raw)
To: Chas Williams, David S. Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni, Simon Horman, Magnus Karlsson, Maciej Fijalkowski,
Stanislav Fomichev, Alexei Starovoitov, Daniel Borkmann,
Jesper Dangaard Brouer, John Fastabend, Jon Maloy,
Alexandra Winter, Thorsten Winkler, James Chapman, David Howells,
Marc Dionne, David Heidelberg, Samuel Ortiz
Cc: linux-atm-general, netdev, linux-kernel, bpf, tipc-discussion,
linux-s390, linux-afs, oe-linux-nfc, Breno Leitao, kernel-team
Convert the ATM SVC and PVC sockets, along with the shared
vcc_getsockopt() helper, to use the new getsockopt_iter callback with
sockopt_t.
Key changes:
- Replace (char __user *optval, int __user *optlen) with sockopt_t *opt
- Use opt->optlen for buffer length (input)
- Use copy_to_iter() instead of put_user()/copy_to_user()
Acked-by: Stanislav Fomichev <sdf@fomichev.me>
Signed-off-by: Breno Leitao <leitao@debian.org>
---
net/atm/common.c | 18 +++++++++++-------
net/atm/common.h | 2 +-
net/atm/pvc.c | 6 +++---
net/atm/svc.c | 15 +++++++--------
4 files changed, 22 insertions(+), 19 deletions(-)
diff --git a/net/atm/common.c b/net/atm/common.c
index fe77f51f6ce18..60132de4eebe1 100644
--- a/net/atm/common.c
+++ b/net/atm/common.c
@@ -23,6 +23,7 @@
#include <net/sock.h> /* struct sock */
#include <linux/uaccess.h>
#include <linux/poll.h>
+#include <linux/uio.h>
#include <linux/atomic.h>
@@ -797,13 +798,13 @@ int vcc_setsockopt(struct socket *sock, int level, int optname,
}
int vcc_getsockopt(struct socket *sock, int level, int optname,
- char __user *optval, int __user *optlen)
+ sockopt_t *opt)
{
struct atm_vcc *vcc;
+ int val;
int len;
- if (get_user(len, optlen))
- return -EFAULT;
+ len = opt->optlen;
if (__SO_LEVEL_MATCH(optname, level) && len != __SO_SIZE(optname))
return -EINVAL;
@@ -812,11 +813,13 @@ int vcc_getsockopt(struct socket *sock, int level, int optname,
case SO_ATMQOS:
if (!test_bit(ATM_VF_HASQOS, &vcc->flags))
return -EINVAL;
- return copy_to_user(optval, &vcc->qos, sizeof(vcc->qos))
+ return copy_to_iter(&vcc->qos, sizeof(vcc->qos),
+ &opt->iter_out) != sizeof(vcc->qos)
? -EFAULT : 0;
case SO_SETCLP:
- return put_user(vcc->atm_options & ATM_ATMOPT_CLP ? 1 : 0,
- (unsigned long __user *)optval) ? -EFAULT : 0;
+ val = vcc->atm_options & ATM_ATMOPT_CLP ? 1 : 0;
+ return copy_to_iter(&val, sizeof(val), &opt->iter_out) !=
+ sizeof(val) ? -EFAULT : 0;
case SO_ATMPVC:
{
struct sockaddr_atmpvc pvc;
@@ -828,7 +831,8 @@ int vcc_getsockopt(struct socket *sock, int level, int optname,
pvc.sap_addr.itf = vcc->dev->number;
pvc.sap_addr.vpi = vcc->vpi;
pvc.sap_addr.vci = vcc->vci;
- return copy_to_user(optval, &pvc, sizeof(pvc)) ? -EFAULT : 0;
+ return copy_to_iter(&pvc, sizeof(pvc), &opt->iter_out) !=
+ sizeof(pvc) ? -EFAULT : 0;
}
default:
return -EINVAL;
diff --git a/net/atm/common.h b/net/atm/common.h
index a1e56e8de698a..ae4502abf0281 100644
--- a/net/atm/common.h
+++ b/net/atm/common.h
@@ -23,7 +23,7 @@ int vcc_compat_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg);
int vcc_setsockopt(struct socket *sock, int level, int optname,
sockptr_t optval, unsigned int optlen);
int vcc_getsockopt(struct socket *sock, int level, int optname,
- char __user *optval, int __user *optlen);
+ sockopt_t *opt);
void vcc_process_recv_queue(struct atm_vcc *vcc);
int atmpvc_init(void);
diff --git a/net/atm/pvc.c b/net/atm/pvc.c
index 8f5e76f5dd9e8..8b2c3e515601e 100644
--- a/net/atm/pvc.c
+++ b/net/atm/pvc.c
@@ -75,13 +75,13 @@ static int pvc_setsockopt(struct socket *sock, int level, int optname,
}
static int pvc_getsockopt(struct socket *sock, int level, int optname,
- char __user *optval, int __user *optlen)
+ sockopt_t *opt)
{
struct sock *sk = sock->sk;
int error;
lock_sock(sk);
- error = vcc_getsockopt(sock, level, optname, optval, optlen);
+ error = vcc_getsockopt(sock, level, optname, opt);
release_sock(sk);
return error;
}
@@ -122,7 +122,7 @@ static const struct proto_ops pvc_proto_ops = {
.listen = sock_no_listen,
.shutdown = pvc_shutdown,
.setsockopt = pvc_setsockopt,
- .getsockopt = pvc_getsockopt,
+ .getsockopt_iter = pvc_getsockopt,
.sendmsg = vcc_sendmsg,
.recvmsg = vcc_recvmsg,
.mmap = sock_no_mmap,
diff --git a/net/atm/svc.c b/net/atm/svc.c
index 005964250ecd2..7c5559f50a99e 100644
--- a/net/atm/svc.c
+++ b/net/atm/svc.c
@@ -21,6 +21,7 @@
#include <linux/bitops.h>
#include <net/sock.h> /* for sock_no_* */
#include <linux/uaccess.h>
+#include <linux/uio.h>
#include <linux/export.h>
#include "resources.h"
@@ -501,25 +502,23 @@ static int svc_setsockopt(struct socket *sock, int level, int optname,
}
static int svc_getsockopt(struct socket *sock, int level, int optname,
- char __user *optval, int __user *optlen)
+ sockopt_t *opt)
{
struct sock *sk = sock->sk;
int error = 0, len;
lock_sock(sk);
if (!__SO_LEVEL_MATCH(optname, level) || optname != SO_ATMSAP) {
- error = vcc_getsockopt(sock, level, optname, optval, optlen);
- goto out;
- }
- if (get_user(len, optlen)) {
- error = -EFAULT;
+ error = vcc_getsockopt(sock, level, optname, opt);
goto out;
}
+ len = opt->optlen;
if (len != sizeof(struct atm_sap)) {
error = -EINVAL;
goto out;
}
- if (copy_to_user(optval, &ATM_SD(sock)->sap, sizeof(struct atm_sap))) {
+ if (copy_to_iter(&ATM_SD(sock)->sap, sizeof(struct atm_sap),
+ &opt->iter_out) != sizeof(struct atm_sap)) {
error = -EFAULT;
goto out;
}
@@ -650,7 +649,7 @@ static const struct proto_ops svc_proto_ops = {
.listen = svc_listen,
.shutdown = svc_shutdown,
.setsockopt = svc_setsockopt,
- .getsockopt = svc_getsockopt,
+ .getsockopt_iter = svc_getsockopt,
.sendmsg = vcc_sendmsg,
.recvmsg = vcc_recvmsg,
.mmap = sock_no_mmap,
--
2.53.0-Meta
^ permalink raw reply related [flat|nested] 8+ messages in thread* [PATCH net-next v2 4/7] xdp: convert to getsockopt_iter
2026-05-15 8:32 [PATCH net-next v2 0/7] net: convert atm/xdp/af_iucv/l2tp_ppp/rxrpc/tipc to getsockopt_iter Breno Leitao
` (2 preceding siblings ...)
2026-05-15 8:32 ` [PATCH net-next v2 3/7] atm: " Breno Leitao
@ 2026-05-15 8:32 ` Breno Leitao
2026-05-15 8:32 ` [PATCH net-next v2 5/7] l2tp: ppp: " Breno Leitao
` (2 subsequent siblings)
6 siblings, 0 replies; 8+ messages in thread
From: Breno Leitao @ 2026-05-15 8:32 UTC (permalink / raw)
To: Chas Williams, David S. Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni, Simon Horman, Magnus Karlsson, Maciej Fijalkowski,
Stanislav Fomichev, Alexei Starovoitov, Daniel Borkmann,
Jesper Dangaard Brouer, John Fastabend, Jon Maloy,
Alexandra Winter, Thorsten Winkler, James Chapman, David Howells,
Marc Dionne, David Heidelberg, Samuel Ortiz
Cc: linux-atm-general, netdev, linux-kernel, bpf, tipc-discussion,
linux-s390, linux-afs, oe-linux-nfc, Breno Leitao, kernel-team
Convert XDP socket's getsockopt implementation to use the new
getsockopt_iter callback with sockopt_t.
Key changes:
- Replace (char __user *optval, int __user *optlen) with sockopt_t *opt
- Use opt->optlen for buffer length (input) and returned size (output)
- Use copy_to_iter() instead of put_user()/copy_to_user()
Acked-by: Stanislav Fomichev <sdf@fomichev.me>
Signed-off-by: Breno Leitao <leitao@debian.org>
---
net/xdp/xsk.c | 24 +++++++++++-------------
1 file changed, 11 insertions(+), 13 deletions(-)
diff --git a/net/xdp/xsk.c b/net/xdp/xsk.c
index 5e5786cd9af55..77f8de054a1be 100644
--- a/net/xdp/xsk.c
+++ b/net/xdp/xsk.c
@@ -22,6 +22,7 @@
#include <linux/net.h>
#include <linux/netdevice.h>
#include <linux/rculist.h>
+#include <linux/uio.h>
#include <linux/vmalloc.h>
#include <net/netdev_queues.h>
@@ -1729,7 +1730,7 @@ struct xdp_statistics_v1 {
};
static int xsk_getsockopt(struct socket *sock, int level, int optname,
- char __user *optval, int __user *optlen)
+ sockopt_t *opt)
{
struct sock *sk = sock->sk;
struct xdp_sock *xs = xdp_sk(sk);
@@ -1738,8 +1739,7 @@ static int xsk_getsockopt(struct socket *sock, int level, int optname,
if (level != SOL_XDP)
return -ENOPROTOOPT;
- if (get_user(len, optlen))
- return -EFAULT;
+ len = opt->optlen;
if (len < 0)
return -EINVAL;
@@ -1773,10 +1773,10 @@ static int xsk_getsockopt(struct socket *sock, int level, int optname,
stats.tx_invalid_descs = xskq_nb_invalid_descs(xs->tx);
mutex_unlock(&xs->mutex);
- if (copy_to_user(optval, &stats, stats_size))
- return -EFAULT;
- if (put_user(stats_size, optlen))
+ if (copy_to_iter(&stats, stats_size, &opt->iter_out) !=
+ stats_size)
return -EFAULT;
+ opt->optlen = stats_size;
return 0;
}
@@ -1825,10 +1825,9 @@ static int xsk_getsockopt(struct socket *sock, int level, int optname,
to_copy = &off_v1;
}
- if (copy_to_user(optval, to_copy, len))
- return -EFAULT;
- if (put_user(len, optlen))
+ if (copy_to_iter(to_copy, len, &opt->iter_out) != len)
return -EFAULT;
+ opt->optlen = len;
return 0;
}
@@ -1845,10 +1844,9 @@ static int xsk_getsockopt(struct socket *sock, int level, int optname,
mutex_unlock(&xs->mutex);
len = sizeof(opts);
- if (copy_to_user(optval, &opts, len))
- return -EFAULT;
- if (put_user(len, optlen))
+ if (copy_to_iter(&opts, len, &opt->iter_out) != len)
return -EFAULT;
+ opt->optlen = len;
return 0;
}
@@ -1949,7 +1947,7 @@ static const struct proto_ops xsk_proto_ops = {
.listen = sock_no_listen,
.shutdown = sock_no_shutdown,
.setsockopt = xsk_setsockopt,
- .getsockopt = xsk_getsockopt,
+ .getsockopt_iter = xsk_getsockopt,
.sendmsg = xsk_sendmsg,
.recvmsg = xsk_recvmsg,
.mmap = xsk_mmap,
--
2.53.0-Meta
^ permalink raw reply related [flat|nested] 8+ messages in thread* [PATCH net-next v2 5/7] l2tp: ppp: convert to getsockopt_iter
2026-05-15 8:32 [PATCH net-next v2 0/7] net: convert atm/xdp/af_iucv/l2tp_ppp/rxrpc/tipc to getsockopt_iter Breno Leitao
` (3 preceding siblings ...)
2026-05-15 8:32 ` [PATCH net-next v2 4/7] xdp: " Breno Leitao
@ 2026-05-15 8:32 ` Breno Leitao
2026-05-15 8:32 ` [PATCH net-next v2 6/7] rxrpc: " Breno Leitao
2026-05-15 8:32 ` [PATCH net-next v2 7/7] tipc: " Breno Leitao
6 siblings, 0 replies; 8+ messages in thread
From: Breno Leitao @ 2026-05-15 8:32 UTC (permalink / raw)
To: Chas Williams, David S. Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni, Simon Horman, Magnus Karlsson, Maciej Fijalkowski,
Stanislav Fomichev, Alexei Starovoitov, Daniel Borkmann,
Jesper Dangaard Brouer, John Fastabend, Jon Maloy,
Alexandra Winter, Thorsten Winkler, James Chapman, David Howells,
Marc Dionne, David Heidelberg, Samuel Ortiz
Cc: linux-atm-general, netdev, linux-kernel, bpf, tipc-discussion,
linux-s390, linux-afs, oe-linux-nfc, Breno Leitao, kernel-team
Convert PPPoL2TP socket's getsockopt implementation to use the new
getsockopt_iter callback with sockopt_t.
Key changes:
- Replace (char __user *optval, int __user *optlen) with sockopt_t *opt
- Use opt->optlen for buffer length (input) and returned size (output)
- Use copy_to_iter() instead of put_user()/copy_to_user()
Acked-by: Stanislav Fomichev <sdf@fomichev.me>
Signed-off-by: Breno Leitao <leitao@debian.org>
---
net/l2tp/l2tp_ppp.c | 20 +++++++-------------
1 file changed, 7 insertions(+), 13 deletions(-)
diff --git a/net/l2tp/l2tp_ppp.c b/net/l2tp/l2tp_ppp.c
index 99d6582f41de2..46143e882af5e 100644
--- a/net/l2tp/l2tp_ppp.c
+++ b/net/l2tp/l2tp_ppp.c
@@ -59,6 +59,7 @@
#include <linux/string.h>
#include <linux/list.h>
#include <linux/uaccess.h>
+#include <linux/uio.h>
#include <linux/kernel.h>
#include <linux/spinlock.h>
@@ -1317,7 +1318,7 @@ static int pppol2tp_session_getsockopt(struct sock *sk,
* or the special tunnel type.
*/
static int pppol2tp_getsockopt(struct socket *sock, int level, int optname,
- char __user *optval, int __user *optlen)
+ sockopt_t *opt)
{
struct sock *sk = sock->sk;
struct l2tp_session *session;
@@ -1328,9 +1329,7 @@ static int pppol2tp_getsockopt(struct socket *sock, int level, int optname,
if (level != SOL_PPPOL2TP)
return -EINVAL;
- if (get_user(len, optlen))
- return -EFAULT;
-
+ len = opt->optlen;
if (len < 0)
return -EINVAL;
@@ -1358,14 +1357,9 @@ static int pppol2tp_getsockopt(struct socket *sock, int level, int optname,
goto end_put_sess;
}
- err = -EFAULT;
- if (put_user(len, optlen))
- goto end_put_sess;
-
- if (copy_to_user((void __user *)optval, &val, len))
- goto end_put_sess;
-
- err = 0;
+ opt->optlen = len;
+ if (copy_to_iter(&val, len, &opt->iter_out) != len)
+ err = -EFAULT;
end_put_sess:
l2tp_session_put(session);
@@ -1634,7 +1628,7 @@ static const struct proto_ops pppol2tp_ops = {
.listen = sock_no_listen,
.shutdown = sock_no_shutdown,
.setsockopt = pppol2tp_setsockopt,
- .getsockopt = pppol2tp_getsockopt,
+ .getsockopt_iter = pppol2tp_getsockopt,
.sendmsg = pppol2tp_sendmsg,
.recvmsg = pppol2tp_recvmsg,
.mmap = sock_no_mmap,
--
2.53.0-Meta
^ permalink raw reply related [flat|nested] 8+ messages in thread* [PATCH net-next v2 6/7] rxrpc: convert to getsockopt_iter
2026-05-15 8:32 [PATCH net-next v2 0/7] net: convert atm/xdp/af_iucv/l2tp_ppp/rxrpc/tipc to getsockopt_iter Breno Leitao
` (4 preceding siblings ...)
2026-05-15 8:32 ` [PATCH net-next v2 5/7] l2tp: ppp: " Breno Leitao
@ 2026-05-15 8:32 ` Breno Leitao
2026-05-15 8:32 ` [PATCH net-next v2 7/7] tipc: " Breno Leitao
6 siblings, 0 replies; 8+ messages in thread
From: Breno Leitao @ 2026-05-15 8:32 UTC (permalink / raw)
To: Chas Williams, David S. Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni, Simon Horman, Magnus Karlsson, Maciej Fijalkowski,
Stanislav Fomichev, Alexei Starovoitov, Daniel Borkmann,
Jesper Dangaard Brouer, John Fastabend, Jon Maloy,
Alexandra Winter, Thorsten Winkler, James Chapman, David Howells,
Marc Dionne, David Heidelberg, Samuel Ortiz
Cc: linux-atm-general, netdev, linux-kernel, bpf, tipc-discussion,
linux-s390, linux-afs, oe-linux-nfc, Breno Leitao, kernel-team
Convert RxRPC socket's getsockopt implementation to use the new
getsockopt_iter callback with sockopt_t.
Key changes:
- Replace (char __user *optval, int __user *optlen) with sockopt_t *opt
- Use opt->optlen for buffer length (input) and returned size (output)
- Use copy_to_iter() instead of put_user()/copy_to_user()
Acked-by: Stanislav Fomichev <sdf@fomichev.me>
Signed-off-by: Breno Leitao <leitao@debian.org>
---
net/rxrpc/af_rxrpc.c | 16 +++++++++-------
1 file changed, 9 insertions(+), 7 deletions(-)
diff --git a/net/rxrpc/af_rxrpc.c b/net/rxrpc/af_rxrpc.c
index 32ec91fa938fb..9ab0f22c881ec 100644
--- a/net/rxrpc/af_rxrpc.c
+++ b/net/rxrpc/af_rxrpc.c
@@ -16,6 +16,7 @@
#include <linux/poll.h>
#include <linux/proc_fs.h>
#include <linux/key-type.h>
+#include <linux/uio.h>
#include <net/net_namespace.h>
#include <net/sock.h>
#include <net/af_rxrpc.h>
@@ -743,23 +744,24 @@ static int rxrpc_setsockopt(struct socket *sock, int level, int optname,
* Get socket options.
*/
static int rxrpc_getsockopt(struct socket *sock, int level, int optname,
- char __user *optval, int __user *_optlen)
+ sockopt_t *opt)
{
- int optlen;
+ int optlen, val;
if (level != SOL_RXRPC)
return -EOPNOTSUPP;
- if (get_user(optlen, _optlen))
- return -EFAULT;
+ optlen = opt->optlen;
switch (optname) {
case RXRPC_SUPPORTED_CMSG:
if (optlen < sizeof(int))
return -ETOOSMALL;
- if (put_user(RXRPC__SUPPORTED - 1, (int __user *)optval) ||
- put_user(sizeof(int), _optlen))
+ val = RXRPC__SUPPORTED - 1;
+ if (copy_to_iter(&val, sizeof(val), &opt->iter_out) !=
+ sizeof(val))
return -EFAULT;
+ opt->optlen = sizeof(val);
return 0;
default:
@@ -1009,7 +1011,7 @@ static const struct proto_ops rxrpc_rpc_ops = {
.listen = rxrpc_listen,
.shutdown = rxrpc_shutdown,
.setsockopt = rxrpc_setsockopt,
- .getsockopt = rxrpc_getsockopt,
+ .getsockopt_iter = rxrpc_getsockopt,
.sendmsg = rxrpc_sendmsg,
.recvmsg = rxrpc_recvmsg,
.mmap = sock_no_mmap,
--
2.53.0-Meta
^ permalink raw reply related [flat|nested] 8+ messages in thread* [PATCH net-next v2 7/7] tipc: convert to getsockopt_iter
2026-05-15 8:32 [PATCH net-next v2 0/7] net: convert atm/xdp/af_iucv/l2tp_ppp/rxrpc/tipc to getsockopt_iter Breno Leitao
` (5 preceding siblings ...)
2026-05-15 8:32 ` [PATCH net-next v2 6/7] rxrpc: " Breno Leitao
@ 2026-05-15 8:32 ` Breno Leitao
6 siblings, 0 replies; 8+ messages in thread
From: Breno Leitao @ 2026-05-15 8:32 UTC (permalink / raw)
To: Chas Williams, David S. Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni, Simon Horman, Magnus Karlsson, Maciej Fijalkowski,
Stanislav Fomichev, Alexei Starovoitov, Daniel Borkmann,
Jesper Dangaard Brouer, John Fastabend, Jon Maloy,
Alexandra Winter, Thorsten Winkler, James Chapman, David Howells,
Marc Dionne, David Heidelberg, Samuel Ortiz
Cc: linux-atm-general, netdev, linux-kernel, bpf, tipc-discussion,
linux-s390, linux-afs, oe-linux-nfc, Breno Leitao, kernel-team
Convert TIPC sockets (msg, packet, stream proto_ops) to use the new
getsockopt_iter callback with sockopt_t.
Key changes:
- Replace (char __user *optval, int __user *optlen) with sockopt_t *sopt
- Use sopt->optlen for buffer length (input) and returned size (output)
- Use copy_to_iter() instead of put_user()/copy_to_user()
The sockopt_t parameter is named sopt to avoid collision with the
existing optname parameter named opt.
Note: Dropped the unnecessary parentheses to make checkpatch happier.
Acked-by: Stanislav Fomichev <sdf@fomichev.me>
Signed-off-by: Breno Leitao <leitao@debian.org>
---
net/tipc/socket.c | 31 ++++++++++++++++---------------
1 file changed, 16 insertions(+), 15 deletions(-)
diff --git a/net/tipc/socket.c b/net/tipc/socket.c
index 9329919fb07f0..858aa6e9566d7 100644
--- a/net/tipc/socket.c
+++ b/net/tipc/socket.c
@@ -37,6 +37,7 @@
#include <linux/rhashtable.h>
#include <linux/sched/signal.h>
+#include <linux/uio.h>
#include <trace/events/sock.h>
#include "core.h"
@@ -3220,8 +3221,7 @@ static int tipc_setsockopt(struct socket *sock, int lvl, int opt,
* @sock: socket structure
* @lvl: option level
* @opt: option identifier
- * @ov: receptacle for option value
- * @ol: receptacle for length of option value
+ * @sopt: socket option container (input buffer length, output value/length)
*
* For stream sockets only, returns 0 length result for all IPPROTO_TCP options
* (to ease compatibility).
@@ -3229,22 +3229,22 @@ static int tipc_setsockopt(struct socket *sock, int lvl, int opt,
* Return: 0 on success, errno otherwise
*/
static int tipc_getsockopt(struct socket *sock, int lvl, int opt,
- char __user *ov, int __user *ol)
+ sockopt_t *sopt)
{
struct sock *sk = sock->sk;
struct tipc_sock *tsk = tipc_sk(sk);
struct tipc_service_range seq;
int len, scope;
+ int res = 0;
u32 value;
- int res;
- if ((lvl == IPPROTO_TCP) && (sock->type == SOCK_STREAM))
- return put_user(0, ol);
+ if (lvl == IPPROTO_TCP && sock->type == SOCK_STREAM) {
+ sopt->optlen = 0;
+ return 0;
+ }
if (lvl != SOL_TIPC)
return -ENOPROTOOPT;
- res = get_user(len, ol);
- if (res)
- return res;
+ len = sopt->optlen;
lock_sock(sk);
@@ -3260,7 +3260,6 @@ static int tipc_getsockopt(struct socket *sock, int lvl, int opt,
break;
case TIPC_CONN_TIMEOUT:
value = tsk->conn_timeout;
- /* no need to set "res", since already 0 at this point */
break;
case TIPC_NODE_RECVQ_DEPTH:
value = 0; /* was tipc_queue_size, now obsolete */
@@ -3289,10 +3288,12 @@ static int tipc_getsockopt(struct socket *sock, int lvl, int opt,
if (len < sizeof(value))
return -EINVAL;
- if (copy_to_user(ov, &value, sizeof(value)))
+ if (copy_to_iter(&value, sizeof(value), &sopt->iter_out) !=
+ sizeof(value))
return -EFAULT;
+ sopt->optlen = sizeof(value);
- return put_user(sizeof(value), ol);
+ return 0;
}
static int tipc_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
@@ -3365,7 +3366,7 @@ static const struct proto_ops msg_ops = {
.listen = sock_no_listen,
.shutdown = tipc_shutdown,
.setsockopt = tipc_setsockopt,
- .getsockopt = tipc_getsockopt,
+ .getsockopt_iter = tipc_getsockopt,
.sendmsg = tipc_sendmsg,
.recvmsg = tipc_recvmsg,
.mmap = sock_no_mmap,
@@ -3385,7 +3386,7 @@ static const struct proto_ops packet_ops = {
.listen = tipc_listen,
.shutdown = tipc_shutdown,
.setsockopt = tipc_setsockopt,
- .getsockopt = tipc_getsockopt,
+ .getsockopt_iter = tipc_getsockopt,
.sendmsg = tipc_send_packet,
.recvmsg = tipc_recvmsg,
.mmap = sock_no_mmap,
@@ -3405,7 +3406,7 @@ static const struct proto_ops stream_ops = {
.listen = tipc_listen,
.shutdown = tipc_shutdown,
.setsockopt = tipc_setsockopt,
- .getsockopt = tipc_getsockopt,
+ .getsockopt_iter = tipc_getsockopt,
.sendmsg = tipc_sendstream,
.recvmsg = tipc_recvstream,
.mmap = sock_no_mmap,
--
2.53.0-Meta
^ permalink raw reply related [flat|nested] 8+ messages in thread