netfilter: switch xt_copy_counters to sockptr_t
authorChristoph Hellwig <hch@lst.de>
Thu, 23 Jul 2020 06:08:53 +0000 (08:08 +0200)
committerDavid S. Miller <davem@davemloft.net>
Fri, 24 Jul 2020 22:41:53 +0000 (15:41 -0700)
Pass a sockptr_t to prepare for set_fs-less handling of the kernel
pointer from bpf-cgroup.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: David S. Miller <davem@davemloft.net>
include/linux/netfilter/x_tables.h
net/ipv4/netfilter/arp_tables.c
net/ipv4/netfilter/ip_tables.c
net/ipv6/netfilter/ip6_tables.c
net/netfilter/x_tables.c

index b8b943ee7b8b6655acb4a5799ae6eed14bf9e610..5deb099d156dcb226498a127fc1597eee6a7d34d 100644 (file)
@@ -301,8 +301,8 @@ int xt_target_to_user(const struct xt_entry_target *t,
 int xt_data_to_user(void __user *dst, const void *src,
                    int usersize, int size, int aligned_size);
 
-void *xt_copy_counters_from_user(const void __user *user, unsigned int len,
-                                struct xt_counters_info *info);
+void *xt_copy_counters(sockptr_t arg, unsigned int len,
+                      struct xt_counters_info *info);
 struct xt_counters *xt_counters_alloc(unsigned int counters);
 
 struct xt_table *xt_register_table(struct net *net,
index 2c8a4dad39d7482991f0e631d440873357b6778a..6d24b686c7f00afc6c3a9c412637f6fd2eb71daf 100644 (file)
@@ -996,8 +996,7 @@ static int do_replace(struct net *net, const void __user *user,
        return ret;
 }
 
-static int do_add_counters(struct net *net, const void __user *user,
-                          unsigned int len)
+static int do_add_counters(struct net *net, sockptr_t arg, unsigned int len)
 {
        unsigned int i;
        struct xt_counters_info tmp;
@@ -1008,7 +1007,7 @@ static int do_add_counters(struct net *net, const void __user *user,
        struct arpt_entry *iter;
        unsigned int addend;
 
-       paddc = xt_copy_counters_from_user(user, len, &tmp);
+       paddc = xt_copy_counters(arg, len, &tmp);
        if (IS_ERR(paddc))
                return PTR_ERR(paddc);
 
@@ -1420,7 +1419,7 @@ static int do_arpt_set_ctl(struct sock *sk, int cmd, void __user *user, unsigned
                break;
 
        case ARPT_SO_SET_ADD_COUNTERS:
-               ret = do_add_counters(sock_net(sk), user, len);
+               ret = do_add_counters(sock_net(sk), USER_SOCKPTR(user), len);
                break;
 
        default:
index 161901dd1cae7f48a77fdbd3ae8250b0105611c7..4697d09c98dc3ebe9357951bd3edc8a35306c403 100644 (file)
@@ -1151,8 +1151,7 @@ do_replace(struct net *net, const void __user *user, unsigned int len)
 }
 
 static int
-do_add_counters(struct net *net, const void __user *user,
-               unsigned int len)
+do_add_counters(struct net *net, sockptr_t arg, unsigned int len)
 {
        unsigned int i;
        struct xt_counters_info tmp;
@@ -1163,7 +1162,7 @@ do_add_counters(struct net *net, const void __user *user,
        struct ipt_entry *iter;
        unsigned int addend;
 
-       paddc = xt_copy_counters_from_user(user, len, &tmp);
+       paddc = xt_copy_counters(arg, len, &tmp);
        if (IS_ERR(paddc))
                return PTR_ERR(paddc);
 
@@ -1629,7 +1628,7 @@ do_ipt_set_ctl(struct sock *sk, int cmd, void __user *user, unsigned int len)
                break;
 
        case IPT_SO_SET_ADD_COUNTERS:
-               ret = do_add_counters(sock_net(sk), user, len);
+               ret = do_add_counters(sock_net(sk), USER_SOCKPTR(user), len);
                break;
 
        default:
index fd1f8f93123188bfe15f2d80eb79432aebf06801..a787aba30e2db73323241741cb08516c9448c784 100644 (file)
@@ -1168,7 +1168,7 @@ do_replace(struct net *net, const void __user *user, unsigned int len)
 }
 
 static int
-do_add_counters(struct net *net, const void __user *user, unsigned int len)
+do_add_counters(struct net *net, sockptr_t arg, unsigned int len)
 {
        unsigned int i;
        struct xt_counters_info tmp;
@@ -1179,7 +1179,7 @@ do_add_counters(struct net *net, const void __user *user, unsigned int len)
        struct ip6t_entry *iter;
        unsigned int addend;
 
-       paddc = xt_copy_counters_from_user(user, len, &tmp);
+       paddc = xt_copy_counters(arg, len, &tmp);
        if (IS_ERR(paddc))
                return PTR_ERR(paddc);
        t = xt_find_table_lock(net, AF_INET6, tmp.name);
@@ -1637,7 +1637,7 @@ do_ip6t_set_ctl(struct sock *sk, int cmd, void __user *user, unsigned int len)
                break;
 
        case IP6T_SO_SET_ADD_COUNTERS:
-               ret = do_add_counters(sock_net(sk), user, len);
+               ret = do_add_counters(sock_net(sk), USER_SOCKPTR(user), len);
                break;
 
        default:
index 32bab45af7e415be7a399d2e488f597e657a2985..b97eb4b538fd4e97b76a3b252573948bf051a48a 100644 (file)
@@ -1028,9 +1028,9 @@ int xt_check_target(struct xt_tgchk_param *par,
 EXPORT_SYMBOL_GPL(xt_check_target);
 
 /**
- * xt_copy_counters_from_user - copy counters and metadata from userspace
+ * xt_copy_counters - copy counters and metadata from a sockptr_t
  *
- * @user: src pointer to userspace memory
+ * @arg: src sockptr
  * @len: alleged size of userspace memory
  * @info: where to store the xt_counters_info metadata
  *
@@ -1047,8 +1047,8 @@ EXPORT_SYMBOL_GPL(xt_check_target);
  * Return: returns pointer that caller has to test via IS_ERR().
  * If IS_ERR is false, caller has to vfree the pointer.
  */
-void *xt_copy_counters_from_user(const void __user *user, unsigned int len,
-                                struct xt_counters_info *info)
+void *xt_copy_counters(sockptr_t arg, unsigned int len,
+                      struct xt_counters_info *info)
 {
        void *mem;
        u64 size;
@@ -1062,12 +1062,12 @@ void *xt_copy_counters_from_user(const void __user *user, unsigned int len,
                        return ERR_PTR(-EINVAL);
 
                len -= sizeof(compat_tmp);
-               if (copy_from_user(&compat_tmp, user, sizeof(compat_tmp)) != 0)
+               if (copy_from_sockptr(&compat_tmp, arg, sizeof(compat_tmp)) != 0)
                        return ERR_PTR(-EFAULT);
 
                memcpy(info->name, compat_tmp.name, sizeof(info->name) - 1);
                info->num_counters = compat_tmp.num_counters;
-               user += sizeof(compat_tmp);
+               sockptr_advance(arg, sizeof(compat_tmp));
        } else
 #endif
        {
@@ -1075,10 +1075,10 @@ void *xt_copy_counters_from_user(const void __user *user, unsigned int len,
                        return ERR_PTR(-EINVAL);
 
                len -= sizeof(*info);
-               if (copy_from_user(info, user, sizeof(*info)) != 0)
+               if (copy_from_sockptr(info, arg, sizeof(*info)) != 0)
                        return ERR_PTR(-EFAULT);
 
-               user += sizeof(*info);
+               sockptr_advance(arg, sizeof(*info));
        }
        info->name[sizeof(info->name) - 1] = '\0';
 
@@ -1092,13 +1092,13 @@ void *xt_copy_counters_from_user(const void __user *user, unsigned int len,
        if (!mem)
                return ERR_PTR(-ENOMEM);
 
-       if (copy_from_user(mem, user, len) == 0)
+       if (copy_from_sockptr(mem, arg, len) == 0)
                return mem;
 
        vfree(mem);
        return ERR_PTR(-EFAULT);
 }
-EXPORT_SYMBOL_GPL(xt_copy_counters_from_user);
+EXPORT_SYMBOL_GPL(xt_copy_counters);
 
 #ifdef CONFIG_COMPAT
 int xt_compat_target_offset(const struct xt_target *target)