diff options
author | Avinash Repaka <avinash.repaka@oracle.com> | 2016-02-29 15:30:57 -0800 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2017-11-30 08:39:10 +0000 |
commit | aa85ae9db9d123c3d37645bbd491f9fe89b43ece (patch) | |
tree | fffd3087804e8074455bd3652409b9f0df42de26 /net/rds/send.c | |
parent | 65ce358100eaf7f7a8ab2b7dc949d562162d1f60 (diff) | |
download | linux-stable-aa85ae9db9d123c3d37645bbd491f9fe89b43ece.tar.gz linux-stable-aa85ae9db9d123c3d37645bbd491f9fe89b43ece.tar.bz2 linux-stable-aa85ae9db9d123c3d37645bbd491f9fe89b43ece.zip |
RDS: make message size limit compliant with spec
[ Upstream commit f9fb69adb6c7acca60977a4db5a5f95b8e66c041 ]
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 <avinash.repaka@oracle.com>
Signed-off-by: Santosh Shilimkar <santosh.shilimkar@oracle.com>
Signed-off-by: Sasha Levin <alexander.levin@verizon.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'net/rds/send.c')
-rw-r--r-- | net/rds/send.c | 31 |
1 files changed, 31 insertions, 0 deletions
diff --git a/net/rds/send.c b/net/rds/send.c index f28651b6ae83..310d57928405 100644 --- a/net/rds/send.c +++ b/net/rds/send.c @@ -988,6 +988,26 @@ static int rds_send_mprds_hash(struct rds_sock *rs, struct rds_connection *conn) return hash; } +static int rds_rdma_bytes(struct msghdr *msg, size_t *rdma_bytes) +{ + struct rds_rdma_args *args; + struct cmsghdr *cmsg; + + for_each_cmsghdr(cmsg, msg) { + if (!CMSG_OK(msg, cmsg)) + return -EINVAL; + + if (cmsg->cmsg_level != SOL_RDS) + continue; + + if (cmsg->cmsg_type == RDS_CMSG_RDMA_ARGS) { + args = CMSG_DATA(cmsg); + *rdma_bytes += args->remote_vec.bytes; + } + } + return 0; +} + int rds_sendmsg(struct socket *sock, struct msghdr *msg, size_t payload_len) { struct sock *sk = sock->sk; @@ -1002,6 +1022,7 @@ int rds_sendmsg(struct socket *sock, struct msghdr *msg, size_t payload_len) int nonblock = msg->msg_flags & MSG_DONTWAIT; long timeo = sock_sndtimeo(sk, nonblock); struct rds_conn_path *cpath; + size_t total_payload_len = payload_len, rdma_payload_len = 0; /* Mirror Linux UDP mirror of BSD error message compatibility */ /* XXX: Perhaps MSG_MORE someday */ @@ -1034,6 +1055,16 @@ int rds_sendmsg(struct socket *sock, struct msghdr *msg, size_t payload_len) } release_sock(sk); + ret = rds_rdma_bytes(msg, &rdma_payload_len); + if (ret) + goto out; + + total_payload_len += rdma_payload_len; + if (max_t(size_t, payload_len, rdma_payload_len) > RDS_MAX_MSG_SIZE) { + ret = -EMSGSIZE; + goto out; + } + if (payload_len > rds_sk_sndbuf(rs)) { ret = -EMSGSIZE; goto out; |