aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/staging
diff options
context:
space:
mode:
authorDan Carpenter <error27@gmail.com>2010-10-21 01:46:58 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2010-11-09 16:32:36 -0500
commiteccbf04a904fc99c54ab37c29a2a4dedcec66e33 (patch)
treefe6d1142f644afe0984bdd3570b89ede21bc1540 /drivers/staging
parent4fc718a4b0cdf3803f370e323ea5252a3d76f52d (diff)
Staging: bcm: use get_user() to access user pointers
This fixes some places that dereference user pointers directly instead of using get_user(). Please especially check my changes to IOCTL_BCM_GET_CURRENT_STATUS. The original code modified the struct which "arg" was pointing to. I think this was a bug in the original code and that we only wanted to write to the OutputBuffer. Also with the original code you could read as much memory as you wanted so I had to put a cap on OutputLength. The only value of OutputLength that makes sense is sizeof(LINK_STATE) so now if OutputLength is not sizeof(LINK_STATE) it returns -EINVAL. Signed-off-by: Dan Carpenter <error27@gmail.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/staging')
-rw-r--r--drivers/staging/bcm/Bcmchar.c49
1 files changed, 32 insertions, 17 deletions
diff --git a/drivers/staging/bcm/Bcmchar.c b/drivers/staging/bcm/Bcmchar.c
index 77fdfe24d999..fead9c56162e 100644
--- a/drivers/staging/bcm/Bcmchar.c
+++ b/drivers/staging/bcm/Bcmchar.c
@@ -1001,13 +1001,15 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg)
1001 } 1001 }
1002#endif 1002#endif
1003 case IOCTL_BE_BUCKET_SIZE: 1003 case IOCTL_BE_BUCKET_SIZE:
1004 Adapter->BEBucketSize = *(PULONG)arg; 1004 Status = 0;
1005 Status = STATUS_SUCCESS; 1005 if (get_user(Adapter->BEBucketSize, (unsigned long __user *)arg))
1006 Status = -EFAULT;
1006 break; 1007 break;
1007 1008
1008 case IOCTL_RTPS_BUCKET_SIZE: 1009 case IOCTL_RTPS_BUCKET_SIZE:
1009 Adapter->rtPSBucketSize = *(PULONG)arg; 1010 Status = 0;
1010 Status = STATUS_SUCCESS; 1011 if (get_user(Adapter->rtPSBucketSize, (unsigned long __user *)arg))
1012 Status = -EFAULT;
1011 break; 1013 break;
1012 case IOCTL_CHIP_RESET: 1014 case IOCTL_CHIP_RESET:
1013 { 1015 {
@@ -1028,11 +1030,15 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg)
1028 case IOCTL_QOS_THRESHOLD: 1030 case IOCTL_QOS_THRESHOLD:
1029 { 1031 {
1030 USHORT uiLoopIndex; 1032 USHORT uiLoopIndex;
1031 for(uiLoopIndex = 0 ; uiLoopIndex < NO_OF_QUEUES ; uiLoopIndex++) 1033
1032 { 1034 Status = 0;
1033 Adapter->PackInfo[uiLoopIndex].uiThreshold = *(PULONG)arg; 1035 for (uiLoopIndex = 0; uiLoopIndex < NO_OF_QUEUES; uiLoopIndex++) {
1036 if (get_user(Adapter->PackInfo[uiLoopIndex].uiThreshold,
1037 (unsigned long __user *)arg)) {
1038 Status = -EFAULT;
1039 break;
1040 }
1034 } 1041 }
1035 Status = STATUS_SUCCESS;
1036 break; 1042 break;
1037 } 1043 }
1038 1044
@@ -1093,7 +1099,8 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg)
1093 } 1099 }
1094 case IOCTL_BCM_GET_CURRENT_STATUS: 1100 case IOCTL_BCM_GET_CURRENT_STATUS:
1095 { 1101 {
1096 LINK_STATE *plink_state = NULL; 1102 LINK_STATE plink_state;
1103
1097 /* Copy Ioctl Buffer structure */ 1104 /* Copy Ioctl Buffer structure */
1098 if(copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER))) 1105 if(copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER)))
1099 { 1106 {
@@ -1101,13 +1108,19 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg)
1101 Status = -EFAULT; 1108 Status = -EFAULT;
1102 break; 1109 break;
1103 } 1110 }
1104 plink_state = (LINK_STATE*)arg; 1111 if (IoBuffer.OutputLength != sizeof(plink_state)) {
1105 plink_state->bIdleMode = (UCHAR)Adapter->IdleMode; 1112 Status = -EINVAL;
1106 plink_state->bShutdownMode = Adapter->bShutStatus; 1113 break;
1107 plink_state->ucLinkStatus = (UCHAR)Adapter->LinkStatus; 1114 }
1108 if(copy_to_user(IoBuffer.OutputBuffer, 1115
1109 (PUCHAR)plink_state, (UINT)IoBuffer.OutputLength)) 1116 if (copy_from_user(&plink_state, (void __user *)arg, sizeof(plink_state))) {
1110 { 1117 Status = -EFAULT;
1118 break;
1119 }
1120 plink_state.bIdleMode = (UCHAR)Adapter->IdleMode;
1121 plink_state.bShutdownMode = Adapter->bShutStatus;
1122 plink_state.ucLinkStatus = (UCHAR)Adapter->LinkStatus;
1123 if (copy_to_user(IoBuffer.OutputBuffer, &plink_state, IoBuffer.OutputLength)) {
1111 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Copy_to_user Failed..\n"); 1124 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Copy_to_user Failed..\n");
1112 Status = -EFAULT; 1125 Status = -EFAULT;
1113 break; 1126 break;
@@ -1331,7 +1344,9 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg)
1331 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Copy From User space failed. status :%d", Status); 1344 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Copy From User space failed. status :%d", Status);
1332 return -EFAULT; 1345 return -EFAULT;
1333 } 1346 }
1334 uiSectorSize = *((PUINT)(IoBuffer.InputBuffer)); /* FIXME: unchecked __user access */ 1347 if (get_user(uiSectorSize, (unsigned int __user *)IoBuffer.InputBuffer))
1348 return -EFAULT;
1349
1335 if((uiSectorSize < MIN_SECTOR_SIZE) || (uiSectorSize > MAX_SECTOR_SIZE)) 1350 if((uiSectorSize < MIN_SECTOR_SIZE) || (uiSectorSize > MAX_SECTOR_SIZE))
1336 { 1351 {
1337 1352