diff options
author | Thomas Graf <tgraf@suug.ch> | 2008-05-28 10:54:22 -0400 |
---|---|---|
committer | YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org> | 2008-06-04 15:02:31 -0400 |
commit | 24ef0da7b864435f221f668bc8a324160d063e78 (patch) | |
tree | 766e3dffc0e878bf07e4d9a4aa0b25b19d8e2785 /net | |
parent | a3c960899e042bc1c2b730a2115fa32da7802039 (diff) |
[IPV6] ADDRCONF: Check range of prefix length
As of now, the prefix length is not vaildated when adding or deleting
addresses. The value is passed directly into the inet6_ifaddr structure
and later passed on to memcmp() as length indicator which relies on
the value never to exceed 128 (bits).
Due to the missing check, the currently code allows for any 8 bit
value to be passed on as prefix length while using the netlink
interface, and any 32 bit value while using the ioctl interface.
[Use unsigned int instead to generate better code - yoshfuji]
Signed-off-by: Thomas Graf <tgraf@suug.ch>
Signed-off-by: YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
Diffstat (limited to 'net')
-rw-r--r-- | net/ipv6/addrconf.c | 10 |
1 files changed, 8 insertions, 2 deletions
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index 3a835578fd1c..c3b20c5afa3e 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c | |||
@@ -2027,7 +2027,7 @@ err_exit: | |||
2027 | * Manual configuration of address on an interface | 2027 | * Manual configuration of address on an interface |
2028 | */ | 2028 | */ |
2029 | static int inet6_addr_add(struct net *net, int ifindex, struct in6_addr *pfx, | 2029 | static int inet6_addr_add(struct net *net, int ifindex, struct in6_addr *pfx, |
2030 | int plen, __u8 ifa_flags, __u32 prefered_lft, | 2030 | unsigned int plen, __u8 ifa_flags, __u32 prefered_lft, |
2031 | __u32 valid_lft) | 2031 | __u32 valid_lft) |
2032 | { | 2032 | { |
2033 | struct inet6_ifaddr *ifp; | 2033 | struct inet6_ifaddr *ifp; |
@@ -2039,6 +2039,9 @@ static int inet6_addr_add(struct net *net, int ifindex, struct in6_addr *pfx, | |||
2039 | 2039 | ||
2040 | ASSERT_RTNL(); | 2040 | ASSERT_RTNL(); |
2041 | 2041 | ||
2042 | if (plen > 128) | ||
2043 | return -EINVAL; | ||
2044 | |||
2042 | /* check the lifetime */ | 2045 | /* check the lifetime */ |
2043 | if (!valid_lft || prefered_lft > valid_lft) | 2046 | if (!valid_lft || prefered_lft > valid_lft) |
2044 | return -EINVAL; | 2047 | return -EINVAL; |
@@ -2095,12 +2098,15 @@ static int inet6_addr_add(struct net *net, int ifindex, struct in6_addr *pfx, | |||
2095 | } | 2098 | } |
2096 | 2099 | ||
2097 | static int inet6_addr_del(struct net *net, int ifindex, struct in6_addr *pfx, | 2100 | static int inet6_addr_del(struct net *net, int ifindex, struct in6_addr *pfx, |
2098 | int plen) | 2101 | unsigned int plen) |
2099 | { | 2102 | { |
2100 | struct inet6_ifaddr *ifp; | 2103 | struct inet6_ifaddr *ifp; |
2101 | struct inet6_dev *idev; | 2104 | struct inet6_dev *idev; |
2102 | struct net_device *dev; | 2105 | struct net_device *dev; |
2103 | 2106 | ||
2107 | if (plen > 128) | ||
2108 | return -EINVAL; | ||
2109 | |||
2104 | dev = __dev_get_by_index(net, ifindex); | 2110 | dev = __dev_get_by_index(net, ifindex); |
2105 | if (!dev) | 2111 | if (!dev) |
2106 | return -ENODEV; | 2112 | return -ENODEV; |