mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-07-24 06:50:12 -04:00
Merge branch 'net-convert-atm-xdp-af_iucv-l2tp_ppp-rxrpc-tipc-to-getsockopt_iter'
Breno Leitao says:
====================
net: convert atm/xdp/af_iucv/l2tp_ppp/rxrpc/tipc to getsockopt_iter
This series continues the conversion of the remaining proto_ops getsockopt
callbacks to the new getsockopt_iter callback introduced in commit 67fab22a7a
("net: add getsockopt_iter callback to proto_ops").
The new callback takes a sockopt_t — a type-safe wrapper around iov_iter
plus an optlen field — instead of raw __user pointers. This:
- Replaces (char __user *optval, int __user *optlen) with sockopt_t *opt
- Reads the input buffer size from opt->optlen instead of get_user()
- Writes the option value via copy_to_iter() instead of copy_to_user()
- Reports the returned length via opt->optlen instead of put_user(),
independently of the bytes copied through the iter
Each conversion is a behaviour-preserving and code-style-preserving refactor;
no big changes being introduced, even when the code looks weird.
====================
Link: https://patch.msgid.link/20260520-getsock_four-v3-0-b8c0b16b7780@debian.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -1574,9 +1573,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;
|
||||
@@ -2228,7 +2226,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,
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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 */
|
||||
@@ -3284,15 +3283,17 @@ static int tipc_getsockopt(struct socket *sock, int lvl, int opt,
|
||||
release_sock(sk);
|
||||
|
||||
if (res)
|
||||
return res; /* "get" failed */
|
||||
return res;
|
||||
|
||||
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,
|
||||
|
||||
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user