netfilter: x_tables: enforce nul-terminated table name from getsockopt GET_ENTRIES

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>
This commit is contained in:
Pablo Neira Ayuso 2016-03-24 21:29:53 +01:00
parent 931401137f
commit b301f25387
4 changed files with 10 additions and 0 deletions

View 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))) if (copy_from_user(&tmp, user, sizeof(tmp)))
return -EFAULT; return -EFAULT;
tmp.name[sizeof(tmp.name) - 1] = '\0';
t = find_table_lock(net, tmp.name, &ret, &ebt_mutex); t = find_table_lock(net, tmp.name, &ret, &ebt_mutex);
if (!t) if (!t)
return ret; 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))) if (copy_from_user(&tmp, user, sizeof(tmp)))
return -EFAULT; return -EFAULT;
tmp.name[sizeof(tmp.name) - 1] = '\0';
t = find_table_lock(net, tmp.name, &ret, &ebt_mutex); t = find_table_lock(net, tmp.name, &ret, &ebt_mutex);
if (!t) if (!t)
return ret; return ret;

View 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); sizeof(struct arpt_get_entries) + get.size);
return -EINVAL; return -EINVAL;
} }
get.name[sizeof(get.name) - 1] = '\0';
t = xt_find_table_lock(net, NFPROTO_ARP, get.name); t = xt_find_table_lock(net, NFPROTO_ARP, get.name);
if (!IS_ERR_OR_NULL(t)) { if (!IS_ERR_OR_NULL(t)) {
@ -1663,6 +1664,7 @@ static int compat_get_entries(struct net *net,
*len, sizeof(get) + get.size); *len, sizeof(get) + get.size);
return -EINVAL; return -EINVAL;
} }
get.name[sizeof(get.name) - 1] = '\0';
xt_compat_lock(NFPROTO_ARP); xt_compat_lock(NFPROTO_ARP);
t = xt_find_table_lock(net, NFPROTO_ARP, get.name); t = xt_find_table_lock(net, NFPROTO_ARP, get.name);

View File

@ -1156,6 +1156,7 @@ get_entries(struct net *net, struct ipt_get_entries __user *uptr,
*len, sizeof(get) + get.size); *len, sizeof(get) + get.size);
return -EINVAL; return -EINVAL;
} }
get.name[sizeof(get.name) - 1] = '\0';
t = xt_find_table_lock(net, AF_INET, get.name); t = xt_find_table_lock(net, AF_INET, get.name);
if (!IS_ERR_OR_NULL(t)) { 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); *len, sizeof(get) + get.size);
return -EINVAL; return -EINVAL;
} }
get.name[sizeof(get.name) - 1] = '\0';
xt_compat_lock(AF_INET); xt_compat_lock(AF_INET);
t = xt_find_table_lock(net, AF_INET, get.name); t = xt_find_table_lock(net, AF_INET, get.name);

View File

@ -1168,6 +1168,7 @@ get_entries(struct net *net, struct ip6t_get_entries __user *uptr,
*len, sizeof(get) + get.size); *len, sizeof(get) + get.size);
return -EINVAL; return -EINVAL;
} }
get.name[sizeof(get.name) - 1] = '\0';
t = xt_find_table_lock(net, AF_INET6, get.name); t = xt_find_table_lock(net, AF_INET6, get.name);
if (!IS_ERR_OR_NULL(t)) { 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); *len, sizeof(get) + get.size);
return -EINVAL; return -EINVAL;
} }
get.name[sizeof(get.name) - 1] = '\0';
xt_compat_lock(AF_INET6); xt_compat_lock(AF_INET6);
t = xt_find_table_lock(net, AF_INET6, get.name); t = xt_find_table_lock(net, AF_INET6, get.name);