Skip to content

Commit f9fb69a

Browse files
Avinash RepakaSantoshShilimkar
Avinash Repaka
authored andcommitted
RDS: make message size limit compliant with spec
RDS support max message size as 1M but the code doesn't check this in all cases. Patch fixes it for RDMA & non-RDMA and RDS MR size and its enforced irrespective of underlying transport. Signed-off-by: Avinash Repaka <[email protected]> Signed-off-by: Santosh Shilimkar <[email protected]>
1 parent 192a798 commit f9fb69a

File tree

3 files changed

+42
-1
lines changed

3 files changed

+42
-1
lines changed

net/rds/rdma.c

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,6 @@
4040
/*
4141
* XXX
4242
* - build with sparse
43-
* - should we limit the size of a mr region? let transport return failure?
4443
* - should we detect duplicate keys on a socket? hmm.
4544
* - an rdma is an mlock, apply rlimit?
4645
*/
@@ -200,6 +199,14 @@ static int __rds_rdma_map(struct rds_sock *rs, struct rds_get_mr_args *args,
200199
goto out;
201200
}
202201

202+
/* Restrict the size of mr irrespective of underlying transport
203+
* To account for unaligned mr regions, subtract one from nr_pages
204+
*/
205+
if ((nr_pages - 1) > (RDS_MAX_MSG_SIZE >> PAGE_SHIFT)) {
206+
ret = -EMSGSIZE;
207+
goto out;
208+
}
209+
203210
rdsdebug("RDS: get_mr addr %llx len %llu nr_pages %u\n",
204211
args->vec.addr, args->vec.bytes, nr_pages);
205212

net/rds/rds.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,9 @@ void rdsdebug(char *fmt, ...)
5050
#define RDS_FRAG_SHIFT 12
5151
#define RDS_FRAG_SIZE ((unsigned int)(1 << RDS_FRAG_SHIFT))
5252

53+
/* Used to limit both RDMA and non-RDMA RDS message to 1MB */
54+
#define RDS_MAX_MSG_SIZE ((unsigned int)(1 << 20))
55+
5356
#define RDS_CONG_MAP_BYTES (65536 / 8)
5457
#define RDS_CONG_MAP_PAGES (PAGE_ALIGN(RDS_CONG_MAP_BYTES) / PAGE_SIZE)
5558
#define RDS_CONG_MAP_PAGE_BITS (PAGE_SIZE * 8)

net/rds/send.c

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -994,6 +994,26 @@ static int rds_send_mprds_hash(struct rds_sock *rs, struct rds_connection *conn)
994994
return hash;
995995
}
996996

997+
static int rds_rdma_bytes(struct msghdr *msg, size_t *rdma_bytes)
998+
{
999+
struct rds_rdma_args *args;
1000+
struct cmsghdr *cmsg;
1001+
1002+
for_each_cmsghdr(cmsg, msg) {
1003+
if (!CMSG_OK(msg, cmsg))
1004+
return -EINVAL;
1005+
1006+
if (cmsg->cmsg_level != SOL_RDS)
1007+
continue;
1008+
1009+
if (cmsg->cmsg_type == RDS_CMSG_RDMA_ARGS) {
1010+
args = CMSG_DATA(cmsg);
1011+
*rdma_bytes += args->remote_vec.bytes;
1012+
}
1013+
}
1014+
return 0;
1015+
}
1016+
9971017
int rds_sendmsg(struct socket *sock, struct msghdr *msg, size_t payload_len)
9981018
{
9991019
struct sock *sk = sock->sk;
@@ -1008,6 +1028,7 @@ int rds_sendmsg(struct socket *sock, struct msghdr *msg, size_t payload_len)
10081028
int nonblock = msg->msg_flags & MSG_DONTWAIT;
10091029
long timeo = sock_sndtimeo(sk, nonblock);
10101030
struct rds_conn_path *cpath;
1031+
size_t total_payload_len = payload_len, rdma_payload_len = 0;
10111032

10121033
/* Mirror Linux UDP mirror of BSD error message compatibility */
10131034
/* XXX: Perhaps MSG_MORE someday */
@@ -1040,6 +1061,16 @@ int rds_sendmsg(struct socket *sock, struct msghdr *msg, size_t payload_len)
10401061
}
10411062
release_sock(sk);
10421063

1064+
ret = rds_rdma_bytes(msg, &rdma_payload_len);
1065+
if (ret)
1066+
goto out;
1067+
1068+
total_payload_len += rdma_payload_len;
1069+
if (max_t(size_t, payload_len, rdma_payload_len) > RDS_MAX_MSG_SIZE) {
1070+
ret = -EMSGSIZE;
1071+
goto out;
1072+
}
1073+
10431074
if (payload_len > rds_sk_sndbuf(rs)) {
10441075
ret = -EMSGSIZE;
10451076
goto out;

0 commit comments

Comments
 (0)