Register a basic compat ioctl handler (32 vs 64 bit compat)

Simply pass the ioctl on to the normal handler.  If the ioctl
helper macros are used correctly this should be safe as they
will handle the packing/unpacking of the data encoded in the
ioctl command.  And actually, if the caller does not use the
IO* macros at all, and just passes small values, it will probably
be OK as well.  We only get in to trouble if they try and use
the upper 32-bits.  Endianness is not really a concern here, we
we are pretty much assumed they user and kernel will match.
This commit is contained in:
Brian Behlendorf 2009-07-21 10:13:58 -07:00
parent ac95d0974b
commit 78d6de97bd
1 changed files with 17 additions and 3 deletions

View File

@ -54,7 +54,7 @@ out:
} }
static int static int
mod_generic_ioctl(struct inode *ino, struct file *filp, mod_generic_ioctl(struct inode *ino, struct file *file,
unsigned int cmd, unsigned long arg) unsigned int cmd, unsigned long arg)
{ {
struct dev_info *di; struct dev_info *di;
@ -66,11 +66,21 @@ mod_generic_ioctl(struct inode *ino, struct file *filp,
return EINVAL; return EINVAL;
rc = di->di_ops->devo_cb_ops->cb_ioctl(di->di_dev, rc = di->di_ops->devo_cb_ops->cb_ioctl(di->di_dev,
(int)cmd,(intptr_t)arg, (int)cmd, (intptr_t)arg,
flags, cr, &rvalp); flags, cr, &rvalp);
return rc; return rc;
} }
#ifdef CONFIG_COMPAT
/* Compatibility handler for ioctls from 32-bit ELF binaries */
static long
mod_generic_compat_ioctl(struct file *file,
unsigned int cmd, unsigned long arg)
{
return mod_generic_ioctl(file->f_dentry->d_inode, file, cmd, arg);
}
#endif /* CONFIG_COMPAT */
int int
__ddi_create_minor_node(dev_info_t *di, char *name, int spec_type, __ddi_create_minor_node(dev_info_t *di, char *name, int spec_type,
minor_t minor_num, char *node_type, minor_t minor_num, char *node_type,
@ -107,8 +117,12 @@ __ddi_create_minor_node(dev_info_t *di, char *name, int spec_type,
/* Setup the fops to cb_ops mapping */ /* Setup the fops to cb_ops mapping */
fops->owner = mod; fops->owner = mod;
if (cb_ops->cb_ioctl) if (cb_ops->cb_ioctl) {
fops->ioctl = mod_generic_ioctl; fops->ioctl = mod_generic_ioctl;
#ifdef CONFIG_COMPAT
fops->compat_ioctl = mod_generic_compat_ioctl;
#endif
}
#if 0 #if 0
if (cb_ops->cb_open) if (cb_ops->cb_open)