Description of problem: 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 response data that was read in an 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. Public via: http://groups.google.com/group/linux.kernel/browse_thread/thread/dc56e7f449ca228f/4a1b93e39323e91a?hl=en#4a1b93e39323e91a
Patch from Jeffrey Layton: 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);
See bug 241545 I'm not sure that this actually has any security implications. It might, but I've not seen any real issues other than delays as requests were retransmitted. There are a number of other smbfs patches I'm considering for 4.7, and those are being tracked in bug 355141. Some of those probably do have security implications.
*** This bug has been marked as a duplicate of 241545 ***