All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2] linux-user: Add most IFTUN ioctls
@ 2020-07-23 23:10 Shu-Chun Weng
  2020-08-05 23:22 ` Shu-Chun Weng
  2020-09-26 16:44 ` Laurent Vivier
  0 siblings, 2 replies; 5+ messages in thread
From: Shu-Chun Weng @ 2020-07-23 23:10 UTC (permalink / raw)
  To: laurent; +Cc: Shu-Chun Weng, qemu-devel, riku.voipio, Josh Kunz

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



^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [PATCH v2] linux-user: Add most IFTUN ioctls
  2020-07-23 23:10 [PATCH v2] linux-user: Add most IFTUN ioctls Shu-Chun Weng
@ 2020-08-05 23:22 ` Shu-Chun Weng
  2020-09-17  7:24   ` Shu-Chun Weng
  2020-09-26 16:44 ` Laurent Vivier
  1 sibling, 1 reply; 5+ messages in thread
From: Shu-Chun Weng @ 2020-08-05 23:22 UTC (permalink / raw)
  To: Laurent Vivier; +Cc: qemu-devel, Riku Voipio, Josh Kunz


[-- Attachment #1.1: Type: text/plain, Size: 7411 bytes --]

Ping: https://patchew.org/QEMU/20200723231020.769893-1-scw@google.com/

On Thu, Jul 23, 2020 at 4:10 PM Shu-Chun Weng <scw@google.com> wrote:

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

[-- Attachment #1.2: Type: text/html, Size: 9067 bytes --]

[-- Attachment #2: S/MIME Cryptographic Signature --]
[-- Type: application/pkcs7-signature, Size: 3844 bytes --]

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH v2] linux-user: Add most IFTUN ioctls
  2020-08-05 23:22 ` Shu-Chun Weng
@ 2020-09-17  7:24   ` Shu-Chun Weng
  0 siblings, 0 replies; 5+ messages in thread
From: Shu-Chun Weng @ 2020-09-17  7:24 UTC (permalink / raw)
  To: Laurent Vivier; +Cc: qemu-devel, Riku Voipio, Josh Kunz


[-- Attachment #1.1: Type: text/plain, Size: 7679 bytes --]

Ping.

On Wed, Aug 5, 2020 at 4:22 PM Shu-Chun Weng <scw@google.com> wrote:

> Ping: https://patchew.org/QEMU/20200723231020.769893-1-scw@google.com/
>
> On Thu, Jul 23, 2020 at 4:10 PM Shu-Chun Weng <scw@google.com> wrote:
>
>> 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
>>
>>

[-- Attachment #1.2: Type: text/html, Size: 9435 bytes --]

[-- Attachment #2: S/MIME Cryptographic Signature --]
[-- Type: application/pkcs7-signature, Size: 3990 bytes --]

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH v2] linux-user: Add most IFTUN ioctls
  2020-07-23 23:10 [PATCH v2] linux-user: Add most IFTUN ioctls Shu-Chun Weng
  2020-08-05 23:22 ` Shu-Chun Weng
@ 2020-09-26 16:44 ` Laurent Vivier
  2020-09-28 16:52   ` Shu-Chun Weng
  1 sibling, 1 reply; 5+ messages in thread
From: Laurent Vivier @ 2020-09-26 16:44 UTC (permalink / raw)
  To: Shu-Chun Weng; +Cc: Josh Kunz, riku.voipio, qemu-devel

Le 24/07/2020 à 01:10, Shu-Chun Weng a écrit :
> 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)))

Why is this IOC_RW?

> +  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)

Why is this 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)

You should use TYPE_PTRVOID to allow QEMU_STRACE to display the pointer.
Or implement the function to dump the structure (see STRUCT_termios and
struct_termios_def).

> +  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);

sizeof(*target_filter) vould be more coherent: we lock the target memory
so use the size of the type of the target.

> +    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));

unlock_user(target_filter, arg, 0) as we don't need to copy the value
back to the target.

> +
> +    if (filter->count) {
> +        if (sizeof(*filter) + filter->count * ETH_ALEN > MAX_STRUCT_SIZE) {

Rather than sizeof() use offsetof(struct tun_filter, addr)

> +            return -TARGET_EFAULT;
> +        }
> +
> +        target_addr = lock_user(VERIFY_READ, arg + sizeof(*filter),

Rather than sizeof() use offsetof(struct tun_filter, addr)

> +                                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),

 offsetof(struct tun_filter, addr)

Thanks,
Laurent


^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH v2] linux-user: Add most IFTUN ioctls
  2020-09-26 16:44 ` Laurent Vivier
@ 2020-09-28 16:52   ` Shu-Chun Weng
  0 siblings, 0 replies; 5+ messages in thread
From: Shu-Chun Weng @ 2020-09-28 16:52 UTC (permalink / raw)
  To: Laurent Vivier; +Cc: qemu-devel, Riku Voipio, Josh Kunz


[-- Attachment #1.1: Type: text/plain, Size: 6981 bytes --]

On Sat, Sep 26, 2020 at 9:44 AM Laurent Vivier <laurent@vivier.eu> wrote:

> Le 24/07/2020 à 01:10, Shu-Chun Weng a écrit :
> > 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)))
>
> Why is this IOC_RW?
>

R:
https://github.com/torvalds/linux/blob/a1b8638ba1320e6684aa98233c15255eb803fac7/drivers/net/tun.c#L3010
W:
https://github.com/torvalds/linux/blob/a1b8638ba1320e6684aa98233c15255eb803fac7/drivers/net/tun.c#L3046

More specifically, the call may update ifr->ifr_name:
https://github.com/torvalds/linux/blob/a1b8638ba1320e6684aa98233c15255eb803fac7/drivers/net/tun.c#L2821


>
> > +  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)
>
> Why is this long?
>

Appears to be a bitmask:
https://github.com/torvalds/linux/blob/a1b8638ba1320e6684aa98233c15255eb803fac7/drivers/net/tun.c#L2853


>
> > +  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)
>
> You should use TYPE_PTRVOID to allow QEMU_STRACE to display the pointer.
> Or implement the function to dump the structure (see STRUCT_termios and
> struct_termios_def).
>

Will change to TYPE_PTRVOID. `struct tun_filter` uses flexible arrays (
https://github.com/torvalds/linux/blob/a4d63c3732f1a0c91abcf5b7f32b4ef7dcd82025/include/uapi/linux/if_tun.h#L111)
and can't even be written with custom converters because the structure size
isn't fixed.

IIRC, it can be implemented on top of my other patch which adds flexible
array support to the thunk infrastructure
https://lists.nongnu.org/archive/html/qemu-devel/2020-08/msg01949.html


>
> > +  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);
>
> sizeof(*target_filter) vould be more coherent: we lock the target memory
> so use the size of the type of the target.
>
> > +    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));
>
> unlock_user(target_filter, arg, 0) as we don't need to copy the value
> back to the target.
>
> > +
> > +    if (filter->count) {
> > +        if (sizeof(*filter) + filter->count * ETH_ALEN >
> MAX_STRUCT_SIZE) {
>
> Rather than sizeof() use offsetof(struct tun_filter, addr)
>
> > +            return -TARGET_EFAULT;
> > +        }
> > +
> > +        target_addr = lock_user(VERIFY_READ, arg + sizeof(*filter),
>
> Rather than sizeof() use offsetof(struct tun_filter, addr)
>
> > +                                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),
>
>  offsetof(struct tun_filter, addr)
>

All changes in syscall.c applied. Will send out v3 soon.

Thank you very much!

Shu-Chun


>
> Thanks,
> Laurent
>

[-- Attachment #1.2: Type: text/html, Size: 9855 bytes --]

[-- Attachment #2: S/MIME Cryptographic Signature --]
[-- Type: application/pkcs7-signature, Size: 3990 bytes --]

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2020-09-28 16:54 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-07-23 23:10 [PATCH v2] linux-user: Add most IFTUN ioctls Shu-Chun Weng
2020-08-05 23:22 ` Shu-Chun Weng
2020-09-17  7:24   ` Shu-Chun Weng
2020-09-26 16:44 ` Laurent Vivier
2020-09-28 16:52   ` Shu-Chun Weng

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.