]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
drop queue-6.1/net-ioctl-use-kernel-memory-on-protocol-ioctl-callba.patch
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 27 Feb 2024 10:48:40 +0000 (11:48 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 27 Feb 2024 10:48:40 +0000 (11:48 +0100)
Not really needed.

queue-6.1/net-ioctl-use-kernel-memory-on-protocol-ioctl-callba.patch [deleted file]
queue-6.1/phonet-pep-fix-racy-skb_queue_empty-use.patch
queue-6.1/phonet-take-correct-lock-to-peek-at-the-rx-queue.patch
queue-6.1/series

diff --git a/queue-6.1/net-ioctl-use-kernel-memory-on-protocol-ioctl-callba.patch b/queue-6.1/net-ioctl-use-kernel-memory-on-protocol-ioctl-callba.patch
deleted file mode 100644 (file)
index 994244a..0000000
+++ /dev/null
@@ -1,1078 +0,0 @@
-From 411791fe82c0b08a8c4ee827713133f47c2e890d Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Fri, 9 Jun 2023 08:27:42 -0700
-Subject: net: ioctl: Use kernel memory on protocol ioctl callbacks
-
-From: Breno Leitao <leitao@debian.org>
-
-[ Upstream commit e1d001fa5b477c4da46a29be1fcece91db7c7c6f ]
-
-Most of the ioctls to net protocols operates directly on userspace
-argument (arg). Usually doing get_user()/put_user() directly in the
-ioctl callback.  This is not flexible, because it is hard to reuse these
-functions without passing userspace buffers.
-
-Change the "struct proto" ioctls to avoid touching userspace memory and
-operate on kernel buffers, i.e., all protocol's ioctl callbacks is
-adapted to operate on a kernel memory other than on userspace (so, no
-more {put,get}_user() and friends being called in the ioctl callback).
-
-This changes the "struct proto" ioctl format in the following way:
-
-    int                     (*ioctl)(struct sock *sk, int cmd,
--                                        unsigned long arg);
-+                                        int *karg);
-
-(Important to say that this patch does not touch the "struct proto_ops"
-protocols)
-
-So, the "karg" argument, which is passed to the ioctl callback, is a
-pointer allocated to kernel space memory (inside a function wrapper).
-This buffer (karg) may contain input argument (copied from userspace in
-a prep function) and it might return a value/buffer, which is copied
-back to userspace if necessary. There is not one-size-fits-all format
-(that is I am using 'may' above), but basically, there are three type of
-ioctls:
-
-1) Do not read from userspace, returns a result to userspace
-2) Read an input parameter from userspace, and does not return anything
-  to userspace
-3) Read an input from userspace, and return a buffer to userspace.
-
-The default case (1) (where no input parameter is given, and an "int" is
-returned to userspace) encompasses more than 90% of the cases, but there
-are two other exceptions. Here is a list of exceptions:
-
-* Protocol RAW:
-   * cmd = SIOCGETVIFCNT:
-     * input and output = struct sioc_vif_req
-   * cmd = SIOCGETSGCNT
-     * input and output = struct sioc_sg_req
-   * Explanation: for the SIOCGETVIFCNT case, userspace passes the input
-     argument, which is struct sioc_vif_req. Then the callback populates
-     the struct, which is copied back to userspace.
-
-* Protocol RAW6:
-   * cmd = SIOCGETMIFCNT_IN6
-     * input and output = struct sioc_mif_req6
-   * cmd = SIOCGETSGCNT_IN6
-     * input and output = struct sioc_sg_req6
-
-* Protocol PHONET:
-  * cmd == SIOCPNADDRESOURCE | SIOCPNDELRESOURCE
-     * input int (4 bytes)
-  * Nothing is copied back to userspace.
-
-For the exception cases, functions sock_sk_ioctl_inout() will
-copy the userspace input, and copy it back to kernel space.
-
-The wrapper that prepare the buffer and put the buffer back to user is
-sk_ioctl(), so, instead of calling sk->sk_prot->ioctl(), the callee now
-calls sk_ioctl(), which will handle all cases.
-
-Signed-off-by: Breno Leitao <leitao@debian.org>
-Reviewed-by: Willem de Bruijn <willemb@google.com>
-Reviewed-by: David Ahern <dsahern@kernel.org>
-Reviewed-by: Kuniyuki Iwashima <kuniyu@amazon.com>
-Link: https://lore.kernel.org/r/20230609152800.830401-1-leitao@debian.org
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
-Stable-dep-of: 3b2d9bc4d4ac ("phonet: take correct lock to peek at the RX queue")
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- include/linux/icmpv6.h      |  6 ++++
- include/linux/mroute.h      | 22 +++++++++++--
- include/linux/mroute6.h     | 31 ++++++++++++++++--
- include/net/phonet/phonet.h | 21 ++++++++++++
- include/net/sock.h          |  5 ++-
- include/net/tcp.h           |  2 +-
- include/net/udp.h           |  2 +-
- net/core/sock.c             | 64 +++++++++++++++++++++++++++++++++++++
- net/dccp/dccp.h             |  2 +-
- net/dccp/proto.c            | 12 +++----
- net/ieee802154/socket.c     | 15 ++++-----
- net/ipv4/af_inet.c          |  2 +-
- net/ipv4/ipmr.c             | 63 ++++++++++++++++++++++--------------
- net/ipv4/raw.c              | 16 +++++-----
- net/ipv4/tcp.c              |  5 +--
- net/ipv4/udp.c              | 12 +++----
- net/ipv6/af_inet6.c         |  2 +-
- net/ipv6/ip6mr.c            | 44 +++++++++++--------------
- net/ipv6/raw.c              | 16 +++++-----
- net/l2tp/l2tp_core.h        |  2 +-
- net/l2tp/l2tp_ip.c          |  9 +++---
- net/mptcp/protocol.c        | 11 +++----
- net/phonet/datagram.c       | 11 +++----
- net/phonet/pep.c            | 11 +++----
- net/phonet/socket.c         |  2 +-
- net/sctp/socket.c           |  8 ++---
- 26 files changed, 267 insertions(+), 129 deletions(-)
-
-diff --git a/include/linux/icmpv6.h b/include/linux/icmpv6.h
-index db0f4fcfdaf4f..1fe33e6741cca 100644
---- a/include/linux/icmpv6.h
-+++ b/include/linux/icmpv6.h
-@@ -111,4 +111,10 @@ static inline bool icmpv6_is_err(int type)
-       return false;
- }
-+static inline int sk_is_icmpv6(struct sock *sk)
-+{
-+      return sk->sk_family == AF_INET6 &&
-+              inet_sk(sk)->inet_num == IPPROTO_ICMPV6;
-+}
-+
- #endif
-diff --git a/include/linux/mroute.h b/include/linux/mroute.h
-index 80b8400ab8b24..94c6e6f549f0a 100644
---- a/include/linux/mroute.h
-+++ b/include/linux/mroute.h
-@@ -16,12 +16,19 @@ static inline int ip_mroute_opt(int opt)
-       return opt >= MRT_BASE && opt <= MRT_MAX;
- }
-+static inline int sk_is_ipmr(struct sock *sk)
-+{
-+      return sk->sk_family == AF_INET &&
-+              inet_sk(sk)->inet_num == IPPROTO_IGMP;
-+}
-+
- int ip_mroute_setsockopt(struct sock *, int, sockptr_t, unsigned int);
- int ip_mroute_getsockopt(struct sock *, int, sockptr_t, sockptr_t);
--int ipmr_ioctl(struct sock *sk, int cmd, void __user *arg);
-+int ipmr_ioctl(struct sock *sk, int cmd, void *arg);
- int ipmr_compat_ioctl(struct sock *sk, unsigned int cmd, void __user *arg);
- int ip_mr_init(void);
- bool ipmr_rule_default(const struct fib_rule *rule);
-+int ipmr_sk_ioctl(struct sock *sk, unsigned int cmd, void __user *arg);
- #else
- static inline int ip_mroute_setsockopt(struct sock *sock, int optname,
-                                      sockptr_t optval, unsigned int optlen)
-@@ -35,7 +42,7 @@ static inline int ip_mroute_getsockopt(struct sock *sk, int optname,
-       return -ENOPROTOOPT;
- }
--static inline int ipmr_ioctl(struct sock *sk, int cmd, void __user *arg)
-+static inline int ipmr_ioctl(struct sock *sk, int cmd, void *arg)
- {
-       return -ENOIOCTLCMD;
- }
-@@ -50,10 +57,21 @@ static inline int ip_mroute_opt(int opt)
-       return 0;
- }
-+static inline int sk_is_ipmr(struct sock *sk)
-+{
-+      return 0;
-+}
-+
- static inline bool ipmr_rule_default(const struct fib_rule *rule)
- {
-       return true;
- }
-+
-+static inline int ipmr_sk_ioctl(struct sock *sk, unsigned int cmd,
-+                              void __user *arg)
-+{
-+      return 1;
-+}
- #endif
- #define VIFF_STATIC 0x8000
-diff --git a/include/linux/mroute6.h b/include/linux/mroute6.h
-index 8f2b307fb1241..2f95d5b4e47af 100644
---- a/include/linux/mroute6.h
-+++ b/include/linux/mroute6.h
-@@ -29,10 +29,10 @@ struct sock;
- extern int ip6_mroute_setsockopt(struct sock *, int, sockptr_t, unsigned int);
- extern int ip6_mroute_getsockopt(struct sock *, int, sockptr_t, sockptr_t);
- extern int ip6_mr_input(struct sk_buff *skb);
--extern int ip6mr_ioctl(struct sock *sk, int cmd, void __user *arg);
- extern int ip6mr_compat_ioctl(struct sock *sk, unsigned int cmd, void __user *arg);
- extern int ip6_mr_init(void);
- extern void ip6_mr_cleanup(void);
-+int ip6mr_ioctl(struct sock *sk, int cmd, void *arg);
- #else
- static inline int ip6_mroute_setsockopt(struct sock *sock, int optname,
-               sockptr_t optval, unsigned int optlen)
-@@ -48,7 +48,7 @@ int ip6_mroute_getsockopt(struct sock *sock,
- }
- static inline
--int ip6mr_ioctl(struct sock *sk, int cmd, void __user *arg)
-+int ip6mr_ioctl(struct sock *sk, int cmd, void *arg)
- {
-       return -ENOIOCTLCMD;
- }
-@@ -100,6 +100,27 @@ extern int ip6mr_get_route(struct net *net, struct sk_buff *skb,
- #ifdef CONFIG_IPV6_MROUTE
- bool mroute6_is_socket(struct net *net, struct sk_buff *skb);
- extern int ip6mr_sk_done(struct sock *sk);
-+static inline int ip6mr_sk_ioctl(struct sock *sk, unsigned int cmd,
-+                               void __user *arg)
-+{
-+      switch (cmd) {
-+      /* These userspace buffers will be consumed by ip6mr_ioctl() */
-+      case SIOCGETMIFCNT_IN6: {
-+              struct sioc_mif_req6 buffer;
-+
-+              return sock_ioctl_inout(sk, cmd, arg, &buffer,
-+                                    sizeof(buffer));
-+              }
-+      case SIOCGETSGCNT_IN6: {
-+              struct sioc_mif_req6 buffer;
-+
-+              return sock_ioctl_inout(sk, cmd, arg, &buffer,
-+                                    sizeof(buffer));
-+              }
-+      }
-+
-+      return 1;
-+}
- #else
- static inline bool mroute6_is_socket(struct net *net, struct sk_buff *skb)
- {
-@@ -109,5 +130,11 @@ static inline int ip6mr_sk_done(struct sock *sk)
- {
-       return 0;
- }
-+
-+static inline int ip6mr_sk_ioctl(struct sock *sk, unsigned int cmd,
-+                               void __user *arg)
-+{
-+      return 1;
-+}
- #endif
- #endif
-diff --git a/include/net/phonet/phonet.h b/include/net/phonet/phonet.h
-index 862f1719b5230..cf5ecae4a2fcd 100644
---- a/include/net/phonet/phonet.h
-+++ b/include/net/phonet/phonet.h
-@@ -109,4 +109,25 @@ void phonet_sysctl_exit(void);
- int isi_register(void);
- void isi_unregister(void);
-+static inline bool sk_is_phonet(struct sock *sk)
-+{
-+      return sk->sk_family == PF_PHONET;
-+}
-+
-+static inline int phonet_sk_ioctl(struct sock *sk, unsigned int cmd,
-+                                void __user *arg)
-+{
-+      int karg;
-+
-+      switch (cmd) {
-+      case SIOCPNADDRESOURCE:
-+      case SIOCPNDELRESOURCE:
-+              if (get_user(karg, (int __user *)arg))
-+                      return -EFAULT;
-+
-+              return sk->sk_prot->ioctl(sk, cmd, &karg);
-+      }
-+      /* A positive return value means that the ioctl was not processed */
-+      return 1;
-+}
- #endif
-diff --git a/include/net/sock.h b/include/net/sock.h
-index 579732d47dfc4..6ea961ee257d2 100644
---- a/include/net/sock.h
-+++ b/include/net/sock.h
-@@ -1258,7 +1258,7 @@ struct proto {
-                                         bool kern);
-       int                     (*ioctl)(struct sock *sk, int cmd,
--                                       unsigned long arg);
-+                                       int *karg);
-       int                     (*init)(struct sock *sk);
-       void                    (*destroy)(struct sock *sk);
-       void                    (*shutdown)(struct sock *sk, int how);
-@@ -3048,6 +3048,9 @@ int sock_get_timeout(long timeo, void *optval, bool old_timeval);
- int sock_copy_user_timeval(struct __kernel_sock_timeval *tv,
-                          sockptr_t optval, int optlen, bool old_timeval);
-+int sock_ioctl_inout(struct sock *sk, unsigned int cmd,
-+                   void __user *arg, void *karg, size_t size);
-+int sk_ioctl(struct sock *sk, unsigned int cmd, void __user *arg);
- static inline bool sk_is_readable(struct sock *sk)
- {
-       if (sk->sk_prot->sock_is_readable)
-diff --git a/include/net/tcp.h b/include/net/tcp.h
-index 8ea1fba84eff9..8d3777e476e0e 100644
---- a/include/net/tcp.h
-+++ b/include/net/tcp.h
-@@ -346,7 +346,7 @@ void tcp_release_cb(struct sock *sk);
- void tcp_wfree(struct sk_buff *skb);
- void tcp_write_timer_handler(struct sock *sk);
- void tcp_delack_timer_handler(struct sock *sk);
--int tcp_ioctl(struct sock *sk, int cmd, unsigned long arg);
-+int tcp_ioctl(struct sock *sk, int cmd, int *karg);
- int tcp_rcv_state_process(struct sock *sk, struct sk_buff *skb);
- void tcp_rcv_established(struct sock *sk, struct sk_buff *skb);
- void tcp_rcv_space_adjust(struct sock *sk);
-diff --git a/include/net/udp.h b/include/net/udp.h
-index fa4cdbe55552c..b5e5d5e2b4e1b 100644
---- a/include/net/udp.h
-+++ b/include/net/udp.h
-@@ -275,7 +275,7 @@ void udp_flush_pending_frames(struct sock *sk);
- int udp_cmsg_send(struct sock *sk, struct msghdr *msg, u16 *gso_size);
- void udp4_hwcsum(struct sk_buff *skb, __be32 src, __be32 dst);
- int udp_rcv(struct sk_buff *skb);
--int udp_ioctl(struct sock *sk, int cmd, unsigned long arg);
-+int udp_ioctl(struct sock *sk, int cmd, int *karg);
- int udp_init_sock(struct sock *sk);
- int udp_pre_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len);
- int __udp_disconnect(struct sock *sk, int flags);
-diff --git a/net/core/sock.c b/net/core/sock.c
-index c8803b95ea0da..e55220cc08640 100644
---- a/net/core/sock.c
-+++ b/net/core/sock.c
-@@ -115,6 +115,9 @@
- #include <linux/memcontrol.h>
- #include <linux/prefetch.h>
- #include <linux/compat.h>
-+#include <linux/mroute.h>
-+#include <linux/mroute6.h>
-+#include <linux/icmpv6.h>
- #include <linux/uaccess.h>
-@@ -139,6 +142,7 @@
- #include <net/tcp.h>
- #include <net/busy_poll.h>
-+#include <net/phonet/phonet.h>
- #include <linux/ethtool.h>
-@@ -4129,3 +4133,63 @@ int sock_bind_add(struct sock *sk, struct sockaddr *addr, int addr_len)
-       return sk->sk_prot->bind_add(sk, addr, addr_len);
- }
- EXPORT_SYMBOL(sock_bind_add);
-+
-+/* Copy 'size' bytes from userspace and return `size` back to userspace */
-+int sock_ioctl_inout(struct sock *sk, unsigned int cmd,
-+                   void __user *arg, void *karg, size_t size)
-+{
-+      int ret;
-+
-+      if (copy_from_user(karg, arg, size))
-+              return -EFAULT;
-+
-+      ret = READ_ONCE(sk->sk_prot)->ioctl(sk, cmd, karg);
-+      if (ret)
-+              return ret;
-+
-+      if (copy_to_user(arg, karg, size))
-+              return -EFAULT;
-+
-+      return 0;
-+}
-+EXPORT_SYMBOL(sock_ioctl_inout);
-+
-+/* This is the most common ioctl prep function, where the result (4 bytes) is
-+ * copied back to userspace if the ioctl() returns successfully. No input is
-+ * copied from userspace as input argument.
-+ */
-+static int sock_ioctl_out(struct sock *sk, unsigned int cmd, void __user *arg)
-+{
-+      int ret, karg = 0;
-+
-+      ret = READ_ONCE(sk->sk_prot)->ioctl(sk, cmd, &karg);
-+      if (ret)
-+              return ret;
-+
-+      return put_user(karg, (int __user *)arg);
-+}
-+
-+/* A wrapper around sock ioctls, which copies the data from userspace
-+ * (depending on the protocol/ioctl), and copies back the result to userspace.
-+ * The main motivation for this function is to pass kernel memory to the
-+ * protocol ioctl callbacks, instead of userspace memory.
-+ */
-+int sk_ioctl(struct sock *sk, unsigned int cmd, void __user *arg)
-+{
-+      int rc = 1;
-+
-+      if (sk_is_ipmr(sk))
-+              rc = ipmr_sk_ioctl(sk, cmd, arg);
-+      else if (sk_is_icmpv6(sk))
-+              rc = ip6mr_sk_ioctl(sk, cmd, arg);
-+      else if (sk_is_phonet(sk))
-+              rc = phonet_sk_ioctl(sk, cmd, arg);
-+
-+      /* If ioctl was processed, returns its value */
-+      if (rc <= 0)
-+              return rc;
-+
-+      /* Otherwise call the default handler */
-+      return sock_ioctl_out(sk, cmd, arg);
-+}
-+EXPORT_SYMBOL(sk_ioctl);
-diff --git a/net/dccp/dccp.h b/net/dccp/dccp.h
-index 9ddc3a9e89e40..1f748ed1279d3 100644
---- a/net/dccp/dccp.h
-+++ b/net/dccp/dccp.h
-@@ -292,7 +292,7 @@ int dccp_getsockopt(struct sock *sk, int level, int optname,
-                   char __user *optval, int __user *optlen);
- int dccp_setsockopt(struct sock *sk, int level, int optname,
-                   sockptr_t optval, unsigned int optlen);
--int dccp_ioctl(struct sock *sk, int cmd, unsigned long arg);
-+int dccp_ioctl(struct sock *sk, int cmd, int *karg);
- int dccp_sendmsg(struct sock *sk, struct msghdr *msg, size_t size);
- int dccp_recvmsg(struct sock *sk, struct msghdr *msg, size_t len, int flags,
-                int *addr_len);
-diff --git a/net/dccp/proto.c b/net/dccp/proto.c
-index c522c76a9f89f..1d25cfcdbe5dc 100644
---- a/net/dccp/proto.c
-+++ b/net/dccp/proto.c
-@@ -363,7 +363,7 @@ __poll_t dccp_poll(struct file *file, struct socket *sock,
- }
- EXPORT_SYMBOL_GPL(dccp_poll);
--int dccp_ioctl(struct sock *sk, int cmd, unsigned long arg)
-+int dccp_ioctl(struct sock *sk, int cmd, int *karg)
- {
-       int rc = -ENOTCONN;
-@@ -374,17 +374,17 @@ int dccp_ioctl(struct sock *sk, int cmd, unsigned long arg)
-       switch (cmd) {
-       case SIOCOUTQ: {
--              int amount = sk_wmem_alloc_get(sk);
-+              *karg = sk_wmem_alloc_get(sk);
-               /* Using sk_wmem_alloc here because sk_wmem_queued is not used by DCCP and
-                * always 0, comparably to UDP.
-                */
--              rc = put_user(amount, (int __user *)arg);
-+              rc = 0;
-       }
-               break;
-       case SIOCINQ: {
-               struct sk_buff *skb;
--              unsigned long amount = 0;
-+              *karg = 0;
-               skb = skb_peek(&sk->sk_receive_queue);
-               if (skb != NULL) {
-@@ -392,9 +392,9 @@ int dccp_ioctl(struct sock *sk, int cmd, unsigned long arg)
-                        * We will only return the amount of this packet since
-                        * that is all that will be read.
-                        */
--                      amount = skb->len;
-+                      *karg = skb->len;
-               }
--              rc = put_user(amount, (int __user *)arg);
-+              rc = 0;
-       }
-               break;
-       default:
-diff --git a/net/ieee802154/socket.c b/net/ieee802154/socket.c
-index 1fa2fe041ec03..9c124705120dd 100644
---- a/net/ieee802154/socket.c
-+++ b/net/ieee802154/socket.c
-@@ -162,7 +162,7 @@ static int ieee802154_sock_ioctl(struct socket *sock, unsigned int cmd,
-       default:
-               if (!sk->sk_prot->ioctl)
-                       return -ENOIOCTLCMD;
--              return sk->sk_prot->ioctl(sk, cmd, arg);
-+              return sk_ioctl(sk, cmd, (void __user *)arg);
-       }
- }
-@@ -531,22 +531,21 @@ static int dgram_bind(struct sock *sk, struct sockaddr *uaddr, int len)
-       return err;
- }
--static int dgram_ioctl(struct sock *sk, int cmd, unsigned long arg)
-+static int dgram_ioctl(struct sock *sk, int cmd, int *karg)
- {
-       switch (cmd) {
-       case SIOCOUTQ:
-       {
--              int amount = sk_wmem_alloc_get(sk);
-+              *karg = sk_wmem_alloc_get(sk);
--              return put_user(amount, (int __user *)arg);
-+              return 0;
-       }
-       case SIOCINQ:
-       {
-               struct sk_buff *skb;
--              unsigned long amount;
--              amount = 0;
-+              *karg = 0;
-               spin_lock_bh(&sk->sk_receive_queue.lock);
-               skb = skb_peek(&sk->sk_receive_queue);
-               if (skb) {
-@@ -554,10 +553,10 @@ static int dgram_ioctl(struct sock *sk, int cmd, unsigned long arg)
-                        * of this packet since that is all
-                        * that will be read.
-                        */
--                      amount = skb->len - ieee802154_hdr_length(skb);
-+                      *karg = skb->len - ieee802154_hdr_length(skb);
-               }
-               spin_unlock_bh(&sk->sk_receive_queue.lock);
--              return put_user(amount, (int __user *)arg);
-+              return 0;
-       }
-       }
-diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c
-index 9408dc3bb42d3..eddedc2f8c5c9 100644
---- a/net/ipv4/af_inet.c
-+++ b/net/ipv4/af_inet.c
-@@ -1007,7 +1007,7 @@ int inet_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
-               break;
-       default:
-               if (sk->sk_prot->ioctl)
--                      err = sk->sk_prot->ioctl(sk, cmd, arg);
-+                      err = sk_ioctl(sk, cmd, (void __user *)arg);
-               else
-                       err = -ENOIOCTLCMD;
-               break;
-diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c
-index d5421c38c2aae..e20f7ab8099ad 100644
---- a/net/ipv4/ipmr.c
-+++ b/net/ipv4/ipmr.c
-@@ -1546,6 +1546,28 @@ int ip_mroute_setsockopt(struct sock *sk, int optname, sockptr_t optval,
-       return ret;
- }
-+/* Execute if this ioctl is a special mroute ioctl */
-+int ipmr_sk_ioctl(struct sock *sk, unsigned int cmd, void __user *arg)
-+{
-+      switch (cmd) {
-+      /* These userspace buffers will be consumed by ipmr_ioctl() */
-+      case SIOCGETVIFCNT: {
-+              struct sioc_vif_req buffer;
-+
-+              return sock_ioctl_inout(sk, cmd, arg, &buffer,
-+                                    sizeof(buffer));
-+              }
-+      case SIOCGETSGCNT: {
-+              struct sioc_sg_req buffer;
-+
-+              return sock_ioctl_inout(sk, cmd, arg, &buffer,
-+                                    sizeof(buffer));
-+              }
-+      }
-+      /* return code > 0 means that the ioctl was not executed */
-+      return 1;
-+}
-+
- /* Getsock opt support for the multicast routing system. */
- int ip_mroute_getsockopt(struct sock *sk, int optname, sockptr_t optval,
-                        sockptr_t optlen)
-@@ -1592,13 +1614,13 @@ int ip_mroute_getsockopt(struct sock *sk, int optname, sockptr_t optval,
- }
- /* The IP multicast ioctl support routines. */
--int ipmr_ioctl(struct sock *sk, int cmd, void __user *arg)
-+int ipmr_ioctl(struct sock *sk, int cmd, void *arg)
- {
--      struct sioc_sg_req sr;
--      struct sioc_vif_req vr;
-       struct vif_device *vif;
-       struct mfc_cache *c;
-       struct net *net = sock_net(sk);
-+      struct sioc_vif_req *vr;
-+      struct sioc_sg_req *sr;
-       struct mr_table *mrt;
-       mrt = ipmr_get_table(net, raw_sk(sk)->ipmr_table ? : RT_TABLE_DEFAULT);
-@@ -1607,40 +1629,33 @@ int ipmr_ioctl(struct sock *sk, int cmd, void __user *arg)
-       switch (cmd) {
-       case SIOCGETVIFCNT:
--              if (copy_from_user(&vr, arg, sizeof(vr)))
--                      return -EFAULT;
--              if (vr.vifi >= mrt->maxvif)
-+              vr = (struct sioc_vif_req *)arg;
-+              if (vr->vifi >= mrt->maxvif)
-                       return -EINVAL;
--              vr.vifi = array_index_nospec(vr.vifi, mrt->maxvif);
-+              vr->vifi = array_index_nospec(vr->vifi, mrt->maxvif);
-               rcu_read_lock();
--              vif = &mrt->vif_table[vr.vifi];
--              if (VIF_EXISTS(mrt, vr.vifi)) {
--                      vr.icount = READ_ONCE(vif->pkt_in);
--                      vr.ocount = READ_ONCE(vif->pkt_out);
--                      vr.ibytes = READ_ONCE(vif->bytes_in);
--                      vr.obytes = READ_ONCE(vif->bytes_out);
-+              vif = &mrt->vif_table[vr->vifi];
-+              if (VIF_EXISTS(mrt, vr->vifi)) {
-+                      vr->icount = READ_ONCE(vif->pkt_in);
-+                      vr->ocount = READ_ONCE(vif->pkt_out);
-+                      vr->ibytes = READ_ONCE(vif->bytes_in);
-+                      vr->obytes = READ_ONCE(vif->bytes_out);
-                       rcu_read_unlock();
--                      if (copy_to_user(arg, &vr, sizeof(vr)))
--                              return -EFAULT;
-                       return 0;
-               }
-               rcu_read_unlock();
-               return -EADDRNOTAVAIL;
-       case SIOCGETSGCNT:
--              if (copy_from_user(&sr, arg, sizeof(sr)))
--                      return -EFAULT;
-+              sr = (struct sioc_sg_req *)arg;
-               rcu_read_lock();
--              c = ipmr_cache_find(mrt, sr.src.s_addr, sr.grp.s_addr);
-+              c = ipmr_cache_find(mrt, sr->src.s_addr, sr->grp.s_addr);
-               if (c) {
--                      sr.pktcnt = c->_c.mfc_un.res.pkt;
--                      sr.bytecnt = c->_c.mfc_un.res.bytes;
--                      sr.wrong_if = c->_c.mfc_un.res.wrong_if;
-+                      sr->pktcnt = c->_c.mfc_un.res.pkt;
-+                      sr->bytecnt = c->_c.mfc_un.res.bytes;
-+                      sr->wrong_if = c->_c.mfc_un.res.wrong_if;
-                       rcu_read_unlock();
--
--                      if (copy_to_user(arg, &sr, sizeof(sr)))
--                              return -EFAULT;
-                       return 0;
-               }
-               rcu_read_unlock();
-diff --git a/net/ipv4/raw.c b/net/ipv4/raw.c
-index 7c63b91edbf7a..a2d1f1ee7df59 100644
---- a/net/ipv4/raw.c
-+++ b/net/ipv4/raw.c
-@@ -858,29 +858,29 @@ static int raw_getsockopt(struct sock *sk, int level, int optname,
-       return do_raw_getsockopt(sk, level, optname, optval, optlen);
- }
--static int raw_ioctl(struct sock *sk, int cmd, unsigned long arg)
-+static int raw_ioctl(struct sock *sk, int cmd, int *karg)
- {
-       switch (cmd) {
-       case SIOCOUTQ: {
--              int amount = sk_wmem_alloc_get(sk);
--
--              return put_user(amount, (int __user *)arg);
-+              *karg = sk_wmem_alloc_get(sk);
-+              return 0;
-       }
-       case SIOCINQ: {
-               struct sk_buff *skb;
--              int amount = 0;
-               spin_lock_bh(&sk->sk_receive_queue.lock);
-               skb = skb_peek(&sk->sk_receive_queue);
-               if (skb)
--                      amount = skb->len;
-+                      *karg = skb->len;
-+              else
-+                      *karg = 0;
-               spin_unlock_bh(&sk->sk_receive_queue.lock);
--              return put_user(amount, (int __user *)arg);
-+              return 0;
-       }
-       default:
- #ifdef CONFIG_IP_MROUTE
--              return ipmr_ioctl(sk, cmd, (void __user *)arg);
-+              return ipmr_ioctl(sk, cmd, karg);
- #else
-               return -ENOIOCTLCMD;
- #endif
-diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
-index 86e7695d91adf..dcbcf238bf3ab 100644
---- a/net/ipv4/tcp.c
-+++ b/net/ipv4/tcp.c
-@@ -598,7 +598,7 @@ __poll_t tcp_poll(struct file *file, struct socket *sock, poll_table *wait)
- }
- EXPORT_SYMBOL(tcp_poll);
--int tcp_ioctl(struct sock *sk, int cmd, unsigned long arg)
-+int tcp_ioctl(struct sock *sk, int cmd, int *karg)
- {
-       struct tcp_sock *tp = tcp_sk(sk);
-       int answ;
-@@ -640,7 +640,8 @@ int tcp_ioctl(struct sock *sk, int cmd, unsigned long arg)
-               return -ENOIOCTLCMD;
-       }
--      return put_user(answ, (int __user *)arg);
-+      *karg = answ;
-+      return 0;
- }
- EXPORT_SYMBOL(tcp_ioctl);
-diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
-index 87d759bab0012..2a5748c246e24 100644
---- a/net/ipv4/udp.c
-+++ b/net/ipv4/udp.c
-@@ -1694,21 +1694,19 @@ static int first_packet_length(struct sock *sk)
-  *    IOCTL requests applicable to the UDP protocol
-  */
--int udp_ioctl(struct sock *sk, int cmd, unsigned long arg)
-+int udp_ioctl(struct sock *sk, int cmd, int *karg)
- {
-       switch (cmd) {
-       case SIOCOUTQ:
-       {
--              int amount = sk_wmem_alloc_get(sk);
--
--              return put_user(amount, (int __user *)arg);
-+              *karg = sk_wmem_alloc_get(sk);
-+              return 0;
-       }
-       case SIOCINQ:
-       {
--              int amount = max_t(int, 0, first_packet_length(sk));
--
--              return put_user(amount, (int __user *)arg);
-+              *karg = max_t(int, 0, first_packet_length(sk));
-+              return 0;
-       }
-       default:
-diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c
-index 0b42eb8c55aaf..37190217d650c 100644
---- a/net/ipv6/af_inet6.c
-+++ b/net/ipv6/af_inet6.c
-@@ -598,7 +598,7 @@ int inet6_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
-               prot = READ_ONCE(sk->sk_prot);
-               if (!prot->ioctl)
-                       return -ENOIOCTLCMD;
--              return prot->ioctl(sk, cmd, arg);
-+              return sk_ioctl(sk, cmd, (void __user *)arg);
-       }
-       /*NOTREACHED*/
-       return 0;
-diff --git a/net/ipv6/ip6mr.c b/net/ipv6/ip6mr.c
-index 27fb5479988af..76db80a7124c8 100644
---- a/net/ipv6/ip6mr.c
-+++ b/net/ipv6/ip6mr.c
-@@ -1879,11 +1879,10 @@ int ip6_mroute_getsockopt(struct sock *sk, int optname, sockptr_t optval,
- /*
-  *    The IP multicast ioctl support routines.
-  */
--
--int ip6mr_ioctl(struct sock *sk, int cmd, void __user *arg)
-+int ip6mr_ioctl(struct sock *sk, int cmd, void *arg)
- {
--      struct sioc_sg_req6 sr;
--      struct sioc_mif_req6 vr;
-+      struct sioc_sg_req6 *sr;
-+      struct sioc_mif_req6 *vr;
-       struct vif_device *vif;
-       struct mfc6_cache *c;
-       struct net *net = sock_net(sk);
-@@ -1895,40 +1894,33 @@ int ip6mr_ioctl(struct sock *sk, int cmd, void __user *arg)
-       switch (cmd) {
-       case SIOCGETMIFCNT_IN6:
--              if (copy_from_user(&vr, arg, sizeof(vr)))
--                      return -EFAULT;
--              if (vr.mifi >= mrt->maxvif)
-+              vr = (struct sioc_mif_req6 *)arg;
-+              if (vr->mifi >= mrt->maxvif)
-                       return -EINVAL;
--              vr.mifi = array_index_nospec(vr.mifi, mrt->maxvif);
-+              vr->mifi = array_index_nospec(vr->mifi, mrt->maxvif);
-               rcu_read_lock();
--              vif = &mrt->vif_table[vr.mifi];
--              if (VIF_EXISTS(mrt, vr.mifi)) {
--                      vr.icount = READ_ONCE(vif->pkt_in);
--                      vr.ocount = READ_ONCE(vif->pkt_out);
--                      vr.ibytes = READ_ONCE(vif->bytes_in);
--                      vr.obytes = READ_ONCE(vif->bytes_out);
-+              vif = &mrt->vif_table[vr->mifi];
-+              if (VIF_EXISTS(mrt, vr->mifi)) {
-+                      vr->icount = READ_ONCE(vif->pkt_in);
-+                      vr->ocount = READ_ONCE(vif->pkt_out);
-+                      vr->ibytes = READ_ONCE(vif->bytes_in);
-+                      vr->obytes = READ_ONCE(vif->bytes_out);
-                       rcu_read_unlock();
--
--                      if (copy_to_user(arg, &vr, sizeof(vr)))
--                              return -EFAULT;
-                       return 0;
-               }
-               rcu_read_unlock();
-               return -EADDRNOTAVAIL;
-       case SIOCGETSGCNT_IN6:
--              if (copy_from_user(&sr, arg, sizeof(sr)))
--                      return -EFAULT;
-+              sr = (struct sioc_sg_req6 *)arg;
-               rcu_read_lock();
--              c = ip6mr_cache_find(mrt, &sr.src.sin6_addr, &sr.grp.sin6_addr);
-+              c = ip6mr_cache_find(mrt, &sr->src.sin6_addr,
-+                                   &sr->grp.sin6_addr);
-               if (c) {
--                      sr.pktcnt = c->_c.mfc_un.res.pkt;
--                      sr.bytecnt = c->_c.mfc_un.res.bytes;
--                      sr.wrong_if = c->_c.mfc_un.res.wrong_if;
-+                      sr->pktcnt = c->_c.mfc_un.res.pkt;
-+                      sr->bytecnt = c->_c.mfc_un.res.bytes;
-+                      sr->wrong_if = c->_c.mfc_un.res.wrong_if;
-                       rcu_read_unlock();
--
--                      if (copy_to_user(arg, &sr, sizeof(sr)))
--                              return -EFAULT;
-                       return 0;
-               }
-               rcu_read_unlock();
-diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c
-index dc31752a7edcc..e361953ca7f45 100644
---- a/net/ipv6/raw.c
-+++ b/net/ipv6/raw.c
-@@ -1116,29 +1116,29 @@ static int rawv6_getsockopt(struct sock *sk, int level, int optname,
-       return do_rawv6_getsockopt(sk, level, optname, optval, optlen);
- }
--static int rawv6_ioctl(struct sock *sk, int cmd, unsigned long arg)
-+static int rawv6_ioctl(struct sock *sk, int cmd, int *karg)
- {
-       switch (cmd) {
-       case SIOCOUTQ: {
--              int amount = sk_wmem_alloc_get(sk);
--
--              return put_user(amount, (int __user *)arg);
-+              *karg = sk_wmem_alloc_get(sk);
-+              return 0;
-       }
-       case SIOCINQ: {
-               struct sk_buff *skb;
--              int amount = 0;
-               spin_lock_bh(&sk->sk_receive_queue.lock);
-               skb = skb_peek(&sk->sk_receive_queue);
-               if (skb)
--                      amount = skb->len;
-+                      *karg = skb->len;
-+              else
-+                      *karg = 0;
-               spin_unlock_bh(&sk->sk_receive_queue.lock);
--              return put_user(amount, (int __user *)arg);
-+              return 0;
-       }
-       default:
- #ifdef CONFIG_IPV6_MROUTE
--              return ip6mr_ioctl(sk, cmd, (void __user *)arg);
-+              return ip6mr_ioctl(sk, cmd, karg);
- #else
-               return -ENOIOCTLCMD;
- #endif
-diff --git a/net/l2tp/l2tp_core.h b/net/l2tp/l2tp_core.h
-index a88e070b431d8..91ebf0a3f4997 100644
---- a/net/l2tp/l2tp_core.h
-+++ b/net/l2tp/l2tp_core.h
-@@ -272,7 +272,7 @@ int l2tp_nl_register_ops(enum l2tp_pwtype pw_type, const struct l2tp_nl_cmd_ops
- void l2tp_nl_unregister_ops(enum l2tp_pwtype pw_type);
- /* IOCTL helper for IP encap modules. */
--int l2tp_ioctl(struct sock *sk, int cmd, unsigned long arg);
-+int l2tp_ioctl(struct sock *sk, int cmd, int *karg);
- /* Extract the tunnel structure from a socket's sk_user_data pointer,
-  * validating the tunnel magic feather.
-diff --git a/net/l2tp/l2tp_ip.c b/net/l2tp/l2tp_ip.c
-index 41a74fc84ca13..2b795c1064f5c 100644
---- a/net/l2tp/l2tp_ip.c
-+++ b/net/l2tp/l2tp_ip.c
-@@ -562,19 +562,18 @@ static int l2tp_ip_recvmsg(struct sock *sk, struct msghdr *msg,
-       return err ? err : copied;
- }
--int l2tp_ioctl(struct sock *sk, int cmd, unsigned long arg)
-+int l2tp_ioctl(struct sock *sk, int cmd, int *karg)
- {
-       struct sk_buff *skb;
--      int amount;
-       switch (cmd) {
-       case SIOCOUTQ:
--              amount = sk_wmem_alloc_get(sk);
-+              *karg = sk_wmem_alloc_get(sk);
-               break;
-       case SIOCINQ:
-               spin_lock_bh(&sk->sk_receive_queue.lock);
-               skb = skb_peek(&sk->sk_receive_queue);
--              amount = skb ? skb->len : 0;
-+              *karg = skb ? skb->len : 0;
-               spin_unlock_bh(&sk->sk_receive_queue.lock);
-               break;
-@@ -582,7 +581,7 @@ int l2tp_ioctl(struct sock *sk, int cmd, unsigned long arg)
-               return -ENOIOCTLCMD;
-       }
--      return put_user(amount, (int __user *)arg);
-+      return 0;
- }
- EXPORT_SYMBOL_GPL(l2tp_ioctl);
-diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c
-index 859b18cb8e4f6..7ea10d7aec961 100644
---- a/net/mptcp/protocol.c
-+++ b/net/mptcp/protocol.c
-@@ -3640,11 +3640,10 @@ static int mptcp_ioctl_outq(const struct mptcp_sock *msk, u64 v)
-       return (int)delta;
- }
--static int mptcp_ioctl(struct sock *sk, int cmd, unsigned long arg)
-+static int mptcp_ioctl(struct sock *sk, int cmd, int *karg)
- {
-       struct mptcp_sock *msk = mptcp_sk(sk);
-       bool slow;
--      int answ;
-       switch (cmd) {
-       case SIOCINQ:
-@@ -3653,24 +3652,24 @@ static int mptcp_ioctl(struct sock *sk, int cmd, unsigned long arg)
-               lock_sock(sk);
-               __mptcp_move_skbs(msk);
--              answ = mptcp_inq_hint(sk);
-+              *karg = mptcp_inq_hint(sk);
-               release_sock(sk);
-               break;
-       case SIOCOUTQ:
-               slow = lock_sock_fast(sk);
--              answ = mptcp_ioctl_outq(msk, READ_ONCE(msk->snd_una));
-+              *karg = mptcp_ioctl_outq(msk, READ_ONCE(msk->snd_una));
-               unlock_sock_fast(sk, slow);
-               break;
-       case SIOCOUTQNSD:
-               slow = lock_sock_fast(sk);
--              answ = mptcp_ioctl_outq(msk, msk->snd_nxt);
-+              *karg = mptcp_ioctl_outq(msk, msk->snd_nxt);
-               unlock_sock_fast(sk, slow);
-               break;
-       default:
-               return -ENOIOCTLCMD;
-       }
--      return put_user(answ, (int __user *)arg);
-+      return 0;
- }
- static void mptcp_subflow_early_fallback(struct mptcp_sock *msk,
-diff --git a/net/phonet/datagram.c b/net/phonet/datagram.c
-index ff5f49ab236ed..3aa50dc7535b7 100644
---- a/net/phonet/datagram.c
-+++ b/net/phonet/datagram.c
-@@ -28,24 +28,21 @@ static void pn_sock_close(struct sock *sk, long timeout)
-       sk_common_release(sk);
- }
--static int pn_ioctl(struct sock *sk, int cmd, unsigned long arg)
-+static int pn_ioctl(struct sock *sk, int cmd, int *karg)
- {
-       struct sk_buff *skb;
--      int answ;
-       switch (cmd) {
-       case SIOCINQ:
-               lock_sock(sk);
-               skb = skb_peek(&sk->sk_receive_queue);
--              answ = skb ? skb->len : 0;
-+              *karg = skb ? skb->len : 0;
-               release_sock(sk);
--              return put_user(answ, (int __user *)arg);
-+              return 0;
-       case SIOCPNADDRESOURCE:
-       case SIOCPNDELRESOURCE: {
--                      u32 res;
--                      if (get_user(res, (u32 __user *)arg))
--                              return -EFAULT;
-+                      u32 res = *karg;
-                       if (res >= 256)
-                               return -EINVAL;
-                       if (cmd == SIOCPNADDRESOURCE)
-diff --git a/net/phonet/pep.c b/net/phonet/pep.c
-index 83ea13a50690b..faba31f2eff29 100644
---- a/net/phonet/pep.c
-+++ b/net/phonet/pep.c
-@@ -917,10 +917,9 @@ static int pep_sock_enable(struct sock *sk, struct sockaddr *addr, int len)
-       return 0;
- }
--static int pep_ioctl(struct sock *sk, int cmd, unsigned long arg)
-+static int pep_ioctl(struct sock *sk, int cmd, int *karg)
- {
-       struct pep_sock *pn = pep_sk(sk);
--      int answ;
-       int ret = -ENOIOCTLCMD;
-       switch (cmd) {
-@@ -933,13 +932,13 @@ static int pep_ioctl(struct sock *sk, int cmd, unsigned long arg)
-               lock_sock(sk);
-               if (sock_flag(sk, SOCK_URGINLINE) &&
-                   !skb_queue_empty(&pn->ctrlreq_queue))
--                      answ = skb_peek(&pn->ctrlreq_queue)->len;
-+                      *karg = skb_peek(&pn->ctrlreq_queue)->len;
-               else if (!skb_queue_empty(&sk->sk_receive_queue))
--                      answ = skb_peek(&sk->sk_receive_queue)->len;
-+                      *karg = skb_peek(&sk->sk_receive_queue)->len;
-               else
--                      answ = 0;
-+                      *karg = 0;
-               release_sock(sk);
--              ret = put_user(answ, (int __user *)arg);
-+              ret = 0;
-               break;
-       case SIOCPNENABLEPIPE:
-diff --git a/net/phonet/socket.c b/net/phonet/socket.c
-index 71e2caf6ab859..967f9b4dc0265 100644
---- a/net/phonet/socket.c
-+++ b/net/phonet/socket.c
-@@ -387,7 +387,7 @@ static int pn_socket_ioctl(struct socket *sock, unsigned int cmd,
-               return put_user(handle, (__u16 __user *)arg);
-       }
--      return sk->sk_prot->ioctl(sk, cmd, arg);
-+      return sk_ioctl(sk, cmd, (void __user *)arg);
- }
- static int pn_socket_listen(struct socket *sock, int backlog)
-diff --git a/net/sctp/socket.c b/net/sctp/socket.c
-index 237a6b04adf6f..9c29bff647a11 100644
---- a/net/sctp/socket.c
-+++ b/net/sctp/socket.c
-@@ -4902,7 +4902,7 @@ static struct sock *sctp_accept(struct sock *sk, int flags, int *err, bool kern)
- }
- /* The SCTP ioctl handler. */
--static int sctp_ioctl(struct sock *sk, int cmd, unsigned long arg)
-+static int sctp_ioctl(struct sock *sk, int cmd, int *karg)
- {
-       int rc = -ENOTCONN;
-@@ -4918,7 +4918,7 @@ static int sctp_ioctl(struct sock *sk, int cmd, unsigned long arg)
-       switch (cmd) {
-       case SIOCINQ: {
-               struct sk_buff *skb;
--              unsigned int amount = 0;
-+              *karg = 0;
-               skb = skb_peek(&sk->sk_receive_queue);
-               if (skb != NULL) {
-@@ -4926,9 +4926,9 @@ static int sctp_ioctl(struct sock *sk, int cmd, unsigned long arg)
-                        * We will only return the amount of this packet since
-                        * that is all that will be read.
-                        */
--                      amount = skb->len;
-+                      *karg = skb->len;
-               }
--              rc = put_user(amount, (int __user *)arg);
-+              rc = 0;
-               break;
-       }
-       default:
--- 
-2.43.0
-
index 7152549d07599f496e489497862703cd07a16cba..e526f8470c4aa3d0bae9794834f86b3f756248db 100644 (file)
@@ -20,14 +20,12 @@ Link: https://lore.kernel.org/r/20240218081214.4806-2-remi@remlab.net
 Signed-off-by: Paolo Abeni <pabeni@redhat.com>
 Signed-off-by: Sasha Levin <sashal@kernel.org>
 ---
- net/phonet/pep.c | 41 ++++++++++++++++++++++++++++++++---------
+ net/phonet/pep.c |   41 ++++++++++++++++++++++++++++++++---------
  1 file changed, 32 insertions(+), 9 deletions(-)
 
-diff --git a/net/phonet/pep.c b/net/phonet/pep.c
-index faba31f2eff29..3dd5f52bc1b58 100644
 --- a/net/phonet/pep.c
 +++ b/net/phonet/pep.c
-@@ -917,6 +917,37 @@ static int pep_sock_enable(struct sock *sk, struct sockaddr *addr, int len)
+@@ -917,6 +917,37 @@ static int pep_sock_enable(struct sock *
        return 0;
  }
  
@@ -62,26 +60,23 @@ index faba31f2eff29..3dd5f52bc1b58 100644
 +      return len;
 +}
 +
- static int pep_ioctl(struct sock *sk, int cmd, int *karg)
+ static int pep_ioctl(struct sock *sk, int cmd, unsigned long arg)
  {
        struct pep_sock *pn = pep_sk(sk);
-@@ -929,15 +960,7 @@ static int pep_ioctl(struct sock *sk, int cmd, int *karg)
+@@ -930,15 +961,7 @@ static int pep_ioctl(struct sock *sk, in
                        break;
                }
  
 -              lock_sock(sk);
 -              if (sock_flag(sk, SOCK_URGINLINE) &&
 -                  !skb_queue_empty(&pn->ctrlreq_queue))
--                      *karg = skb_peek(&pn->ctrlreq_queue)->len;
+-                      answ = skb_peek(&pn->ctrlreq_queue)->len;
 -              else if (!skb_queue_empty(&sk->sk_receive_queue))
--                      *karg = skb_peek(&sk->sk_receive_queue)->len;
+-                      answ = skb_peek(&sk->sk_receive_queue)->len;
 -              else
--                      *karg = 0;
+-                      answ = 0;
 -              release_sock(sk);
-+              *karg = pep_first_packet_length(sk);
-               ret = 0;
++              answ = pep_first_packet_length(sk);
+               ret = put_user(answ, (int __user *)arg);
                break;
  
--- 
-2.43.0
-
index 711d9e3495f42f051e25900a518ce93f7845a9f1..0d814ad56e9eb7fab9a1b2ea82f766a73e13ddce 100644 (file)
@@ -21,26 +21,21 @@ Link: https://lore.kernel.org/r/20240218081214.4806-1-remi@remlab.net
 Signed-off-by: Paolo Abeni <pabeni@redhat.com>
 Signed-off-by: Sasha Levin <sashal@kernel.org>
 ---
- net/phonet/datagram.c | 4 ++--
+ net/phonet/datagram.c |    4 ++--
  1 file changed, 2 insertions(+), 2 deletions(-)
 
-diff --git a/net/phonet/datagram.c b/net/phonet/datagram.c
-index 3aa50dc7535b7..976fe250b5095 100644
 --- a/net/phonet/datagram.c
 +++ b/net/phonet/datagram.c
-@@ -34,10 +34,10 @@ static int pn_ioctl(struct sock *sk, int cmd, int *karg)
+@@ -35,10 +35,10 @@ static int pn_ioctl(struct sock *sk, int
  
        switch (cmd) {
        case SIOCINQ:
 -              lock_sock(sk);
 +              spin_lock_bh(&sk->sk_receive_queue.lock);
                skb = skb_peek(&sk->sk_receive_queue);
-               *karg = skb ? skb->len : 0;
+               answ = skb ? skb->len : 0;
 -              release_sock(sk);
 +              spin_unlock_bh(&sk->sk_receive_queue.lock);
-               return 0;
+               return put_user(answ, (int __user *)arg);
  
        case SIOCPNADDRESOURCE:
--- 
-2.43.0
-
index 847a39908333afb0059e05d5ca34f15467bd4329..647f260cceae99ccdfa30095228d322efe8b2fc2 100644 (file)
@@ -175,7 +175,6 @@ netfilter-nf_tables-register-hooks-last-when-adding-.patch
 netfilter-nf_tables-use-kzalloc-for-hook-allocation.patch
 net-mctp-put-sock-on-tag-allocation-failure.patch
 net-sparx5-add-spinlock-for-frame-transmission-from-.patch
-net-ioctl-use-kernel-memory-on-protocol-ioctl-callba.patch
 phonet-take-correct-lock-to-peek-at-the-rx-queue.patch
 phonet-pep-fix-racy-skb_queue_empty-use.patch
 fix-write-to-cloned-skb-in-ipv6_hop_ioam.patch