|
@@ -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,
|