Commit:     c18c732ec6bf372aa959ca6534cbfc32e464defd
Parent:     adddd49ddf4ce5a5997f0695b194587290ea72e9
Author:     Steve French <[EMAIL PROTECTED]>
AuthorDate: Wed Oct 17 18:01:11 2007 +0000
Committer:  Steve French <[EMAIL PROTECTED]>
CommitDate: Wed Oct 17 18:01:11 2007 +0000

    [CIFS] fix bad handling of EAGAIN error on kernel_recvmsg in 
    When kernel_recvmsg returns -EAGAIN or -ERESTARTSYS, then
    cifs_demultiplex_thread sleeps for a bit and then tries the read again.
    When it does this, it's not zeroing out the length and that throws off
    the value of total_read. Fix it to zero out the length.
    Can cause memory corruption:
    If kernel_recvmsg returns an error and total_read is a large enough
    value, then we'll end up going through the loop again. total_read will
    be a bogus value, as will (pdu_length-total_read). When this happens we
    end up calling kernel_recvmsg with a bogus value (possibly larger than
    the current iov_len).
    At that point, memcpy_toiovec can overrun iov. It will start walking
    up the stack, casting other things that are there to struct iovecs
    (since it assumes that it's been passed an array of them). Any pointer
    on the stack at an address above the kvec is a candidate for corruption
    Many thanks to Ulrich Obergfell for pointing this out.
    Signed-off-by: Jeff Layton <[EMAIL PROTECTED]>
    Signed-off-by: Steve French <[EMAIL PROTECTED]>
 fs/cifs/CHANGES   |    3 ++-
 fs/cifs/connect.c |    6 +++++-
 2 files changed, 7 insertions(+), 2 deletions(-)

diff --git a/fs/cifs/CHANGES b/fs/cifs/CHANGES
index 70c90c0..2459ef0 100644
--- a/fs/cifs/CHANGES
+++ b/fs/cifs/CHANGES
@@ -10,7 +10,8 @@ opened, read and written as if they were files).  When 1st 
 connect fails (e.g. due to signing negotiation failure) fix
 leak that causes cifsd not to stop and rmmod to fail to cleanup
 cifs_request_buffers pool. Fix problem with POSIX Open/Mkdir on
-bigendian architectures.
+bigendian architectures. Fix possible memory corruption when
+EAGAIN returned on kern_recvmsg.
 Version 1.50
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index 494455e..676bbf2 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -415,7 +415,10 @@ incomplete_rcv:
                        msleep(1); /* minimum sleep to prevent looping
                                allowing socket to clear and app threads to set
                                tcpStatus CifsNeedReconnect if server hung */
-                       continue;
+                       if (pdu_length < 4)
+                               goto incomplete_rcv;
+                       else
+                               continue;
                } else if (length <= 0) {
                        if (server->tcpStatus == CifsNew) {
                                cFYI(1, ("tcp session abend after SMBnegprot"));
@@ -543,6 +546,7 @@ incomplete_rcv:
                                              allowing socket to clear and app
                                              threads to set tcpStatus
                                              CifsNeedReconnect if server hung*/
+                               length = 0;
                        } else if (length <= 0) {
                                cERROR(1, ("Received no data, expecting %d",
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

Reply via email to