* [PATCH net] packet: compat support for sock_fprog
@ 2016-06-07 16:06 Willem de Bruijn
2016-06-09 9:52 ` Daniel Borkmann
2016-06-10 6:41 ` David Miller
0 siblings, 2 replies; 3+ messages in thread
From: Willem de Bruijn @ 2016-06-07 16:06 UTC (permalink / raw)
To: netdev; +Cc: daniel, davem, deller, Willem de Bruijn
From: Willem de Bruijn <willemb@google.com>
Socket option PACKET_FANOUT_DATA takes a struct sock_fprog as argument
if PACKET_FANOUT has mode PACKET_FANOUT_CBPF. This structure contains
a pointer into user memory. If userland is 32-bit and kernel is 64-bit
the two disagree about the layout of struct sock_fprog.
Add compat setsockopt support to convert a 32-bit compat_sock_fprog to
a 64-bit sock_fprog. This is analogous to compat_sock_fprog support for
SO_REUSEPORT added in commit 1957598840f4 ("soreuseport: add compat
case for setsockopt SO_ATTACH_REUSEPORT_CBPF").
Reported-by: Daniel Borkmann <daniel@iogearbox.net>
Signed-off-by: Willem de Bruijn <willemb@google.com>
---
include/net/compat.h | 1 +
net/compat.c | 17 +++++++++++++++--
net/packet/af_packet.c | 25 +++++++++++++++++++++++++
3 files changed, 41 insertions(+), 2 deletions(-)
diff --git a/include/net/compat.h b/include/net/compat.h
index 48103cf..13de0cc 100644
--- a/include/net/compat.h
+++ b/include/net/compat.h
@@ -42,6 +42,7 @@ int compat_sock_get_timestampns(struct sock *, struct timespec __user *);
int get_compat_msghdr(struct msghdr *, struct compat_msghdr __user *,
struct sockaddr __user **, struct iovec **);
+struct sock_fprog __user *get_compat_bpf_fprog(char __user *optval);
asmlinkage long compat_sys_sendmsg(int, struct compat_msghdr __user *,
unsigned int);
asmlinkage long compat_sys_sendmmsg(int, struct compat_mmsghdr __user *,
diff --git a/net/compat.c b/net/compat.c
index 1373947..1cd2ec0 100644
--- a/net/compat.c
+++ b/net/compat.c
@@ -309,8 +309,8 @@ void scm_detach_fds_compat(struct msghdr *kmsg, struct scm_cookie *scm)
__scm_destroy(scm);
}
-static int do_set_attach_filter(struct socket *sock, int level, int optname,
- char __user *optval, unsigned int optlen)
+/* allocate a 64-bit sock_fprog on the user stack for duration of syscall. */
+struct sock_fprog __user *get_compat_bpf_fprog(char __user *optval)
{
struct compat_sock_fprog __user *fprog32 = (struct compat_sock_fprog __user *)optval;
struct sock_fprog __user *kfprog = compat_alloc_user_space(sizeof(struct sock_fprog));
@@ -323,6 +323,19 @@ static int do_set_attach_filter(struct socket *sock, int level, int optname,
__get_user(ptr, &fprog32->filter) ||
__put_user(len, &kfprog->len) ||
__put_user(compat_ptr(ptr), &kfprog->filter))
+ return NULL;
+
+ return kfprog;
+}
+EXPORT_SYMBOL_GPL(get_compat_bpf_fprog);
+
+static int do_set_attach_filter(struct socket *sock, int level, int optname,
+ char __user *optval, unsigned int optlen)
+{
+ struct sock_fprog __user *kfprog;
+
+ kfprog = get_compat_bpf_fprog(optval);
+ if (!kfprog)
return -EFAULT;
return sock_setsockopt(sock, level, optname, (char __user *)kfprog,
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c
index 4040eb9..9bff6ef 100644
--- a/net/packet/af_packet.c
+++ b/net/packet/af_packet.c
@@ -93,6 +93,7 @@
#include <net/inet_common.h>
#endif
#include <linux/bpf.h>
+#include <net/compat.h>
#include "internal.h"
@@ -3940,6 +3941,27 @@ static int packet_getsockopt(struct socket *sock, int level, int optname,
}
+#ifdef CONFIG_COMPAT
+static int compat_packet_setsockopt(struct socket *sock, int level, int optname,
+ char __user *optval, unsigned int optlen)
+{
+ struct packet_sock *po = pkt_sk(sock->sk);
+
+ if (level != SOL_PACKET)
+ return -ENOPROTOOPT;
+
+ if (optname == PACKET_FANOUT_DATA &&
+ po->fanout && po->fanout->type == PACKET_FANOUT_CBPF) {
+ optval = (char __user *)get_compat_bpf_fprog(optval);
+ if (!optval)
+ return -EFAULT;
+ optlen = sizeof(struct sock_fprog);
+ }
+
+ return packet_setsockopt(sock, level, optname, optval, optlen);
+}
+#endif
+
static int packet_notifier(struct notifier_block *this,
unsigned long msg, void *ptr)
{
@@ -4416,6 +4438,9 @@ static const struct proto_ops packet_ops = {
.shutdown = sock_no_shutdown,
.setsockopt = packet_setsockopt,
.getsockopt = packet_getsockopt,
+#ifdef CONFIG_COMPAT
+ .compat_setsockopt = compat_packet_setsockopt,
+#endif
.sendmsg = packet_sendmsg,
.recvmsg = packet_recvmsg,
.mmap = packet_mmap,
--
2.8.0.rc3.226.g39d4020
^ permalink raw reply related [flat|nested] 3+ messages in thread
* Re: [PATCH net] packet: compat support for sock_fprog
2016-06-07 16:06 [PATCH net] packet: compat support for sock_fprog Willem de Bruijn
@ 2016-06-09 9:52 ` Daniel Borkmann
2016-06-10 6:41 ` David Miller
1 sibling, 0 replies; 3+ messages in thread
From: Daniel Borkmann @ 2016-06-09 9:52 UTC (permalink / raw)
To: Willem de Bruijn, netdev; +Cc: davem, deller, Willem de Bruijn
On 06/07/2016 06:06 PM, Willem de Bruijn wrote:
> From: Willem de Bruijn <willemb@google.com>
>
> Socket option PACKET_FANOUT_DATA takes a struct sock_fprog as argument
> if PACKET_FANOUT has mode PACKET_FANOUT_CBPF. This structure contains
> a pointer into user memory. If userland is 32-bit and kernel is 64-bit
> the two disagree about the layout of struct sock_fprog.
>
> Add compat setsockopt support to convert a 32-bit compat_sock_fprog to
> a 64-bit sock_fprog. This is analogous to compat_sock_fprog support for
> SO_REUSEPORT added in commit 1957598840f4 ("soreuseport: add compat
> case for setsockopt SO_ATTACH_REUSEPORT_CBPF").
>
> Reported-by: Daniel Borkmann <daniel@iogearbox.net>
> Signed-off-by: Willem de Bruijn <willemb@google.com>
Looks good to me, thanks Willem!
Acked-by: Daniel Borkmann <daniel@iogearbox.net>
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PATCH net] packet: compat support for sock_fprog
2016-06-07 16:06 [PATCH net] packet: compat support for sock_fprog Willem de Bruijn
2016-06-09 9:52 ` Daniel Borkmann
@ 2016-06-10 6:41 ` David Miller
1 sibling, 0 replies; 3+ messages in thread
From: David Miller @ 2016-06-10 6:41 UTC (permalink / raw)
To: willemdebruijn.kernel; +Cc: netdev, daniel, deller, willemb
From: Willem de Bruijn <willemdebruijn.kernel@gmail.com>
Date: Tue, 7 Jun 2016 12:06:34 -0400
> From: Willem de Bruijn <willemb@google.com>
>
> Socket option PACKET_FANOUT_DATA takes a struct sock_fprog as argument
> if PACKET_FANOUT has mode PACKET_FANOUT_CBPF. This structure contains
> a pointer into user memory. If userland is 32-bit and kernel is 64-bit
> the two disagree about the layout of struct sock_fprog.
>
> Add compat setsockopt support to convert a 32-bit compat_sock_fprog to
> a 64-bit sock_fprog. This is analogous to compat_sock_fprog support for
> SO_REUSEPORT added in commit 1957598840f4 ("soreuseport: add compat
> case for setsockopt SO_ATTACH_REUSEPORT_CBPF").
>
> Reported-by: Daniel Borkmann <daniel@iogearbox.net>
> Signed-off-by: Willem de Bruijn <willemb@google.com>
Applied.
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2016-06-10 6:41 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2016-06-07 16:06 [PATCH net] packet: compat support for sock_fprog Willem de Bruijn
2016-06-09 9:52 ` Daniel Borkmann
2016-06-10 6:41 ` David Miller
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).