diff options
| author | Breno Leitao <leitao@debian.org> | 2026-05-20 19:53:47 +0300 |
|---|---|---|
| committer | Jakub Kicinski <kuba@kernel.org> | 2026-05-22 21:11:09 +0300 |
| commit | 4177767daf83f4e7bd9b017febd4198b3fad20e9 (patch) | |
| tree | 2493c5dfdf648d5e4df53e6d210ecf3803c052af | |
| parent | 347fdd4df85fc14a45a90c89fe54fccce36bd317 (diff) | |
| download | linux-4177767daf83f4e7bd9b017febd4198b3fad20e9.tar.xz | |
atm: convert to getsockopt_iter
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>
Link: https://patch.msgid.link/20260520-getsock_four-v3-2-b8c0b16b7780@debian.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
| -rw-r--r-- | net/atm/common.c | 18 | ||||
| -rw-r--r-- | net/atm/common.h | 2 | ||||
| -rw-r--r-- | net/atm/pvc.c | 6 | ||||
| -rw-r--r-- | 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 fe77f51f6ce1..60132de4eebe 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 a1e56e8de698..ae4502abf028 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 8f5e76f5dd9e..8b2c3e515601 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 005964250ecd..7c5559f50a99 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 @@ out: } 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, |
