return -EINVAL;
tot_pages += nr_pages;
+
+ /*
+ * nr_pages for one entry is limited to (UINT_MAX>>PAGE_SHIFT)+1,
+ * so tot_pages cannot overflow without first going negative.
+ */
+ if ((int)tot_pages < 0)
+ return -EINVAL;
}
return tot_pages;
struct rds_rdma_args *args;
struct rds_iovec vec;
struct rm_rdma_op *op = &rm->rdma;
- unsigned int nr_pages;
+ int nr_pages;
unsigned int nr_bytes;
struct page **pages = NULL;
struct rds_iovec __user *local_vec;
}
nr_pages = rds_rdma_pages(args);
- if (nr_pages < 0)
+ if (nr_pages < 0) {
+ ret = -EINVAL;
goto out;
+ }
pages = kcalloc(nr_pages, sizeof(struct page *), GFP_KERNEL);
if (!pages) {
}
op->op_bytes = nr_bytes;
- ret = 0;
out:
kfree(pages);
if (ret)
rds_rdma_free_op(op);
-
- rds_stats_inc(s_send_rdma);
+ else
+ rds_stats_inc(s_send_rdma);
return ret;
}