]> Pileus Git - ~andy/linux/blobdiff - fs/cifs/transport.c
Linux 3.14
[~andy/linux] / fs / cifs / transport.c
index b375709528467b5a1a74e078fae2aeb7813e1a1e..18cd5650a5fc6106394691f6ee5baf37f5d8d49b 100644 (file)
@@ -270,6 +270,26 @@ cifs_rqst_page_to_kvec(struct smb_rqst *rqst, unsigned int idx,
                iov->iov_len = rqst->rq_pagesz;
 }
 
+static unsigned long
+rqst_len(struct smb_rqst *rqst)
+{
+       unsigned int i;
+       struct kvec *iov = rqst->rq_iov;
+       unsigned long buflen = 0;
+
+       /* total up iov array first */
+       for (i = 0; i < rqst->rq_nvec; i++)
+               buflen += iov[i].iov_len;
+
+       /* add in the page array if there is one */
+       if (rqst->rq_npages) {
+               buflen += rqst->rq_pagesz * (rqst->rq_npages - 1);
+               buflen += rqst->rq_tailsz;
+       }
+
+       return buflen;
+}
+
 static int
 smb_send_rqst(struct TCP_Server_Info *server, struct smb_rqst *rqst)
 {
@@ -277,6 +297,7 @@ smb_send_rqst(struct TCP_Server_Info *server, struct smb_rqst *rqst)
        struct kvec *iov = rqst->rq_iov;
        int n_vec = rqst->rq_nvec;
        unsigned int smb_buf_length = get_rfc1002_length(iov[0].iov_base);
+       unsigned long send_length;
        unsigned int i;
        size_t total_len = 0, sent;
        struct socket *ssocket = server->ssocket;
@@ -285,6 +306,14 @@ smb_send_rqst(struct TCP_Server_Info *server, struct smb_rqst *rqst)
        if (ssocket == NULL)
                return -ENOTSOCK;
 
+       /* sanity check send length */
+       send_length = rqst_len(rqst);
+       if (send_length != smb_buf_length + 4) {
+               WARN(1, "Send length mismatch(send_length=%lu smb_buf_length=%u)\n",
+                       send_length, smb_buf_length);
+               return -EIO;
+       }
+
        cifs_dbg(FYI, "Sending smb: smb_len=%u\n", smb_buf_length);
        dump_smb(iov[0].iov_base, iov[0].iov_len);