netfilter: x_tables: enforce nul-terminated table name from getsockopt GET_ENTRIES
authorPablo Neira Ayuso <pablo@netfilter.org>
Thu, 24 Mar 2016 20:29:53 +0000 (21:29 +0100)
committerPablo Neira Ayuso <pablo@netfilter.org>
Mon, 28 Mar 2016 15:59:24 +0000 (17:59 +0200)
Make sure the table names via getsockopt GET_ENTRIES is nul-terminated
in ebtables and all the x_tables variants and their respective compat
code. Uncovered by KASAN.

Reported-by: Baozeng Ding <sploving1@gmail.com>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
net/bridge/netfilter/ebtables.c
net/ipv4/netfilter/arp_tables.c
net/ipv4/netfilter/ip_tables.c
net/ipv6/netfilter/ip6_tables.c

index 67b2e27999aa21fbcd45a42f73963dde7d974544..8570bc7744c25cc92e2301f8686cd21a1f26baab 100644 (file)
@@ -1521,6 +1521,8 @@ static int do_ebt_get_ctl(struct sock *sk, int cmd, void __user *user, int *len)
        if (copy_from_user(&tmp, user, sizeof(tmp)))
                return -EFAULT;
 
+       tmp.name[sizeof(tmp.name) - 1] = '\0';
+
        t = find_table_lock(net, tmp.name, &ret, &ebt_mutex);
        if (!t)
                return ret;
@@ -2332,6 +2334,8 @@ static int compat_do_ebt_get_ctl(struct sock *sk, int cmd,
        if (copy_from_user(&tmp, user, sizeof(tmp)))
                return -EFAULT;
 
+       tmp.name[sizeof(tmp.name) - 1] = '\0';
+
        t = find_table_lock(net, tmp.name, &ret, &ebt_mutex);
        if (!t)
                return ret;
index a1bb5e7129a2fe94b09273e283ccf27962db8e7e..4133b0f513afe5a40e523511f24b4652c68b1b57 100644 (file)
@@ -969,6 +969,7 @@ static int get_entries(struct net *net, struct arpt_get_entries __user *uptr,
                         sizeof(struct arpt_get_entries) + get.size);
                return -EINVAL;
        }
+       get.name[sizeof(get.name) - 1] = '\0';
 
        t = xt_find_table_lock(net, NFPROTO_ARP, get.name);
        if (!IS_ERR_OR_NULL(t)) {
@@ -1663,6 +1664,7 @@ static int compat_get_entries(struct net *net,
                         *len, sizeof(get) + get.size);
                return -EINVAL;
        }
+       get.name[sizeof(get.name) - 1] = '\0';
 
        xt_compat_lock(NFPROTO_ARP);
        t = xt_find_table_lock(net, NFPROTO_ARP, get.name);
index 89b5d959eda314ce57a1a7ae8bf365ac334bf0b6..631c100a13384203c06ec531ef901cd3aac74f90 100644 (file)
@@ -1156,6 +1156,7 @@ get_entries(struct net *net, struct ipt_get_entries __user *uptr,
                         *len, sizeof(get) + get.size);
                return -EINVAL;
        }
+       get.name[sizeof(get.name) - 1] = '\0';
 
        t = xt_find_table_lock(net, AF_INET, get.name);
        if (!IS_ERR_OR_NULL(t)) {
@@ -1935,6 +1936,7 @@ compat_get_entries(struct net *net, struct compat_ipt_get_entries __user *uptr,
                         *len, sizeof(get) + get.size);
                return -EINVAL;
        }
+       get.name[sizeof(get.name) - 1] = '\0';
 
        xt_compat_lock(AF_INET);
        t = xt_find_table_lock(net, AF_INET, get.name);
index 541b59f83595271ccbfa4f531f7246af5790e76f..86b67b70b62677ac014577f58d0bdafdd18ecf9e 100644 (file)
@@ -1168,6 +1168,7 @@ get_entries(struct net *net, struct ip6t_get_entries __user *uptr,
                         *len, sizeof(get) + get.size);
                return -EINVAL;
        }
+       get.name[sizeof(get.name) - 1] = '\0';
 
        t = xt_find_table_lock(net, AF_INET6, get.name);
        if (!IS_ERR_OR_NULL(t)) {
@@ -1944,6 +1945,7 @@ compat_get_entries(struct net *net, struct compat_ip6t_get_entries __user *uptr,
                         *len, sizeof(get) + get.size);
                return -EINVAL;
        }
+       get.name[sizeof(get.name) - 1] = '\0';
 
        xt_compat_lock(AF_INET6);
        t = xt_find_table_lock(net, AF_INET6, get.name);