Loading drivers/ieee1394/raw1394.c +91 −5 Original line number Diff line number Diff line Loading @@ -42,6 +42,7 @@ #include <asm/uaccess.h> #include <asm/atomic.h> #include <linux/devfs_fs_kernel.h> #include <linux/compat.h> #include "csr1212.h" #include "ieee1394.h" Loading Loading @@ -406,6 +407,65 @@ static void fcp_request(struct hpsb_host *host, int nodeid, int direction, queue_complete_req(req); } #ifdef CONFIG_COMPAT struct compat_raw1394_req { __u32 type; __s32 error; __u32 misc; __u32 generation; __u32 length; __u64 address; __u64 tag; __u64 sendb; __u64 recvb; } __attribute__((packed)); static const char __user *raw1394_compat_write(const char __user *buf) { struct compat_raw1394_req __user *cr = (typeof(cr)) buf; struct raw1394_request __user *r; r = compat_alloc_user_space(sizeof(struct raw1394_request)); #define C(x) __copy_in_user(&r->x, &cr->x, sizeof(r->x)) if (copy_in_user(r, cr, sizeof(struct compat_raw1394_req)) || C(address) || C(tag) || C(sendb) || C(recvb)) return ERR_PTR(-EFAULT); return (const char __user *)r; } #undef C #define P(x) __put_user(r->x, &cr->x) static int raw1394_compat_read(const char __user *buf, struct raw1394_request *r) { struct compat_raw1394_req __user *cr = (typeof(cr)) r; if (!access_ok(VERIFY_WRITE,cr,sizeof(struct compat_raw1394_req)) || P(type) || P(error) || P(misc) || P(generation) || P(length) || P(address) || P(tag) || P(sendb) || P(recvb)) return -EFAULT; return sizeof(struct compat_raw1394_req); } #undef P #endif static ssize_t raw1394_read(struct file *file, char __user * buffer, size_t count, loff_t * offset_is_ignored) { Loading @@ -415,6 +475,11 @@ static ssize_t raw1394_read(struct file *file, char __user * buffer, struct pending_request *req; ssize_t ret; #ifdef CONFIG_COMPAT if (count == sizeof(struct compat_raw1394_req)) { /* ok */ } else #endif if (count != sizeof(struct raw1394_request)) { return -EINVAL; } Loading Loading @@ -446,12 +511,22 @@ static ssize_t raw1394_read(struct file *file, char __user * buffer, req->req.error = RAW1394_ERROR_MEMFAULT; } } #ifdef CONFIG_COMPAT if (count == sizeof(struct compat_raw1394_req) && sizeof(struct compat_raw1394_req) != sizeof(struct raw1394_request)) { ret = raw1394_compat_read(buffer, &req->req); } else #endif { if (copy_to_user(buffer, &req->req, sizeof(req->req))) { ret = -EFAULT; goto out; } ret = (ssize_t) sizeof(struct raw1394_request); } out: free_pending_request(req); return ret; Loading Loading @@ -2274,6 +2349,7 @@ static int state_connected(struct file_info *fi, struct pending_request *req) return handle_async_request(fi, req, node); } static ssize_t raw1394_write(struct file *file, const char __user * buffer, size_t count, loff_t * offset_is_ignored) { Loading @@ -2281,6 +2357,15 @@ static ssize_t raw1394_write(struct file *file, const char __user * buffer, struct pending_request *req; ssize_t retval = 0; #ifdef CONFIG_COMPAT if (count == sizeof(struct compat_raw1394_req) && sizeof(struct compat_raw1394_req) != sizeof(struct raw1394_request)) { buffer = raw1394_compat_write(buffer); if (IS_ERR(buffer)) return PTR_ERR(buffer); } else #endif if (count != sizeof(struct raw1394_request)) { return -EINVAL; } Loading Loading @@ -2893,6 +2978,7 @@ static struct file_operations raw1394_fops = { .write = raw1394_write, .mmap = raw1394_mmap, .ioctl = raw1394_ioctl, // .compat_ioctl = ... someone needs to do this .poll = raw1394_poll, .open = raw1394_open, .release = raw1394_release, Loading Loading
drivers/ieee1394/raw1394.c +91 −5 Original line number Diff line number Diff line Loading @@ -42,6 +42,7 @@ #include <asm/uaccess.h> #include <asm/atomic.h> #include <linux/devfs_fs_kernel.h> #include <linux/compat.h> #include "csr1212.h" #include "ieee1394.h" Loading Loading @@ -406,6 +407,65 @@ static void fcp_request(struct hpsb_host *host, int nodeid, int direction, queue_complete_req(req); } #ifdef CONFIG_COMPAT struct compat_raw1394_req { __u32 type; __s32 error; __u32 misc; __u32 generation; __u32 length; __u64 address; __u64 tag; __u64 sendb; __u64 recvb; } __attribute__((packed)); static const char __user *raw1394_compat_write(const char __user *buf) { struct compat_raw1394_req __user *cr = (typeof(cr)) buf; struct raw1394_request __user *r; r = compat_alloc_user_space(sizeof(struct raw1394_request)); #define C(x) __copy_in_user(&r->x, &cr->x, sizeof(r->x)) if (copy_in_user(r, cr, sizeof(struct compat_raw1394_req)) || C(address) || C(tag) || C(sendb) || C(recvb)) return ERR_PTR(-EFAULT); return (const char __user *)r; } #undef C #define P(x) __put_user(r->x, &cr->x) static int raw1394_compat_read(const char __user *buf, struct raw1394_request *r) { struct compat_raw1394_req __user *cr = (typeof(cr)) r; if (!access_ok(VERIFY_WRITE,cr,sizeof(struct compat_raw1394_req)) || P(type) || P(error) || P(misc) || P(generation) || P(length) || P(address) || P(tag) || P(sendb) || P(recvb)) return -EFAULT; return sizeof(struct compat_raw1394_req); } #undef P #endif static ssize_t raw1394_read(struct file *file, char __user * buffer, size_t count, loff_t * offset_is_ignored) { Loading @@ -415,6 +475,11 @@ static ssize_t raw1394_read(struct file *file, char __user * buffer, struct pending_request *req; ssize_t ret; #ifdef CONFIG_COMPAT if (count == sizeof(struct compat_raw1394_req)) { /* ok */ } else #endif if (count != sizeof(struct raw1394_request)) { return -EINVAL; } Loading Loading @@ -446,12 +511,22 @@ static ssize_t raw1394_read(struct file *file, char __user * buffer, req->req.error = RAW1394_ERROR_MEMFAULT; } } #ifdef CONFIG_COMPAT if (count == sizeof(struct compat_raw1394_req) && sizeof(struct compat_raw1394_req) != sizeof(struct raw1394_request)) { ret = raw1394_compat_read(buffer, &req->req); } else #endif { if (copy_to_user(buffer, &req->req, sizeof(req->req))) { ret = -EFAULT; goto out; } ret = (ssize_t) sizeof(struct raw1394_request); } out: free_pending_request(req); return ret; Loading Loading @@ -2274,6 +2349,7 @@ static int state_connected(struct file_info *fi, struct pending_request *req) return handle_async_request(fi, req, node); } static ssize_t raw1394_write(struct file *file, const char __user * buffer, size_t count, loff_t * offset_is_ignored) { Loading @@ -2281,6 +2357,15 @@ static ssize_t raw1394_write(struct file *file, const char __user * buffer, struct pending_request *req; ssize_t retval = 0; #ifdef CONFIG_COMPAT if (count == sizeof(struct compat_raw1394_req) && sizeof(struct compat_raw1394_req) != sizeof(struct raw1394_request)) { buffer = raw1394_compat_write(buffer); if (IS_ERR(buffer)) return PTR_ERR(buffer); } else #endif if (count != sizeof(struct raw1394_request)) { return -EINVAL; } Loading Loading @@ -2893,6 +2978,7 @@ static struct file_operations raw1394_fops = { .write = raw1394_write, .mmap = raw1394_mmap, .ioctl = raw1394_ioctl, // .compat_ioctl = ... someone needs to do this .poll = raw1394_poll, .open = raw1394_open, .release = raw1394_release, Loading