|
@@ -846,6 +846,7 @@ static int rds_rm_size(struct msghdr *msg, int data_len)
|
|
|
{
|
|
|
struct cmsghdr *cmsg;
|
|
|
int size = 0;
|
|
|
+ int cmsg_groups = 0;
|
|
|
int retval;
|
|
|
|
|
|
for (cmsg = CMSG_FIRSTHDR(msg); cmsg; cmsg = CMSG_NXTHDR(msg, cmsg)) {
|
|
@@ -857,19 +858,23 @@ static int rds_rm_size(struct msghdr *msg, int data_len)
|
|
|
|
|
|
switch (cmsg->cmsg_type) {
|
|
|
case RDS_CMSG_RDMA_ARGS:
|
|
|
+ cmsg_groups |= 1;
|
|
|
retval = rds_rdma_extra_size(CMSG_DATA(cmsg));
|
|
|
if (retval < 0)
|
|
|
return retval;
|
|
|
size += retval;
|
|
|
+
|
|
|
break;
|
|
|
|
|
|
case RDS_CMSG_RDMA_DEST:
|
|
|
case RDS_CMSG_RDMA_MAP:
|
|
|
+ cmsg_groups |= 2;
|
|
|
/* these are valid but do no add any size */
|
|
|
break;
|
|
|
|
|
|
case RDS_CMSG_ATOMIC_CSWP:
|
|
|
case RDS_CMSG_ATOMIC_FADD:
|
|
|
+ cmsg_groups |= 1;
|
|
|
size += sizeof(struct scatterlist);
|
|
|
break;
|
|
|
|
|
@@ -881,6 +886,10 @@ static int rds_rm_size(struct msghdr *msg, int data_len)
|
|
|
|
|
|
size += ceil(data_len, PAGE_SIZE) * sizeof(struct scatterlist);
|
|
|
|
|
|
+ /* Ensure (DEST, MAP) are never used with (ARGS, ATOMIC) */
|
|
|
+ if (cmsg_groups == 3)
|
|
|
+ return -EINVAL;
|
|
|
+
|
|
|
return size;
|
|
|
}
|
|
|
|