1 |
unnilennium |
1.1 |
From 72e7e7b7d378e7ba3afe18ea41802aac5366b094 Mon Sep 17 00:00:00 2001 |
2 |
|
|
From: Ralph Boehme <slow@samba.org> |
3 |
|
|
Date: Sun, 19 Mar 2017 15:58:17 +0100 |
4 |
|
|
Subject: [PATCH 01/13] CVE-2017-2619: s3/smbd: re-open directory after |
5 |
|
|
dptr_CloseDir() |
6 |
|
|
|
7 |
|
|
dptr_CloseDir() will close and invalidate the fsp's file descriptor, we |
8 |
|
|
have to reopen it. |
9 |
|
|
|
10 |
|
|
Bug: https://bugzilla.samba.org/show_bug.cgi?id=12496 |
11 |
|
|
|
12 |
|
|
Signed-off-by: Ralph Boehme <slow@samba.org> |
13 |
|
|
Reviewed-by: Uri Simchoni <uri@samba.org> |
14 |
|
|
--- |
15 |
|
|
source3/smbd/smb2_query_directory.c | 17 +++++++++++++++++ |
16 |
|
|
1 file changed, 17 insertions(+) |
17 |
|
|
|
18 |
|
|
diff --git a/source3/smbd/smb2_query_directory.c b/source3/smbd/smb2_query_directory.c |
19 |
|
|
index 4b6ca1b..1703310 100644 |
20 |
|
|
--- a/source3/smbd/smb2_query_directory.c |
21 |
|
|
+++ b/source3/smbd/smb2_query_directory.c |
22 |
|
|
@@ -24,6 +24,7 @@ |
23 |
|
|
#include "../libcli/smb/smb_common.h" |
24 |
|
|
#include "trans2.h" |
25 |
|
|
#include "../lib/util/tevent_ntstatus.h" |
26 |
|
|
+#include "system/filesys.h" |
27 |
|
|
|
28 |
|
|
static struct tevent_req *smbd_smb2_query_directory_send(TALLOC_CTX *mem_ctx, |
29 |
|
|
struct tevent_context *ev, |
30 |
|
|
@@ -322,7 +323,23 @@ static struct tevent_req *smbd_smb2_query_directory_send(TALLOC_CTX *mem_ctx, |
31 |
|
|
} |
32 |
|
|
|
33 |
|
|
if (in_flags & SMB2_CONTINUE_FLAG_REOPEN) { |
34 |
|
|
+ int flags; |
35 |
|
|
+ |
36 |
|
|
dptr_CloseDir(fsp); |
37 |
|
|
+ |
38 |
|
|
+ /* |
39 |
|
|
+ * dptr_CloseDir() will close and invalidate the fsp's file |
40 |
|
|
+ * descriptor, we have to reopen it. |
41 |
|
|
+ */ |
42 |
|
|
+ |
43 |
|
|
+ flags = O_RDONLY; |
44 |
|
|
+#ifdef O_DIRECTORY |
45 |
|
|
+ flags |= O_DIRECTORY; |
46 |
|
|
+#endif |
47 |
|
|
+ status = fd_open(conn, fsp, flags, 0); |
48 |
|
|
+ if (tevent_req_nterror(req, status)) { |
49 |
|
|
+ return tevent_req_post(req, ev); |
50 |
|
|
+ } |
51 |
|
|
} |
52 |
|
|
|
53 |
|
|
if (!smbreq->posix_pathnames) { |
54 |
|
|
-- |
55 |
|
|
2.9.3 |
56 |
|
|
|
57 |
|
|
|
58 |
|
|
From f9a9e7ed2f11c8eb9f8f9f40ec054e9735614e91 Mon Sep 17 00:00:00 2001 |
59 |
|
|
From: Ralph Boehme <slow@samba.org> |
60 |
|
|
Date: Sun, 19 Mar 2017 18:52:10 +0100 |
61 |
|
|
Subject: [PATCH 02/13] CVE-2017-2619: s4/torture: add SMB2_FIND tests with |
62 |
|
|
SMB2_CONTINUE_FLAG_REOPEN flag |
63 |
|
|
|
64 |
|
|
Bug: https://bugzilla.samba.org/show_bug.cgi?id=12496 |
65 |
|
|
|
66 |
|
|
Signed-off-by: Ralph Boehme <slow@samba.org> |
67 |
|
|
Reviewed-by: Uri Simchoni <uri@samba.org> |
68 |
|
|
--- |
69 |
|
|
source4/torture/smb2/dir.c | 12 ++++++++++-- |
70 |
|
|
1 file changed, 10 insertions(+), 2 deletions(-) |
71 |
|
|
|
72 |
|
|
diff --git a/source4/torture/smb2/dir.c b/source4/torture/smb2/dir.c |
73 |
|
|
index 98844b4..db8e456 100644 |
74 |
|
|
--- a/source4/torture/smb2/dir.c |
75 |
|
|
+++ b/source4/torture/smb2/dir.c |
76 |
|
|
@@ -674,7 +674,7 @@ bool fill_result(void *private_data, |
77 |
|
|
return true; |
78 |
|
|
} |
79 |
|
|
|
80 |
|
|
-enum continue_type {CONT_SINGLE, CONT_INDEX, CONT_RESTART}; |
81 |
|
|
+enum continue_type {CONT_SINGLE, CONT_INDEX, CONT_RESTART, CONT_REOPEN}; |
82 |
|
|
|
83 |
|
|
static NTSTATUS multiple_smb2_search(struct smb2_tree *tree, |
84 |
|
|
TALLOC_CTX *tctx, |
85 |
|
|
@@ -700,6 +700,9 @@ static NTSTATUS multiple_smb2_search(struct smb2_tree *tree, |
86 |
|
|
|
87 |
|
|
/* The search should start from the beginning everytime */ |
88 |
|
|
f.in.continue_flags = SMB2_CONTINUE_FLAG_RESTART; |
89 |
|
|
+ if (cont_type == CONT_REOPEN) { |
90 |
|
|
+ f.in.continue_flags = SMB2_CONTINUE_FLAG_REOPEN; |
91 |
|
|
+ } |
92 |
|
|
|
93 |
|
|
do { |
94 |
|
|
status = smb2_find_level(tree, tree, &f, &count, &d); |
95 |
|
|
@@ -803,18 +806,23 @@ static bool test_many_files(struct torture_context *tctx, |
96 |
|
|
{"SMB2_FIND_BOTH_DIRECTORY_INFO", "SINGLE", SMB2_FIND_BOTH_DIRECTORY_INFO, RAW_SEARCH_DATA_BOTH_DIRECTORY_INFO, CONT_SINGLE}, |
97 |
|
|
{"SMB2_FIND_BOTH_DIRECTORY_INFO", "INDEX", SMB2_FIND_BOTH_DIRECTORY_INFO, RAW_SEARCH_DATA_BOTH_DIRECTORY_INFO, CONT_INDEX}, |
98 |
|
|
{"SMB2_FIND_BOTH_DIRECTORY_INFO", "RESTART", SMB2_FIND_BOTH_DIRECTORY_INFO, RAW_SEARCH_DATA_BOTH_DIRECTORY_INFO, CONT_RESTART}, |
99 |
|
|
+ {"SMB2_FIND_BOTH_DIRECTORY_INFO", "REOPEN", SMB2_FIND_BOTH_DIRECTORY_INFO, RAW_SEARCH_DATA_BOTH_DIRECTORY_INFO, CONT_REOPEN}, |
100 |
|
|
{"SMB2_FIND_DIRECTORY_INFO", "SINGLE", SMB2_FIND_DIRECTORY_INFO, RAW_SEARCH_DATA_DIRECTORY_INFO, CONT_SINGLE}, |
101 |
|
|
{"SMB2_FIND_DIRECTORY_INFO", "INDEX", SMB2_FIND_DIRECTORY_INFO, RAW_SEARCH_DATA_DIRECTORY_INFO, CONT_INDEX}, |
102 |
|
|
{"SMB2_FIND_DIRECTORY_INFO", "RESTART", SMB2_FIND_DIRECTORY_INFO, RAW_SEARCH_DATA_DIRECTORY_INFO, CONT_RESTART}, |
103 |
|
|
+ {"SMB2_FIND_DIRECTORY_INFO", "REOPEN", SMB2_FIND_DIRECTORY_INFO, RAW_SEARCH_DATA_DIRECTORY_INFO, CONT_REOPEN}, |
104 |
|
|
{"SMB2_FIND_FULL_DIRECTORY_INFO", "SINGLE", SMB2_FIND_FULL_DIRECTORY_INFO, RAW_SEARCH_DATA_FULL_DIRECTORY_INFO, CONT_SINGLE}, |
105 |
|
|
{"SMB2_FIND_FULL_DIRECTORY_INFO", "INDEX", SMB2_FIND_FULL_DIRECTORY_INFO, RAW_SEARCH_DATA_FULL_DIRECTORY_INFO, CONT_INDEX}, |
106 |
|
|
{"SMB2_FIND_FULL_DIRECTORY_INFO", "RESTART", SMB2_FIND_FULL_DIRECTORY_INFO, RAW_SEARCH_DATA_FULL_DIRECTORY_INFO, CONT_RESTART}, |
107 |
|
|
+ {"SMB2_FIND_FULL_DIRECTORY_INFO", "REOPEN", SMB2_FIND_FULL_DIRECTORY_INFO, RAW_SEARCH_DATA_FULL_DIRECTORY_INFO, CONT_REOPEN}, |
108 |
|
|
{"SMB2_FIND_ID_FULL_DIRECTORY_INFO", "SINGLE", SMB2_FIND_ID_FULL_DIRECTORY_INFO, RAW_SEARCH_DATA_ID_FULL_DIRECTORY_INFO, CONT_SINGLE}, |
109 |
|
|
{"SMB2_FIND_ID_FULL_DIRECTORY_INFO", "INDEX", SMB2_FIND_ID_FULL_DIRECTORY_INFO, RAW_SEARCH_DATA_ID_FULL_DIRECTORY_INFO, CONT_INDEX}, |
110 |
|
|
{"SMB2_FIND_ID_FULL_DIRECTORY_INFO", "RESTART", SMB2_FIND_ID_FULL_DIRECTORY_INFO, RAW_SEARCH_DATA_ID_FULL_DIRECTORY_INFO, CONT_RESTART}, |
111 |
|
|
+ {"SMB2_FIND_ID_FULL_DIRECTORY_INFO", "REOPEN", SMB2_FIND_ID_FULL_DIRECTORY_INFO, RAW_SEARCH_DATA_ID_FULL_DIRECTORY_INFO, CONT_REOPEN}, |
112 |
|
|
{"SMB2_FIND_ID_BOTH_DIRECTORY_INFO", "SINGLE", SMB2_FIND_ID_BOTH_DIRECTORY_INFO, RAW_SEARCH_DATA_ID_BOTH_DIRECTORY_INFO, CONT_SINGLE}, |
113 |
|
|
{"SMB2_FIND_ID_BOTH_DIRECTORY_INFO", "INDEX", SMB2_FIND_ID_BOTH_DIRECTORY_INFO, RAW_SEARCH_DATA_ID_BOTH_DIRECTORY_INFO, CONT_INDEX}, |
114 |
|
|
- {"SMB2_FIND_ID_BOTH_DIRECTORY_INFO", "RESTART", SMB2_FIND_ID_BOTH_DIRECTORY_INFO, RAW_SEARCH_DATA_ID_BOTH_DIRECTORY_INFO, CONT_RESTART} |
115 |
|
|
+ {"SMB2_FIND_ID_BOTH_DIRECTORY_INFO", "RESTART", SMB2_FIND_ID_BOTH_DIRECTORY_INFO, RAW_SEARCH_DATA_ID_BOTH_DIRECTORY_INFO, CONT_RESTART}, |
116 |
|
|
+ {"SMB2_FIND_ID_BOTH_DIRECTORY_INFO", "REOPEN", SMB2_FIND_ID_BOTH_DIRECTORY_INFO, RAW_SEARCH_DATA_ID_BOTH_DIRECTORY_INFO, CONT_REOPEN}, |
117 |
|
|
}; |
118 |
|
|
|
119 |
|
|
smb2_deltree(tree, DNAME); |
120 |
|
|
-- |
121 |
|
|
2.9.3 |
122 |
|
|
|
123 |
|
|
|
124 |
|
|
From d329035b5bda87ab95a33b8d4af1936079db6fd1 Mon Sep 17 00:00:00 2001 |
125 |
|
|
From: Jeremy Allison <jra@samba.org> |
126 |
|
|
Date: Mon, 19 Dec 2016 11:55:56 -0800 |
127 |
|
|
Subject: [PATCH 03/13] CVE-2017-2619: s3: smbd: Create wrapper function for |
128 |
|
|
OpenDir in preparation for making robust. |
129 |
|
|
|
130 |
|
|
BUG: https://bugzilla.samba.org/show_bug.cgi?id=12496 |
131 |
|
|
|
132 |
|
|
Signed-off-by: Jeremy Allison <jra@samba.org> |
133 |
|
|
Reviewed-by: Uri Simchoni <uri@samba.org> |
134 |
|
|
--- |
135 |
|
|
source3/smbd/dir.c | 15 ++++++++++++++- |
136 |
|
|
1 file changed, 14 insertions(+), 1 deletion(-) |
137 |
|
|
|
138 |
|
|
diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c |
139 |
|
|
index 3805915..cbd32e3 100644 |
140 |
|
|
--- a/source3/smbd/dir.c |
141 |
|
|
+++ b/source3/smbd/dir.c |
142 |
|
|
@@ -1588,7 +1588,8 @@ static int smb_Dir_destructor(struct smb_Dir *dirp) |
143 |
|
|
Open a directory. |
144 |
|
|
********************************************************************/ |
145 |
|
|
|
146 |
|
|
-struct smb_Dir *OpenDir(TALLOC_CTX *mem_ctx, connection_struct *conn, |
147 |
|
|
+static struct smb_Dir *OpenDir_internal(TALLOC_CTX *mem_ctx, |
148 |
|
|
+ connection_struct *conn, |
149 |
|
|
const char *name, |
150 |
|
|
const char *mask, |
151 |
|
|
uint32_t attr) |
152 |
|
|
@@ -1628,6 +1629,18 @@ struct smb_Dir *OpenDir(TALLOC_CTX *mem_ctx, connection_struct *conn, |
153 |
|
|
return NULL; |
154 |
|
|
} |
155 |
|
|
|
156 |
|
|
+struct smb_Dir *OpenDir(TALLOC_CTX *mem_ctx, connection_struct *conn, |
157 |
|
|
+ const char *name, |
158 |
|
|
+ const char *mask, |
159 |
|
|
+ uint32_t attr) |
160 |
|
|
+{ |
161 |
|
|
+ return OpenDir_internal(mem_ctx, |
162 |
|
|
+ conn, |
163 |
|
|
+ name, |
164 |
|
|
+ mask, |
165 |
|
|
+ attr); |
166 |
|
|
+} |
167 |
|
|
+ |
168 |
|
|
/******************************************************************* |
169 |
|
|
Open a directory from an fsp. |
170 |
|
|
********************************************************************/ |
171 |
|
|
-- |
172 |
|
|
2.9.3 |
173 |
|
|
|
174 |
|
|
|
175 |
|
|
From 484dda03a69f5c687b6ec6db1332bcc51e72e0c2 Mon Sep 17 00:00:00 2001 |
176 |
|
|
From: Jeremy Allison <jra@samba.org> |
177 |
|
|
Date: Mon, 19 Dec 2016 16:25:26 -0800 |
178 |
|
|
Subject: [PATCH 04/13] CVE-2017-2619: s3: smbd: Opendir_internal() early |
179 |
|
|
return if SMB_VFS_OPENDIR failed. |
180 |
|
|
|
181 |
|
|
BUG: https://bugzilla.samba.org/show_bug.cgi?id=12496 |
182 |
|
|
|
183 |
|
|
Signed-off-by: Jeremy Allison <jra@samba.org> |
184 |
|
|
Reviewed-by: Uri Simchoni <uri@samba.org> |
185 |
|
|
--- |
186 |
|
|
source3/smbd/dir.c | 16 ++++++++-------- |
187 |
|
|
1 file changed, 8 insertions(+), 8 deletions(-) |
188 |
|
|
|
189 |
|
|
diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c |
190 |
|
|
index cbd32e3..ea4b301 100644 |
191 |
|
|
--- a/source3/smbd/dir.c |
192 |
|
|
+++ b/source3/smbd/dir.c |
193 |
|
|
@@ -1601,20 +1601,12 @@ static struct smb_Dir *OpenDir_internal(TALLOC_CTX *mem_ctx, |
194 |
|
|
return NULL; |
195 |
|
|
} |
196 |
|
|
|
197 |
|
|
- dirp->conn = conn; |
198 |
|
|
- dirp->name_cache_size = lp_directory_name_cache_size(SNUM(conn)); |
199 |
|
|
- |
200 |
|
|
dirp->dir_path = talloc_strdup(dirp, name); |
201 |
|
|
if (!dirp->dir_path) { |
202 |
|
|
errno = ENOMEM; |
203 |
|
|
goto fail; |
204 |
|
|
} |
205 |
|
|
|
206 |
|
|
- if (sconn && !sconn->using_smb2) { |
207 |
|
|
- sconn->searches.dirhandles_open++; |
208 |
|
|
- } |
209 |
|
|
- talloc_set_destructor(dirp, smb_Dir_destructor); |
210 |
|
|
- |
211 |
|
|
dirp->dir = SMB_VFS_OPENDIR(conn, dirp->dir_path, mask, attr); |
212 |
|
|
if (!dirp->dir) { |
213 |
|
|
DEBUG(5,("OpenDir: Can't open %s. %s\n", dirp->dir_path, |
214 |
|
|
@@ -1622,6 +1614,14 @@ static struct smb_Dir *OpenDir_internal(TALLOC_CTX *mem_ctx, |
215 |
|
|
goto fail; |
216 |
|
|
} |
217 |
|
|
|
218 |
|
|
+ dirp->conn = conn; |
219 |
|
|
+ dirp->name_cache_size = lp_directory_name_cache_size(SNUM(conn)); |
220 |
|
|
+ |
221 |
|
|
+ if (sconn && !sconn->using_smb2) { |
222 |
|
|
+ sconn->searches.dirhandles_open++; |
223 |
|
|
+ } |
224 |
|
|
+ talloc_set_destructor(dirp, smb_Dir_destructor); |
225 |
|
|
+ |
226 |
|
|
return dirp; |
227 |
|
|
|
228 |
|
|
fail: |
229 |
|
|
-- |
230 |
|
|
2.9.3 |
231 |
|
|
|
232 |
|
|
|
233 |
|
|
From 84d4bbde7c1682e4c8daf680f930a14e3444f659 Mon Sep 17 00:00:00 2001 |
234 |
|
|
From: Jeremy Allison <jra@samba.org> |
235 |
|
|
Date: Mon, 19 Dec 2016 16:35:00 -0800 |
236 |
|
|
Subject: [PATCH 05/13] CVE-2017-2619: s3: smbd: Create and use |
237 |
|
|
open_dir_safely(). Use from OpenDir(). |
238 |
|
|
|
239 |
|
|
Hardens OpenDir against TOC/TOU races. |
240 |
|
|
|
241 |
|
|
BUG: https://bugzilla.samba.org/show_bug.cgi?id=12496 |
242 |
|
|
|
243 |
|
|
Signed-off-by: Jeremy Allison <jra@samba.org> |
244 |
|
|
Reviewed-by: Uri Simchoni <uri@samba.org> |
245 |
|
|
--- |
246 |
|
|
source3/smbd/dir.c | 70 +++++++++++++++++++++++++++++++++++++++++++++++------- |
247 |
|
|
1 file changed, 61 insertions(+), 9 deletions(-) |
248 |
|
|
|
249 |
|
|
diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c |
250 |
|
|
index ea4b301..39a6e67 100644 |
251 |
|
|
--- a/source3/smbd/dir.c |
252 |
|
|
+++ b/source3/smbd/dir.c |
253 |
|
|
@@ -1601,15 +1601,9 @@ static struct smb_Dir *OpenDir_internal(TALLOC_CTX *mem_ctx, |
254 |
|
|
return NULL; |
255 |
|
|
} |
256 |
|
|
|
257 |
|
|
- dirp->dir_path = talloc_strdup(dirp, name); |
258 |
|
|
- if (!dirp->dir_path) { |
259 |
|
|
- errno = ENOMEM; |
260 |
|
|
- goto fail; |
261 |
|
|
- } |
262 |
|
|
- |
263 |
|
|
- dirp->dir = SMB_VFS_OPENDIR(conn, dirp->dir_path, mask, attr); |
264 |
|
|
+ dirp->dir = SMB_VFS_OPENDIR(conn, name, mask, attr); |
265 |
|
|
if (!dirp->dir) { |
266 |
|
|
- DEBUG(5,("OpenDir: Can't open %s. %s\n", dirp->dir_path, |
267 |
|
|
+ DEBUG(5,("OpenDir: Can't open %s. %s\n", name, |
268 |
|
|
strerror(errno) )); |
269 |
|
|
goto fail; |
270 |
|
|
} |
271 |
|
|
@@ -1629,12 +1623,70 @@ static struct smb_Dir *OpenDir_internal(TALLOC_CTX *mem_ctx, |
272 |
|
|
return NULL; |
273 |
|
|
} |
274 |
|
|
|
275 |
|
|
+/**************************************************************************** |
276 |
|
|
+ Open a directory handle by pathname, ensuring it's under the share path. |
277 |
|
|
+****************************************************************************/ |
278 |
|
|
+ |
279 |
|
|
+static struct smb_Dir *open_dir_safely(TALLOC_CTX *ctx, |
280 |
|
|
+ connection_struct *conn, |
281 |
|
|
+ const char *name, |
282 |
|
|
+ const char *wcard, |
283 |
|
|
+ uint32_t attr) |
284 |
|
|
+{ |
285 |
|
|
+ struct smb_Dir *dir_hnd = NULL; |
286 |
|
|
+ char *saved_dir = vfs_GetWd(ctx, conn); |
287 |
|
|
+ NTSTATUS status; |
288 |
|
|
+ |
289 |
|
|
+ if (saved_dir == NULL) { |
290 |
|
|
+ return NULL; |
291 |
|
|
+ } |
292 |
|
|
+ |
293 |
|
|
+ if (vfs_ChDir(conn, name) == -1) { |
294 |
|
|
+ goto out; |
295 |
|
|
+ } |
296 |
|
|
+ |
297 |
|
|
+ /* |
298 |
|
|
+ * Now the directory is pinned, use |
299 |
|
|
+ * REALPATH to ensure we can access it. |
300 |
|
|
+ */ |
301 |
|
|
+ status = check_name(conn, "."); |
302 |
|
|
+ if (!NT_STATUS_IS_OK(status)) { |
303 |
|
|
+ goto out; |
304 |
|
|
+ } |
305 |
|
|
+ |
306 |
|
|
+ dir_hnd = OpenDir_internal(ctx, |
307 |
|
|
+ conn, |
308 |
|
|
+ ".", |
309 |
|
|
+ wcard, |
310 |
|
|
+ attr); |
311 |
|
|
+ |
312 |
|
|
+ if (dir_hnd == NULL) { |
313 |
|
|
+ goto out; |
314 |
|
|
+ } |
315 |
|
|
+ |
316 |
|
|
+ /* |
317 |
|
|
+ * OpenDir_internal only gets "." as the dir name. |
318 |
|
|
+ * Store the real dir name here. |
319 |
|
|
+ */ |
320 |
|
|
+ |
321 |
|
|
+ dir_hnd->dir_path = talloc_strdup(dir_hnd, name); |
322 |
|
|
+ if (!dir_hnd->dir_path) { |
323 |
|
|
+ errno = ENOMEM; |
324 |
|
|
+ } |
325 |
|
|
+ |
326 |
|
|
+ out: |
327 |
|
|
+ |
328 |
|
|
+ vfs_ChDir(conn, saved_dir); |
329 |
|
|
+ TALLOC_FREE(saved_dir); |
330 |
|
|
+ return dir_hnd; |
331 |
|
|
+} |
332 |
|
|
+ |
333 |
|
|
struct smb_Dir *OpenDir(TALLOC_CTX *mem_ctx, connection_struct *conn, |
334 |
|
|
const char *name, |
335 |
|
|
const char *mask, |
336 |
|
|
uint32_t attr) |
337 |
|
|
{ |
338 |
|
|
- return OpenDir_internal(mem_ctx, |
339 |
|
|
+ return open_dir_safely(mem_ctx, |
340 |
|
|
conn, |
341 |
|
|
name, |
342 |
|
|
mask, |
343 |
|
|
-- |
344 |
|
|
2.9.3 |
345 |
|
|
|
346 |
|
|
|
347 |
|
|
From 8aece1e0d15bf059daf70259142e8ad35a7658ed Mon Sep 17 00:00:00 2001 |
348 |
|
|
From: Jeremy Allison <jra@samba.org> |
349 |
|
|
Date: Mon, 19 Dec 2016 12:13:20 -0800 |
350 |
|
|
Subject: [PATCH 06/13] CVE-2017-2619: s3: smbd: OpenDir_fsp() use early |
351 |
|
|
returns. |
352 |
|
|
|
353 |
|
|
BUG: https://bugzilla.samba.org/show_bug.cgi?id=12496 |
354 |
|
|
|
355 |
|
|
Signed-off-by: Jeremy Allison <jra@samba.org> |
356 |
|
|
Reviewed-by: Uri Simchoni <uri@samba.org> |
357 |
|
|
--- |
358 |
|
|
source3/smbd/dir.c | 34 +++++++++++++++++++++------------- |
359 |
|
|
1 file changed, 21 insertions(+), 13 deletions(-) |
360 |
|
|
|
361 |
|
|
diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c |
362 |
|
|
index 39a6e67..ea4f1ab 100644 |
363 |
|
|
--- a/source3/smbd/dir.c |
364 |
|
|
+++ b/source3/smbd/dir.c |
365 |
|
|
@@ -1706,7 +1706,17 @@ static struct smb_Dir *OpenDir_fsp(TALLOC_CTX *mem_ctx, connection_struct *conn, |
366 |
|
|
struct smbd_server_connection *sconn = conn->sconn; |
367 |
|
|
|
368 |
|
|
if (!dirp) { |
369 |
|
|
- return NULL; |
370 |
|
|
+ goto fail; |
371 |
|
|
+ } |
372 |
|
|
+ |
373 |
|
|
+ if (!fsp->is_directory) { |
374 |
|
|
+ errno = EBADF; |
375 |
|
|
+ goto fail; |
376 |
|
|
+ } |
377 |
|
|
+ |
378 |
|
|
+ if (fsp->fh->fd == -1) { |
379 |
|
|
+ errno = EBADF; |
380 |
|
|
+ goto fail; |
381 |
|
|
} |
382 |
|
|
|
383 |
|
|
dirp->conn = conn; |
384 |
|
|
@@ -1723,18 +1733,16 @@ static struct smb_Dir *OpenDir_fsp(TALLOC_CTX *mem_ctx, connection_struct *conn, |
385 |
|
|
} |
386 |
|
|
talloc_set_destructor(dirp, smb_Dir_destructor); |
387 |
|
|
|
388 |
|
|
- if (fsp->is_directory && fsp->fh->fd != -1) { |
389 |
|
|
- dirp->dir = SMB_VFS_FDOPENDIR(fsp, mask, attr); |
390 |
|
|
- if (dirp->dir != NULL) { |
391 |
|
|
- dirp->fsp = fsp; |
392 |
|
|
- } else { |
393 |
|
|
- DEBUG(10,("OpenDir_fsp: SMB_VFS_FDOPENDIR on %s returned " |
394 |
|
|
- "NULL (%s)\n", |
395 |
|
|
- dirp->dir_path, |
396 |
|
|
- strerror(errno))); |
397 |
|
|
- if (errno != ENOSYS) { |
398 |
|
|
- return NULL; |
399 |
|
|
- } |
400 |
|
|
+ dirp->dir = SMB_VFS_FDOPENDIR(fsp, mask, attr); |
401 |
|
|
+ if (dirp->dir != NULL) { |
402 |
|
|
+ dirp->fsp = fsp; |
403 |
|
|
+ } else { |
404 |
|
|
+ DEBUG(10,("OpenDir_fsp: SMB_VFS_FDOPENDIR on %s returned " |
405 |
|
|
+ "NULL (%s)\n", |
406 |
|
|
+ dirp->dir_path, |
407 |
|
|
+ strerror(errno))); |
408 |
|
|
+ if (errno != ENOSYS) { |
409 |
|
|
+ return NULL; |
410 |
|
|
} |
411 |
|
|
} |
412 |
|
|
|
413 |
|
|
-- |
414 |
|
|
2.9.3 |
415 |
|
|
|
416 |
|
|
|
417 |
|
|
From 16fa5af1a491c410d4579434b7e9f6e388ea319b Mon Sep 17 00:00:00 2001 |
418 |
|
|
From: Jeremy Allison <jra@samba.org> |
419 |
|
|
Date: Mon, 19 Dec 2016 12:15:59 -0800 |
420 |
|
|
Subject: [PATCH 07/13] CVE-2017-2619: s3: smbd: OpenDir_fsp() - Fix memory |
421 |
|
|
leak on error. |
422 |
|
|
|
423 |
|
|
BUG: https://bugzilla.samba.org/show_bug.cgi?id=12496 |
424 |
|
|
|
425 |
|
|
Signed-off-by: Jeremy Allison <jra@samba.org> |
426 |
|
|
Reviewed-by: Uri Simchoni <uri@samba.org> |
427 |
|
|
--- |
428 |
|
|
source3/smbd/dir.c | 2 +- |
429 |
|
|
1 file changed, 1 insertion(+), 1 deletion(-) |
430 |
|
|
|
431 |
|
|
diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c |
432 |
|
|
index ea4f1ab..b8034be 100644 |
433 |
|
|
--- a/source3/smbd/dir.c |
434 |
|
|
+++ b/source3/smbd/dir.c |
435 |
|
|
@@ -1742,7 +1742,7 @@ static struct smb_Dir *OpenDir_fsp(TALLOC_CTX *mem_ctx, connection_struct *conn, |
436 |
|
|
dirp->dir_path, |
437 |
|
|
strerror(errno))); |
438 |
|
|
if (errno != ENOSYS) { |
439 |
|
|
- return NULL; |
440 |
|
|
+ goto fail; |
441 |
|
|
} |
442 |
|
|
} |
443 |
|
|
|
444 |
|
|
-- |
445 |
|
|
2.9.3 |
446 |
|
|
|
447 |
|
|
|
448 |
|
|
From 2c1830915b0b59646503ee4d043fd9176090627f Mon Sep 17 00:00:00 2001 |
449 |
|
|
From: Jeremy Allison <jra@samba.org> |
450 |
|
|
Date: Mon, 19 Dec 2016 12:32:07 -0800 |
451 |
|
|
Subject: [PATCH 08/13] CVE-2017-2619: s3: smbd: Move the reference counting |
452 |
|
|
and destructor setup to just before retuning success. |
453 |
|
|
|
454 |
|
|
BUG: https://bugzilla.samba.org/show_bug.cgi?id=12496 |
455 |
|
|
|
456 |
|
|
Signed-off-by: Jeremy Allison <jra@samba.org> |
457 |
|
|
Reviewed-by: Uri Simchoni <uri@samba.org> |
458 |
|
|
--- |
459 |
|
|
source3/smbd/dir.c | 10 +++++----- |
460 |
|
|
1 file changed, 5 insertions(+), 5 deletions(-) |
461 |
|
|
|
462 |
|
|
diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c |
463 |
|
|
index b8034be..6b62f14 100644 |
464 |
|
|
--- a/source3/smbd/dir.c |
465 |
|
|
+++ b/source3/smbd/dir.c |
466 |
|
|
@@ -1728,11 +1728,6 @@ static struct smb_Dir *OpenDir_fsp(TALLOC_CTX *mem_ctx, connection_struct *conn, |
467 |
|
|
goto fail; |
468 |
|
|
} |
469 |
|
|
|
470 |
|
|
- if (sconn && !sconn->using_smb2) { |
471 |
|
|
- sconn->searches.dirhandles_open++; |
472 |
|
|
- } |
473 |
|
|
- talloc_set_destructor(dirp, smb_Dir_destructor); |
474 |
|
|
- |
475 |
|
|
dirp->dir = SMB_VFS_FDOPENDIR(fsp, mask, attr); |
476 |
|
|
if (dirp->dir != NULL) { |
477 |
|
|
dirp->fsp = fsp; |
478 |
|
|
@@ -1757,6 +1752,11 @@ static struct smb_Dir *OpenDir_fsp(TALLOC_CTX *mem_ctx, connection_struct *conn, |
479 |
|
|
goto fail; |
480 |
|
|
} |
481 |
|
|
|
482 |
|
|
+ if (sconn && !sconn->using_smb2) { |
483 |
|
|
+ sconn->searches.dirhandles_open++; |
484 |
|
|
+ } |
485 |
|
|
+ talloc_set_destructor(dirp, smb_Dir_destructor); |
486 |
|
|
+ |
487 |
|
|
return dirp; |
488 |
|
|
|
489 |
|
|
fail: |
490 |
|
|
-- |
491 |
|
|
2.9.3 |
492 |
|
|
|
493 |
|
|
|
494 |
|
|
From 72bf8c2c2b2c4aff1ac4da52aa087c060ea5eef1 Mon Sep 17 00:00:00 2001 |
495 |
|
|
From: Jeremy Allison <jra@samba.org> |
496 |
|
|
Date: Mon, 19 Dec 2016 12:35:32 -0800 |
497 |
|
|
Subject: [PATCH 09/13] CVE-2017-2619: s3: smbd: Correctly fallback to |
498 |
|
|
open_dir_safely if FDOPENDIR not supported on system. |
499 |
|
|
|
500 |
|
|
BUG: https://bugzilla.samba.org/show_bug.cgi?id=12496 |
501 |
|
|
|
502 |
|
|
Signed-off-by: Jeremy Allison <jra@samba.org> |
503 |
|
|
Reviewed-by: Uri Simchoni <uri@samba.org> |
504 |
|
|
--- |
505 |
|
|
source3/smbd/dir.c | 15 +++++++-------- |
506 |
|
|
1 file changed, 7 insertions(+), 8 deletions(-) |
507 |
|
|
|
508 |
|
|
diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c |
509 |
|
|
index 6b62f14..3432788 100644 |
510 |
|
|
--- a/source3/smbd/dir.c |
511 |
|
|
+++ b/source3/smbd/dir.c |
512 |
|
|
@@ -1742,14 +1742,13 @@ static struct smb_Dir *OpenDir_fsp(TALLOC_CTX *mem_ctx, connection_struct *conn, |
513 |
|
|
} |
514 |
|
|
|
515 |
|
|
if (dirp->dir == NULL) { |
516 |
|
|
- /* FDOPENDIR didn't work. Use OPENDIR instead. */ |
517 |
|
|
- dirp->dir = SMB_VFS_OPENDIR(conn, dirp->dir_path, mask, attr); |
518 |
|
|
- } |
519 |
|
|
- |
520 |
|
|
- if (!dirp->dir) { |
521 |
|
|
- DEBUG(5,("OpenDir_fsp: Can't open %s. %s\n", dirp->dir_path, |
522 |
|
|
- strerror(errno) )); |
523 |
|
|
- goto fail; |
524 |
|
|
+ /* FDOPENDIR is not supported. Use OPENDIR instead. */ |
525 |
|
|
+ TALLOC_FREE(dirp); |
526 |
|
|
+ return open_dir_safely(mem_ctx, |
527 |
|
|
+ conn, |
528 |
|
|
+ fsp->fsp_name->base_name, |
529 |
|
|
+ mask, |
530 |
|
|
+ attr); |
531 |
|
|
} |
532 |
|
|
|
533 |
|
|
if (sconn && !sconn->using_smb2) { |
534 |
|
|
-- |
535 |
|
|
2.9.3 |
536 |
|
|
|
537 |
|
|
|
538 |
|
|
From 015e488ce39e097944acdad7a88a801386d9935b Mon Sep 17 00:00:00 2001 |
539 |
|
|
From: Jeremy Allison <jra@samba.org> |
540 |
|
|
Date: Thu, 15 Dec 2016 12:52:13 -0800 |
541 |
|
|
Subject: [PATCH 10/13] CVE-2017-2619: s3: smbd: Remove O_NOFOLLOW guards. We |
542 |
|
|
insist on O_NOFOLLOW existing. |
543 |
|
|
|
544 |
|
|
BUG: https://bugzilla.samba.org/show_bug.cgi?id=12496 |
545 |
|
|
|
546 |
|
|
Signed-off-by: Jeremy Allison <jra@samba.org> |
547 |
|
|
Reviewed-by: Uri Simchoni <uri@samba.org> |
548 |
|
|
--- |
549 |
|
|
source3/smbd/open.c | 6 +----- |
550 |
|
|
1 file changed, 1 insertion(+), 5 deletions(-) |
551 |
|
|
|
552 |
|
|
diff --git a/source3/smbd/open.c b/source3/smbd/open.c |
553 |
|
|
index 1c67684..a014b5e 100644 |
554 |
|
|
--- a/source3/smbd/open.c |
555 |
|
|
+++ b/source3/smbd/open.c |
556 |
|
|
@@ -363,8 +363,7 @@ NTSTATUS fd_open(struct connection_struct *conn, |
557 |
|
|
struct smb_filename *smb_fname = fsp->fsp_name; |
558 |
|
|
NTSTATUS status = NT_STATUS_OK; |
559 |
|
|
|
560 |
|
|
-#ifdef O_NOFOLLOW |
561 |
|
|
- /* |
562 |
|
|
+ /* |
563 |
|
|
* Never follow symlinks on a POSIX client. The |
564 |
|
|
* client should be doing this. |
565 |
|
|
*/ |
566 |
|
|
@@ -372,12 +371,10 @@ NTSTATUS fd_open(struct connection_struct *conn, |
567 |
|
|
if ((fsp->posix_flags & FSP_POSIX_FLAGS_OPEN) || !lp_follow_symlinks(SNUM(conn))) { |
568 |
|
|
flags |= O_NOFOLLOW; |
569 |
|
|
} |
570 |
|
|
-#endif |
571 |
|
|
|
572 |
|
|
fsp->fh->fd = SMB_VFS_OPEN(conn, smb_fname, fsp, flags, mode); |
573 |
|
|
if (fsp->fh->fd == -1) { |
574 |
|
|
int posix_errno = errno; |
575 |
|
|
-#ifdef O_NOFOLLOW |
576 |
|
|
#if defined(ENOTSUP) && defined(OSF1) |
577 |
|
|
/* handle special Tru64 errno */ |
578 |
|
|
if (errno == ENOTSUP) { |
579 |
|
|
@@ -394,7 +391,6 @@ NTSTATUS fd_open(struct connection_struct *conn, |
580 |
|
|
if (errno == EMLINK) { |
581 |
|
|
posix_errno = ELOOP; |
582 |
|
|
} |
583 |
|
|
-#endif /* O_NOFOLLOW */ |
584 |
|
|
status = map_nt_error_from_unix(posix_errno); |
585 |
|
|
if (errno == EMFILE) { |
586 |
|
|
static time_t last_warned = 0L; |
587 |
|
|
-- |
588 |
|
|
2.9.3 |
589 |
|
|
|
590 |
|
|
|
591 |
|
|
From b7199aaa0a4d10dd6b3d2a040e345a209ec0c42f Mon Sep 17 00:00:00 2001 |
592 |
|
|
From: Jeremy Allison <jra@samba.org> |
593 |
|
|
Date: Thu, 15 Dec 2016 12:56:08 -0800 |
594 |
|
|
Subject: [PATCH 11/13] CVE-2017-2619: s3: smbd: Move special handling of |
595 |
|
|
symlink errno's into a utility function. |
596 |
|
|
|
597 |
|
|
BUG: https://bugzilla.samba.org/show_bug.cgi?id=12496 |
598 |
|
|
|
599 |
|
|
Signed-off-by: Jeremy Allison <jra@samba.org> |
600 |
|
|
Reviewed-by: Uri Simchoni <uri@samba.org> |
601 |
|
|
--- |
602 |
|
|
source3/smbd/open.c | 43 ++++++++++++++++++++++++++----------------- |
603 |
|
|
1 file changed, 26 insertions(+), 17 deletions(-) |
604 |
|
|
|
605 |
|
|
diff --git a/source3/smbd/open.c b/source3/smbd/open.c |
606 |
|
|
index a014b5e..b4b77cd 100644 |
607 |
|
|
--- a/source3/smbd/open.c |
608 |
|
|
+++ b/source3/smbd/open.c |
609 |
|
|
@@ -352,6 +352,31 @@ static NTSTATUS check_base_file_access(struct connection_struct *conn, |
610 |
|
|
} |
611 |
|
|
|
612 |
|
|
/**************************************************************************** |
613 |
|
|
+ Handle differing symlink errno's |
614 |
|
|
+****************************************************************************/ |
615 |
|
|
+ |
616 |
|
|
+static int link_errno_convert(int err) |
617 |
|
|
+{ |
618 |
|
|
+#if defined(ENOTSUP) && defined(OSF1) |
619 |
|
|
+ /* handle special Tru64 errno */ |
620 |
|
|
+ if (err == ENOTSUP) { |
621 |
|
|
+ err = ELOOP; |
622 |
|
|
+ } |
623 |
|
|
+#endif /* ENOTSUP */ |
624 |
|
|
+#ifdef EFTYPE |
625 |
|
|
+ /* fix broken NetBSD errno */ |
626 |
|
|
+ if (err == EFTYPE) { |
627 |
|
|
+ err = ELOOP; |
628 |
|
|
+ } |
629 |
|
|
+#endif /* EFTYPE */ |
630 |
|
|
+ /* fix broken FreeBSD errno */ |
631 |
|
|
+ if (err == EMLINK) { |
632 |
|
|
+ err = ELOOP; |
633 |
|
|
+ } |
634 |
|
|
+ return err; |
635 |
|
|
+} |
636 |
|
|
+ |
637 |
|
|
+/**************************************************************************** |
638 |
|
|
fd support routines - attempt to do a dos_open. |
639 |
|
|
****************************************************************************/ |
640 |
|
|
|
641 |
|
|
@@ -374,23 +399,7 @@ NTSTATUS fd_open(struct connection_struct *conn, |
642 |
|
|
|
643 |
|
|
fsp->fh->fd = SMB_VFS_OPEN(conn, smb_fname, fsp, flags, mode); |
644 |
|
|
if (fsp->fh->fd == -1) { |
645 |
|
|
- int posix_errno = errno; |
646 |
|
|
-#if defined(ENOTSUP) && defined(OSF1) |
647 |
|
|
- /* handle special Tru64 errno */ |
648 |
|
|
- if (errno == ENOTSUP) { |
649 |
|
|
- posix_errno = ELOOP; |
650 |
|
|
- } |
651 |
|
|
-#endif /* ENOTSUP */ |
652 |
|
|
-#ifdef EFTYPE |
653 |
|
|
- /* fix broken NetBSD errno */ |
654 |
|
|
- if (errno == EFTYPE) { |
655 |
|
|
- posix_errno = ELOOP; |
656 |
|
|
- } |
657 |
|
|
-#endif /* EFTYPE */ |
658 |
|
|
- /* fix broken FreeBSD errno */ |
659 |
|
|
- if (errno == EMLINK) { |
660 |
|
|
- posix_errno = ELOOP; |
661 |
|
|
- } |
662 |
|
|
+ int posix_errno = link_errno_convert(errno); |
663 |
|
|
status = map_nt_error_from_unix(posix_errno); |
664 |
|
|
if (errno == EMFILE) { |
665 |
|
|
static time_t last_warned = 0L; |
666 |
|
|
-- |
667 |
|
|
2.9.3 |
668 |
|
|
|
669 |
|
|
|
670 |
|
|
From eda8d6ed343b32efb7055778b13252842b8c4f61 Mon Sep 17 00:00:00 2001 |
671 |
|
|
From: Jeremy Allison <jra@samba.org> |
672 |
|
|
Date: Thu, 15 Dec 2016 13:04:46 -0800 |
673 |
|
|
Subject: [PATCH 12/13] CVE-2017-2619: s3: smbd: Add the core functions to |
674 |
|
|
prevent symlink open races. |
675 |
|
|
|
676 |
|
|
BUG: https://bugzilla.samba.org/show_bug.cgi?id=12496 |
677 |
|
|
|
678 |
|
|
Signed-off-by: Jeremy Allison <jra@samba.org> |
679 |
|
|
Reviewed-by: Uri Simchoni <uri@samba.org> |
680 |
|
|
--- |
681 |
|
|
source3/smbd/open.c | 237 ++++++++++++++++++++++++++++++++++++++++++++++++++++ |
682 |
|
|
1 file changed, 237 insertions(+) |
683 |
|
|
|
684 |
|
|
diff --git a/source3/smbd/open.c b/source3/smbd/open.c |
685 |
|
|
index b4b77cd..aa5df2c 100644 |
686 |
|
|
--- a/source3/smbd/open.c |
687 |
|
|
+++ b/source3/smbd/open.c |
688 |
|
|
@@ -376,6 +376,243 @@ static int link_errno_convert(int err) |
689 |
|
|
return err; |
690 |
|
|
} |
691 |
|
|
|
692 |
|
|
+static int non_widelink_open(struct connection_struct *conn, |
693 |
|
|
+ const char *conn_rootdir, |
694 |
|
|
+ files_struct *fsp, |
695 |
|
|
+ struct smb_filename *smb_fname, |
696 |
|
|
+ int flags, |
697 |
|
|
+ mode_t mode, |
698 |
|
|
+ unsigned int link_depth); |
699 |
|
|
+ |
700 |
|
|
+/**************************************************************************** |
701 |
|
|
+ Follow a symlink in userspace. |
702 |
|
|
+****************************************************************************/ |
703 |
|
|
+ |
704 |
|
|
+static int process_symlink_open(struct connection_struct *conn, |
705 |
|
|
+ const char *conn_rootdir, |
706 |
|
|
+ files_struct *fsp, |
707 |
|
|
+ struct smb_filename *smb_fname, |
708 |
|
|
+ int flags, |
709 |
|
|
+ mode_t mode, |
710 |
|
|
+ unsigned int link_depth) |
711 |
|
|
+{ |
712 |
|
|
+ int fd = -1; |
713 |
|
|
+ char *link_target = NULL; |
714 |
|
|
+ int link_len = -1; |
715 |
|
|
+ char *oldwd = NULL; |
716 |
|
|
+ size_t rootdir_len = 0; |
717 |
|
|
+ char *resolved_name = NULL; |
718 |
|
|
+ bool matched = false; |
719 |
|
|
+ int saved_errno = 0; |
720 |
|
|
+ |
721 |
|
|
+ /* |
722 |
|
|
+ * Ensure we don't get stuck in a symlink loop. |
723 |
|
|
+ */ |
724 |
|
|
+ link_depth++; |
725 |
|
|
+ if (link_depth >= 20) { |
726 |
|
|
+ errno = ELOOP; |
727 |
|
|
+ goto out; |
728 |
|
|
+ } |
729 |
|
|
+ |
730 |
|
|
+ /* Allocate space for the link target. */ |
731 |
|
|
+ link_target = talloc_array(talloc_tos(), char, PATH_MAX); |
732 |
|
|
+ if (link_target == NULL) { |
733 |
|
|
+ errno = ENOMEM; |
734 |
|
|
+ goto out; |
735 |
|
|
+ } |
736 |
|
|
+ |
737 |
|
|
+ /* Read the link target. */ |
738 |
|
|
+ link_len = SMB_VFS_READLINK(conn, |
739 |
|
|
+ smb_fname->base_name, |
740 |
|
|
+ link_target, |
741 |
|
|
+ PATH_MAX - 1); |
742 |
|
|
+ if (link_len == -1) { |
743 |
|
|
+ goto out; |
744 |
|
|
+ } |
745 |
|
|
+ |
746 |
|
|
+ /* Ensure it's at least null terminated. */ |
747 |
|
|
+ link_target[link_len] = '\0'; |
748 |
|
|
+ |
749 |
|
|
+ /* Convert to an absolute path. */ |
750 |
|
|
+ resolved_name = SMB_VFS_REALPATH(conn, link_target); |
751 |
|
|
+ if (resolved_name == NULL) { |
752 |
|
|
+ goto out; |
753 |
|
|
+ } |
754 |
|
|
+ |
755 |
|
|
+ /* |
756 |
|
|
+ * We know conn_rootdir starts with '/' and |
757 |
|
|
+ * does not end in '/'. FIXME ! Should we |
758 |
|
|
+ * smb_assert this ? |
759 |
|
|
+ */ |
760 |
|
|
+ rootdir_len = strlen(conn_rootdir); |
761 |
|
|
+ |
762 |
|
|
+ matched = (strncmp(conn_rootdir, resolved_name, rootdir_len) == 0); |
763 |
|
|
+ if (!matched) { |
764 |
|
|
+ errno = EACCES; |
765 |
|
|
+ goto out; |
766 |
|
|
+ } |
767 |
|
|
+ |
768 |
|
|
+ /* |
769 |
|
|
+ * Turn into a path relative to the share root. |
770 |
|
|
+ */ |
771 |
|
|
+ if (resolved_name[rootdir_len] == '\0') { |
772 |
|
|
+ /* Link to the root of the share. */ |
773 |
|
|
+ smb_fname->base_name = talloc_strdup(talloc_tos(), "."); |
774 |
|
|
+ if (smb_fname->base_name == NULL) { |
775 |
|
|
+ errno = ENOMEM; |
776 |
|
|
+ goto out; |
777 |
|
|
+ } |
778 |
|
|
+ } else if (resolved_name[rootdir_len] == '/') { |
779 |
|
|
+ smb_fname->base_name = &resolved_name[rootdir_len+1]; |
780 |
|
|
+ } else { |
781 |
|
|
+ errno = EACCES; |
782 |
|
|
+ goto out; |
783 |
|
|
+ } |
784 |
|
|
+ |
785 |
|
|
+ oldwd = vfs_GetWd(talloc_tos(), conn); |
786 |
|
|
+ if (oldwd == NULL) { |
787 |
|
|
+ goto out; |
788 |
|
|
+ } |
789 |
|
|
+ |
790 |
|
|
+ /* Ensure we operate from the root of the share. */ |
791 |
|
|
+ if (vfs_ChDir(conn, conn_rootdir) == -1) { |
792 |
|
|
+ goto out; |
793 |
|
|
+ } |
794 |
|
|
+ |
795 |
|
|
+ /* And do it all again.. */ |
796 |
|
|
+ fd = non_widelink_open(conn, |
797 |
|
|
+ conn_rootdir, |
798 |
|
|
+ fsp, |
799 |
|
|
+ smb_fname, |
800 |
|
|
+ flags, |
801 |
|
|
+ mode, |
802 |
|
|
+ link_depth); |
803 |
|
|
+ if (fd == -1) { |
804 |
|
|
+ saved_errno = errno; |
805 |
|
|
+ } |
806 |
|
|
+ |
807 |
|
|
+ out: |
808 |
|
|
+ |
809 |
|
|
+ SAFE_FREE(resolved_name); |
810 |
|
|
+ TALLOC_FREE(link_target); |
811 |
|
|
+ if (oldwd != NULL) { |
812 |
|
|
+ int ret = vfs_ChDir(conn, oldwd); |
813 |
|
|
+ if (ret == -1) { |
814 |
|
|
+ smb_panic("unable to get back to old directory\n"); |
815 |
|
|
+ } |
816 |
|
|
+ TALLOC_FREE(oldwd); |
817 |
|
|
+ } |
818 |
|
|
+ if (saved_errno != 0) { |
819 |
|
|
+ errno = saved_errno; |
820 |
|
|
+ } |
821 |
|
|
+ return fd; |
822 |
|
|
+} |
823 |
|
|
+ |
824 |
|
|
+/**************************************************************************** |
825 |
|
|
+ Non-widelink open. |
826 |
|
|
+****************************************************************************/ |
827 |
|
|
+ |
828 |
|
|
+static int non_widelink_open(struct connection_struct *conn, |
829 |
|
|
+ const char *conn_rootdir, |
830 |
|
|
+ files_struct *fsp, |
831 |
|
|
+ struct smb_filename *smb_fname, |
832 |
|
|
+ int flags, |
833 |
|
|
+ mode_t mode, |
834 |
|
|
+ unsigned int link_depth) |
835 |
|
|
+{ |
836 |
|
|
+ NTSTATUS status; |
837 |
|
|
+ int fd = -1; |
838 |
|
|
+ struct smb_filename *smb_fname_rel = NULL; |
839 |
|
|
+ int saved_errno = 0; |
840 |
|
|
+ char *oldwd = NULL; |
841 |
|
|
+ char *parent_dir = NULL; |
842 |
|
|
+ const char *final_component = NULL; |
843 |
|
|
+ |
844 |
|
|
+ if (!parent_dirname(talloc_tos(), |
845 |
|
|
+ smb_fname->base_name, |
846 |
|
|
+ &parent_dir, |
847 |
|
|
+ &final_component)) { |
848 |
|
|
+ goto out; |
849 |
|
|
+ } |
850 |
|
|
+ |
851 |
|
|
+ oldwd = vfs_GetWd(talloc_tos(), conn); |
852 |
|
|
+ if (oldwd == NULL) { |
853 |
|
|
+ goto out; |
854 |
|
|
+ } |
855 |
|
|
+ |
856 |
|
|
+ /* Pin parent directory in place. */ |
857 |
|
|
+ if (vfs_ChDir(conn, parent_dir) == -1) { |
858 |
|
|
+ goto out; |
859 |
|
|
+ } |
860 |
|
|
+ |
861 |
|
|
+ /* Ensure the relative path is below the share. */ |
862 |
|
|
+ status = check_reduced_name(conn, final_component); |
863 |
|
|
+ if (!NT_STATUS_IS_OK(status)) { |
864 |
|
|
+ saved_errno = map_errno_from_nt_status(status); |
865 |
|
|
+ goto out; |
866 |
|
|
+ } |
867 |
|
|
+ |
868 |
|
|
+ smb_fname_rel = synthetic_smb_fname(talloc_tos(), |
869 |
|
|
+ final_component, |
870 |
|
|
+ smb_fname->stream_name, |
871 |
|
|
+ &smb_fname->st); |
872 |
|
|
+ |
873 |
|
|
+ flags |= O_NOFOLLOW; |
874 |
|
|
+ |
875 |
|
|
+ { |
876 |
|
|
+ struct smb_filename *tmp_name = fsp->fsp_name; |
877 |
|
|
+ fsp->fsp_name = smb_fname_rel; |
878 |
|
|
+ fd = SMB_VFS_OPEN(conn, smb_fname_rel, fsp, flags, mode); |
879 |
|
|
+ fsp->fsp_name = tmp_name; |
880 |
|
|
+ } |
881 |
|
|
+ |
882 |
|
|
+ if (fd == -1) { |
883 |
|
|
+ saved_errno = link_errno_convert(errno); |
884 |
|
|
+ if (saved_errno == ELOOP) { |
885 |
|
|
+ if (fsp->posix_flags & FSP_POSIX_FLAGS_OPEN) { |
886 |
|
|
+ /* Never follow symlinks on posix open. */ |
887 |
|
|
+ goto out; |
888 |
|
|
+ } |
889 |
|
|
+ if (!lp_follow_symlinks(SNUM(conn))) { |
890 |
|
|
+ /* Explicitly no symlinks. */ |
891 |
|
|
+ goto out; |
892 |
|
|
+ } |
893 |
|
|
+ /* |
894 |
|
|
+ * We have a symlink. Follow in userspace |
895 |
|
|
+ * to ensure it's under the share definition. |
896 |
|
|
+ */ |
897 |
|
|
+ fd = process_symlink_open(conn, |
898 |
|
|
+ conn_rootdir, |
899 |
|
|
+ fsp, |
900 |
|
|
+ smb_fname_rel, |
901 |
|
|
+ flags, |
902 |
|
|
+ mode, |
903 |
|
|
+ link_depth); |
904 |
|
|
+ if (fd == -1) { |
905 |
|
|
+ saved_errno = |
906 |
|
|
+ link_errno_convert(errno); |
907 |
|
|
+ } |
908 |
|
|
+ } |
909 |
|
|
+ } |
910 |
|
|
+ |
911 |
|
|
+ out: |
912 |
|
|
+ |
913 |
|
|
+ TALLOC_FREE(parent_dir); |
914 |
|
|
+ TALLOC_FREE(smb_fname_rel); |
915 |
|
|
+ |
916 |
|
|
+ if (oldwd != NULL) { |
917 |
|
|
+ int ret = vfs_ChDir(conn, oldwd); |
918 |
|
|
+ if (ret == -1) { |
919 |
|
|
+ smb_panic("unable to get back to old directory\n"); |
920 |
|
|
+ } |
921 |
|
|
+ TALLOC_FREE(oldwd); |
922 |
|
|
+ } |
923 |
|
|
+ if (saved_errno != 0) { |
924 |
|
|
+ errno = saved_errno; |
925 |
|
|
+ } |
926 |
|
|
+ return fd; |
927 |
|
|
+} |
928 |
|
|
+ |
929 |
|
|
/**************************************************************************** |
930 |
|
|
fd support routines - attempt to do a dos_open. |
931 |
|
|
****************************************************************************/ |
932 |
|
|
-- |
933 |
|
|
2.9.3 |
934 |
|
|
|
935 |
|
|
|
936 |
|
|
From 81094d0c7519936b08d22efc22ba78e5bab24cd1 Mon Sep 17 00:00:00 2001 |
937 |
|
|
From: Jeremy Allison <jra@samba.org> |
938 |
|
|
Date: Thu, 15 Dec 2016 13:06:31 -0800 |
939 |
|
|
Subject: [PATCH 13/13] CVE-2017-2619: s3: smbd: Use the new |
940 |
|
|
non_widelink_open() function. |
941 |
|
|
|
942 |
|
|
BUG: https://bugzilla.samba.org/show_bug.cgi?id=12496 |
943 |
|
|
|
944 |
|
|
Signed-off-by: Jeremy Allison <jra@samba.org> |
945 |
|
|
Reviewed-by: Uri Simchoni <uri@samba.org> |
946 |
|
|
--- |
947 |
|
|
source3/smbd/open.c | 23 ++++++++++++++++++++++- |
948 |
|
|
1 file changed, 22 insertions(+), 1 deletion(-) |
949 |
|
|
|
950 |
|
|
diff --git a/source3/smbd/open.c b/source3/smbd/open.c |
951 |
|
|
index aa5df2c..0b66487 100644 |
952 |
|
|
--- a/source3/smbd/open.c |
953 |
|
|
+++ b/source3/smbd/open.c |
954 |
|
|
@@ -634,7 +634,28 @@ NTSTATUS fd_open(struct connection_struct *conn, |
955 |
|
|
flags |= O_NOFOLLOW; |
956 |
|
|
} |
957 |
|
|
|
958 |
|
|
- fsp->fh->fd = SMB_VFS_OPEN(conn, smb_fname, fsp, flags, mode); |
959 |
|
|
+ /* Ensure path is below share definition. */ |
960 |
|
|
+ if (!lp_widelinks(SNUM(conn))) { |
961 |
|
|
+ const char *conn_rootdir = SMB_VFS_CONNECTPATH(conn, |
962 |
|
|
+ smb_fname->base_name); |
963 |
|
|
+ if (conn_rootdir == NULL) { |
964 |
|
|
+ return NT_STATUS_NO_MEMORY; |
965 |
|
|
+ } |
966 |
|
|
+ /* |
967 |
|
|
+ * Only follow symlinks within a share |
968 |
|
|
+ * definition. |
969 |
|
|
+ */ |
970 |
|
|
+ fsp->fh->fd = non_widelink_open(conn, |
971 |
|
|
+ conn_rootdir, |
972 |
|
|
+ fsp, |
973 |
|
|
+ smb_fname, |
974 |
|
|
+ flags, |
975 |
|
|
+ mode, |
976 |
|
|
+ 0); |
977 |
|
|
+ } else { |
978 |
|
|
+ fsp->fh->fd = SMB_VFS_OPEN(conn, smb_fname, fsp, flags, mode); |
979 |
|
|
+ } |
980 |
|
|
+ |
981 |
|
|
if (fsp->fh->fd == -1) { |
982 |
|
|
int posix_errno = link_errno_convert(errno); |
983 |
|
|
status = map_nt_error_from_unix(posix_errno); |
984 |
|
|
-- |
985 |
|
|
2.9.3 |
986 |
|
|
|