From: Breno Leitao Date: Wed, 20 May 2026 16:53:47 +0000 (-0700) Subject: atm: convert to getsockopt_iter X-Git-Url: http://git.ipfire.org/gitweb/index.cgi?a=commitdiff_plain;h=4177767daf83f4e7bd9b017febd4198b3fad20e9;p=thirdparty%2Fkernel%2Flinux.git 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 Signed-off-by: Breno Leitao Link: https://patch.msgid.link/20260520-getsock_four-v3-2-b8c0b16b7780@debian.org Signed-off-by: Jakub Kicinski --- 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 /* struct sock */ #include #include +#include #include @@ -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 #include /* for sock_no_* */ #include +#include #include #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,