Gitweb: http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=ce88cc5ed80de746f5bd2d8242291c87e7b87f63 Commit: ce88cc5ed80de746f5bd2d8242291c87e7b87f63 Parent: 941e492bdb1239d2ca8f5736cdfd3ff83d00cb90 Author: Jeff Layton <[EMAIL PROTECTED]> AuthorDate: Wed Feb 6 01:36:43 2008 -0800 Committer: Linus Torvalds <[EMAIL PROTECTED]> CommitDate: Wed Feb 6 10:41:02 2008 -0800
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 <[EMAIL PROTECTED]> Signed-off-by: Andrew Morton <[EMAIL PROTECTED]> Signed-off-by: Linus Torvalds <[EMAIL PROTECTED]> --- fs/smbfs/sock.c | 5 ++--- 1 files changed, 2 insertions(+), 3 deletions(-) diff --git a/fs/smbfs/sock.c b/fs/smbfs/sock.c index e48bd82..e37fe4d 100644 --- a/fs/smbfs/sock.c +++ b/fs/smbfs/sock.c @@ -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); - To unsubscribe from this list: send the line "unsubscribe git-commits-head" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html