1 |
From 364275d1ae8c55242497e7c8804fb28aa3b73465 Mon Sep 17 00:00:00 2001 |
2 |
From: Jeremy Allison <jra@samba.org> |
3 |
Date: Fri, 8 Sep 2017 10:13:14 -0700 |
4 |
Subject: [PATCH] CVE-2017-12163: s3:smbd: Prevent client short SMB1 write from |
5 |
writing server memory to file. |
6 |
|
7 |
BUG: https://bugzilla.samba.org/show_bug.cgi?id=13020 |
8 |
|
9 |
Signed-off-by: Jeremy Allison <jra@samba.org> |
10 |
Signed-off-by: Stefan Metzmacher <metze@samba.org> |
11 |
--- |
12 |
source3/smbd/reply.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++ |
13 |
1 file changed, 50 insertions(+) |
14 |
|
15 |
diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c |
16 |
index 317143f..7b07078 100644 |
17 |
--- a/source3/smbd/reply.c |
18 |
+++ b/source3/smbd/reply.c |
19 |
@@ -4474,6 +4474,9 @@ void reply_writebraw(struct smb_request *req) |
20 |
} |
21 |
|
22 |
/* Ensure we don't write bytes past the end of this packet. */ |
23 |
+ /* |
24 |
+ * This already protects us against CVE-2017-12163. |
25 |
+ */ |
26 |
if (data + numtowrite > smb_base(req->inbuf) + smb_len(req->inbuf)) { |
27 |
reply_nterror(req, NT_STATUS_INVALID_PARAMETER); |
28 |
error_to_writebrawerr(req); |
29 |
@@ -4574,6 +4577,11 @@ void reply_writebraw(struct smb_request *req) |
30 |
exit_server_cleanly("secondary writebraw failed"); |
31 |
} |
32 |
|
33 |
+ /* |
34 |
+ * We are not vulnerable to CVE-2017-12163 |
35 |
+ * here as we are guarenteed to have numtowrite |
36 |
+ * bytes available - we just read from the client. |
37 |
+ */ |
38 |
nwritten = write_file(req,fsp,buf+4,startpos+nwritten,numtowrite); |
39 |
if (nwritten == -1) { |
40 |
TALLOC_FREE(buf); |
41 |
@@ -4647,6 +4655,7 @@ void reply_writeunlock(struct smb_request *req) |
42 |
connection_struct *conn = req->conn; |
43 |
ssize_t nwritten = -1; |
44 |
size_t numtowrite; |
45 |
+ size_t remaining; |
46 |
off_t startpos; |
47 |
const char *data; |
48 |
NTSTATUS status = NT_STATUS_OK; |
49 |
@@ -4679,6 +4688,17 @@ void reply_writeunlock(struct smb_request *req) |
50 |
startpos = IVAL_TO_SMB_OFF_T(req->vwv+2, 0); |
51 |
data = (const char *)req->buf + 3; |
52 |
|
53 |
+ /* |
54 |
+ * Ensure client isn't asking us to write more than |
55 |
+ * they sent. CVE-2017-12163. |
56 |
+ */ |
57 |
+ remaining = smbreq_bufrem(req, data); |
58 |
+ if (numtowrite > remaining) { |
59 |
+ reply_nterror(req, NT_STATUS_INVALID_PARAMETER); |
60 |
+ END_PROFILE(SMBwriteunlock); |
61 |
+ return; |
62 |
+ } |
63 |
+ |
64 |
if (!fsp->print_file && numtowrite > 0) { |
65 |
init_strict_lock_struct(fsp, (uint64_t)req->smbpid, |
66 |
(uint64_t)startpos, (uint64_t)numtowrite, WRITE_LOCK, |
67 |
@@ -4756,6 +4776,7 @@ void reply_write(struct smb_request *req) |
68 |
{ |
69 |
connection_struct *conn = req->conn; |
70 |
size_t numtowrite; |
71 |
+ size_t remaining; |
72 |
ssize_t nwritten = -1; |
73 |
off_t startpos; |
74 |
const char *data; |
75 |
@@ -4796,6 +4817,17 @@ void reply_write(struct smb_request *req) |
76 |
startpos = IVAL_TO_SMB_OFF_T(req->vwv+2, 0); |
77 |
data = (const char *)req->buf + 3; |
78 |
|
79 |
+ /* |
80 |
+ * Ensure client isn't asking us to write more than |
81 |
+ * they sent. CVE-2017-12163. |
82 |
+ */ |
83 |
+ remaining = smbreq_bufrem(req, data); |
84 |
+ if (numtowrite > remaining) { |
85 |
+ reply_nterror(req, NT_STATUS_INVALID_PARAMETER); |
86 |
+ END_PROFILE(SMBwrite); |
87 |
+ return; |
88 |
+ } |
89 |
+ |
90 |
if (!fsp->print_file) { |
91 |
init_strict_lock_struct(fsp, (uint64_t)req->smbpid, |
92 |
(uint64_t)startpos, (uint64_t)numtowrite, WRITE_LOCK, |
93 |
@@ -5018,6 +5050,9 @@ void reply_write_and_X(struct smb_request *req) |
94 |
goto out; |
95 |
} |
96 |
} else { |
97 |
+ /* |
98 |
+ * This already protects us against CVE-2017-12163. |
99 |
+ */ |
100 |
if (smb_doff > smblen || smb_doff + numtowrite < numtowrite || |
101 |
smb_doff + numtowrite > smblen) { |
102 |
reply_nterror(req, NT_STATUS_INVALID_PARAMETER); |
103 |
@@ -5444,6 +5479,7 @@ void reply_writeclose(struct smb_request *req) |
104 |
{ |
105 |
connection_struct *conn = req->conn; |
106 |
size_t numtowrite; |
107 |
+ size_t remaining; |
108 |
ssize_t nwritten = -1; |
109 |
NTSTATUS close_status = NT_STATUS_OK; |
110 |
off_t startpos; |
111 |
@@ -5477,6 +5513,17 @@ void reply_writeclose(struct smb_request *req) |
112 |
mtime = convert_time_t_to_timespec(srv_make_unix_date3(req->vwv+4)); |
113 |
data = (const char *)req->buf + 1; |
114 |
|
115 |
+ /* |
116 |
+ * Ensure client isn't asking us to write more than |
117 |
+ * they sent. CVE-2017-12163. |
118 |
+ */ |
119 |
+ remaining = smbreq_bufrem(req, data); |
120 |
+ if (numtowrite > remaining) { |
121 |
+ reply_nterror(req, NT_STATUS_INVALID_PARAMETER); |
122 |
+ END_PROFILE(SMBwriteclose); |
123 |
+ return; |
124 |
+ } |
125 |
+ |
126 |
if (fsp->print_file == NULL) { |
127 |
init_strict_lock_struct(fsp, (uint64_t)req->smbpid, |
128 |
(uint64_t)startpos, (uint64_t)numtowrite, WRITE_LOCK, |
129 |
@@ -6069,6 +6116,9 @@ void reply_printwrite(struct smb_request *req) |
130 |
|
131 |
numtowrite = SVAL(req->buf, 1); |
132 |
|
133 |
+ /* |
134 |
+ * This already protects us against CVE-2017-12163. |
135 |
+ */ |
136 |
if (req->buflen < numtowrite + 3) { |
137 |
reply_nterror(req, NT_STATUS_INVALID_PARAMETER); |
138 |
END_PROFILE(SMBsplwr); |
139 |
-- |
140 |
1.9.1 |
141 |
|