]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
atm: convert to getsockopt_iter
authorBreno Leitao <leitao@debian.org>
Wed, 20 May 2026 16:53:47 +0000 (09:53 -0700)
committerJakub Kicinski <kuba@kernel.org>
Fri, 22 May 2026 18:11:09 +0000 (11:11 -0700)
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>
net/atm/common.c
net/atm/common.h
net/atm/pvc.c
net/atm/svc.c

index fe77f51f6ce18466b1e03b6230e23d0688cb929d..60132de4eebe11b71db143107d8fe47351c9bed4 100644 (file)
@@ -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;
index a1e56e8de698a3abb112f278381bb841c6837524..ae4502abf0281635fec8e7bbd81376970a48415c 100644 (file)
@@ -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);
index 8f5e76f5dd9e8d2188b39e0e6d0657360b663254..8b2c3e515601e08e7bfd233b10e8afae8b102cc0 100644 (file)
@@ -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,
index 005964250ecd2970a7c7b62c54a8df262e66a773..7c5559f50a99e385a7eb33e35b9f6edd84cf990b 100644 (file)
@@ -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,