Skip to content

Commit

Permalink
ipvs: Add boundary check on ioctl arguments
Browse files Browse the repository at this point in the history
The ipvs code has a nifty system for doing the size of ioctl command
copies; it defines an array with values into which it indexes the cmd
to find the right length.

Unfortunately, the ipvs code forgot to check if the cmd was in the
range that the array provides, allowing for an index outside of the
array, which then gives a "garbage" result into the length, which
then gets used for copying into a stack buffer.

Fix this by adding sanity checks on these as well as the copy size.

[ [email protected]: adjusted limit to IP_VS_SO_GET_MAX ]
Signed-off-by: Arjan van de Ven <[email protected]>
Acked-by: Julian Anastasov <[email protected]>
Signed-off-by: Simon Horman <[email protected]>
Signed-off-by: Patrick McHardy <[email protected]>
  • Loading branch information
fenrus75 authored and kaber committed Jan 4, 2010
1 parent ae24e57 commit 04bcef2
Showing 1 changed file with 13 additions and 1 deletion.
14 changes: 13 additions & 1 deletion net/netfilter/ipvs/ip_vs_ctl.c
Original file line number Diff line number Diff line change
Expand Up @@ -2077,6 +2077,10 @@ do_ip_vs_set_ctl(struct sock *sk, int cmd, void __user *user, unsigned int len)
if (!capable(CAP_NET_ADMIN))
return -EPERM;

if (cmd < IP_VS_BASE_CTL || cmd > IP_VS_SO_SET_MAX)
return -EINVAL;
if (len < 0 || len > MAX_ARG_LEN)
return -EINVAL;
if (len != set_arglen[SET_CMDID(cmd)]) {
pr_err("set_ctl: len %u != %u\n",
len, set_arglen[SET_CMDID(cmd)]);
Expand Down Expand Up @@ -2352,17 +2356,25 @@ do_ip_vs_get_ctl(struct sock *sk, int cmd, void __user *user, int *len)
{
unsigned char arg[128];
int ret = 0;
unsigned int copylen;

if (!capable(CAP_NET_ADMIN))
return -EPERM;

if (cmd < IP_VS_BASE_CTL || cmd > IP_VS_SO_GET_MAX)
return -EINVAL;

if (*len < get_arglen[GET_CMDID(cmd)]) {
pr_err("get_ctl: len %u < %u\n",
*len, get_arglen[GET_CMDID(cmd)]);
return -EINVAL;
}

if (copy_from_user(arg, user, get_arglen[GET_CMDID(cmd)]) != 0)
copylen = get_arglen[GET_CMDID(cmd)];
if (copylen > 128)
return -EINVAL;

if (copy_from_user(arg, user, copylen) != 0)
return -EFAULT;

if (mutex_lock_interruptible(&__ip_vs_mutex))
Expand Down

0 comments on commit 04bcef2

Please sign in to comment.