summaryrefslogtreecommitdiff
blob: 74840e62869935b8c4334b9f216e6a87ca036471 (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
diff -urN linux-2.6.7-hardened-r14/fs/smbfs/proc.c linux-2.6.7-hardened-r15/fs/smbfs/proc.c
--- linux-2.6.7-hardened-r14/fs/smbfs/proc.c	2004-11-24 12:46:34.000000000 -0500
+++ linux-2.6.7-hardened-r15/fs/smbfs/proc.c	2004-11-24 12:53:38.883511896 -0500
@@ -1423,9 +1423,9 @@
 	 * So we must first calculate the amount of padding used by the server.
 	 */
 	data_off -= hdrlen;
-	if (data_off > SMB_READX_MAX_PAD) {
-		PARANOIA("offset is larger than max pad!\n");
-		PARANOIA("%d > %d\n", data_off, SMB_READX_MAX_PAD);
+	if (data_off > SMB_READX_MAX_PAD || data_off < 0) {
+		PARANOIA("offset is larger than SMB_READX_MAX_PAD or negative!\n");
+		PARANOIA("%d > %d || %d < 0\n", data_off, SMB_READX_MAX_PAD, data_off);
 		req->rq_rlen = req->rq_bufsize + 1;
 		return;
 	}
diff -urN linux-2.6.7-hardened-r14/fs/smbfs/request.c linux-2.6.7-hardened-r15/fs/smbfs/request.c
--- linux-2.6.7-hardened-r14/fs/smbfs/request.c	2004-11-24 12:46:34.000000000 -0500
+++ linux-2.6.7-hardened-r15/fs/smbfs/request.c	2004-11-24 12:53:38.885511592 -0500
@@ -588,6 +588,10 @@
 	data_count  = WVAL(inbuf, smb_drcnt);
 
 	/* Modify offset for the split header/buffer we use */
+	if (data_offset < hdrlen)
+		goto out_bad_data;
+	if (parm_offset < hdrlen)
+		goto out_bad_parm;
 	data_offset -= hdrlen;
 	parm_offset -= hdrlen;
 
@@ -607,6 +611,10 @@
 		req->rq_lparm = parm_count;
 		req->rq_data = req->rq_buffer + data_offset;
 		req->rq_parm = req->rq_buffer + parm_offset;
+		if (parm_offset + parm_count > req->rq_rlen)
+			goto out_bad_parm;
+		if (data_offset + data_count > req->rq_rlen)
+			goto out_bad_data;
 		return 0;
 	}
 
@@ -634,6 +642,7 @@
 		req->rq_trans2buffer = smb_kmalloc(buf_len, GFP_NOFS);
 		if (!req->rq_trans2buffer)
 			goto out_no_mem;
+		memset(req->rq_trans2buffer, 0, buf_len);
 
 		req->rq_parm = req->rq_trans2buffer;
 		req->rq_data = req->rq_trans2buffer + parm_tot;
@@ -643,8 +652,12 @@
 
 	if (parm_disp + parm_count > req->rq_total_parm)
 		goto out_bad_parm;
+	if (parm_offset + parm_count > req->rq_rlen)
+		goto out_bad_parm;
 	if (data_disp + data_count > req->rq_total_data)
 		goto out_bad_data;
+	if (data_offset + data_count > req->rq_rlen)
+		goto out_bad_data;
 
 	inbuf = req->rq_buffer;
 	memcpy(req->rq_parm + parm_disp, inbuf + parm_offset, parm_count);
@@ -657,8 +670,11 @@
 	 * Check whether we've received all of the data. Note that
 	 * we use the packet totals -- total lengths might shrink!
 	 */
-	if (req->rq_ldata >= data_tot && req->rq_lparm >= parm_tot)
+	if (req->rq_ldata >= data_tot && req->rq_lparm >= parm_tot) {
+		req->rq_ldata = data_tot;
+		req->rq_lparm = parm_tot;
 		return 0;
+	}
 	return 1;
 
 out_too_long:
@@ -676,13 +692,13 @@
 	req->rq_errno = -EIO;
 	goto out;
 out_bad_parm:
-	printk(KERN_ERR "smb_trans2: invalid parms, disp=%d, cnt=%d, tot=%d\n",
-	       parm_disp, parm_count, parm_tot);
+	printk(KERN_ERR "smb_trans2: invalid parms, disp=%d, cnt=%d, tot=%d, ofs=%d\n",
+	       parm_disp, parm_count, parm_tot, parm_offset);
 	req->rq_errno = -EIO;
 	goto out;
 out_bad_data:
-	printk(KERN_ERR "smb_trans2: invalid data, disp=%d, cnt=%d, tot=%d\n",
-	       data_disp, data_count, data_tot);
+	printk(KERN_ERR "smb_trans2: invalid data, disp=%d, cnt=%d, tot=%d, ofs=%d\n",
+	       data_disp, data_count, data_tot, data_offset);
 	req->rq_errno = -EIO;
 out:
 	return req->rq_errno;