ATM 32-bit ioctl compatibility
Subsystems (3)
PATCH 1/1 ATM 32-bit ioctl compatibility
We lack compat ioctl support through most of the ATM code. This patch deals with most of it, and I can now at least use BR2684 and PPPoATM with 32-bit userspace.
I haven't added a .compat_ioctl method to struct atm_ioctl, because AFAICT none of the current users need any conversion -- so we can just call the ->ioctl() method in every case. I looked at br2684, clip, lec, mpc, pppoatm and atmtcp.
In svc_compat_ioctl() the only mangling which is needed is to change COMPAT_ATM_ADDPARTY to ATM_ADDPARTY. Although it's defined as
_IOW('a', ATMIOC_SPECIAL+4,struct atm_iobuf)
it doesn't actually _take_ a struct atm_iobuf as an argument -- it takes a struct sockaddr_atmsvc, which _is_ the same between 32-bit and 64-bit code, so doesn't need conversion.
Almost all of vcc_ioctl() would have been identical, so I converted that into a core do_vcc_ioctl() function with an 'int compat' argument.
I've done the same with atm_dev_ioctl(), where there _are_ a few differences, but still it's relatively contained and there would otherwise have been a lot of duplication.
I haven't done any of the actual device-specific ioctls, although I've added a compat_ioctl method to struct atmdev_ops.
include/linux/atm.h +14 -3
@@ -231,10 +231,21 @@ static __inline__ int atmpvc_addr_in_use(struct sockaddr_atmpvc addr)*/ struct atmif_sioc { -int number; -int length; -void __user *arg; +int number; +int length; +void __user *arg; }; +#ifdef __KERNEL__ +#ifdef CONFIG_COMPAT +#include <linux/compat.h> +struct compat_atmif_sioc { +int number; +int length; +compat_uptr_t arg; +}; +#endif +#endif +typedef unsigned short atm_backend_t ;#endif
include/linux/atmdev.h +15 -0
@@ -100,6 +100,10 @@ struct atm_dev_stats {/* use backend to make new if */ #define ATM_ADDPARTY _IOW('a', ATMIOC_SPECIAL+4,struct atm_iobuf)/* add party to p2mp call */ +#ifdef CONFIG_COMPAT +/* It actually takes struct sockaddr_atmsvc, not struct atm_iobuf */ +#define COMPAT_ATM_ADDPARTY _IOW('a', ATMIOC_SPECIAL+4,struct compat_atm_iobuf) +#endif #define ATM_DROPPARTY _IOW('a', ATMIOC_SPECIAL+5,int)/* drop party from p2mp call */
@@ -224,6 +228,13 @@ struct atm_cirange {extern struct proc_dir_entry *atm_proc_root;#endif +#ifdef CONFIG_COMPAT +#include <linux/compat.h> +struct compat_atm_iobuf { +int length; +compat_uptr_t buffer; +}; +#endif struct k_atm_aal_stats {#define __HANDLE_ITEM (i) atomic_t i
@@ -379,6 +390,10 @@ struct atmdev_ops { /* only send is required */int (*open)(struct atm_vcc *vcc);void (*close)(struct atm_vcc *vcc);int (*ioctl)(struct atm_dev *dev,unsigned int cmd,void __user *arg); +#ifdef CONFIG_COMPAT +int (*compat_ioctl)(struct atm_dev *dev,unsigned int cmd, +void __user *arg); +#endif int (*getsockopt)(struct atm_vcc *vcc,int level,int optname,void __user *optval,int optlen); int (*setsockopt)(struct atm_vcc *vcc,int level,int optname,
net/atm/common.h +1 -0
@@ -19,6 +19,7 @@ int vcc_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *m, size_t total_len);unsigned int vcc_poll (struct file *file,struct socket *sock,poll_table *wait);int vcc_ioctl (struct socket *sock,unsigned int cmd,unsigned long arg); +int vcc_compat_ioctl (struct socket *sock,unsigned int cmd,unsigned long arg);int vcc_setsockopt (struct socket *sock,int level,int optname,char __user *optval,int optlen); int vcc_getsockopt(struct socket *sock, int level, int optname,
net/atm/ioctl.c +43 -6
89 lines not on this page · raw message
net/atm/pvc.c +3 -0
@@ -113,6 +113,9 @@ static const struct proto_ops pvc_proto_ops = { .getname = pvc_getname, .poll = vcc_poll, .ioctl = vcc_ioctl, +#ifdef CONFIG_COMPAT + .compat_ioctl = vcc_compat_ioctl, +#endif .listen = sock_no_listen, .shutdown = pvc_shutdown, .setsockopt = pvc_setsockopt,
net/atm/resources.c +68 -20
133 lines not on this page · raw message
net/atm/resources.h +1 -1
@@ -13,7 +13,7 @@extern struct list_head atm_devs;extern struct mutex atm_dev_mutex; -int atm_dev_ioctl (unsigned int cmd,void __user *arg); +int atm_dev_ioctl (unsigned int cmd,void __user *arg,int compat);#ifdef CONFIG_PROC_FS
net/atm/svc.c +19 -0
@@ -604,6 +604,22 @@ static int svc_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)return error; } +#ifdef CONFIG_COMPAT +static int svc_compat_ioctl (struct socket *sock,unsigned int cmd,unsigned long arg) +{ +/* The definition of ATM_ADDPARTY uses the size of struct atm_iobuf. +But actually it takes a struct sockaddr_atmsvc, which doesn't need +compat handling. So all we have to do is fix up cmd... */ +if (cmd ==COMPAT_ATM_ADDPARTY ) + cmd =ATM_ADDPARTY ; + +if (cmd ==ATM_ADDPARTY || cmd ==ATM_DROPPARTY ) +return svc_ioctl (sock, cmd, arg); +else +return vcc_compat_ioctl (sock, cmd, arg); +} +#endif /* CONFIG_COMPAT */ +static const struct proto_ops svc_proto_ops = { .family =PF_ATMSVC , .owner =THIS_MODULE ,
@@ -616,6 +632,9 @@ static const struct proto_ops svc_proto_ops = { .getname = svc_getname, .poll = vcc_poll, .ioctl = svc_ioctl, +#ifdef CONFIG_COMPAT + .compat_ioctl = svc_compat_ioctl, +#endif .listen = svc_listen, .shutdown = svc_shutdown, .setsockopt = svc_setsockopt,
Signature · 2 lines
David Woodhouse Open Source Technology Centre [email protected] Intel Corporation
David Miller
maintainerFrom: David Woodhouse <[email protected]>
Date: Wed, 03 Dec 2008 16:00:31 +0000
Quoted 19 lines
We lack compat ioctl support through most of the ATM code. This patch deals with most of it, and I can now at least use BR2684 and PPPoATM with 32-bit userspace.
I haven't added a .compat_ioctl method to struct
atm_ioctl, because AFAICT none of the current users need any conversion -- so we can just call the ->ioctl() method in every case. I looked at br2684, clip, lec, mpc, pppoatm and atmtcp.In
svc_compat_ioctl()the only mangling which is needed is to changeCOMPAT_ATM_ADDPARTYtoATM_ADDPARTY. Although it's defined as
_IOW('a', ATMIOC_SPECIAL+4,struct atm_iobuf)
it doesn't actually _take_ a structatm_iobufas an argument -- it takes a structsockaddr_atmsvc, which _is_ the same between 32-bit and 64-bit code, so doesn't need conversion.Almost all of
vcc_ioctl()would have been identical, so I converted that into a coredo_vcc_ioctl()function with an 'int compat' argument.
Quoted 8 lines
I've done the same with
atm_dev_ioctl(), where there _are_ a few differences, but still it's relatively contained and there would otherwise have been a lot of duplication.I haven't done any of the actual device-specific ioctls, although I've added a
compat_ioctlmethod to structatmdev_ops.Signed-off-by David Woodhouse <[email protected]>
Looks good David, applied to net-next-2.6, thanks!