* [PATCH] aacraid 32/64 ioctl support (update)
@ 2004-06-16 15:52 Mark Haverkamp
2004-06-16 16:01 ` Christoph Hellwig
0 siblings, 1 reply; 9+ messages in thread
From: Mark Haverkamp @ 2004-06-16 15:52 UTC (permalink / raw)
To: James Bottomley, linux-scsi; +Cc: Mark Salyzyn
Here is an updated patch from Adaptec that adds support for 32 bit apps
access to ioctl with 64 bit kernel. Built against 2.6.7
This patch fixes a problem that existed in my previous submission.
Signed-off-by: Mark Haverkamp <markh@osdl.org>
===== drivers/scsi/aacraid/aacraid.h 1.14 vs edited =====
--- 1.14/drivers/scsi/aacraid/aacraid.h 2004-05-10 13:02:37 -07:00
+++ edited/drivers/scsi/aacraid/aacraid.h 2004-06-04 13:44:08 -07:00
@@ -650,6 +650,7 @@
struct aac_fib_context {
s16 type; // used for verification of structure
s16 size;
+ u32 unique; // unique value representing this context
ulong jiffies; // used for cleanup - dmb changed to ulong
struct list_head next; // used to link context's into a linked list
struct semaphore wait_sem; // this is used to wait for the next fib to arrive.
@@ -1226,11 +1227,11 @@
u32 disknum;
u32 cnum;
};
-
+
struct fib_ioctl
{
- char *fibctx;
- int wait;
+ u32 fibctx;
+ s32 wait;
char *fib;
};
===== drivers/scsi/aacraid/commctrl.c 1.5 vs edited =====
--- 1.5/drivers/scsi/aacraid/commctrl.c 2004-05-10 13:22:40 -07:00
+++ edited/drivers/scsi/aacraid/commctrl.c 2004-06-15 14:59:29 -07:00
@@ -92,11 +92,12 @@
*/
kfib->header.XferState = 0;
} else {
- if (fib_send(kfib->header.Command, fibptr, le32_to_cpu(kfib->header.Size) , FsaNormal,
- 1, 1, NULL, NULL) != 0)
- {
+ int retval = fib_send(kfib->header.Command, fibptr,
+ le32_to_cpu(kfib->header.Size) , FsaNormal,
+ 1, 1, NULL, NULL);
+ if (retval != 0) {
fib_free(fibptr);
- return -EINVAL;
+ return retval;
}
if (fib_complete(fibptr) != 0) {
fib_free(fibptr);
@@ -130,14 +131,24 @@
{
struct aac_fib_context * fibctx;
int status;
- unsigned long flags;
fibctx = kmalloc(sizeof(struct aac_fib_context), GFP_KERNEL);
if (fibctx == NULL) {
status = -ENOMEM;
} else {
+ unsigned long flags;
+ struct list_head * entry;
+ struct aac_fib_context * context;
+
fibctx->type = FSAFS_NTC_GET_ADAPTER_FIB_CONTEXT;
fibctx->size = sizeof(struct aac_fib_context);
+ /*
+ * Yes yes, I know this could be an index, but we have a
+ * better guarantee of uniqueness for the locked loop below.
+ * Without the aid of a persistent history, this also helps
+ * reduce the chance that the opaque context would be reused.
+ */
+ fibctx->unique = (u32)((ulong)fibctx & 0xFFFFFFFF);
/*
* Initialize the mutex used to wait for the next AIF.
*/
@@ -155,9 +166,22 @@
* AdapterFibContext list.
*/
spin_lock_irqsave(&dev->fib_lock, flags);
+ /* Ensure that we have a unique identifier */
+ entry = dev->fib_list.next;
+ while(entry != &dev->fib_list) {
+ context = list_entry(entry, struct aac_fib_context, next);
+ if (context->unique == fibctx->unique) {
+ /* Not unique (32 bits) */
+ fibctx->unique++;
+ entry = dev->fib_list.next;
+ } else {
+ entry = entry->next;
+ }
+ }
list_add_tail(&fibctx->next, &dev->fib_list);
spin_unlock_irqrestore(&dev->fib_lock, flags);
- if (copy_to_user(arg, &fibctx, sizeof(struct aac_fib_context *))) {
+ if (copy_to_user(arg, &fibctx->unique,
+ sizeof(fibctx->unique))) {
status = -EFAULT;
} else {
status = 0;
@@ -178,43 +202,44 @@
static int next_getadapter_fib(struct aac_dev * dev, void *arg)
{
struct fib_ioctl f;
- struct aac_fib_context *fibctx, *aifcp;
struct fib *fib;
+ struct aac_fib_context *fibctx;
int status;
struct list_head * entry;
- int found;
unsigned long flags;
if(copy_from_user((void *)&f, arg, sizeof(struct fib_ioctl)))
return -EFAULT;
/*
- * Extract the AdapterFibContext from the Input parameters.
- */
- fibctx = (struct aac_fib_context *) f.fibctx;
-
- /*
* Verify that the HANDLE passed in was a valid AdapterFibContext
*
* Search the list of AdapterFibContext addresses on the adapter
* to be sure this is a valid address
*/
- found = 0;
entry = dev->fib_list.next;
+ fibctx = NULL;
while(entry != &dev->fib_list) {
- aifcp = list_entry(entry, struct aac_fib_context, next);
- if(fibctx == aifcp) { /* We found a winner */
- found = 1;
+ fibctx = list_entry(entry, struct aac_fib_context, next);
+ /*
+ * Extract the AdapterFibContext from the Input parameters.
+ */
+ if(fibctx->unique == f.fibctx) { /* We found a winner */
break;
}
entry = entry->next;
+ fibctx = NULL;
}
- if (found == 0)
+ if (!fibctx) {
+ dprintk ((KERN_INFO "Fib Context not found\n"));
return -EINVAL;
+ }
if((fibctx->type != FSAFS_NTC_GET_ADAPTER_FIB_CONTEXT) ||
- (fibctx->size != sizeof(struct aac_fib_context)))
+ (fibctx->size != sizeof(struct aac_fib_context))) {
+ dprintk ((KERN_INFO "Fib Context corrupt?\n"));
return -EINVAL;
+ }
status = 0;
spin_lock_irqsave(&dev->fib_lock, flags);
/*
@@ -309,16 +334,10 @@
static int close_getadapter_fib(struct aac_dev * dev, void *arg)
{
- struct aac_fib_context *fibctx, *aifcp;
+ struct aac_fib_context *fibctx;
int status;
unsigned long flags;
struct list_head * entry;
- int found;
-
- /*
- * Extract the fibctx from the input parameters
- */
- fibctx = arg;
/*
* Verify that the HANDLE passed in was a valid AdapterFibContext
@@ -327,19 +346,23 @@
* to be sure this is a valid address
*/
- found = 0;
entry = dev->fib_list.next;
+ fibctx = NULL;
while(entry != &dev->fib_list) {
- aifcp = list_entry(entry, struct aac_fib_context, next);
- if(fibctx == aifcp) { /* We found a winner */
- found = 1;
+ fibctx = list_entry(entry, struct aac_fib_context, next);
+ /*
+ * Extract the fibctx from the input parameters
+ */
+ if(fibctx->unique == (u32)(unsigned long)arg) {
+ /* We found a winner */
break;
}
entry = entry->next;
+ fibctx = NULL;
}
- if(found == 0)
+ if (!fibctx)
return 0; /* Already gone */
if((fibctx->type != FSAFS_NTC_GET_ADAPTER_FIB_CONTEXT) ||
@@ -356,8 +379,9 @@
* @dev: adapter
* @arg: ioctl arguments
*
- * This routine returns the firmware version.
- * Under Linux, there have been no version incompatibilities, so this is simple!
+ * This routine returns the driver version.
+ * Under Linux, there have been no version incompatibilities, so this is
+ * simple!
*/
static int check_revision(struct aac_dev *dev, void *arg)
@@ -419,6 +443,11 @@
goto cleanup;
}
+ if (fibsize > FIB_DATA_SIZE_IN_BYTES) {
+ rcode = -EINVAL;
+ goto cleanup;
+ }
+
if(copy_from_user(srbcmd, user_srb,fibsize)){
printk(KERN_DEBUG"aacraid: Could not copy srb from user\n");
rcode = -EFAULT;
@@ -438,7 +467,7 @@
srbcmd->retry_limit =cpu_to_le32(0); // Obsolete parameter
srbcmd->cdb_size = cpu_to_le32(srbcmd->cdb_size);
- switch(srbcmd->flags){
+ switch (srbcmd->flags & (SRB_DataIn | SRB_DataOut)) {
case SRB_DataOut:
data_dir = DMA_TO_DEVICE;
break;
@@ -451,17 +480,26 @@
default:
data_dir = DMA_NONE;
}
- if( dev->pae_support ==1 ) {
+ if(dev->pae_support == 1) {
struct sgmap64* psg = (struct sgmap64*)&srbcmd->sg;
byte_count = 0;
- // This should also catch if user used the 32 bit sgmap
- actual_fibsize = sizeof (struct aac_srb) + (((srbcmd->sg.count & 0xff) - 1) * sizeof (struct sgentry64));
+ /*
+ * This should also catch if user used the 32 bit sgmap
+ */
+ actual_fibsize = sizeof (struct aac_srb) -
+ sizeof(struct sgentry) + ((srbcmd->sg.count & 0xff) *
+ sizeof (struct sgentry64));
if(actual_fibsize != fibsize){ // User made a mistake - should not continue
printk(KERN_DEBUG"aacraid: Bad Size specified in Raw SRB command\n");
rcode = -EINVAL;
goto cleanup;
}
+ if ((data_dir == DMA_NONE) && psg->count) {
+ printk(KERN_DEBUG"aacraid: SG with no direction specified in Raw SRB command\n");
+ rcode = -EINVAL;
+ goto cleanup;
+ }
for (i = 0; i < psg->count; i++) {
dma_addr_t addr;
@@ -503,6 +541,11 @@
actual_fibsize = sizeof (struct aac_srb) + (((srbcmd->sg.count & 0xff) - 1) * sizeof (struct sgentry));
if(actual_fibsize != fibsize){ // User made a mistake - should not continue
printk(KERN_DEBUG"aacraid: Bad Size specified in Raw SRB command\n");
+ rcode = -EINVAL;
+ goto cleanup;
+ }
+ if ((data_dir == DMA_NONE) && psg->count) {
+ printk(KERN_DEBUG"aacraid: SG with no direction specified in Raw SRB command\n");
rcode = -EINVAL;
goto cleanup;
}
===== drivers/scsi/aacraid/linit.c 1.29 vs edited =====
--- 1.29/drivers/scsi/aacraid/linit.c 2004-05-10 04:42:31 -07:00
+++ edited/drivers/scsi/aacraid/linit.c 2004-06-15 15:39:05 -07:00
@@ -42,6 +42,7 @@
#include <linux/slab.h>
#include <linux/spinlock.h>
#include <asm/semaphore.h>
+#include <linux/syscalls.h>
#include <scsi/scsi.h>
#include <scsi/scsi_cmnd.h>
@@ -50,6 +51,9 @@
#include <scsi/scsi_tcq.h>
#include <scsi/scsicam.h>
#include <scsi/scsi_eh.h>
+#if (defined(CONFIG_COMPAT))
+# include <linux/ioctl32.h>
+#endif
#include "aacraid.h"
@@ -168,6 +172,30 @@
{ aac_rx_init, "aacraid", "ADAPTEC ", "ASR-2025SA ", 1 }, /* ASR-2025SA (ZCR DIMM SATA) */
};
+#if (defined(CONFIG_COMPAT))
+/*
+ * Promote 32 bit apps that call get_next_adapter_fib_ioctl to 64 bit version
+ */
+int aac_get_next_adapter_fib_ioctl(unsigned int fd, unsigned int cmd,
+ unsigned long arg, struct file *file)
+{
+ struct fib_ioctl f;
+ mm_segment_t fs;
+ int retval;
+
+ memset (&f, 0, sizeof(f));
+ if(copy_from_user((void *)&f, (void *)arg,
+ sizeof(struct fib_ioctl) - sizeof(u32)))
+ return -EFAULT;
+ fs = get_fs();
+ set_fs(get_ds());
+ retval = sys_ioctl(fd, cmd, (unsigned long)&f);
+ set_fs(fs);
+ return retval;
+}
+#endif
+
+
/**
* aac_queuecommand - queue a SCSI command
* @cmd: SCSI command to queue
@@ -643,12 +671,39 @@
printk(KERN_WARNING
"aacraid: unable to register \"aac\" device.\n");
}
+# if (defined(CONFIG_COMPAT))
+ register_ioctl32_conversion(FSACTL_MINIPORT_REV_CHECK, NULL);
+ register_ioctl32_conversion(FSACTL_SENDFIB, NULL);
+ register_ioctl32_conversion(FSACTL_OPEN_GET_ADAPTER_FIB, NULL);
+ register_ioctl32_conversion(FSACTL_GET_NEXT_ADAPTER_FIB,
+ aac_get_next_adapter_fib_ioctl);
+ register_ioctl32_conversion(FSACTL_CLOSE_GET_ADAPTER_FIB, NULL);
+ register_ioctl32_conversion(FSACTL_SEND_RAW_SRB, NULL);
+ register_ioctl32_conversion(FSACTL_GET_PCI_INFO, NULL);
+ register_ioctl32_conversion(FSACTL_QUERY_DISK, NULL);
+ register_ioctl32_conversion(FSACTL_DELETE_DISK, NULL);
+ register_ioctl32_conversion(FSACTL_FORCE_DELETE_DISK, NULL);
+ register_ioctl32_conversion(2131, NULL);
+# endif
return 0;
}
static void __exit aac_exit(void)
{
+# if (defined(CONFIG_COMPAT))
+ unregister_ioctl32_conversion(FSACTL_MINIPORT_REV_CHECK);
+ unregister_ioctl32_conversion(FSACTL_SENDFIB);
+ unregister_ioctl32_conversion(FSACTL_OPEN_GET_ADAPTER_FIB);
+ unregister_ioctl32_conversion(FSACTL_GET_NEXT_ADAPTER_FIB);
+ unregister_ioctl32_conversion(FSACTL_CLOSE_GET_ADAPTER_FIB);
+ unregister_ioctl32_conversion(FSACTL_SEND_RAW_SRB);
+ unregister_ioctl32_conversion(FSACTL_GET_PCI_INFO);
+ unregister_ioctl32_conversion(FSACTL_QUERY_DISK);
+ unregister_ioctl32_conversion(FSACTL_DELETE_DISK);
+ unregister_ioctl32_conversion(FSACTL_FORCE_DELETE_DISK);
+ unregister_ioctl32_conversion(2131);
+# endif
unregister_chrdev(aac_cfg_major, "aac");
pci_unregister_driver(&aac_pci_driver);
}
--
Mark Haverkamp <markh@osdl.org>
^ permalink raw reply [flat|nested] 9+ messages in thread* Re: [PATCH] aacraid 32/64 ioctl support (update) 2004-06-16 15:52 [PATCH] aacraid 32/64 ioctl support (update) Mark Haverkamp @ 2004-06-16 16:01 ` Christoph Hellwig 2004-06-16 16:02 ` Christoph Hellwig 0 siblings, 1 reply; 9+ messages in thread From: Christoph Hellwig @ 2004-06-16 16:01 UTC (permalink / raw) To: Mark Haverkamp; +Cc: James Bottomley, linux-scsi, Mark Salyzyn On Wed, Jun 16, 2004 at 08:52:17AM -0700, Mark Haverkamp wrote: > + if (retval != 0) { the != 0 is superflous. > - if( dev->pae_support ==1 ) { > + if(dev->pae_support == 1) { if you're fixing up the strange style in the driver please go to the right indentation directly (space before opening brace) > +++ edited/drivers/scsi/aacraid/linit.c 2004-06-15 15:39:05 -07:00 > @@ -42,6 +42,7 @@ > #include <linux/slab.h> > #include <linux/spinlock.h> > #include <asm/semaphore.h> > +#include <linux/syscalls.h> <linux/*.h> before <asm/*.h> please > #include <scsi/scsi_tcq.h> > #include <scsi/scsicam.h> > #include <scsi/scsi_eh.h> > +#if (defined(CONFIG_COMPAT)) > +# include <linux/ioctl32.h> > +#endif ioctl32.h should be fine to include even without CONFIG_COMPAT > > #include "aacraid.h" > > @@ -168,6 +172,30 @@ > { aac_rx_init, "aacraid", "ADAPTEC ", "ASR-2025SA ", 1 }, /* ASR-2025SA (ZCR DIMM SATA) */ > }; > > +#if (defined(CONFIG_COMPAT)) just ifdef instead of all those braces. > +/* > + * Promote 32 bit apps that call get_next_adapter_fib_ioctl to 64 bit version > + */ > +int aac_get_next_adapter_fib_ioctl(unsigned int fd, unsigned int cmd, > + unsigned long arg, struct file *file) > +{ > + struct fib_ioctl f; > + mm_segment_t fs; > + int retval; > + > + memset (&f, 0, sizeof(f)); > + if(copy_from_user((void *)&f, (void *)arg, > + sizeof(struct fib_ioctl) - sizeof(u32))) > + return -EFAULT; > + fs = get_fs(); > + set_fs(get_ds()); > + retval = sys_ioctl(fd, cmd, (unsigned long)&f); > + set_fs(fs); > + return retval; use compat_alloc_userspace here. > @@ -643,12 +671,39 @@ > printk(KERN_WARNING > "aacraid: unable to register \"aac\" device.\n"); > } > +# if (defined(CONFIG_COMPAT)) > + register_ioctl32_conversion(FSACTL_MINIPORT_REV_CHECK, NULL); > + register_ioctl32_conversion(FSACTL_SENDFIB, NULL); > + register_ioctl32_conversion(FSACTL_OPEN_GET_ADAPTER_FIB, NULL); > + register_ioctl32_conversion(FSACTL_GET_NEXT_ADAPTER_FIB, > + aac_get_next_adapter_fib_ioctl); > + register_ioctl32_conversion(FSACTL_CLOSE_GET_ADAPTER_FIB, NULL); > + register_ioctl32_conversion(FSACTL_SEND_RAW_SRB, NULL); > + register_ioctl32_conversion(FSACTL_GET_PCI_INFO, NULL); > + register_ioctl32_conversion(FSACTL_QUERY_DISK, NULL); > + register_ioctl32_conversion(FSACTL_DELETE_DISK, NULL); > + register_ioctl32_conversion(FSACTL_FORCE_DELETE_DISK, NULL); > + register_ioctl32_conversion(2131, NULL); > +# endif #ifdef please and no additional indentation inside the ifdef please. > static void __exit aac_exit(void) > { > +# if (defined(CONFIG_COMPAT)) > + unregister_ioctl32_conversion(FSACTL_MINIPORT_REV_CHECK); > + unregister_ioctl32_conversion(FSACTL_SENDFIB); > + unregister_ioctl32_conversion(FSACTL_OPEN_GET_ADAPTER_FIB); > + unregister_ioctl32_conversion(FSACTL_GET_NEXT_ADAPTER_FIB); > + unregister_ioctl32_conversion(FSACTL_CLOSE_GET_ADAPTER_FIB); > + unregister_ioctl32_conversion(FSACTL_SEND_RAW_SRB); > + unregister_ioctl32_conversion(FSACTL_GET_PCI_INFO); > + unregister_ioctl32_conversion(FSACTL_QUERY_DISK); > + unregister_ioctl32_conversion(FSACTL_DELETE_DISK); > + unregister_ioctl32_conversion(FSACTL_FORCE_DELETE_DISK); > + unregister_ioctl32_conversion(2131); > +# endif dito. ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH] aacraid 32/64 ioctl support (update) 2004-06-16 16:01 ` Christoph Hellwig @ 2004-06-16 16:02 ` Christoph Hellwig 2004-06-16 17:12 ` Mark Haverkamp 0 siblings, 1 reply; 9+ messages in thread From: Christoph Hellwig @ 2004-06-16 16:02 UTC (permalink / raw) To: Mark Haverkamp; +Cc: James Bottomley, linux-scsi, Mark Salyzyn On Wed, Jun 16, 2004 at 05:01:07PM +0100, Christoph Hellwig wrote: > > + register_ioctl32_conversion(2131, NULL); > > +# endif > > #ifdef please and no additional indentation inside the ifdef please. btw, what's ioctl2131? It doesn't seem to be implemented, so no need to translate it. ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH] aacraid 32/64 ioctl support (update) 2004-06-16 16:02 ` Christoph Hellwig @ 2004-06-16 17:12 ` Mark Haverkamp 2004-06-16 17:19 ` Christoph Hellwig 0 siblings, 1 reply; 9+ messages in thread From: Mark Haverkamp @ 2004-06-16 17:12 UTC (permalink / raw) To: Christoph Hellwig, James Bottomley; +Cc: linux-scsi, Mark Salyzyn On Wed, 2004-06-16 at 09:02, Christoph Hellwig wrote: > On Wed, Jun 16, 2004 at 05:01:07PM +0100, Christoph Hellwig wrote: > > > + register_ioctl32_conversion(2131, NULL); > > > +# endif > > > > #ifdef please and no additional indentation inside the ifdef please. > > btw, what's ioctl2131? It doesn't seem to be implemented, so no need to translate it. Christoph, I think that I have addressed all of your comments in this patch. removed != 0 fixed indentation fixed include order fixed ifdefs used compat_alloc_user_space I checked, and 2131 is implemented in aachba.c and looks like it gets container info. --- James, Here is the updated patch. ===== drivers/scsi/aacraid/aacraid.h 1.14 vs edited ===== --- 1.14/drivers/scsi/aacraid/aacraid.h 2004-05-10 13:02:37 -07:00 +++ edited/drivers/scsi/aacraid/aacraid.h 2004-06-04 13:44:08 -07:00 @@ -650,6 +650,7 @@ struct aac_fib_context { s16 type; // used for verification of structure s16 size; + u32 unique; // unique value representing this context ulong jiffies; // used for cleanup - dmb changed to ulong struct list_head next; // used to link context's into a linked list struct semaphore wait_sem; // this is used to wait for the next fib to arrive. @@ -1226,11 +1227,11 @@ u32 disknum; u32 cnum; }; - + struct fib_ioctl { - char *fibctx; - int wait; + u32 fibctx; + s32 wait; char *fib; }; ===== drivers/scsi/aacraid/commctrl.c 1.5 vs edited ===== --- 1.5/drivers/scsi/aacraid/commctrl.c 2004-05-10 13:22:40 -07:00 +++ edited/drivers/scsi/aacraid/commctrl.c 2004-06-16 10:05:11 -07:00 @@ -92,11 +92,12 @@ */ kfib->header.XferState = 0; } else { - if (fib_send(kfib->header.Command, fibptr, le32_to_cpu(kfib->header.Size) , FsaNormal, - 1, 1, NULL, NULL) != 0) - { + int retval = fib_send(kfib->header.Command, fibptr, + le32_to_cpu(kfib->header.Size) , FsaNormal, + 1, 1, NULL, NULL); + if (retval) { fib_free(fibptr); - return -EINVAL; + return retval; } if (fib_complete(fibptr) != 0) { fib_free(fibptr); @@ -130,14 +131,24 @@ { struct aac_fib_context * fibctx; int status; - unsigned long flags; fibctx = kmalloc(sizeof(struct aac_fib_context), GFP_KERNEL); if (fibctx == NULL) { status = -ENOMEM; } else { + unsigned long flags; + struct list_head * entry; + struct aac_fib_context * context; + fibctx->type = FSAFS_NTC_GET_ADAPTER_FIB_CONTEXT; fibctx->size = sizeof(struct aac_fib_context); + /* + * Yes yes, I know this could be an index, but we have a + * better guarantee of uniqueness for the locked loop below. + * Without the aid of a persistent history, this also helps + * reduce the chance that the opaque context would be reused. + */ + fibctx->unique = (u32)((ulong)fibctx & 0xFFFFFFFF); /* * Initialize the mutex used to wait for the next AIF. */ @@ -155,9 +166,22 @@ * AdapterFibContext list. */ spin_lock_irqsave(&dev->fib_lock, flags); + /* Ensure that we have a unique identifier */ + entry = dev->fib_list.next; + while (entry != &dev->fib_list) { + context = list_entry(entry, struct aac_fib_context, next); + if (context->unique == fibctx->unique) { + /* Not unique (32 bits) */ + fibctx->unique++; + entry = dev->fib_list.next; + } else { + entry = entry->next; + } + } list_add_tail(&fibctx->next, &dev->fib_list); spin_unlock_irqrestore(&dev->fib_lock, flags); - if (copy_to_user(arg, &fibctx, sizeof(struct aac_fib_context *))) { + if (copy_to_user(arg, &fibctx->unique, + sizeof(fibctx->unique))) { status = -EFAULT; } else { status = 0; @@ -178,43 +202,44 @@ static int next_getadapter_fib(struct aac_dev * dev, void *arg) { struct fib_ioctl f; - struct aac_fib_context *fibctx, *aifcp; struct fib *fib; + struct aac_fib_context *fibctx; int status; struct list_head * entry; - int found; unsigned long flags; if(copy_from_user((void *)&f, arg, sizeof(struct fib_ioctl))) return -EFAULT; /* - * Extract the AdapterFibContext from the Input parameters. - */ - fibctx = (struct aac_fib_context *) f.fibctx; - - /* * Verify that the HANDLE passed in was a valid AdapterFibContext * * Search the list of AdapterFibContext addresses on the adapter * to be sure this is a valid address */ - found = 0; entry = dev->fib_list.next; + fibctx = NULL; - while(entry != &dev->fib_list) { - aifcp = list_entry(entry, struct aac_fib_context, next); - if(fibctx == aifcp) { /* We found a winner */ - found = 1; + while (entry != &dev->fib_list) { + fibctx = list_entry(entry, struct aac_fib_context, next); + /* + * Extract the AdapterFibContext from the Input parameters. + */ + if (fibctx->unique == f.fibctx) { /* We found a winner */ break; } entry = entry->next; + fibctx = NULL; } - if (found == 0) + if (!fibctx) { + dprintk ((KERN_INFO "Fib Context not found\n")); return -EINVAL; + } if((fibctx->type != FSAFS_NTC_GET_ADAPTER_FIB_CONTEXT) || - (fibctx->size != sizeof(struct aac_fib_context))) + (fibctx->size != sizeof(struct aac_fib_context))) { + dprintk ((KERN_INFO "Fib Context corrupt?\n")); return -EINVAL; + } status = 0; spin_lock_irqsave(&dev->fib_lock, flags); /* @@ -309,16 +334,10 @@ static int close_getadapter_fib(struct aac_dev * dev, void *arg) { - struct aac_fib_context *fibctx, *aifcp; + struct aac_fib_context *fibctx; int status; unsigned long flags; struct list_head * entry; - int found; - - /* - * Extract the fibctx from the input parameters - */ - fibctx = arg; /* * Verify that the HANDLE passed in was a valid AdapterFibContext @@ -327,19 +346,23 @@ * to be sure this is a valid address */ - found = 0; entry = dev->fib_list.next; + fibctx = NULL; while(entry != &dev->fib_list) { - aifcp = list_entry(entry, struct aac_fib_context, next); - if(fibctx == aifcp) { /* We found a winner */ - found = 1; + fibctx = list_entry(entry, struct aac_fib_context, next); + /* + * Extract the fibctx from the input parameters + */ + if (fibctx->unique == (u32)(unsigned long)arg) { + /* We found a winner */ break; } entry = entry->next; + fibctx = NULL; } - if(found == 0) + if (!fibctx) return 0; /* Already gone */ if((fibctx->type != FSAFS_NTC_GET_ADAPTER_FIB_CONTEXT) || @@ -356,8 +379,9 @@ * @dev: adapter * @arg: ioctl arguments * - * This routine returns the firmware version. - * Under Linux, there have been no version incompatibilities, so this is simple! + * This routine returns the driver version. + * Under Linux, there have been no version incompatibilities, so this is + * simple! */ static int check_revision(struct aac_dev *dev, void *arg) @@ -419,6 +443,11 @@ goto cleanup; } + if (fibsize > FIB_DATA_SIZE_IN_BYTES) { + rcode = -EINVAL; + goto cleanup; + } + if(copy_from_user(srbcmd, user_srb,fibsize)){ printk(KERN_DEBUG"aacraid: Could not copy srb from user\n"); rcode = -EFAULT; @@ -438,7 +467,7 @@ srbcmd->retry_limit =cpu_to_le32(0); // Obsolete parameter srbcmd->cdb_size = cpu_to_le32(srbcmd->cdb_size); - switch(srbcmd->flags){ + switch (srbcmd->flags & (SRB_DataIn | SRB_DataOut)) { case SRB_DataOut: data_dir = DMA_TO_DEVICE; break; @@ -451,17 +480,26 @@ default: data_dir = DMA_NONE; } - if( dev->pae_support ==1 ) { + if (dev->pae_support == 1) { struct sgmap64* psg = (struct sgmap64*)&srbcmd->sg; byte_count = 0; - // This should also catch if user used the 32 bit sgmap - actual_fibsize = sizeof (struct aac_srb) + (((srbcmd->sg.count & 0xff) - 1) * sizeof (struct sgentry64)); + /* + * This should also catch if user used the 32 bit sgmap + */ + actual_fibsize = sizeof (struct aac_srb) - + sizeof(struct sgentry) + ((srbcmd->sg.count & 0xff) * + sizeof (struct sgentry64)); if(actual_fibsize != fibsize){ // User made a mistake - should not continue printk(KERN_DEBUG"aacraid: Bad Size specified in Raw SRB command\n"); rcode = -EINVAL; goto cleanup; } + if ((data_dir == DMA_NONE) && psg->count) { + printk(KERN_DEBUG"aacraid: SG with no direction specified in Raw SRB command\n"); + rcode = -EINVAL; + goto cleanup; + } for (i = 0; i < psg->count; i++) { dma_addr_t addr; @@ -503,6 +541,11 @@ actual_fibsize = sizeof (struct aac_srb) + (((srbcmd->sg.count & 0xff) - 1) * sizeof (struct sgentry)); if(actual_fibsize != fibsize){ // User made a mistake - should not continue printk(KERN_DEBUG"aacraid: Bad Size specified in Raw SRB command\n"); + rcode = -EINVAL; + goto cleanup; + } + if ((data_dir == DMA_NONE) && psg->count) { + printk(KERN_DEBUG"aacraid: SG with no direction specified in Raw SRB command\n"); rcode = -EINVAL; goto cleanup; } ===== drivers/scsi/aacraid/linit.c 1.29 vs edited ===== --- 1.29/drivers/scsi/aacraid/linit.c 2004-05-10 04:42:31 -07:00 +++ edited/drivers/scsi/aacraid/linit.c 2004-06-16 10:05:29 -07:00 @@ -31,6 +31,7 @@ #define AAC_DRIVER_BUILD_DATE __DATE__ #define AAC_DRIVERNAME "aacraid" +#include <linux/compat.h> #include <linux/blkdev.h> #include <linux/completion.h> #include <linux/init.h> @@ -41,6 +42,8 @@ #include <linux/pci.h> #include <linux/slab.h> #include <linux/spinlock.h> +#include <linux/syscalls.h> +#include <linux/ioctl32.h> #include <asm/semaphore.h> #include <scsi/scsi.h> @@ -168,6 +171,27 @@ { aac_rx_init, "aacraid", "ADAPTEC ", "ASR-2025SA ", 1 }, /* ASR-2025SA (ZCR DIMM SATA) */ }; +#ifdef CONFIG_COMPAT +/* + * Promote 32 bit apps that call get_next_adapter_fib_ioctl to 64 bit version + */ +int aac_get_next_adapter_fib_ioctl(unsigned int fd, unsigned int cmd, + unsigned long arg, struct file *file) +{ + struct fib_ioctl *f; + int retval; + + f = compat_alloc_user_space(sizeof(*f)); + memset (f, 0, sizeof(*f)); + if (copy_from_user((void *)f, (void *)arg, + sizeof(struct fib_ioctl) - sizeof(u32))) + return -EFAULT; + retval = sys_ioctl(fd, cmd, (unsigned long)f); + return retval; +} +#endif + + /** * aac_queuecommand - queue a SCSI command * @cmd: SCSI command to queue @@ -643,12 +667,39 @@ printk(KERN_WARNING "aacraid: unable to register \"aac\" device.\n"); } +#ifdef CONFIG_COMPAT + register_ioctl32_conversion(FSACTL_MINIPORT_REV_CHECK, NULL); + register_ioctl32_conversion(FSACTL_SENDFIB, NULL); + register_ioctl32_conversion(FSACTL_OPEN_GET_ADAPTER_FIB, NULL); + register_ioctl32_conversion(FSACTL_GET_NEXT_ADAPTER_FIB, + aac_get_next_adapter_fib_ioctl); + register_ioctl32_conversion(FSACTL_CLOSE_GET_ADAPTER_FIB, NULL); + register_ioctl32_conversion(FSACTL_SEND_RAW_SRB, NULL); + register_ioctl32_conversion(FSACTL_GET_PCI_INFO, NULL); + register_ioctl32_conversion(FSACTL_QUERY_DISK, NULL); + register_ioctl32_conversion(FSACTL_DELETE_DISK, NULL); + register_ioctl32_conversion(FSACTL_FORCE_DELETE_DISK, NULL); + register_ioctl32_conversion(2131, NULL); +#endif return 0; } static void __exit aac_exit(void) { +#ifdef CONFIG_COMPAT + unregister_ioctl32_conversion(FSACTL_MINIPORT_REV_CHECK); + unregister_ioctl32_conversion(FSACTL_SENDFIB); + unregister_ioctl32_conversion(FSACTL_OPEN_GET_ADAPTER_FIB); + unregister_ioctl32_conversion(FSACTL_GET_NEXT_ADAPTER_FIB); + unregister_ioctl32_conversion(FSACTL_CLOSE_GET_ADAPTER_FIB); + unregister_ioctl32_conversion(FSACTL_SEND_RAW_SRB); + unregister_ioctl32_conversion(FSACTL_GET_PCI_INFO); + unregister_ioctl32_conversion(FSACTL_QUERY_DISK); + unregister_ioctl32_conversion(FSACTL_DELETE_DISK); + unregister_ioctl32_conversion(FSACTL_FORCE_DELETE_DISK); + unregister_ioctl32_conversion(2131); +#endif unregister_chrdev(aac_cfg_major, "aac"); pci_unregister_driver(&aac_pci_driver); } -- Mark Haverkamp <markh@osdl.org> ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH] aacraid 32/64 ioctl support (update) 2004-06-16 17:12 ` Mark Haverkamp @ 2004-06-16 17:19 ` Christoph Hellwig 2004-06-16 17:51 ` Mark Haverkamp 2004-06-16 18:23 ` Mark Haverkamp 0 siblings, 2 replies; 9+ messages in thread From: Christoph Hellwig @ 2004-06-16 17:19 UTC (permalink / raw) To: Mark Haverkamp Cc: Christoph Hellwig, James Bottomley, linux-scsi, Mark Salyzyn On Wed, Jun 16, 2004 at 10:12:00AM -0700, Mark Haverkamp wrote: > On Wed, 2004-06-16 at 09:02, Christoph Hellwig wrote: > > On Wed, Jun 16, 2004 at 05:01:07PM +0100, Christoph Hellwig wrote: > > > > + register_ioctl32_conversion(2131, NULL); > > > > +# endif > > > > > > #ifdef please and no additional indentation inside the ifdef please. > > > > btw, what's ioctl2131? It doesn't seem to be implemented, so no need to translate it. > > Christoph, > > I think that I have addressed all of your comments in this patch. > > removed != 0 > fixed indentation > fixed include order > fixed ifdefs > used compat_alloc_user_space Although the compat_alloc_user_space implementations I looked at don't fail I think a check for NULL wouldn't hurt. > I checked, and 2131 is implemented in aachba.c and looks like it gets > container info. Hmm, could we please get a symbolic name for that from adaptec? > +#ifdef CONFIG_COMPAT > +/* > + * Promote 32 bit apps that call get_next_adapter_fib_ioctl to 64 bit version > + */ > +int aac_get_next_adapter_fib_ioctl(unsigned int fd, unsigned int cmd, > + unsigned long arg, struct file *file) hmm, should probably be static. > +{ > + struct fib_ioctl *f; > + int retval; > + > + f = compat_alloc_user_space(sizeof(*f)); > + memset (f, 0, sizeof(*f)); superflous space before the opening brace here. > + if (copy_from_user((void *)f, (void *)arg, > + sizeof(struct fib_ioctl) - sizeof(u32))) > + return -EFAULT; > + retval = sys_ioctl(fd, cmd, (unsigned long)f); > + return retval; No need for retval here. ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH] aacraid 32/64 ioctl support (update) 2004-06-16 17:19 ` Christoph Hellwig @ 2004-06-16 17:51 ` Mark Haverkamp 2004-06-16 17:53 ` Christoph Hellwig 2004-06-16 18:23 ` Mark Haverkamp 1 sibling, 1 reply; 9+ messages in thread From: Mark Haverkamp @ 2004-06-16 17:51 UTC (permalink / raw) To: Christoph Hellwig; +Cc: James Bottomley, linux-scsi, Mark Salyzyn On Wed, 2004-06-16 at 10:19, Christoph Hellwig wrote: > On Wed, Jun 16, 2004 at 10:12:00AM -0700, Mark Haverkamp wrote: > > On Wed, 2004-06-16 at 09:02, Christoph Hellwig wrote: > > > On Wed, Jun 16, 2004 at 05:01:07PM +0100, Christoph Hellwig wrote: > > > > > + register_ioctl32_conversion(2131, NULL); > > > > > +# endif > > > > > > > > #ifdef please and no additional indentation inside the ifdef please. > > > > > > btw, what's ioctl2131? It doesn't seem to be implemented, so no need to translate it. > > > > Christoph, > > > > I think that I have addressed all of your comments in this patch. > > > > removed != 0 > > fixed indentation > > fixed include order > > fixed ifdefs > > used compat_alloc_user_space > > Although the compat_alloc_user_space implementations I looked at don't fail I > think a check for NULL wouldn't hurt. The places that I looked where they check the return value use access_ok(). What do you think? > > > I checked, and 2131 is implemented in aachba.c and looks like it gets > > container info. > > Hmm, could we please get a symbolic name for that from adaptec? I sent a note to Mark at adaptec about this. I'll post a revised patch when I hear from him. > > > +#ifdef CONFIG_COMPAT > > +/* > > + * Promote 32 bit apps that call get_next_adapter_fib_ioctl to 64 bit version > > + */ > > +int aac_get_next_adapter_fib_ioctl(unsigned int fd, unsigned int cmd, > > + unsigned long arg, struct file *file) > > hmm, should probably be static. OK > > > +{ > > + struct fib_ioctl *f; > > + int retval; > > + > > + f = compat_alloc_user_space(sizeof(*f)); I just noticed this. Can we use memset on a user pointer? If not, what would be the best way to handle this? > > + memset (f, 0, sizeof(*f)); > > superflous space before the opening brace here. OK > > > + if (copy_from_user((void *)f, (void *)arg, > > + sizeof(struct fib_ioctl) - sizeof(u32))) > > + return -EFAULT; > > + retval = sys_ioctl(fd, cmd, (unsigned long)f); > > + return retval; > > No need for retval here. OK -- Mark Haverkamp <markh@osdl.org> ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH] aacraid 32/64 ioctl support (update) 2004-06-16 17:51 ` Mark Haverkamp @ 2004-06-16 17:53 ` Christoph Hellwig 2004-06-16 17:52 ` David S. Miller 0 siblings, 1 reply; 9+ messages in thread From: Christoph Hellwig @ 2004-06-16 17:53 UTC (permalink / raw) To: Mark Haverkamp Cc: James Bottomley, linux-scsi, Mark Salyzyn, linux-arch, linux-kernel > > Although the compat_alloc_user_space implementations I looked at don't fail I > > think a check for NULL wouldn't hurt. > > The places that I looked where they check the return value use > access_ok(). What do you think? > > > + f = compat_alloc_user_space(sizeof(*f)); > > I just noticed this. Can we use memset on a user pointer? If not, what > would be the best way to handle this? Good question. Maybe the architecture-folks know an answer? ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH] aacraid 32/64 ioctl support (update) 2004-06-16 17:53 ` Christoph Hellwig @ 2004-06-16 17:52 ` David S. Miller 0 siblings, 0 replies; 9+ messages in thread From: David S. Miller @ 2004-06-16 17:52 UTC (permalink / raw) To: Christoph Hellwig Cc: markh, James.Bottomley, linux-scsi, mark_salyzyn, linux-arch, linux-kernel On Wed, 16 Jun 2004 18:53:25 +0100 Christoph Hellwig <hch@infradead.org> wrote: > > I just noticed this. Can we use memset on a user pointer? If not, what > > would be the best way to handle this? > > > Good question. Maybe the architecture-folks know an answer? Use clear_user() ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH] aacraid 32/64 ioctl support (update) 2004-06-16 17:19 ` Christoph Hellwig 2004-06-16 17:51 ` Mark Haverkamp @ 2004-06-16 18:23 ` Mark Haverkamp 1 sibling, 0 replies; 9+ messages in thread From: Mark Haverkamp @ 2004-06-16 18:23 UTC (permalink / raw) To: Christoph Hellwig; +Cc: James Bottomley, linux-scsi, Mark Salyzyn Christoph, James, Fixed comment items: check return value of compat_alloc_user_space with access_ok Got a name for 2131 aac_get_next... is static replaced memset with clear_user hopefully got all the '(' stuff this time removed retval ===== drivers/scsi/aacraid/aachba.c 1.22 vs edited ===== --- 1.22/drivers/scsi/aacraid/aachba.c 2004-01-10 16:21:26 -08:00 +++ edited/drivers/scsi/aacraid/aachba.c 2004-06-16 10:54:24 -07:00 @@ -1197,7 +1197,7 @@ return delete_disk(dev, arg); case FSACTL_FORCE_DELETE_DISK: return force_delete_disk(dev, arg); - case 2131: + case FSACTL_GET_CONTAINERS: return aac_get_containers(dev); default: return -ENOTTY; ===== drivers/scsi/aacraid/aacraid.h 1.14 vs edited ===== --- 1.14/drivers/scsi/aacraid/aacraid.h 2004-05-10 13:02:37 -07:00 +++ edited/drivers/scsi/aacraid/aacraid.h 2004-06-16 10:55:44 -07:00 @@ -650,6 +650,7 @@ struct aac_fib_context { s16 type; // used for verification of structure s16 size; + u32 unique; // unique value representing this context ulong jiffies; // used for cleanup - dmb changed to ulong struct list_head next; // used to link context's into a linked list struct semaphore wait_sem; // this is used to wait for the next fib to arrive. @@ -1226,11 +1227,11 @@ u32 disknum; u32 cnum; }; - + struct fib_ioctl { - char *fibctx; - int wait; + u32 fibctx; + s32 wait; char *fib; }; @@ -1271,6 +1272,7 @@ #define FSACTL_MINIPORT_REV_CHECK CTL_CODE(2107, METHOD_BUFFERED) #define FSACTL_GET_PCI_INFO CTL_CODE(2119, METHOD_BUFFERED) #define FSACTL_FORCE_DELETE_DISK CTL_CODE(2120, METHOD_NEITHER) +#define FSACTL_GET_CONTAINERS 2131 struct aac_common ===== drivers/scsi/aacraid/commctrl.c 1.5 vs edited ===== --- 1.5/drivers/scsi/aacraid/commctrl.c 2004-05-10 13:22:40 -07:00 +++ edited/drivers/scsi/aacraid/commctrl.c 2004-06-16 11:18:30 -07:00 @@ -92,11 +92,12 @@ */ kfib->header.XferState = 0; } else { - if (fib_send(kfib->header.Command, fibptr, le32_to_cpu(kfib->header.Size) , FsaNormal, - 1, 1, NULL, NULL) != 0) - { + int retval = fib_send(kfib->header.Command, fibptr, + le32_to_cpu(kfib->header.Size) , FsaNormal, + 1, 1, NULL, NULL); + if (retval) { fib_free(fibptr); - return -EINVAL; + return retval; } if (fib_complete(fibptr) != 0) { fib_free(fibptr); @@ -130,14 +131,24 @@ { struct aac_fib_context * fibctx; int status; - unsigned long flags; fibctx = kmalloc(sizeof(struct aac_fib_context), GFP_KERNEL); if (fibctx == NULL) { status = -ENOMEM; } else { + unsigned long flags; + struct list_head * entry; + struct aac_fib_context * context; + fibctx->type = FSAFS_NTC_GET_ADAPTER_FIB_CONTEXT; fibctx->size = sizeof(struct aac_fib_context); + /* + * Yes yes, I know this could be an index, but we have a + * better guarantee of uniqueness for the locked loop below. + * Without the aid of a persistent history, this also helps + * reduce the chance that the opaque context would be reused. + */ + fibctx->unique = (u32)((ulong)fibctx & 0xFFFFFFFF); /* * Initialize the mutex used to wait for the next AIF. */ @@ -155,9 +166,22 @@ * AdapterFibContext list. */ spin_lock_irqsave(&dev->fib_lock, flags); + /* Ensure that we have a unique identifier */ + entry = dev->fib_list.next; + while (entry != &dev->fib_list) { + context = list_entry(entry, struct aac_fib_context, next); + if (context->unique == fibctx->unique) { + /* Not unique (32 bits) */ + fibctx->unique++; + entry = dev->fib_list.next; + } else { + entry = entry->next; + } + } list_add_tail(&fibctx->next, &dev->fib_list); spin_unlock_irqrestore(&dev->fib_lock, flags); - if (copy_to_user(arg, &fibctx, sizeof(struct aac_fib_context *))) { + if (copy_to_user(arg, &fibctx->unique, + sizeof(fibctx->unique))) { status = -EFAULT; } else { status = 0; @@ -178,43 +202,44 @@ static int next_getadapter_fib(struct aac_dev * dev, void *arg) { struct fib_ioctl f; - struct aac_fib_context *fibctx, *aifcp; struct fib *fib; + struct aac_fib_context *fibctx; int status; struct list_head * entry; - int found; unsigned long flags; if(copy_from_user((void *)&f, arg, sizeof(struct fib_ioctl))) return -EFAULT; /* - * Extract the AdapterFibContext from the Input parameters. - */ - fibctx = (struct aac_fib_context *) f.fibctx; - - /* * Verify that the HANDLE passed in was a valid AdapterFibContext * * Search the list of AdapterFibContext addresses on the adapter * to be sure this is a valid address */ - found = 0; entry = dev->fib_list.next; + fibctx = NULL; - while(entry != &dev->fib_list) { - aifcp = list_entry(entry, struct aac_fib_context, next); - if(fibctx == aifcp) { /* We found a winner */ - found = 1; + while (entry != &dev->fib_list) { + fibctx = list_entry(entry, struct aac_fib_context, next); + /* + * Extract the AdapterFibContext from the Input parameters. + */ + if (fibctx->unique == f.fibctx) { /* We found a winner */ break; } entry = entry->next; + fibctx = NULL; } - if (found == 0) + if (!fibctx) { + dprintk ((KERN_INFO "Fib Context not found\n")); return -EINVAL; + } if((fibctx->type != FSAFS_NTC_GET_ADAPTER_FIB_CONTEXT) || - (fibctx->size != sizeof(struct aac_fib_context))) + (fibctx->size != sizeof(struct aac_fib_context))) { + dprintk ((KERN_INFO "Fib Context corrupt?\n")); return -EINVAL; + } status = 0; spin_lock_irqsave(&dev->fib_lock, flags); /* @@ -309,16 +334,10 @@ static int close_getadapter_fib(struct aac_dev * dev, void *arg) { - struct aac_fib_context *fibctx, *aifcp; + struct aac_fib_context *fibctx; int status; unsigned long flags; struct list_head * entry; - int found; - - /* - * Extract the fibctx from the input parameters - */ - fibctx = arg; /* * Verify that the HANDLE passed in was a valid AdapterFibContext @@ -327,19 +346,23 @@ * to be sure this is a valid address */ - found = 0; entry = dev->fib_list.next; + fibctx = NULL; while(entry != &dev->fib_list) { - aifcp = list_entry(entry, struct aac_fib_context, next); - if(fibctx == aifcp) { /* We found a winner */ - found = 1; + fibctx = list_entry(entry, struct aac_fib_context, next); + /* + * Extract the fibctx from the input parameters + */ + if (fibctx->unique == (u32)(unsigned long)arg) { + /* We found a winner */ break; } entry = entry->next; + fibctx = NULL; } - if(found == 0) + if (!fibctx) return 0; /* Already gone */ if((fibctx->type != FSAFS_NTC_GET_ADAPTER_FIB_CONTEXT) || @@ -356,8 +379,9 @@ * @dev: adapter * @arg: ioctl arguments * - * This routine returns the firmware version. - * Under Linux, there have been no version incompatibilities, so this is simple! + * This routine returns the driver version. + * Under Linux, there have been no version incompatibilities, so this is + * simple! */ static int check_revision(struct aac_dev *dev, void *arg) @@ -419,6 +443,11 @@ goto cleanup; } + if (fibsize > FIB_DATA_SIZE_IN_BYTES) { + rcode = -EINVAL; + goto cleanup; + } + if(copy_from_user(srbcmd, user_srb,fibsize)){ printk(KERN_DEBUG"aacraid: Could not copy srb from user\n"); rcode = -EFAULT; @@ -438,7 +467,7 @@ srbcmd->retry_limit =cpu_to_le32(0); // Obsolete parameter srbcmd->cdb_size = cpu_to_le32(srbcmd->cdb_size); - switch(srbcmd->flags){ + switch (srbcmd->flags & (SRB_DataIn | SRB_DataOut)) { case SRB_DataOut: data_dir = DMA_TO_DEVICE; break; @@ -451,17 +480,26 @@ default: data_dir = DMA_NONE; } - if( dev->pae_support ==1 ) { + if (dev->pae_support == 1) { struct sgmap64* psg = (struct sgmap64*)&srbcmd->sg; byte_count = 0; - // This should also catch if user used the 32 bit sgmap - actual_fibsize = sizeof (struct aac_srb) + (((srbcmd->sg.count & 0xff) - 1) * sizeof (struct sgentry64)); + /* + * This should also catch if user used the 32 bit sgmap + */ + actual_fibsize = sizeof(struct aac_srb) - + sizeof(struct sgentry) + ((srbcmd->sg.count & 0xff) * + sizeof(struct sgentry64)); if(actual_fibsize != fibsize){ // User made a mistake - should not continue printk(KERN_DEBUG"aacraid: Bad Size specified in Raw SRB command\n"); rcode = -EINVAL; goto cleanup; } + if ((data_dir == DMA_NONE) && psg->count) { + printk(KERN_DEBUG"aacraid: SG with no direction specified in Raw SRB command\n"); + rcode = -EINVAL; + goto cleanup; + } for (i = 0; i < psg->count; i++) { dma_addr_t addr; @@ -503,6 +541,11 @@ actual_fibsize = sizeof (struct aac_srb) + (((srbcmd->sg.count & 0xff) - 1) * sizeof (struct sgentry)); if(actual_fibsize != fibsize){ // User made a mistake - should not continue printk(KERN_DEBUG"aacraid: Bad Size specified in Raw SRB command\n"); + rcode = -EINVAL; + goto cleanup; + } + if ((data_dir == DMA_NONE) && psg->count) { + printk(KERN_DEBUG"aacraid: SG with no direction specified in Raw SRB command\n"); rcode = -EINVAL; goto cleanup; } ===== drivers/scsi/aacraid/linit.c 1.29 vs edited ===== --- 1.29/drivers/scsi/aacraid/linit.c 2004-05-10 04:42:31 -07:00 +++ edited/drivers/scsi/aacraid/linit.c 2004-06-16 11:02:38 -07:00 @@ -31,6 +31,7 @@ #define AAC_DRIVER_BUILD_DATE __DATE__ #define AAC_DRIVERNAME "aacraid" +#include <linux/compat.h> #include <linux/blkdev.h> #include <linux/completion.h> #include <linux/init.h> @@ -41,6 +42,8 @@ #include <linux/pci.h> #include <linux/slab.h> #include <linux/spinlock.h> +#include <linux/syscalls.h> +#include <linux/ioctl32.h> #include <asm/semaphore.h> #include <scsi/scsi.h> @@ -168,6 +171,29 @@ { aac_rx_init, "aacraid", "ADAPTEC ", "ASR-2025SA ", 1 }, /* ASR-2025SA (ZCR DIMM SATA) */ }; +#ifdef CONFIG_COMPAT +/* + * Promote 32 bit apps that call get_next_adapter_fib_ioctl to 64 bit version + */ +static int aac_get_next_adapter_fib_ioctl(unsigned int fd, unsigned int cmd, + unsigned long arg, struct file *file) +{ + struct fib_ioctl *f; + + f = compat_alloc_user_space(sizeof(*f)); + if (!access_ok(VERIFY_WRITE, f, sizeof(*f))) + return -EFAULT; + + clear_user(f, sizeof(*f)); + if (copy_from_user((void *)f, (void *)arg, + sizeof(struct fib_ioctl) - sizeof(u32))) + return -EFAULT; + + return sys_ioctl(fd, cmd, (unsigned long)f); +} +#endif + + /** * aac_queuecommand - queue a SCSI command * @cmd: SCSI command to queue @@ -643,12 +669,39 @@ printk(KERN_WARNING "aacraid: unable to register \"aac\" device.\n"); } +#ifdef CONFIG_COMPAT + register_ioctl32_conversion(FSACTL_MINIPORT_REV_CHECK, NULL); + register_ioctl32_conversion(FSACTL_SENDFIB, NULL); + register_ioctl32_conversion(FSACTL_OPEN_GET_ADAPTER_FIB, NULL); + register_ioctl32_conversion(FSACTL_GET_NEXT_ADAPTER_FIB, + aac_get_next_adapter_fib_ioctl); + register_ioctl32_conversion(FSACTL_CLOSE_GET_ADAPTER_FIB, NULL); + register_ioctl32_conversion(FSACTL_SEND_RAW_SRB, NULL); + register_ioctl32_conversion(FSACTL_GET_PCI_INFO, NULL); + register_ioctl32_conversion(FSACTL_QUERY_DISK, NULL); + register_ioctl32_conversion(FSACTL_DELETE_DISK, NULL); + register_ioctl32_conversion(FSACTL_FORCE_DELETE_DISK, NULL); + register_ioctl32_conversion(FSACTL_GET_CONTAINERS, NULL); +#endif return 0; } static void __exit aac_exit(void) { +#ifdef CONFIG_COMPAT + unregister_ioctl32_conversion(FSACTL_MINIPORT_REV_CHECK); + unregister_ioctl32_conversion(FSACTL_SENDFIB); + unregister_ioctl32_conversion(FSACTL_OPEN_GET_ADAPTER_FIB); + unregister_ioctl32_conversion(FSACTL_GET_NEXT_ADAPTER_FIB); + unregister_ioctl32_conversion(FSACTL_CLOSE_GET_ADAPTER_FIB); + unregister_ioctl32_conversion(FSACTL_SEND_RAW_SRB); + unregister_ioctl32_conversion(FSACTL_GET_PCI_INFO); + unregister_ioctl32_conversion(FSACTL_QUERY_DISK); + unregister_ioctl32_conversion(FSACTL_DELETE_DISK); + unregister_ioctl32_conversion(FSACTL_FORCE_DELETE_DISK); + unregister_ioctl32_conversion(FSACTL_GET_CONTAINERS); +#endif unregister_chrdev(aac_cfg_major, "aac"); pci_unregister_driver(&aac_pci_driver); } -- Mark Haverkamp <markh@osdl.org> ^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2004-06-16 18:24 UTC | newest] Thread overview: 9+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2004-06-16 15:52 [PATCH] aacraid 32/64 ioctl support (update) Mark Haverkamp 2004-06-16 16:01 ` Christoph Hellwig 2004-06-16 16:02 ` Christoph Hellwig 2004-06-16 17:12 ` Mark Haverkamp 2004-06-16 17:19 ` Christoph Hellwig 2004-06-16 17:51 ` Mark Haverkamp 2004-06-16 17:53 ` Christoph Hellwig 2004-06-16 17:52 ` David S. Miller 2004-06-16 18:23 ` Mark Haverkamp
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox