summaryrefslogtreecommitdiffstats
path: root/cifs-sanity-check-length-of-data-to-send-before-sending.patch
blob: b0f31156e46596921ddfd27f932e988afdefcdba (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
Path: news.gmane.org!not-for-mail
From: Jeff Layton <jlayton-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
Newsgroups: gmane.linux.kernel.cifs
Subject: [PATCH] cifs: sanity check length of data to send before sending
Date: Fri, 14 Feb 2014 07:21:00 -0500
Lines: 72
Approved: news@gmane.org
Message-ID: <1392380460-6997-1-git-send-email-jlayton@redhat.com>
NNTP-Posting-Host: plane.gmane.org
X-Trace: ger.gmane.org 1392380460 7637 80.91.229.3 (14 Feb 2014 12:21:00 GMT)
X-Complaints-To: usenet@ger.gmane.org
NNTP-Posting-Date: Fri, 14 Feb 2014 12:21:00 +0000 (UTC)
Cc: linux-cifs-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
To: smfrench-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org
Original-X-From: linux-cifs-owner-u79uwXL29TY76Z2rM5mHXA@public.gmane.org Fri Feb 14 13:21:08 2014
Return-path: <linux-cifs-owner-u79uwXL29TY76Z2rM5mHXA@public.gmane.org>
Envelope-to: glkc-linux-cifs-wOFGN7rlS/M9smdsby/KFg@public.gmane.org
Original-Received: from vger.kernel.org ([209.132.180.67])
	by plane.gmane.org with esmtp (Exim 4.69)
	(envelope-from <linux-cifs-owner-u79uwXL29TY76Z2rM5mHXA@public.gmane.org>)
	id 1WEHlT-0001gj-Pf
	for glkc-linux-cifs-wOFGN7rlS/M9smdsby/KFg@public.gmane.org; Fri, 14 Feb 2014 13:21:08 +0100
Original-Received: (majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org) by vger.kernel.org via listexpand
	id S1751935AbaBNMVH (ORCPT <rfc822;glkc-linux-cifs@m.gmane.org>);
	Fri, 14 Feb 2014 07:21:07 -0500
Original-Received: from mail-qc0-f170.google.com ([209.85.216.170]:60206 "EHLO
	mail-qc0-f170.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org
	with ESMTP id S1751288AbaBNMVG (ORCPT
	<rfc822;linux-cifs-u79uwXL29TY76Z2rM5mHXA@public.gmane.org>); Fri, 14 Feb 2014 07:21:06 -0500
Original-Received: by mail-qc0-f170.google.com with SMTP id e9so20306487qcy.29
        for <linux-cifs-u79uwXL29TY76Z2rM5mHXA@public.gmane.org>; Fri, 14 Feb 2014 04:21:05 -0800 (PST)
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
        d=1e100.net; s=20130820;
        h=x-gm-message-state:sender:from:to:cc:subject:date:message-id;
        bh=8FvTfO9jKY+Fzw5nmoxw6PuPxfXM/khvtS/Hnxnu+to=;
        b=i7Gy5AwQiFX7hVMJJMjvAR61u2zO8E7tTAgE0SfPp25untipj/RTae8xcA+0vVrznY
         sZwOPATUyFmu2mXAKh5L0WutFNF3SQirPVgM5jaKlMZQT253YInioO1AwD00Jtio00LX
         wOt19I6v3umZfSqCBw1dyDiH66kX4xKaKqdQoY2+nEsicG4RJvp4PpaLhG454nfpVxfN
         HeskcNJ5RBvg17JpDvKX6THqbKWsHSHHqKKCROERxeTbs7HTgV9jTNSDeOuPr6Loiovi
         9DBQwQwMmlC9NebDqR5xatva30WRhyCp/xyHNaoY+aVk8N6r5YlFphLmLRvmaZ0Ed2CH
         17WA==
X-Gm-Message-State: ALoCoQmHyaepi0IHvwKS024wRq/srAdGRdo0UGUynLggzf843S3Yj7dwW53RjNbTDG1Y4w+/mqOB
X-Received: by 10.229.13.133 with SMTP id c5mr12315963qca.22.1392380465000;
        Fri, 14 Feb 2014 04:21:05 -0800 (PST)
Original-Received: from tlielax.poochiereds.net ([2001:470:8:d63:3a60:77ff:fe93:a95d])
        by mx.google.com with ESMTPSA id u4sm15047497qai.21.2014.02.14.04.21.04
        for <multiple recipients>
        (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128);
        Fri, 14 Feb 2014 04:21:04 -0800 (PST)
X-Mailer: git-send-email 1.8.5.3
Original-Sender: linux-cifs-owner-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
Precedence: bulk
List-ID: <linux-cifs.vger.kernel.org>
X-Mailing-List: linux-cifs-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
Xref: news.gmane.org gmane.linux.kernel.cifs:9402
Archived-At: <http://permalink.gmane.org/gmane.linux.kernel.cifs/9402>

We had a bug discovered recently where an upper layer function
(cifs_iovec_write) could pass down a smb_rqst with an invalid amount of
data in it. The length of the SMB frame would be correct, but the rqst
struct would cause smb_send_rqst to send nearly 4GB of data.

This should never be the case. Add some sanity checking to the beginning
of smb_send_rqst that ensures that the amount of data we're going to
send agrees with the length in the RFC1002 header. If it doesn't, WARN()
and return -EIO to the upper layers.

Signed-off-by: Jeff Layton <jlayton-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
---
 fs/cifs/transport.c | 29 +++++++++++++++++++++++++++++
 1 file changed, 29 insertions(+)

diff --git a/fs/cifs/transport.c b/fs/cifs/transport.c
index b37570952846..18cd5650a5fc 100644
--- a/fs/cifs/transport.c
+++ b/fs/cifs/transport.c
@@ -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);
 
-- 
1.8.5.3