Commit aa0a4ef4 authored by Andy Grover's avatar Andy Grover

RDS: Make sure cmsgs aren't used in improper ways

It hasn't cropped up in the field, but this code ensures it is
impossible to issue operations that pass an rdma cookie (DEST, MAP)
in the same sendmsg call that's actually initiating rdma or atomic
ops.

Disallowing this perverse-but-technically-allowed usage makes silent
RDMA heuristics slightly easier.
Signed-off-by: default avatarAndy Grover <andy.grover@oracle.com>
parent 2c3a5f9a
...@@ -846,6 +846,7 @@ static int rds_rm_size(struct msghdr *msg, int data_len) ...@@ -846,6 +846,7 @@ static int rds_rm_size(struct msghdr *msg, int data_len)
{ {
struct cmsghdr *cmsg; struct cmsghdr *cmsg;
int size = 0; int size = 0;
int cmsg_groups = 0;
int retval; int retval;
for (cmsg = CMSG_FIRSTHDR(msg); cmsg; cmsg = CMSG_NXTHDR(msg, cmsg)) { 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) ...@@ -857,19 +858,23 @@ static int rds_rm_size(struct msghdr *msg, int data_len)
switch (cmsg->cmsg_type) { switch (cmsg->cmsg_type) {
case RDS_CMSG_RDMA_ARGS: case RDS_CMSG_RDMA_ARGS:
cmsg_groups |= 1;
retval = rds_rdma_extra_size(CMSG_DATA(cmsg)); retval = rds_rdma_extra_size(CMSG_DATA(cmsg));
if (retval < 0) if (retval < 0)
return retval; return retval;
size += retval; size += retval;
break; break;
case RDS_CMSG_RDMA_DEST: case RDS_CMSG_RDMA_DEST:
case RDS_CMSG_RDMA_MAP: case RDS_CMSG_RDMA_MAP:
cmsg_groups |= 2;
/* these are valid but do no add any size */ /* these are valid but do no add any size */
break; break;
case RDS_CMSG_ATOMIC_CSWP: case RDS_CMSG_ATOMIC_CSWP:
case RDS_CMSG_ATOMIC_FADD: case RDS_CMSG_ATOMIC_FADD:
cmsg_groups |= 1;
size += sizeof(struct scatterlist); size += sizeof(struct scatterlist);
break; break;
...@@ -881,6 +886,10 @@ static int rds_rm_size(struct msghdr *msg, int data_len) ...@@ -881,6 +886,10 @@ static int rds_rm_size(struct msghdr *msg, int data_len)
size += ceil(data_len, PAGE_SIZE) * sizeof(struct scatterlist); 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; return size;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment