|
From: | Shu-Chun Weng |
Subject: | Re: [PATCH v2] linux-user: Add most IFTUN ioctls |
Date: | Wed, 5 Aug 2020 16:22:49 -0700 |
The three options handling `struct sock_fprog` (TUNATTACHFILTER,
TUNDETACHFILTER, and TUNGETFILTER) are not implemented. Linux kernel
keeps a user space pointer in them which we cannot correctly handle.
Signed-off-by: Josh Kunz <jkz@google.com>
Signed-off-by: Shu-Chun Weng <scw@google.com>
---
v2:
Title changed from "linux-user: Add several IFTUN ioctls"
Properly specify the argument types for various options, including a custom
implementation for TUNSETTXFILTER.
#ifdef guards for macros introduced up to 5 years ago.
linux-user/ioctls.h | 45 +++++++++++++++++++++++++++++++++++++++
linux-user/syscall.c | 36 +++++++++++++++++++++++++++++++
linux-user/syscall_defs.h | 32 ++++++++++++++++++++++++++++
3 files changed, 113 insertions(+)
diff --git a/linux-user/ioctls.h b/linux-user/ioctls.h
index 0713ae1311..b9fb01f558 100644
--- a/linux-user/ioctls.h
+++ b/linux-user/ioctls.h
@@ -593,3 +593,48 @@
IOCTL(KCOV_DISABLE, 0, TYPE_NULL)
IOCTL(KCOV_INIT_TRACE, IOC_R, TYPE_ULONG)
#endif
+
+ IOCTL(TUNSETDEBUG, IOC_W, TYPE_INT)
+ IOCTL(TUNSETIFF, IOC_RW, MK_PTR(MK_STRUCT(STRUCT_short_ifreq)))
+ IOCTL(TUNSETPERSIST, IOC_W, TYPE_INT)
+ IOCTL(TUNSETOWNER, IOC_W, TYPE_INT)
+ IOCTL(TUNSETLINK, IOC_W, TYPE_INT)
+ IOCTL(TUNSETGROUP, IOC_W, TYPE_INT)
+ IOCTL(TUNGETFEATURES, IOC_R, MK_PTR(TYPE_INT))
+ IOCTL(TUNSETOFFLOAD, IOC_W, TYPE_LONG)
+ IOCTL_SPECIAL(TUNSETTXFILTER, IOC_W, do_ioctl_TUNSETTXFILTER,
+ /*
+ * We can't represent `struct tun_filter` in thunk so leaving
+ * this empty. do_ioctl_TUNSETTXFILTER will do the conversion.
+ */
+ TYPE_NULL)
+ IOCTL(TUNGETIFF, IOC_R, MK_PTR(MK_STRUCT(STRUCT_short_ifreq)))
+ IOCTL(TUNGETSNDBUF, IOC_R, MK_PTR(TYPE_INT))
+ IOCTL(TUNSETSNDBUF, IOC_W, MK_PTR(TYPE_INT))
+ /*
+ * TUNATTACHFILTER and TUNDETACHFILTER are not supported. Linux kernel keeps a
+ * user pointer in TUNATTACHFILTER, which we are not able to correctly handle.
+ */
+ IOCTL(TUNGETVNETHDRSZ, IOC_R, MK_PTR(TYPE_INT))
+ IOCTL(TUNSETVNETHDRSZ, IOC_W, MK_PTR(TYPE_INT))
+ IOCTL(TUNSETQUEUE, IOC_W, MK_PTR(MK_STRUCT(STRUCT_short_ifreq)))
+ IOCTL(TUNSETIFINDEX , IOC_W, MK_PTR(TYPE_INT))
+ /* TUNGETFILTER is not supported: see TUNATTACHFILTER. */
+ IOCTL(TUNSETVNETLE, IOC_W, MK_PTR(TYPE_INT))
+ IOCTL(TUNGETVNETLE, IOC_R, MK_PTR(TYPE_INT))
+#ifdef TUNSETVNETBE
+ IOCTL(TUNSETVNETBE, IOC_W, MK_PTR(TYPE_INT))
+ IOCTL(TUNGETVNETBE, IOC_R, MK_PTR(TYPE_INT))
+#endif
+#ifdef TUNSETSTEERINGEBPF
+ IOCTL(TUNSETSTEERINGEBPF, IOC_W, MK_PTR(TYPE_INT))
+#endif
+#ifdef TUNSETFILTEREBPF
+ IOCTL(TUNSETFILTEREBPF, IOC_W, MK_PTR(TYPE_INT))
+#endif
+#ifdef TUNSETCARRIER
+ IOCTL(TUNSETCARRIER, IOC_W, MK_PTR(TYPE_INT))
+#endif
+#ifdef TUNGETDEVNETNS
+ IOCTL(TUNGETDEVNETNS, IOC_R, TYPE_NULL)
+#endif
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 1211e759c2..7f1efed189 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -56,6 +56,7 @@
#include <linux/wireless.h>
#include <linux/icmp.h>
#include <linux/icmpv6.h>
+#include <linux/if_tun.h>
#include <linux/errqueue.h>
#include <linux/random.h>
#ifdef CONFIG_TIMERFD
@@ -5422,6 +5423,41 @@ static abi_long do_ioctl_drm(const IOCTLEntry *ie, uint8_t *buf_temp,
#endif
+static abi_long do_ioctl_TUNSETTXFILTER(const IOCTLEntry *ie, uint8_t *buf_temp,
+ int fd, int cmd, abi_long arg)
+{
+ struct tun_filter *filter = (struct tun_filter *)buf_temp;
+ struct tun_filter *target_filter;
+ char *target_addr;
+
+ assert(ie->access == IOC_W);
+
+ target_filter = lock_user(VERIFY_READ, arg, sizeof(*filter), 1);
+ if (!target_filter) {
+ return -TARGET_EFAULT;
+ }
+ filter->flags = tswap16(target_filter->flags);
+ filter->count = tswap16(target_filter->count);
+ unlock_user(target_filter, arg, sizeof(*filter));
+
+ if (filter->count) {
+ if (sizeof(*filter) + filter->count * ETH_ALEN > MAX_STRUCT_SIZE) {
+ return -TARGET_EFAULT;
+ }
+
+ target_addr = lock_user(VERIFY_READ, arg + sizeof(*filter),
+ filter->count * ETH_ALEN, 1);
+ if (!target_addr) {
+ return -TARGET_EFAULT;
+ }
+ memcpy(filter->addr, target_addr, filter->count * ETH_ALEN);
+ unlock_user(target_addr, arg + sizeof(*filter),
+ filter->count * ETH_ALEN);
+ }
+
+ return get_errno(safe_ioctl(fd, ie->host_cmd, filter));
+}
+
IOCTLEntry ioctl_entries[] = {
#define IOCTL(cmd, access, ...) \
{ TARGET_ ## cmd, cmd, #cmd, access, 0, { __VA_ARGS__ } },
diff --git a/linux-user/syscall_defs.h b/linux-user/syscall_defs.h
index 3c261cff0e..7ef0ff0328 100644
--- a/linux-user/syscall_defs.h
+++ b/linux-user/syscall_defs.h
@@ -891,6 +891,38 @@ struct target_rtc_pll_info {
#define TARGET_SIOCGIWNAME 0x8B01 /* get name == wireless protocol */
+/* From <linux/if_tun.h> */
+
+#define TARGET_TUNSETDEBUG TARGET_IOW('T', 201, int)
+#define TARGET_TUNSETIFF TARGET_IOW('T', 202, int)
+#define TARGET_TUNSETPERSIST TARGET_IOW('T', 203, int)
+#define TARGET_TUNSETOWNER TARGET_IOW('T', 204, int)
+#define TARGET_TUNSETLINK TARGET_IOW('T', 205, int)
+#define TARGET_TUNSETGROUP TARGET_IOW('T', 206, int)
+#define TARGET_TUNGETFEATURES TARGET_IOR('T', 207, unsigned int)
+#define TARGET_TUNSETOFFLOAD TARGET_IOW('T', 208, unsigned int)
+#define TARGET_TUNSETTXFILTER TARGET_IOW('T', 209, unsigned int)
+#define TARGET_TUNGETIFF TARGET_IOR('T', 210, unsigned int)
+#define TARGET_TUNGETSNDBUF TARGET_IOR('T', 211, int)
+#define TARGET_TUNSETSNDBUF TARGET_IOW('T', 212, int)
+/*
+ * TUNATTACHFILTER and TUNDETACHFILTER are not supported. Linux kernel keeps a
+ * user pointer in TUNATTACHFILTER, which we are not able to correctly handle.
+ */
+#define TARGET_TUNGETVNETHDRSZ TARGET_IOR('T', 215, int)
+#define TARGET_TUNSETVNETHDRSZ TARGET_IOW('T', 216, int)
+#define TARGET_TUNSETQUEUE TARGET_IOW('T', 217, int)
+#define TARGET_TUNSETIFINDEX TARGET_IOW('T', 218, unsigned int)
+/* TUNGETFILTER is not supported: see TUNATTACHFILTER. */
+#define TARGET_TUNSETVNETLE TARGET_IOW('T', 220, int)
+#define TARGET_TUNGETVNETLE TARGET_IOR('T', 221, int)
+#define TARGET_TUNSETVNETBE TARGET_IOW('T', 222, int)
+#define TARGET_TUNGETVNETBE TARGET_IOR('T', 223, int)
+#define TARGET_TUNSETSTEERINGEBPF TARGET_IOR('T', 224, int)
+#define TARGET_TUNSETFILTEREBPF TARGET_IOR('T', 225, int)
+#define TARGET_TUNSETCARRIER TARGET_IOW('T', 226, int)
+#define TARGET_TUNGETDEVNETNS TARGET_IO('T', 227)
+
/* From <linux/random.h> */
#define TARGET_RNDGETENTCNT TARGET_IOR('R', 0x00, int)
--
2.28.0.rc0.142.g3c755180ce-goog
smime.p7s
Description: S/MIME Cryptographic Signature
[Prev in Thread] | Current Thread | [Next in Thread] |