Message ID | 20110809082404.GA24845@mail.gmail.com |
---|---|
State | RFC, archived |
Delegated to: | David Miller |
Headers | show |
Hi Jean, That was my first variant of the patch, but that way the code does more than it's suppose to do: the call of do_ip_getsockopt becomes unaware of the context from which it is called (ip_getsockopt or compat_ip_getsockopt). We should act in a compat manner only when called from compat_ip_getsockopt. The issue that needed a fix was that in compat mode the flag was set to 0 thus silently disabling the call of put_cmsg_compat (see net/core/scm.c). Thanks for the review, Tiberiu On Tuesday, August 09, 2011 11:24:04 am Jean Sacren wrote: > From: Daniel Baluta <dbaluta@ixiacom.com> > Date: Sun, 07 Aug 2011 02:20:50 +0300 > > > IP_PKTOPTIONS is broken for 32-bit applications running > > in COMPAT mode on 64-bit kernels. > > > > This happens because msghdr's msg_flags field is always > > set to zero. When running in COMPAT mode this should be > > set to MSG_CMSG_COMPAT instead. > > > > Signed-off-by: Tiberiu Szocs-Mihai <tszocs@ixiacom.com> > > Signed-off-by: Daniel Baluta <dbaluta@ixiacom.com> > > --- > > > > net/ipv4/ip_sockglue.c | 9 +++++---- > > 1 files changed, 5 insertions(+), 4 deletions(-) > > > > diff --git a/net/ipv4/ip_sockglue.c b/net/ipv4/ip_sockglue.c > > index ab0c9ef..c77f5a8 100644 > > --- a/net/ipv4/ip_sockglue.c > > +++ b/net/ipv4/ip_sockglue.c > > @@ -1067,7 +1067,7 @@ EXPORT_SYMBOL(compat_ip_setsockopt); > > > > */ > > > > static int do_ip_getsockopt(struct sock *sk, int level, int optname, > > > > - char __user *optval, int __user *optlen) > > + char __user *optval, int __user *optlen, unsigned flags) > > > > { > > > > struct inet_sock *inet = inet_sk(sk); > > int val; > > > > @@ -1240,7 +1240,7 @@ static int do_ip_getsockopt(struct sock *sk, int > > level, int optname, > > > > msg.msg_control = optval; > > msg.msg_controllen = len; > > > > - msg.msg_flags = 0; > > + msg.msg_flags = flags; > > > > if (inet->cmsg_flags & IP_CMSG_PKTINFO) { > > > > struct in_pktinfo info; > > > > @@ -1294,7 +1294,7 @@ int ip_getsockopt(struct sock *sk, int level, > > > > { > > > > int err; > > > > - err = do_ip_getsockopt(sk, level, optname, optval, optlen); > > + err = do_ip_getsockopt(sk, level, optname, optval, optlen, 0); > > > > #ifdef CONFIG_NETFILTER > > > > /* we need to exclude all possible ENOPROTOOPTs except default case */ > > if (err == -ENOPROTOOPT && optname != IP_PKTOPTIONS && > > > > @@ -1327,7 +1327,8 @@ int compat_ip_getsockopt(struct sock *sk, int > > level, int optname, > > > > return compat_mc_getsockopt(sk, level, optname, optval, optlen, > > > > ip_getsockopt); > > > > - err = do_ip_getsockopt(sk, level, optname, optval, optlen); > > + err = do_ip_getsockopt(sk, level, optname, optval, optlen, > > + MSG_CMSG_COMPAT); > > > > #ifdef CONFIG_NETFILTER > > > > /* we need to exclude all possible ENOPROTOOPTs except default case */ > > I think the original patch can be simplified. Feedback is greatly > appreciated. > > diff --git a/net/ipv4/ip_sockglue.c b/net/ipv4/ip_sockglue.c > index ab0c9ef..f6eed68 100644 > --- a/net/ipv4/ip_sockglue.c > +++ b/net/ipv4/ip_sockglue.c > @@ -1240,7 +1240,7 @@ static int do_ip_getsockopt(struct sock *sk, int > level, int optname, > > msg.msg_control = optval; > msg.msg_controllen = len; > - msg.msg_flags = 0; > + msg.msg_flags = MSG_CMSG_COMPAT; > > if (inet->cmsg_flags & IP_CMSG_PKTINFO) { > struct in_pktinfo info; -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
diff --git a/net/ipv4/ip_sockglue.c b/net/ipv4/ip_sockglue.c index ab0c9ef..f6eed68 100644 --- a/net/ipv4/ip_sockglue.c +++ b/net/ipv4/ip_sockglue.c @@ -1240,7 +1240,7 @@ static int do_ip_getsockopt(struct sock *sk, int level, int optname, msg.msg_control = optval; msg.msg_controllen = len; - msg.msg_flags = 0; + msg.msg_flags = MSG_CMSG_COMPAT; if (inet->cmsg_flags & IP_CMSG_PKTINFO) { struct in_pktinfo info;