]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
af_packet: convert to getsockopt_iter
authorBreno Leitao <leitao@debian.org>
Wed, 8 Apr 2026 10:30:31 +0000 (03:30 -0700)
committerJakub Kicinski <kuba@kernel.org>
Mon, 13 Apr 2026 21:56:29 +0000 (14:56 -0700)
Convert AF_PACKET'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()
- For PACKET_HDRLEN which reads from optval: use opt->iter_in with
  copy_from_iter() for the input read, then the common opt->iter_out
  copy_to_iter() epilogue handles the output

Signed-off-by: Breno Leitao <leitao@debian.org>
Acked-by: Stanislav Fomichev <sdf@fomichev.me>
Link: https://patch.msgid.link/20260408-getsockopt-v3-3-061bb9cb355d@debian.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
net/packet/af_packet.c

index bb2d88205e5a65e020eea821c0ac0c5bedaf7e7c..1da78b6ad3d5f0957eaf4ad61399cb813ea864cd 100644 (file)
@@ -49,6 +49,7 @@
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 
 #include <linux/ethtool.h>
+#include <linux/uio.h>
 #include <linux/filter.h>
 #include <linux/types.h>
 #include <linux/mm.h>
@@ -4051,7 +4052,7 @@ packet_setsockopt(struct socket *sock, int level, int optname, sockptr_t optval,
 }
 
 static int packet_getsockopt(struct socket *sock, int level, int optname,
-                            char __user *optval, int __user *optlen)
+                            sockopt_t *opt)
 {
        int len;
        int val, lv = sizeof(val);
@@ -4065,8 +4066,7 @@ static int packet_getsockopt(struct socket *sock, int level, int optname,
        if (level != SOL_PACKET)
                return -ENOPROTOOPT;
 
-       if (get_user(len, optlen))
-               return -EFAULT;
+       len = opt->optlen;
 
        if (len < 0)
                return -EINVAL;
@@ -4115,7 +4115,7 @@ static int packet_getsockopt(struct socket *sock, int level, int optname,
                        len = sizeof(int);
                if (len < sizeof(int))
                        return -EINVAL;
-               if (copy_from_user(&val, optval, len))
+               if (copy_from_iter(&val, len, &opt->iter_in) != len)
                        return -EFAULT;
                switch (val) {
                case TPACKET_V1:
@@ -4171,9 +4171,8 @@ static int packet_getsockopt(struct socket *sock, int level, int optname,
 
        if (len > lv)
                len = lv;
-       if (put_user(len, optlen))
-               return -EFAULT;
-       if (copy_to_user(optval, data, len))
+       opt->optlen = len;
+       if (copy_to_iter(data, len, &opt->iter_out) != len)
                return -EFAULT;
        return 0;
 }
@@ -4672,7 +4671,7 @@ static const struct proto_ops packet_ops = {
        .listen =       sock_no_listen,
        .shutdown =     sock_no_shutdown,
        .setsockopt =   packet_setsockopt,
-       .getsockopt =   packet_getsockopt,
+       .getsockopt_iter =      packet_getsockopt,
        .sendmsg =      packet_sendmsg,
        .recvmsg =      packet_recvmsg,
        .mmap =         packet_mmap,