diff options
author | Dan Carpenter <error27@gmail.com> | 2010-10-21 01:46:58 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2010-11-09 16:32:36 -0500 |
commit | eccbf04a904fc99c54ab37c29a2a4dedcec66e33 (patch) | |
tree | fe6d1142f644afe0984bdd3570b89ede21bc1540 /drivers/staging | |
parent | 4fc718a4b0cdf3803f370e323ea5252a3d76f52d (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.c | 49 |
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 | ||