smbfs: fix calculation of kernel_recvmsg size parameter in smb_receive()
smb_receive calls kernel_recvmsg with a size that's the minimum of the amount of buffer space in the kvec passed in or req->rq_rlen (which represents the length of the response). This does not take into account any data that was read in a request earlier pass through smb_receive. If the first pass through smb_receive receives some but not all of the response, then the next pass can call kernel_recvmsg with a size field that's too big. kernel_recvmsg can overrun into the next response, throwing off the alignment and making it unrecognizable. This causes messages like this to pop up in the ring buffer: smb_get_length: Invalid NBT packet, code=69 as well as other errors indicating that the response is unrecognizable. Typically this is seen on a smbfs mount under heavy I/O. This patch changes the code to use (req->rq_rlen - req->rq_bytes_recvd) instead instead of just req->rq_rlen, since that should represent the amount of unread data in the response. I think this is correct, but an ACK or NACK from someone more familiar with this code would be appreciated... Signed-off-by: Jeff Layton <jlayton@redhat.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
parent
941e492bdb
commit
ce88cc5ed8
|
@ -329,9 +329,8 @@ smb_receive(struct smb_sb_info *server, struct smb_request *req)
|
|||
msg.msg_control = NULL;
|
||||
|
||||
/* Dont repeat bytes and count available bufferspace */
|
||||
rlen = smb_move_iov(&p, &num, iov, req->rq_bytes_recvd);
|
||||
if (req->rq_rlen < rlen)
|
||||
rlen = req->rq_rlen;
|
||||
rlen = min_t(int, smb_move_iov(&p, &num, iov, req->rq_bytes_recvd),
|
||||
(req->rq_rlen - req->rq_bytes_recvd));
|
||||
|
||||
result = kernel_recvmsg(sock, &msg, p, num, rlen, flags);
|
||||
|
||||
|
|
Loading…
Reference in New Issue