Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 98e77438 authored by Daniel Baluta's avatar Daniel Baluta Committed by David S. Miller
Browse files

ipv6: Fix ipv6_getsockopt for IPV6_2292PKTOPTIONS



IPV6_2292PKTOPTIONS is broken for 32-bit applications running
in COMPAT mode on 64-bit kernels.

The same problem was fixed for IPv4 with the patch:
ipv4: Fix ip_getsockopt for IP_PKTOPTIONS,
commit dd23198e

Signed-off-by: default avatarSorin Dumitru <sdumitru@ixiacom.com>
Signed-off-by: default avatarDaniel Baluta <dbaluta@ixiacom.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 2d5b2c5c
Loading
Loading
Loading
Loading
+5 −4
Original line number Original line Diff line number Diff line
@@ -913,7 +913,7 @@ static int ipv6_getsockopt_sticky(struct sock *sk, struct ipv6_txoptions *opt,
}
}


static int do_ipv6_getsockopt(struct sock *sk, int level, int optname,
static int do_ipv6_getsockopt(struct sock *sk, int level, int optname,
		    char __user *optval, int __user *optlen)
		    char __user *optval, int __user *optlen, unsigned flags)
{
{
	struct ipv6_pinfo *np = inet6_sk(sk);
	struct ipv6_pinfo *np = inet6_sk(sk);
	int len;
	int len;
@@ -962,7 +962,7 @@ static int do_ipv6_getsockopt(struct sock *sk, int level, int optname,


		msg.msg_control = optval;
		msg.msg_control = optval;
		msg.msg_controllen = len;
		msg.msg_controllen = len;
		msg.msg_flags = 0;
		msg.msg_flags = flags;


		lock_sock(sk);
		lock_sock(sk);
		skb = np->pktoptions;
		skb = np->pktoptions;
@@ -1222,7 +1222,7 @@ int ipv6_getsockopt(struct sock *sk, int level, int optname,
	if(level != SOL_IPV6)
	if(level != SOL_IPV6)
		return -ENOPROTOOPT;
		return -ENOPROTOOPT;


	err = do_ipv6_getsockopt(sk, level, optname, optval, optlen);
	err = do_ipv6_getsockopt(sk, level, optname, optval, optlen, 0);
#ifdef CONFIG_NETFILTER
#ifdef CONFIG_NETFILTER
	/* we need to exclude all possible ENOPROTOOPTs except default case */
	/* we need to exclude all possible ENOPROTOOPTs except default case */
	if (err == -ENOPROTOOPT && optname != IPV6_2292PKTOPTIONS) {
	if (err == -ENOPROTOOPT && optname != IPV6_2292PKTOPTIONS) {
@@ -1264,7 +1264,8 @@ int compat_ipv6_getsockopt(struct sock *sk, int level, int optname,
		return compat_mc_getsockopt(sk, level, optname, optval, optlen,
		return compat_mc_getsockopt(sk, level, optname, optval, optlen,
			ipv6_getsockopt);
			ipv6_getsockopt);


	err = do_ipv6_getsockopt(sk, level, optname, optval, optlen);
	err = do_ipv6_getsockopt(sk, level, optname, optval, optlen,
				 MSG_CMSG_COMPAT);
#ifdef CONFIG_NETFILTER
#ifdef CONFIG_NETFILTER
	/* we need to exclude all possible ENOPROTOOPTs except default case */
	/* we need to exclude all possible ENOPROTOOPTs except default case */
	if (err == -ENOPROTOOPT && optname != IPV6_2292PKTOPTIONS) {
	if (err == -ENOPROTOOPT && optname != IPV6_2292PKTOPTIONS) {