netfilter/ip_tables: clean up compat {get,set}sockopt handling
authorChristoph Hellwig <hch@lst.de>
Fri, 17 Jul 2020 06:23:17 +0000 (08:23 +0200)
committerDavid S. Miller <davem@davemloft.net>
Mon, 20 Jul 2020 01:16:40 +0000 (18:16 -0700)
Merge the native and compat {get,set}sockopt handlers using
in_compat_syscall().

Signed-off-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: David S. Miller <davem@davemloft.net>
net/ipv4/netfilter/ip_tables.c

index 5bf9fa0..fbfad38 100644 (file)
@@ -944,8 +944,7 @@ static int compat_table_info(const struct xt_table_info *info,
 }
 #endif
 
-static int get_info(struct net *net, void __user *user,
-                   const int *len, int compat)
+static int get_info(struct net *net, void __user *user, const int *len)
 {
        char name[XT_TABLE_MAXNAMELEN];
        struct xt_table *t;
@@ -959,7 +958,7 @@ static int get_info(struct net *net, void __user *user,
 
        name[XT_TABLE_MAXNAMELEN-1] = '\0';
 #ifdef CONFIG_COMPAT
-       if (compat)
+       if (in_compat_syscall())
                xt_compat_lock(AF_INET);
 #endif
        t = xt_request_find_table_lock(net, AF_INET, name);
@@ -969,7 +968,7 @@ static int get_info(struct net *net, void __user *user,
 #ifdef CONFIG_COMPAT
                struct xt_table_info tmp;
 
-               if (compat) {
+               if (in_compat_syscall()) {
                        ret = compat_table_info(private, &tmp);
                        xt_compat_flush_offsets(AF_INET);
                        private = &tmp;
@@ -995,7 +994,7 @@ static int get_info(struct net *net, void __user *user,
        } else
                ret = PTR_ERR(t);
 #ifdef CONFIG_COMPAT
-       if (compat)
+       if (in_compat_syscall())
                xt_compat_unlock(AF_INET);
 #endif
        return ret;
@@ -1153,7 +1152,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, int compat)
+               unsigned int len)
 {
        unsigned int i;
        struct xt_counters_info tmp;
@@ -1164,7 +1163,8 @@ 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, compat);
+       paddc = xt_copy_counters_from_user(user, len, &tmp,
+                                          in_compat_syscall());
        if (IS_ERR(paddc))
                return PTR_ERR(paddc);
 
@@ -1534,31 +1534,6 @@ compat_do_replace(struct net *net, void __user *user, unsigned int len)
        return ret;
 }
 
-static int
-compat_do_ipt_set_ctl(struct sock *sk, int cmd, void __user *user,
-                     unsigned int len)
-{
-       int ret;
-
-       if (!ns_capable(sock_net(sk)->user_ns, CAP_NET_ADMIN))
-               return -EPERM;
-
-       switch (cmd) {
-       case IPT_SO_SET_REPLACE:
-               ret = compat_do_replace(sock_net(sk), user, len);
-               break;
-
-       case IPT_SO_SET_ADD_COUNTERS:
-               ret = do_add_counters(sock_net(sk), user, len, 1);
-               break;
-
-       default:
-               ret = -EINVAL;
-       }
-
-       return ret;
-}
-
 struct compat_ipt_get_entries {
        char name[XT_TABLE_MAXNAMELEN];
        compat_uint_t size;
@@ -1634,29 +1609,6 @@ compat_get_entries(struct net *net, struct compat_ipt_get_entries __user *uptr,
        xt_compat_unlock(AF_INET);
        return ret;
 }
-
-static int do_ipt_get_ctl(struct sock *, int, void __user *, int *);
-
-static int
-compat_do_ipt_get_ctl(struct sock *sk, int cmd, void __user *user, int *len)
-{
-       int ret;
-
-       if (!ns_capable(sock_net(sk)->user_ns, CAP_NET_ADMIN))
-               return -EPERM;
-
-       switch (cmd) {
-       case IPT_SO_GET_INFO:
-               ret = get_info(sock_net(sk), user, len, 1);
-               break;
-       case IPT_SO_GET_ENTRIES:
-               ret = compat_get_entries(sock_net(sk), user, len);
-               break;
-       default:
-               ret = do_ipt_get_ctl(sk, cmd, user, len);
-       }
-       return ret;
-}
 #endif
 
 static int
@@ -1669,11 +1621,16 @@ do_ipt_set_ctl(struct sock *sk, int cmd, void __user *user, unsigned int len)
 
        switch (cmd) {
        case IPT_SO_SET_REPLACE:
-               ret = do_replace(sock_net(sk), user, len);
+#ifdef CONFIG_COMPAT
+               if (in_compat_syscall())
+                       ret = compat_do_replace(sock_net(sk), user, len);
+               else
+#endif
+                       ret = do_replace(sock_net(sk), user, len);
                break;
 
        case IPT_SO_SET_ADD_COUNTERS:
-               ret = do_add_counters(sock_net(sk), user, len, 0);
+               ret = do_add_counters(sock_net(sk), user, len);
                break;
 
        default:
@@ -1693,11 +1650,16 @@ do_ipt_get_ctl(struct sock *sk, int cmd, void __user *user, int *len)
 
        switch (cmd) {
        case IPT_SO_GET_INFO:
-               ret = get_info(sock_net(sk), user, len, 0);
+               ret = get_info(sock_net(sk), user, len);
                break;
 
        case IPT_SO_GET_ENTRIES:
-               ret = get_entries(sock_net(sk), user, len);
+#ifdef CONFIG_COMPAT
+               if (in_compat_syscall())
+                       ret = compat_get_entries(sock_net(sk), user, len);
+               else
+#endif
+                       ret = get_entries(sock_net(sk), user, len);
                break;
 
        case IPT_SO_GET_REVISION_MATCH:
@@ -1886,15 +1848,9 @@ static struct nf_sockopt_ops ipt_sockopts = {
        .set_optmin     = IPT_BASE_CTL,
        .set_optmax     = IPT_SO_SET_MAX+1,
        .set            = do_ipt_set_ctl,
-#ifdef CONFIG_COMPAT
-       .compat_set     = compat_do_ipt_set_ctl,
-#endif
        .get_optmin     = IPT_BASE_CTL,
        .get_optmax     = IPT_SO_GET_MAX+1,
        .get            = do_ipt_get_ctl,
-#ifdef CONFIG_COMPAT
-       .compat_get     = compat_do_ipt_get_ctl,
-#endif
        .owner          = THIS_MODULE,
 };