aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/firewire/core-cdev.c
diff options
context:
space:
mode:
authorRussell King <rmk+kernel@arm.linux.org.uk>2010-05-17 17:24:04 +0100
committerRussell King <rmk+kernel@arm.linux.org.uk>2010-05-17 17:24:04 +0100
commitac1d426e825ab5778995f2f6f053ca2e6b45c622 (patch)
tree75b91356ca39463e0112931aa6790802fb1e07a2 /drivers/firewire/core-cdev.c
parentfda0e18c8a7a3e02747c2b045b4fcd2c920410b9 (diff)
parenta3685f00652af83f12b63e3b4ef48f29581ba48b (diff)
downloadkernel_samsung_smdk4412-ac1d426e825ab5778995f2f6f053ca2e6b45c622.zip
kernel_samsung_smdk4412-ac1d426e825ab5778995f2f6f053ca2e6b45c622.tar.gz
kernel_samsung_smdk4412-ac1d426e825ab5778995f2f6f053ca2e6b45c622.tar.bz2
Merge branch 'devel-stable' into devel
Conflicts: arch/arm/Kconfig arch/arm/include/asm/system.h arch/arm/mm/Kconfig
Diffstat (limited to 'drivers/firewire/core-cdev.c')
-rw-r--r--drivers/firewire/core-cdev.c24
1 files changed, 14 insertions, 10 deletions
diff --git a/drivers/firewire/core-cdev.c b/drivers/firewire/core-cdev.c
index 8be720b..14a34d9 100644
--- a/drivers/firewire/core-cdev.c
+++ b/drivers/firewire/core-cdev.c
@@ -34,6 +34,7 @@
#include <linux/mutex.h>
#include <linux/poll.h>
#include <linux/sched.h>
+#include <linux/slab.h>
#include <linux/spinlock.h>
#include <linux/string.h>
#include <linux/time.h>
@@ -959,6 +960,8 @@ static int ioctl_queue_iso(struct client *client, union ioctl_arg *arg)
u.packet.header_length = GET_HEADER_LENGTH(control);
if (ctx->type == FW_ISO_CONTEXT_TRANSMIT) {
+ if (u.packet.header_length % 4 != 0)
+ return -EINVAL;
header_length = u.packet.header_length;
} else {
/*
@@ -968,7 +971,8 @@ static int ioctl_queue_iso(struct client *client, union ioctl_arg *arg)
if (ctx->header_size == 0) {
if (u.packet.header_length > 0)
return -EINVAL;
- } else if (u.packet.header_length % ctx->header_size != 0) {
+ } else if (u.packet.header_length == 0 ||
+ u.packet.header_length % ctx->header_size != 0) {
return -EINVAL;
}
header_length = 0;
@@ -1353,24 +1357,24 @@ static int dispatch_ioctl(struct client *client,
return -ENODEV;
if (_IOC_TYPE(cmd) != '#' ||
- _IOC_NR(cmd) >= ARRAY_SIZE(ioctl_handlers))
+ _IOC_NR(cmd) >= ARRAY_SIZE(ioctl_handlers) ||
+ _IOC_SIZE(cmd) > sizeof(buffer))
return -EINVAL;
- if (_IOC_DIR(cmd) & _IOC_WRITE) {
- if (_IOC_SIZE(cmd) > sizeof(buffer) ||
- copy_from_user(&buffer, arg, _IOC_SIZE(cmd)))
+ if (_IOC_DIR(cmd) == _IOC_READ)
+ memset(&buffer, 0, _IOC_SIZE(cmd));
+
+ if (_IOC_DIR(cmd) & _IOC_WRITE)
+ if (copy_from_user(&buffer, arg, _IOC_SIZE(cmd)))
return -EFAULT;
- }
ret = ioctl_handlers[_IOC_NR(cmd)](client, &buffer);
if (ret < 0)
return ret;
- if (_IOC_DIR(cmd) & _IOC_READ) {
- if (_IOC_SIZE(cmd) > sizeof(buffer) ||
- copy_to_user(arg, &buffer, _IOC_SIZE(cmd)))
+ if (_IOC_DIR(cmd) & _IOC_READ)
+ if (copy_to_user(arg, &buffer, _IOC_SIZE(cmd)))
return -EFAULT;
- }
return ret;
}