diff options
| author | Daniel Baluta <dbaluta@ixiacom.com> | 2011-08-08 01:31:07 -0400 |
|---|---|---|
| committer | David S. Miller <davem@davemloft.net> | 2011-08-08 01:31:07 -0400 |
| commit | dd23198e58cd35259dd09e8892bbdb90f1d57748 (patch) | |
| tree | 33dc663c72aa08282e53ccff5049f2598617fcca /net | |
| parent | 8bab6f14084460d722f253221efa4148d3fc8b16 (diff) | |
ipv4: Fix ip_getsockopt for IP_PKTOPTIONS
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>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
| -rw-r--r-- | 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 ab0c9efd1efa..8905e92f896a 100644 --- a/net/ipv4/ip_sockglue.c +++ b/net/ipv4/ip_sockglue.c | |||
| @@ -1067,7 +1067,7 @@ EXPORT_SYMBOL(compat_ip_setsockopt); | |||
| 1067 | */ | 1067 | */ |
| 1068 | 1068 | ||
| 1069 | static int do_ip_getsockopt(struct sock *sk, int level, int optname, | 1069 | static int do_ip_getsockopt(struct sock *sk, int level, int optname, |
| 1070 | char __user *optval, int __user *optlen) | 1070 | char __user *optval, int __user *optlen, unsigned flags) |
| 1071 | { | 1071 | { |
| 1072 | struct inet_sock *inet = inet_sk(sk); | 1072 | struct inet_sock *inet = inet_sk(sk); |
| 1073 | int val; | 1073 | int val; |
| @@ -1240,7 +1240,7 @@ static int do_ip_getsockopt(struct sock *sk, int level, int optname, | |||
| 1240 | 1240 | ||
| 1241 | msg.msg_control = optval; | 1241 | msg.msg_control = optval; |
| 1242 | msg.msg_controllen = len; | 1242 | msg.msg_controllen = len; |
| 1243 | msg.msg_flags = 0; | 1243 | msg.msg_flags = flags; |
| 1244 | 1244 | ||
| 1245 | if (inet->cmsg_flags & IP_CMSG_PKTINFO) { | 1245 | if (inet->cmsg_flags & IP_CMSG_PKTINFO) { |
| 1246 | struct in_pktinfo info; | 1246 | struct in_pktinfo info; |
| @@ -1294,7 +1294,7 @@ int ip_getsockopt(struct sock *sk, int level, | |||
| 1294 | { | 1294 | { |
| 1295 | int err; | 1295 | int err; |
| 1296 | 1296 | ||
| 1297 | err = do_ip_getsockopt(sk, level, optname, optval, optlen); | 1297 | err = do_ip_getsockopt(sk, level, optname, optval, optlen, 0); |
| 1298 | #ifdef CONFIG_NETFILTER | 1298 | #ifdef CONFIG_NETFILTER |
| 1299 | /* we need to exclude all possible ENOPROTOOPTs except default case */ | 1299 | /* we need to exclude all possible ENOPROTOOPTs except default case */ |
| 1300 | if (err == -ENOPROTOOPT && optname != IP_PKTOPTIONS && | 1300 | if (err == -ENOPROTOOPT && optname != IP_PKTOPTIONS && |
| @@ -1327,7 +1327,8 @@ int compat_ip_getsockopt(struct sock *sk, int level, int optname, | |||
| 1327 | return compat_mc_getsockopt(sk, level, optname, optval, optlen, | 1327 | return compat_mc_getsockopt(sk, level, optname, optval, optlen, |
| 1328 | ip_getsockopt); | 1328 | ip_getsockopt); |
| 1329 | 1329 | ||
| 1330 | err = do_ip_getsockopt(sk, level, optname, optval, optlen); | 1330 | err = do_ip_getsockopt(sk, level, optname, optval, optlen, |
| 1331 | MSG_CMSG_COMPAT); | ||
| 1331 | 1332 | ||
| 1332 | #ifdef CONFIG_NETFILTER | 1333 | #ifdef CONFIG_NETFILTER |
| 1333 | /* we need to exclude all possible ENOPROTOOPTs except default case */ | 1334 | /* we need to exclude all possible ENOPROTOOPTs except default case */ |
