]> Pileus Git - ~andy/linux/blobdiff - drivers/infiniband/core/uverbs_main.c
Merge branches 'cxgb4', 'flowsteer' and 'misc' into for-linus
[~andy/linux] / drivers / infiniband / core / uverbs_main.c
index 34386943ebcff4cf18849082add568f5fc73bc5a..08219fb3338b0652f350da1af864b4cfb355ff3c 100644 (file)
@@ -668,25 +668,30 @@ static ssize_t ib_uverbs_write(struct file *filp, const char __user *buf,
                if ((hdr.in_words + ex_hdr.provider_in_words) * 8 != count)
                        return -EINVAL;
 
+               if (ex_hdr.cmd_hdr_reserved)
+                       return -EINVAL;
+
                if (ex_hdr.response) {
                        if (!hdr.out_words && !ex_hdr.provider_out_words)
                                return -EINVAL;
+
+                       if (!access_ok(VERIFY_WRITE,
+                                      (void __user *) (unsigned long) ex_hdr.response,
+                                      (hdr.out_words + ex_hdr.provider_out_words) * 8))
+                               return -EFAULT;
                } else {
                        if (hdr.out_words || ex_hdr.provider_out_words)
                                return -EINVAL;
                }
 
-               INIT_UDATA(&ucore,
-                          (hdr.in_words) ? buf : 0,
-                          (unsigned long)ex_hdr.response,
-                          hdr.in_words * 8,
-                          hdr.out_words * 8);
-
-               INIT_UDATA(&uhw,
-                          (ex_hdr.provider_in_words) ? buf + ucore.inlen : 0,
-                          (ex_hdr.provider_out_words) ? (unsigned long)ex_hdr.response + ucore.outlen : 0,
-                          ex_hdr.provider_in_words * 8,
-                          ex_hdr.provider_out_words * 8);
+               INIT_UDATA_BUF_OR_NULL(&ucore, buf, (unsigned long) ex_hdr.response,
+                                      hdr.in_words * 8, hdr.out_words * 8);
+
+               INIT_UDATA_BUF_OR_NULL(&uhw,
+                                      buf + ucore.inlen,
+                                      (unsigned long) ex_hdr.response + ucore.outlen,
+                                      ex_hdr.provider_in_words * 8,
+                                      ex_hdr.provider_out_words * 8);
 
                err = uverbs_ex_cmd_table[command](file,
                                                   &ucore,