1 |
jpp |
1.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 |
|
|
|