Skip to content

Commit 38b5afe

Browse files
lxinLee Jones
authored andcommitted
ipv6: check sk sk_type and protocol early in ip_mroute_set/getsockopt
[ Upstream commit 99253eb ] Commit 5e1859f ("ipv4: ipmr: various fixes and cleanups") fixed the issue for ipv4 ipmr: ip_mroute_setsockopt() & ip_mroute_getsockopt() should not access/set raw_sk(sk)->ipmr_table before making sure the socket is a raw socket, and protocol is IGMP The same fix should be done for ipv6 ipmr as well. This patch can fix the panic caused by overwriting the same offset as ipmr_table as in raw_sk(sk) when accessing other type's socket by ip_mroute_setsockopt(). Signed-off-by: Xin Long <lucien.xin@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net> Signed-off-by: Sasha Levin <sashal@kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> Signed-off-by: Lee Jones <lee.jones@linaro.org> Change-Id: I8d48f4611a2f2d0cb7ad5146036f571f12ecb1fc
1 parent f6cb346 commit 38b5afe

1 file changed

Lines changed: 8 additions & 3 deletions

File tree

net/ipv6/ip6mr.c

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1665,6 +1665,10 @@ int ip6_mroute_setsockopt(struct sock *sk, int optname, char __user *optval, uns
16651665
struct net *net = sock_net(sk);
16661666
struct mr6_table *mrt;
16671667

1668+
if (sk->sk_type != SOCK_RAW ||
1669+
inet_sk(sk)->inet_num != IPPROTO_ICMPV6)
1670+
return -EOPNOTSUPP;
1671+
16681672
mrt = ip6mr_get_table(net, raw6_sk(sk)->ip6mr_table ? : RT6_TABLE_DFLT);
16691673
if (mrt == NULL)
16701674
return -ENOENT;
@@ -1676,9 +1680,6 @@ int ip6_mroute_setsockopt(struct sock *sk, int optname, char __user *optval, uns
16761680

16771681
switch (optname) {
16781682
case MRT6_INIT:
1679-
if (sk->sk_type != SOCK_RAW ||
1680-
inet_sk(sk)->inet_num != IPPROTO_ICMPV6)
1681-
return -EOPNOTSUPP;
16821683
if (optlen < sizeof(int))
16831684
return -EINVAL;
16841685

@@ -1815,6 +1816,10 @@ int ip6_mroute_getsockopt(struct sock *sk, int optname, char __user *optval,
18151816
struct net *net = sock_net(sk);
18161817
struct mr6_table *mrt;
18171818

1819+
if (sk->sk_type != SOCK_RAW ||
1820+
inet_sk(sk)->inet_num != IPPROTO_ICMPV6)
1821+
return -EOPNOTSUPP;
1822+
18181823
mrt = ip6mr_get_table(net, raw6_sk(sk)->ip6mr_table ? : RT6_TABLE_DFLT);
18191824
if (mrt == NULL)
18201825
return -ENOENT;

0 commit comments

Comments
 (0)