Here tap_ioctl is updated to a user_uintptr_t to make use of CHERI capabilities and a compat_tap_ioctl function is so that when arg is a value and not a pointer, it is handled correctly. --- drivers/net/tap.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-)
diff --git a/drivers/net/tap.c b/drivers/net/tap.c index 9e75ed3f08ce..0bea2a4280c9 100644 --- a/drivers/net/tap.c +++ b/drivers/net/tap.c @@ -986,7 +986,7 @@ static int set_offload(struct tap_queue *q, unsigned long arg) * provide compatibility with generic tun/tap interface */ static long tap_ioctl(struct file *file, unsigned int cmd, - unsigned long arg) + user_uintptr_t arg) { struct tap_queue *q = file->private_data; struct tap_dev *tap; @@ -1134,6 +1134,17 @@ static long tap_ioctl(struct file *file, unsigned int cmd, } }
+#ifdef CONFIG_COMPAT +static long compat_tap_ioctl(struct file *file, unsigned int cmd, + unsigned long arg) +{ + user_uintptr_t cmd_arg = (cmd != TUNSETOFFLOAD) ? + (user_uintptr_t)compat_ptr(arg) : + (user_uintptr_t)arg; + return tap_ioctl(file, cmd, cmd_arg); +} +#endif + static const struct file_operations tap_fops = { .owner = THIS_MODULE, .open = tap_open, @@ -1143,7 +1154,9 @@ static const struct file_operations tap_fops = { .poll = tap_poll, .llseek = no_llseek, .unlocked_ioctl = tap_ioctl, - .compat_ioctl = compat_ptr_ioctl, +#ifdef CONFIG_COMPAT + .compat_ioctl = compat_tap_ioctl, +#endif };
static int tap_get_user_xdp(struct tap_queue *q, struct xdp_buff *xdp)