1 From 9f1a51917649795123bedbefdea678317d392b48 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.
7 BUG: https://bugzilla.samba.org/show_bug.cgi?id=13020
9 Signed-off-by: Jeremy Allison <jra@samba.org>
10 Signed-off-by: Stefan Metzmacher <metze@samba.org>
12 source3/smbd/reply.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++
13 1 file changed, 50 insertions(+)
15 diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c
16 index 1583c2358bb..9625670d653 100644
17 --- a/source3/smbd/reply.c
18 +++ b/source3/smbd/reply.c
19 @@ -3977,6 +3977,9 @@ void reply_writebraw(struct smb_request *req)
22 /* Ensure we don't write bytes past the end of this packet. */
24 + * This already protects us against CVE-2017-12163.
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 @@ -4078,6 +4081,11 @@ void reply_writebraw(struct smb_request *req)
30 exit_server_cleanly("secondary writebraw failed");
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.
38 nwritten = write_file(req,fsp,buf+4,startpos+nwritten,numtowrite);
41 @@ -4159,6 +4167,7 @@ void reply_writeunlock(struct smb_request *req)
42 connection_struct *conn = req->conn;
43 ssize_t nwritten = -1;
48 NTSTATUS status = NT_STATUS_OK;
49 @@ -4191,6 +4200,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;
54 + * Ensure client isn't asking us to write more than
55 + * they sent. CVE-2017-12163.
57 + remaining = smbreq_bufrem(req, data);
58 + if (numtowrite > remaining) {
59 + reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
60 + END_PROFILE(SMBwriteunlock);
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 @@ -4272,6 +4292,7 @@ void reply_write(struct smb_request *req)
69 connection_struct *conn = req->conn;
72 ssize_t nwritten = -1;
75 @@ -4312,6 +4333,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;
80 + * Ensure client isn't asking us to write more than
81 + * they sent. CVE-2017-12163.
83 + remaining = smbreq_bufrem(req, data);
84 + if (numtowrite > remaining) {
85 + reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
86 + END_PROFILE(SMBwrite);
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 @@ -4523,6 +4555,9 @@ void reply_write_and_X(struct smb_request *req)
98 + * This already protects us against CVE-2017-12163.
100 if (smb_doff > smblen || smb_doff + numtowrite < numtowrite ||
101 smb_doff + numtowrite > smblen) {
102 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
103 @@ -4892,6 +4927,7 @@ void reply_writeclose(struct smb_request *req)
105 connection_struct *conn = req->conn;
108 ssize_t nwritten = -1;
109 NTSTATUS close_status = NT_STATUS_OK;
111 @@ -4925,6 +4961,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;
116 + * Ensure client isn't asking us to write more than
117 + * they sent. CVE-2017-12163.
119 + remaining = smbreq_bufrem(req, data);
120 + if (numtowrite > remaining) {
121 + reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
122 + END_PROFILE(SMBwriteclose);
126 if (!fsp->print_file) {
127 init_strict_lock_struct(fsp, (uint64_t)req->smbpid,
128 (uint64_t)startpos, (uint64_t)numtowrite, WRITE_LOCK,
129 @@ -5495,6 +5542,9 @@ void reply_printwrite(struct smb_request *req)
131 numtowrite = SVAL(req->buf, 1);
134 + * This already protects us against CVE-2017-12163.
136 if (req->buflen < numtowrite + 3) {
137 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
138 END_PROFILE(SMBsplwr);