]> git.ipfire.org Git - ipfire-2.x.git/blame - src/patches/samba/CVE-2017-2619.patch
samba: import security updates from redhead
[ipfire-2.x.git] / src / patches / samba / CVE-2017-2619.patch
CommitLineData
0476a657
AF
1From a398754c9bb1639f762979765de6c540c714b5cb Mon Sep 17 00:00:00 2001
2From: Jeremy Allison <jra@samba.org>
3Date: Mon, 20 Mar 2017 11:32:19 -0700
4Subject: [PATCH 01/15] CVE-2017-2619: s3/smbd: re-open directory after
5 dptr_CloseDir()
6
7dptr_CloseDir() will close and invalidate the fsp's file descriptor, we
8have to reopen it.
9
10Bug: https://bugzilla.samba.org/show_bug.cgi?id=12496
11
12Signed-off-by: Ralph Bohme <slow@samba.org>
13Signed-off-by: Jeremy Allison <jra@samba.org>
14---
15 source3/smbd/open.c | 2 +-
16 source3/smbd/proto.h | 2 ++
17 source3/smbd/smb2_find.c | 17 +++++++++++++++++
18 3 files changed, 20 insertions(+), 1 deletion(-)
19
20diff --git a/source3/smbd/open.c b/source3/smbd/open.c
21index 441b8cd4362..35eee0a1485 100644
22--- a/source3/smbd/open.c
23+++ b/source3/smbd/open.c
24@@ -197,7 +197,7 @@ static NTSTATUS check_base_file_access(struct connection_struct *conn,
25 fd support routines - attempt to do a dos_open.
26 ****************************************************************************/
27
28-static NTSTATUS fd_open(struct connection_struct *conn,
29+NTSTATUS fd_open(struct connection_struct *conn,
30 files_struct *fsp,
31 int flags,
32 mode_t mode)
33diff --git a/source3/smbd/proto.h b/source3/smbd/proto.h
34index f5fad2bbb50..594edfa1e98 100644
35--- a/source3/smbd/proto.h
36+++ b/source3/smbd/proto.h
37@@ -603,6 +603,8 @@ NTSTATUS smb1_file_se_access_check(connection_struct *conn,
38 const struct security_token *token,
39 uint32_t access_desired,
40 uint32_t *access_granted);
41+NTSTATUS fd_open(struct connection_struct *conn, files_struct *fsp,
42+ int flags, mode_t mode);
43 NTSTATUS fd_close(files_struct *fsp);
44 void change_file_owner_to_parent(connection_struct *conn,
45 const char *inherit_from_dir,
46diff --git a/source3/smbd/smb2_find.c b/source3/smbd/smb2_find.c
47index 6fe6545c128..9dd3176497b 100644
48--- a/source3/smbd/smb2_find.c
49+++ b/source3/smbd/smb2_find.c
50@@ -24,6 +24,7 @@
51 #include "../libcli/smb/smb_common.h"
52 #include "trans2.h"
53 #include "../lib/util/tevent_ntstatus.h"
54+#include "system/filesys.h"
55
56 static struct tevent_req *smbd_smb2_find_send(TALLOC_CTX *mem_ctx,
57 struct tevent_context *ev,
58@@ -301,7 +302,23 @@ static struct tevent_req *smbd_smb2_find_send(TALLOC_CTX *mem_ctx,
59 }
60
61 if (in_flags & SMB2_CONTINUE_FLAG_REOPEN) {
62+ int flags;
63+
64 dptr_CloseDir(fsp);
65+
66+ /*
67+ * dptr_CloseDir() will close and invalidate the fsp's file
68+ * descriptor, we have to reopen it.
69+ */
70+
71+ flags = O_RDONLY;
72+#ifdef O_DIRECTORY
73+ flags |= O_DIRECTORY;
74+#endif
75+ status = fd_open(conn, fsp, flags, 0);
76+ if (tevent_req_nterror(req, status)) {
77+ return tevent_req_post(req, ev);
78+ }
79 }
80
81 wcard_has_wild = ms_has_wild(in_file_name);
82--
832.13.5
84
85
86From a35fa98b99aa60132eb2c083d6393c28905e2045 Mon Sep 17 00:00:00 2001
87From: Jeremy Allison <jra@samba.org>
88Date: Tue, 28 Feb 2017 09:24:07 -0800
89Subject: [PATCH 02/15] s3: vfs: dirsort doesn't handle opendir of "."
90 correctly.
91
92Needs to store $cwd path for correct sorting.
93
94BUG: https://bugzilla.samba.org/show_bug.cgi?id=12499
95
96Signed-off-by: Jeremy Allison <jra@samba.org>
97---
98 source3/modules/vfs_dirsort.c | 4 ++++
99 1 file changed, 4 insertions(+)
100
101diff --git a/source3/modules/vfs_dirsort.c b/source3/modules/vfs_dirsort.c
102index 66582e67890..dbcf0b16ed3 100644
103--- a/source3/modules/vfs_dirsort.c
104+++ b/source3/modules/vfs_dirsort.c
105@@ -153,6 +153,10 @@ static SMB_STRUCT_DIR *dirsort_opendir(vfs_handle_struct *handle,
106 return NULL;
107 }
108
109+ if (ISDOT(data->smb_fname->base_name)) {
110+ data->smb_fname->base_name = vfs_GetWd(data, handle->conn);
111+ }
112+
113 /* Open the underlying directory and count the number of entries */
114 data->source_directory = SMB_VFS_NEXT_OPENDIR(handle, fname, mask,
115 attr);
116--
1172.13.5
118
119
120From 23d2849d724a0f5bdf51dc7d7db438ed9fb4c2a9 Mon Sep 17 00:00:00 2001
121From: Jeremy Allison <jra@samba.org>
122Date: Mon, 13 Mar 2017 13:44:42 -0700
123Subject: [PATCH 03/15] s3: VFS: vfs_streams_xattr.c: Make streams_xattr_open()
124 store the same path as streams_xattr_recheck().
125
126If the open is changing directories, fsp->fsp_name->base_name
127will be the full path from the share root, whilst
128smb_fname will be relative to the $cwd.
129
130BUG: https://bugzilla.samba.org/show_bug.cgi?id=12546
131
132Back-ported from a24ba3e4083200ec9885363efc5769f43183fb6b
133
134Signed-off-by: Jeremy Allison <jra@samba.org>
135---
136 source3/modules/vfs_streams_xattr.c | 9 ++++++++-
137 1 file changed, 8 insertions(+), 1 deletion(-)
138
139diff --git a/source3/modules/vfs_streams_xattr.c b/source3/modules/vfs_streams_xattr.c
140index 731c813f4d7..be46f8dc1e6 100644
141--- a/source3/modules/vfs_streams_xattr.c
142+++ b/source3/modules/vfs_streams_xattr.c
143@@ -511,8 +511,15 @@ static int streams_xattr_open(vfs_handle_struct *handle,
144
145 sio->xattr_name = talloc_strdup(VFS_MEMCTX_FSP_EXTENSION(handle, fsp),
146 xattr_name);
147+ /*
148+ * sio->base needs to be a copy of fsp->fsp_name->base_name,
149+ * making it identical to streams_xattr_recheck(). If the
150+ * open is changing directories, fsp->fsp_name->base_name
151+ * will be the full path from the share root, whilst
152+ * smb_fname will be relative to the $cwd.
153+ */
154 sio->base = talloc_strdup(VFS_MEMCTX_FSP_EXTENSION(handle, fsp),
155- smb_fname->base_name);
156+ fsp->fsp_name->base_name);
157 sio->fsp_name_ptr = fsp->fsp_name;
158 sio->handle = handle;
159 sio->fsp = fsp;
160--
1612.13.5
162
163
164From 91935aaf77c70e3e2436af1d6e4a538d29fd4276 Mon Sep 17 00:00:00 2001
165From: Jeremy Allison <jra@samba.org>
166Date: Mon, 13 Mar 2017 13:54:04 -0700
167Subject: [PATCH 04/15] vfs_streams_xattr: use fsp, not base_fsp
168
169The base_fsp's fd is always -1 as it's closed after being openend in
170create_file_unixpath().
171
172Additionally in streams_xattr_open force using of SMB_VFS_FSETXATTR() by
173sticking the just created fd into the fsp (and removing it afterwards).
174
175BUG: https://bugzilla.samba.org/show_bug.cgi?id=12591
176
177Back-ported from 021189e32ba507832b5e821e5cda8a2889225955.
178
179Signed-off-by: Jeremy Allison <jra@samba.org>
180---
181 source3/modules/vfs_streams_xattr.c | 205 +++++++++++++++++-------------------
182 1 file changed, 99 insertions(+), 106 deletions(-)
183
184diff --git a/source3/modules/vfs_streams_xattr.c b/source3/modules/vfs_streams_xattr.c
185index be46f8dc1e6..a4ab84bba71 100644
186--- a/source3/modules/vfs_streams_xattr.c
187+++ b/source3/modules/vfs_streams_xattr.c
188@@ -229,7 +229,7 @@ static int streams_xattr_fstat(vfs_handle_struct *handle, files_struct *fsp,
189 return -1;
190 }
191
192- sbuf->st_ex_size = get_xattr_size(handle->conn, fsp->base_fsp,
193+ sbuf->st_ex_size = get_xattr_size(handle->conn, fsp,
194 io->base, io->xattr_name);
195 if (sbuf->st_ex_size == -1) {
196 return -1;
197@@ -364,6 +364,7 @@ static int streams_xattr_open(vfs_handle_struct *handle,
198 char *xattr_name = NULL;
199 int baseflags;
200 int hostfd = -1;
201+ int ret;
202
203 DEBUG(10, ("streams_xattr_open called for %s\n",
204 smb_fname_str_dbg(smb_fname)));
205@@ -375,133 +376,125 @@ static int streams_xattr_open(vfs_handle_struct *handle,
206 /* If the default stream is requested, just open the base file. */
207 if (is_ntfs_default_stream_smb_fname(smb_fname)) {
208 char *tmp_stream_name;
209- int ret;
210
211 tmp_stream_name = smb_fname->stream_name;
212 smb_fname->stream_name = NULL;
213
214 ret = SMB_VFS_NEXT_OPEN(handle, smb_fname, fsp, flags, mode);
215
216- smb_fname->stream_name = tmp_stream_name;
217-
218- return ret;
219- }
220+ smb_fname->stream_name = tmp_stream_name;
221
222- status = streams_xattr_get_name(talloc_tos(), smb_fname->stream_name,
223- &xattr_name);
224- if (!NT_STATUS_IS_OK(status)) {
225- errno = map_errno_from_nt_status(status);
226- goto fail;
227- }
228+ return ret;
229+ }
230
231- /* Create an smb_filename with stream_name == NULL. */
232- status = create_synthetic_smb_fname(talloc_tos(),
233- smb_fname->base_name,
234- NULL, NULL,
235- &smb_fname_base);
236- if (!NT_STATUS_IS_OK(status)) {
237- errno = map_errno_from_nt_status(status);
238- goto fail;
239- }
240+ status = streams_xattr_get_name(talloc_tos(), smb_fname->stream_name,
241+ &xattr_name);
242+ if (!NT_STATUS_IS_OK(status)) {
243+ errno = map_errno_from_nt_status(status);
244+ goto fail;
245+ }
246
247- /*
248- * We use baseflags to turn off nasty side-effects when opening the
249- * underlying file.
250- */
251- baseflags = flags;
252- baseflags &= ~O_TRUNC;
253- baseflags &= ~O_EXCL;
254- baseflags &= ~O_CREAT;
255+ /* Create an smb_filename with stream_name == NULL. */
256+ status = create_synthetic_smb_fname(talloc_tos(),
257+ smb_fname->base_name,
258+ NULL, NULL,
259+ &smb_fname_base);
260+ if (!NT_STATUS_IS_OK(status)) {
261+ errno = map_errno_from_nt_status(status);
262+ goto fail;
263+ }
264
265- hostfd = SMB_VFS_OPEN(handle->conn, smb_fname_base, fsp,
266- baseflags, mode);
267+ /*
268+ * We use baseflags to turn off nasty side-effects when opening the
269+ * underlying file.
270+ */
271+ baseflags = flags;
272+ baseflags &= ~O_TRUNC;
273+ baseflags &= ~O_EXCL;
274+ baseflags &= ~O_CREAT;
275
276- TALLOC_FREE(smb_fname_base);
277+ hostfd = SMB_VFS_OPEN(handle->conn, smb_fname_base, fsp,
278+ baseflags, mode);
279
280- /* It is legit to open a stream on a directory, but the base
281- * fd has to be read-only.
282- */
283- if ((hostfd == -1) && (errno == EISDIR)) {
284- baseflags &= ~O_ACCMODE;
285- baseflags |= O_RDONLY;
286- hostfd = SMB_VFS_OPEN(handle->conn, smb_fname, fsp, baseflags,
287- mode);
288- }
289+ TALLOC_FREE(smb_fname_base);
290
291- if (hostfd == -1) {
292- goto fail;
293- }
294+ /* It is legit to open a stream on a directory, but the base
295+ * fd has to be read-only.
296+ */
297+ if ((hostfd == -1) && (errno == EISDIR)) {
298+ baseflags &= ~O_ACCMODE;
299+ baseflags |= O_RDONLY;
300+ hostfd = SMB_VFS_OPEN(handle->conn, smb_fname, fsp, baseflags,
301+ mode);
302+ }
303
304- status = get_ea_value(talloc_tos(), handle->conn, NULL,
305- smb_fname->base_name, xattr_name, &ea);
306+ if (hostfd == -1) {
307+ goto fail;
308+ }
309
310- DEBUG(10, ("get_ea_value returned %s\n", nt_errstr(status)));
311+ status = get_ea_value(talloc_tos(), handle->conn, NULL,
312+ smb_fname->base_name, xattr_name, &ea);
313
314- if (!NT_STATUS_IS_OK(status)
315- && !NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) {
316- /*
317- * The base file is not there. This is an error even if we got
318- * O_CREAT, the higher levels should have created the base
319- * file for us.
320- */
321- DEBUG(10, ("streams_xattr_open: base file %s not around, "
322- "returning ENOENT\n", smb_fname->base_name));
323- errno = ENOENT;
324- goto fail;
325- }
326+ DEBUG(10, ("get_ea_value returned %s\n", nt_errstr(status)));
327
328- if (!NT_STATUS_IS_OK(status)) {
329- /*
330- * The attribute does not exist
331- */
332+ if (!NT_STATUS_IS_OK(status)
333+ && !NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) {
334+ /*
335+ * The base file is not there. This is an error even if we got
336+ * O_CREAT, the higher levels should have created the base
337+ * file for us.
338+ */
339+ DEBUG(10, ("streams_xattr_open: base file %s not around, "
340+ "returning ENOENT\n", smb_fname->base_name));
341+ errno = ENOENT;
342+ goto fail;
343+ }
344
345- if (flags & O_CREAT) {
346+ if (!NT_STATUS_IS_OK(status)) {
347 /*
348- * Darn, xattrs need at least 1 byte
349+ * The attribute does not exist
350 */
351- char null = '\0';
352
353- DEBUG(10, ("creating attribute %s on file %s\n",
354- xattr_name, smb_fname->base_name));
355+ if (flags & O_CREAT) {
356+ /*
357+ * Darn, xattrs need at least 1 byte
358+ */
359+ char null = '\0';
360+
361+ DEBUG(10, ("creating attribute %s on file %s\n",
362+ xattr_name, smb_fname->base_name));
363+
364+ fsp->fh->fd = hostfd;
365+ ret = SMB_VFS_FSETXATTR(fsp, xattr_name,
366+ &null, sizeof(null),
367+ flags & O_EXCL ? XATTR_CREATE : 0);
368+ fsp->fh->fd = -1;
369+ if (ret != 0) {
370+ goto fail;
371+ }
372+ }
373+ }
374
375+ if (flags & O_TRUNC) {
376+ char null = '\0';
377 if (fsp->base_fsp->fh->fd != -1) {
378- if (SMB_VFS_FSETXATTR(
379- fsp->base_fsp, xattr_name,
380- &null, sizeof(null),
381- flags & O_EXCL ? XATTR_CREATE : 0) == -1) {
382+ if (SMB_VFS_FSETXATTR(
383+ fsp->base_fsp, xattr_name,
384+ &null, sizeof(null),
385+ flags & O_EXCL ? XATTR_CREATE : 0) == -1) {
386 goto fail;
387 }
388 } else {
389- if (SMB_VFS_SETXATTR(
390- handle->conn, smb_fname->base_name,
391- xattr_name, &null, sizeof(null),
392- flags & O_EXCL ? XATTR_CREATE : 0) == -1) {
393+ if (SMB_VFS_SETXATTR(
394+ handle->conn, smb_fname->base_name,
395+ xattr_name, &null, sizeof(null),
396+ flags & O_EXCL ? XATTR_CREATE : 0) == -1) {
397 goto fail;
398 }
399 }
400 }
401- }
402-
403- if (flags & O_TRUNC) {
404- char null = '\0';
405- if (fsp->base_fsp->fh->fd != -1) {
406- if (SMB_VFS_FSETXATTR(
407- fsp->base_fsp, xattr_name,
408- &null, sizeof(null),
409- flags & O_EXCL ? XATTR_CREATE : 0) == -1) {
410- goto fail;
411- }
412- } else {
413- if (SMB_VFS_SETXATTR(
414- handle->conn, smb_fname->base_name,
415- xattr_name, &null, sizeof(null),
416- flags & O_EXCL ? XATTR_CREATE : 0) == -1) {
417- goto fail;
418- }
419- }
420- }
421
422- sio = (struct stream_io *)VFS_ADD_FSP_EXTENSION(handle, fsp,
423+ sio = (struct stream_io *)VFS_ADD_FSP_EXTENSION(handle, fsp,
424 struct stream_io,
425 NULL);
426 if (sio == NULL) {
427@@ -868,7 +861,7 @@ static ssize_t streams_xattr_pwrite(vfs_handle_struct *handle,
428 return -1;
429 }
430
431- status = get_ea_value(talloc_tos(), handle->conn, fsp->base_fsp,
432+ status = get_ea_value(talloc_tos(), handle->conn, fsp,
433 sio->base, sio->xattr_name, &ea);
434 if (!NT_STATUS_IS_OK(status)) {
435 return -1;
436@@ -892,13 +885,13 @@ static ssize_t streams_xattr_pwrite(vfs_handle_struct *handle,
437
438 memcpy(ea.value.data + offset, data, n);
439
440- if (fsp->base_fsp->fh->fd != -1) {
441- ret = SMB_VFS_FSETXATTR(fsp->base_fsp,
442+ if (fsp->fh->fd != -1) {
443+ ret = SMB_VFS_FSETXATTR(fsp,
444 sio->xattr_name,
445 ea.value.data, ea.value.length, 0);
446 } else {
447 ret = SMB_VFS_SETXATTR(fsp->conn,
448- fsp->base_fsp->fsp_name->base_name,
449+ fsp->fsp_name->base_name,
450 sio->xattr_name,
451 ea.value.data, ea.value.length, 0);
452 }
453@@ -932,7 +925,7 @@ static ssize_t streams_xattr_pread(vfs_handle_struct *handle,
454 return -1;
455 }
456
457- status = get_ea_value(talloc_tos(), handle->conn, fsp->base_fsp,
458+ status = get_ea_value(talloc_tos(), handle->conn, fsp,
459 sio->base, sio->xattr_name, &ea);
460 if (!NT_STATUS_IS_OK(status)) {
461 return -1;
462@@ -977,7 +970,7 @@ static int streams_xattr_ftruncate(struct vfs_handle_struct *handle,
463 return -1;
464 }
465
466- status = get_ea_value(talloc_tos(), handle->conn, fsp->base_fsp,
467+ status = get_ea_value(talloc_tos(), handle->conn, fsp,
468 sio->base, sio->xattr_name, &ea);
469 if (!NT_STATUS_IS_OK(status)) {
470 return -1;
471@@ -1002,13 +995,13 @@ static int streams_xattr_ftruncate(struct vfs_handle_struct *handle,
472 ea.value.length = offset + 1;
473 ea.value.data[offset] = 0;
474
475- if (fsp->base_fsp->fh->fd != -1) {
476- ret = SMB_VFS_FSETXATTR(fsp->base_fsp,
477+ if (fsp->fh->fd != -1) {
478+ ret = SMB_VFS_FSETXATTR(fsp,
479 sio->xattr_name,
480 ea.value.data, ea.value.length, 0);
481 } else {
482 ret = SMB_VFS_SETXATTR(fsp->conn,
483- fsp->base_fsp->fsp_name->base_name,
484+ fsp->fsp_name->base_name,
485 sio->xattr_name,
486 ea.value.data, ea.value.length, 0);
487 }
488--
4892.13.5
490
491
492From 3f3c731faaa59f4d3ce7e49c12795c40e048d29f Mon Sep 17 00:00:00 2001
493From: Jeremy Allison <jra@samba.org>
494Date: Mon, 19 Dec 2016 11:55:56 -0800
495Subject: [PATCH 05/15] s3: smbd: Create wrapper function for OpenDir in
496 preparation for making robust.
497
498CVE-2017-2619
499
500BUG: https://bugzilla.samba.org/show_bug.cgi?id=12496
501
502Signed-off-by: Jeremy Allison <jra@samba.org>
503---
504 source3/smbd/dir.c | 15 ++++++++++++++-
505 1 file changed, 14 insertions(+), 1 deletion(-)
506
507diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c
508index 18ecf066824..ebe2641f813 100644
509--- a/source3/smbd/dir.c
510+++ b/source3/smbd/dir.c
511@@ -1367,7 +1367,8 @@ static int smb_Dir_destructor(struct smb_Dir *dirp)
512 Open a directory.
513 ********************************************************************/
514
515-struct smb_Dir *OpenDir(TALLOC_CTX *mem_ctx, connection_struct *conn,
516+static struct smb_Dir *OpenDir_internal(TALLOC_CTX *mem_ctx,
517+ connection_struct *conn,
518 const char *name,
519 const char *mask,
520 uint32 attr)
521@@ -1407,6 +1408,18 @@ struct smb_Dir *OpenDir(TALLOC_CTX *mem_ctx, connection_struct *conn,
522 return NULL;
523 }
524
525+struct smb_Dir *OpenDir(TALLOC_CTX *mem_ctx, connection_struct *conn,
526+ const char *name,
527+ const char *mask,
528+ uint32_t attr)
529+{
530+ return OpenDir_internal(mem_ctx,
531+ conn,
532+ name,
533+ mask,
534+ attr);
535+}
536+
537 /*******************************************************************
538 Open a directory from an fsp.
539 ********************************************************************/
540--
5412.13.5
542
543
544From 7efeb067c1586e0f1cfbb775b1efcb3b92005140 Mon Sep 17 00:00:00 2001
545From: Jeremy Allison <jra@samba.org>
546Date: Mon, 19 Dec 2016 16:25:26 -0800
547Subject: [PATCH 06/15] s3: smbd: Opendir_internal() early return if
548 SMB_VFS_OPENDIR failed.
549
550CVE-2017-2619
551
552BUG: https://bugzilla.samba.org/show_bug.cgi?id=12496
553
554Signed-off-by: Jeremy Allison <jra@samba.org>
555---
556 source3/smbd/dir.c | 14 +++++++-------
557 1 file changed, 7 insertions(+), 7 deletions(-)
558
559diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c
560index ebe2641f813..65327dd0dd1 100644
561--- a/source3/smbd/dir.c
562+++ b/source3/smbd/dir.c
563@@ -1380,6 +1380,13 @@ static struct smb_Dir *OpenDir_internal(TALLOC_CTX *mem_ctx,
564 return NULL;
565 }
566
567+ dirp->dir = SMB_VFS_OPENDIR(conn, name, mask, attr);
568+ if (!dirp->dir) {
569+ DEBUG(5,("OpenDir: Can't open %s. %s\n", name,
570+ strerror(errno) ));
571+ goto fail;
572+ }
573+
574 dirp->conn = conn;
575 dirp->name_cache_size = lp_directory_name_cache_size(SNUM(conn));
576
577@@ -1394,13 +1401,6 @@ static struct smb_Dir *OpenDir_internal(TALLOC_CTX *mem_ctx,
578 }
579 talloc_set_destructor(dirp, smb_Dir_destructor);
580
581- dirp->dir = SMB_VFS_OPENDIR(conn, dirp->dir_path, mask, attr);
582- if (!dirp->dir) {
583- DEBUG(5,("OpenDir: Can't open %s. %s\n", dirp->dir_path,
584- strerror(errno) ));
585- goto fail;
586- }
587-
588 return dirp;
589
590 fail:
591--
5922.13.5
593
594
595From 49d22a0c51ef1f78f0488a7c35131887704e987b Mon Sep 17 00:00:00 2001
596From: Jeremy Allison <jra@samba.org>
597Date: Mon, 19 Dec 2016 16:35:00 -0800
598Subject: [PATCH 07/15] s3: smbd: Create and use open_dir_safely(). Use from
599 OpenDir().
600
601Hardens OpenDir against TOC/TOU races.
602
603CVE-2017-2619
604
605BUG: https://bugzilla.samba.org/show_bug.cgi?id=12496
606
607Signed-off-by: Jeremy Allison <jra@samba.org>
608---
609 source3/smbd/dir.c | 66 ++++++++++++++++++++++++++++++++++++++++++++++++------
610 1 file changed, 59 insertions(+), 7 deletions(-)
611
612diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c
613index 65327dd0dd1..2d168c3ba9f 100644
614--- a/source3/smbd/dir.c
615+++ b/source3/smbd/dir.c
616@@ -1390,12 +1390,6 @@ static struct smb_Dir *OpenDir_internal(TALLOC_CTX *mem_ctx,
617 dirp->conn = conn;
618 dirp->name_cache_size = lp_directory_name_cache_size(SNUM(conn));
619
620- dirp->dir_path = talloc_strdup(dirp, name);
621- if (!dirp->dir_path) {
622- errno = ENOMEM;
623- goto fail;
624- }
625-
626 if (sconn && !sconn->using_smb2) {
627 sconn->searches.dirhandles_open++;
628 }
629@@ -1408,12 +1402,70 @@ static struct smb_Dir *OpenDir_internal(TALLOC_CTX *mem_ctx,
630 return NULL;
631 }
632
633+/****************************************************************************
634+ Open a directory handle by pathname, ensuring it's under the share path.
635+****************************************************************************/
636+
637+static struct smb_Dir *open_dir_safely(TALLOC_CTX *ctx,
638+ connection_struct *conn,
639+ const char *name,
640+ const char *wcard,
641+ uint32_t attr)
642+{
643+ struct smb_Dir *dir_hnd = NULL;
644+ char *saved_dir = vfs_GetWd(ctx, conn);
645+ NTSTATUS status;
646+
647+ if (saved_dir == NULL) {
648+ return NULL;
649+ }
650+
651+ if (vfs_ChDir(conn, name) == -1) {
652+ goto out;
653+ }
654+
655+ /*
656+ * Now the directory is pinned, use
657+ * REALPATH to ensure we can access it.
658+ */
659+ status = check_name(conn, ".");
660+ if (!NT_STATUS_IS_OK(status)) {
661+ goto out;
662+ }
663+
664+ dir_hnd = OpenDir_internal(ctx,
665+ conn,
666+ ".",
667+ wcard,
668+ attr);
669+
670+ if (dir_hnd == NULL) {
671+ goto out;
672+ }
673+
674+ /*
675+ * OpenDir_internal only gets "." as the dir name.
676+ * Store the real dir name here.
677+ */
678+
679+ dir_hnd->dir_path = talloc_strdup(dir_hnd, name);
680+ if (!dir_hnd->dir_path) {
681+ errno = ENOMEM;
682+ }
683+
684+ out:
685+
686+ vfs_ChDir(conn, saved_dir);
687+ TALLOC_FREE(saved_dir);
688+ return dir_hnd;
689+}
690+
691 struct smb_Dir *OpenDir(TALLOC_CTX *mem_ctx, connection_struct *conn,
692 const char *name,
693 const char *mask,
694 uint32_t attr)
695 {
696- return OpenDir_internal(mem_ctx,
697+ return open_dir_safely(mem_ctx,
698 conn,
699 name,
700 mask,
701--
7022.13.5
703
704
705From 6426ae1f9ef53158a6fbe1912dfec40d834115fe Mon Sep 17 00:00:00 2001
706From: Jeremy Allison <jra@samba.org>
707Date: Mon, 19 Dec 2016 12:13:20 -0800
708Subject: [PATCH 08/15] s3: smbd: OpenDir_fsp() use early returns.
709
710CVE-2017-2619
711
712BUG: https://bugzilla.samba.org/show_bug.cgi?id=12496
713
714Signed-off-by: Jeremy Allison <jra@samba.org>
715---
716 source3/smbd/dir.c | 34 +++++++++++++++++++++-------------
717 1 file changed, 21 insertions(+), 13 deletions(-)
718
719diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c
720index 2d168c3ba9f..6aed4a6da46 100644
721--- a/source3/smbd/dir.c
722+++ b/source3/smbd/dir.c
723@@ -1485,7 +1485,17 @@ static struct smb_Dir *OpenDir_fsp(TALLOC_CTX *mem_ctx, connection_struct *conn,
724 struct smbd_server_connection *sconn = conn->sconn;
725
726 if (!dirp) {
727- return NULL;
728+ goto fail;
729+ }
730+
731+ if (!fsp->is_directory) {
732+ errno = EBADF;
733+ goto fail;
734+ }
735+
736+ if (fsp->fh->fd == -1) {
737+ errno = EBADF;
738+ goto fail;
739 }
740
741 dirp->conn = conn;
742@@ -1502,18 +1512,16 @@ static struct smb_Dir *OpenDir_fsp(TALLOC_CTX *mem_ctx, connection_struct *conn,
743 }
744 talloc_set_destructor(dirp, smb_Dir_destructor);
745
746- if (fsp->is_directory && fsp->fh->fd != -1) {
747- dirp->dir = SMB_VFS_FDOPENDIR(fsp, mask, attr);
748- if (dirp->dir != NULL) {
749- dirp->fsp = fsp;
750- } else {
751- DEBUG(10,("OpenDir_fsp: SMB_VFS_FDOPENDIR on %s returned "
752- "NULL (%s)\n",
753- dirp->dir_path,
754- strerror(errno)));
755- if (errno != ENOSYS) {
756- return NULL;
757- }
758+ dirp->dir = SMB_VFS_FDOPENDIR(fsp, mask, attr);
759+ if (dirp->dir != NULL) {
760+ dirp->fsp = fsp;
761+ } else {
762+ DEBUG(10,("OpenDir_fsp: SMB_VFS_FDOPENDIR on %s returned "
763+ "NULL (%s)\n",
764+ dirp->dir_path,
765+ strerror(errno)));
766+ if (errno != ENOSYS) {
767+ return NULL;
768 }
769 }
770
771--
7722.13.5
773
774
775From f6581858ce665b880c5fea465ec61b1b0c504d89 Mon Sep 17 00:00:00 2001
776From: Jeremy Allison <jra@samba.org>
777Date: Mon, 19 Dec 2016 12:15:59 -0800
778Subject: [PATCH 09/15] s3: smbd: OpenDir_fsp() - Fix memory leak on error.
779
780CVE-2017-2619
781
782BUG: https://bugzilla.samba.org/show_bug.cgi?id=12496
783
784Signed-off-by: Jeremy Allison <jra@samba.org>
785---
786 source3/smbd/dir.c | 2 +-
787 1 file changed, 1 insertion(+), 1 deletion(-)
788
789diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c
790index 6aed4a6da46..efd1a73aab6 100644
791--- a/source3/smbd/dir.c
792+++ b/source3/smbd/dir.c
793@@ -1521,7 +1521,7 @@ static struct smb_Dir *OpenDir_fsp(TALLOC_CTX *mem_ctx, connection_struct *conn,
794 dirp->dir_path,
795 strerror(errno)));
796 if (errno != ENOSYS) {
797- return NULL;
798+ goto fail;
799 }
800 }
801
802--
8032.13.5
804
805
806From bacba6987e58d44886d04b1dd5e36f7781dcd9b0 Mon Sep 17 00:00:00 2001
807From: Jeremy Allison <jra@samba.org>
808Date: Mon, 19 Dec 2016 12:32:07 -0800
809Subject: [PATCH 10/15] s3: smbd: Move the reference counting and destructor
810 setup to just before retuning success.
811
812CVE-2017-2619
813
814BUG: https://bugzilla.samba.org/show_bug.cgi?id=12496
815
816Signed-off-by: Jeremy Allison <jra@samba.org>
817---
818 source3/smbd/dir.c | 10 +++++-----
819 1 file changed, 5 insertions(+), 5 deletions(-)
820
821diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c
822index efd1a73aab6..5eca128c033 100644
823--- a/source3/smbd/dir.c
824+++ b/source3/smbd/dir.c
825@@ -1507,11 +1507,6 @@ static struct smb_Dir *OpenDir_fsp(TALLOC_CTX *mem_ctx, connection_struct *conn,
826 goto fail;
827 }
828
829- if (sconn && !sconn->using_smb2) {
830- sconn->searches.dirhandles_open++;
831- }
832- talloc_set_destructor(dirp, smb_Dir_destructor);
833-
834 dirp->dir = SMB_VFS_FDOPENDIR(fsp, mask, attr);
835 if (dirp->dir != NULL) {
836 dirp->fsp = fsp;
837@@ -1536,6 +1531,11 @@ static struct smb_Dir *OpenDir_fsp(TALLOC_CTX *mem_ctx, connection_struct *conn,
838 goto fail;
839 }
840
841+ if (sconn && !sconn->using_smb2) {
842+ sconn->searches.dirhandles_open++;
843+ }
844+ talloc_set_destructor(dirp, smb_Dir_destructor);
845+
846 return dirp;
847
848 fail:
849--
8502.13.5
851
852
853From 34b3d05b55f5c40de76ba65d6b028818518a519f Mon Sep 17 00:00:00 2001
854From: Jeremy Allison <jra@samba.org>
855Date: Mon, 19 Dec 2016 12:35:32 -0800
856Subject: [PATCH 11/15] s3: smbd: Correctly fallback to open_dir_safely if
857 FDOPENDIR not supported on system.
858
859CVE-2017-2619
860
861BUG: https://bugzilla.samba.org/show_bug.cgi?id=12496
862
863Signed-off-by: Jeremy Allison <jra@samba.org>
864---
865 source3/smbd/dir.c | 15 +++++++--------
866 1 file changed, 7 insertions(+), 8 deletions(-)
867
868diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c
869index 5eca128c033..7690cb18c1a 100644
870--- a/source3/smbd/dir.c
871+++ b/source3/smbd/dir.c
872@@ -1521,14 +1521,13 @@ static struct smb_Dir *OpenDir_fsp(TALLOC_CTX *mem_ctx, connection_struct *conn,
873 }
874
875 if (dirp->dir == NULL) {
876- /* FDOPENDIR didn't work. Use OPENDIR instead. */
877- dirp->dir = SMB_VFS_OPENDIR(conn, dirp->dir_path, mask, attr);
878- }
879-
880- if (!dirp->dir) {
881- DEBUG(5,("OpenDir_fsp: Can't open %s. %s\n", dirp->dir_path,
882- strerror(errno) ));
883- goto fail;
884+ /* FDOPENDIR is not supported. Use OPENDIR instead. */
885+ TALLOC_FREE(dirp);
886+ return open_dir_safely(mem_ctx,
887+ conn,
888+ fsp->fsp_name->base_name,
889+ mask,
890+ attr);
891 }
892
893 if (sconn && !sconn->using_smb2) {
894--
8952.13.5
896
897
898From 84bc8b232a4495bff270b7800833ef6785937576 Mon Sep 17 00:00:00 2001
899From: Jeremy Allison <jra@samba.org>
900Date: Thu, 15 Dec 2016 12:52:13 -0800
901Subject: [PATCH 12/15] s3: smbd: Remove O_NOFOLLOW guards. We insist on
902 O_NOFOLLOW existing.
903
904CVE-2017-2619
905
906BUG: https://bugzilla.samba.org/show_bug.cgi?id=12496
907
908Signed-off-by: Jeremy Allison <jra@samba.org>
909---
910 source3/smbd/open.c | 4 +---
911 1 file changed, 1 insertion(+), 3 deletions(-)
912
913diff --git a/source3/smbd/open.c b/source3/smbd/open.c
914index 35eee0a1485..8417f8aca4a 100644
915--- a/source3/smbd/open.c
916+++ b/source3/smbd/open.c
917@@ -205,8 +205,7 @@ NTSTATUS fd_open(struct connection_struct *conn,
918 struct smb_filename *smb_fname = fsp->fsp_name;
919 NTSTATUS status = NT_STATUS_OK;
920
921-#ifdef O_NOFOLLOW
922- /*
923+ /*
924 * Never follow symlinks on a POSIX client. The
925 * client should be doing this.
926 */
927@@ -214,7 +213,6 @@ NTSTATUS fd_open(struct connection_struct *conn,
928 if (fsp->posix_open || !lp_symlinks(SNUM(conn))) {
929 flags |= O_NOFOLLOW;
930 }
931-#endif
932
933 fsp->fh->fd = SMB_VFS_OPEN(conn, smb_fname, fsp, flags, mode);
934 if (fsp->fh->fd == -1) {
935--
9362.13.5
937
938
939From af0c5a266ae65ad2a638fe48a7ad7d77417f97d7 Mon Sep 17 00:00:00 2001
940From: Jeremy Allison <jra@samba.org>
941Date: Thu, 15 Dec 2016 12:56:08 -0800
942Subject: [PATCH 13/15] s3: smbd: Move special handling of symlink errno's into
943 a utility function.
944
945CVE-2017-2619
946
947BUG: https://bugzilla.samba.org/show_bug.cgi?id=12496
948
949Signed-off-by: Jeremy Allison <jra@samba.org>
950---
951 source3/smbd/open.c | 30 ++++++++++++++++++++++++++++--
952 1 file changed, 28 insertions(+), 2 deletions(-)
953
954diff --git a/source3/smbd/open.c b/source3/smbd/open.c
955index 8417f8aca4a..e727e89e9d8 100644
956--- a/source3/smbd/open.c
957+++ b/source3/smbd/open.c
958@@ -194,6 +194,31 @@ static NTSTATUS check_base_file_access(struct connection_struct *conn,
959 }
960
961 /****************************************************************************
962+ Handle differing symlink errno's
963+****************************************************************************/
964+
965+static int link_errno_convert(int err)
966+{
967+#if defined(ENOTSUP) && defined(OSF1)
968+ /* handle special Tru64 errno */
969+ if (err == ENOTSUP) {
970+ err = ELOOP;
971+ }
972+#endif /* ENOTSUP */
973+#ifdef EFTYPE
974+ /* fix broken NetBSD errno */
975+ if (err == EFTYPE) {
976+ err = ELOOP;
977+ }
978+#endif /* EFTYPE */
979+ /* fix broken FreeBSD errno */
980+ if (err == EMLINK) {
981+ err = ELOOP;
982+ }
983+ return err;
984+}
985+
986+/****************************************************************************
987 fd support routines - attempt to do a dos_open.
988 ****************************************************************************/
989
990@@ -216,8 +241,9 @@ NTSTATUS fd_open(struct connection_struct *conn,
991
992 fsp->fh->fd = SMB_VFS_OPEN(conn, smb_fname, fsp, flags, mode);
993 if (fsp->fh->fd == -1) {
994- status = map_nt_error_from_unix(errno);
995- if (errno == EMFILE) {
996+ int posix_errno = link_errno_convert(errno);
997+ status = map_nt_error_from_unix(posix_errno);
998+ if (posix_errno == EMFILE) {
999 static time_t last_warned = 0L;
1000
1001 if (time((time_t *) NULL) > last_warned) {
1002--
10032.13.5
1004
1005
1006From c3bc4ff0367d7a3ebfd64db6defddea0bc3a5f4a Mon Sep 17 00:00:00 2001
1007From: Jeremy Allison <jra@samba.org>
1008Date: Thu, 15 Dec 2016 13:04:46 -0800
1009Subject: [PATCH 14/15] s3: smbd: Add the core functions to prevent symlink
1010 open races.
1011
1012CVE-2017-2619
1013
1014BUG: https://bugzilla.samba.org/show_bug.cgi?id=12496
1015
1016Signed-off-by: Jeremy Allison <jra@samba.org>
1017---
1018 source3/smbd/open.c | 242 ++++++++++++++++++++++++++++++++++++++++++++++++++++
1019 1 file changed, 242 insertions(+)
1020
1021diff --git a/source3/smbd/open.c b/source3/smbd/open.c
1022index e727e89e9d8..0998adc416a 100644
1023--- a/source3/smbd/open.c
1024+++ b/source3/smbd/open.c
1025@@ -218,6 +218,248 @@ static int link_errno_convert(int err)
1026 return err;
1027 }
1028
1029+static int non_widelink_open(struct connection_struct *conn,
1030+ const char *conn_rootdir,
1031+ files_struct *fsp,
1032+ struct smb_filename *smb_fname,
1033+ int flags,
1034+ mode_t mode,
1035+ unsigned int link_depth);
1036+
1037+/****************************************************************************
1038+ Follow a symlink in userspace.
1039+****************************************************************************/
1040+
1041+static int process_symlink_open(struct connection_struct *conn,
1042+ const char *conn_rootdir,
1043+ files_struct *fsp,
1044+ struct smb_filename *smb_fname,
1045+ int flags,
1046+ mode_t mode,
1047+ unsigned int link_depth)
1048+{
1049+ int fd = -1;
1050+ char *link_target = NULL;
1051+ int link_len = -1;
1052+ char *oldwd = NULL;
1053+ size_t rootdir_len = 0;
1054+ char *resolved_name = NULL;
1055+ bool matched = false;
1056+ int saved_errno = 0;
1057+
1058+ /*
1059+ * Ensure we don't get stuck in a symlink loop.
1060+ */
1061+ link_depth++;
1062+ if (link_depth >= 20) {
1063+ errno = ELOOP;
1064+ goto out;
1065+ }
1066+
1067+ /* Allocate space for the link target. */
1068+ link_target = talloc_array(talloc_tos(), char, PATH_MAX);
1069+ if (link_target == NULL) {
1070+ errno = ENOMEM;
1071+ goto out;
1072+ }
1073+
1074+ /* Read the link target. */
1075+ link_len = SMB_VFS_READLINK(conn,
1076+ smb_fname->base_name,
1077+ link_target,
1078+ PATH_MAX - 1);
1079+ if (link_len == -1) {
1080+ goto out;
1081+ }
1082+
1083+ /* Ensure it's at least null terminated. */
1084+ link_target[link_len] = '\0';
1085+
1086+ /* Convert to an absolute path. */
1087+ resolved_name = SMB_VFS_REALPATH(conn, link_target);
1088+ if (resolved_name == NULL) {
1089+ goto out;
1090+ }
1091+
1092+ /*
1093+ * We know conn_rootdir starts with '/' and
1094+ * does not end in '/'. FIXME ! Should we
1095+ * smb_assert this ?
1096+ */
1097+ rootdir_len = strlen(conn_rootdir);
1098+
1099+ matched = (strncmp(conn_rootdir, resolved_name, rootdir_len) == 0);
1100+ if (!matched) {
1101+ errno = EACCES;
1102+ goto out;
1103+ }
1104+
1105+ /*
1106+ * Turn into a path relative to the share root.
1107+ */
1108+ if (resolved_name[rootdir_len] == '\0') {
1109+ /* Link to the root of the share. */
1110+ smb_fname->base_name = talloc_strdup(talloc_tos(), ".");
1111+ if (smb_fname->base_name == NULL) {
1112+ errno = ENOMEM;
1113+ goto out;
1114+ }
1115+ } else if (resolved_name[rootdir_len] == '/') {
1116+ smb_fname->base_name = &resolved_name[rootdir_len+1];
1117+ } else {
1118+ errno = EACCES;
1119+ goto out;
1120+ }
1121+
1122+ oldwd = vfs_GetWd(talloc_tos(), conn);
1123+ if (oldwd == NULL) {
1124+ goto out;
1125+ }
1126+
1127+ /* Ensure we operate from the root of the share. */
1128+ if (vfs_ChDir(conn, conn_rootdir) == -1) {
1129+ goto out;
1130+ }
1131+
1132+ /* And do it all again.. */
1133+ fd = non_widelink_open(conn,
1134+ conn_rootdir,
1135+ fsp,
1136+ smb_fname,
1137+ flags,
1138+ mode,
1139+ link_depth);
1140+ if (fd == -1) {
1141+ saved_errno = errno;
1142+ }
1143+
1144+ out:
1145+
1146+ SAFE_FREE(resolved_name);
1147+ TALLOC_FREE(link_target);
1148+ if (oldwd != NULL) {
1149+ int ret = vfs_ChDir(conn, oldwd);
1150+ if (ret == -1) {
1151+ smb_panic("unable to get back to old directory\n");
1152+ }
1153+ TALLOC_FREE(oldwd);
1154+ }
1155+ if (saved_errno != 0) {
1156+ errno = saved_errno;
1157+ }
1158+ return fd;
1159+}
1160+
1161+/****************************************************************************
1162+ Non-widelink open.
1163+****************************************************************************/
1164+
1165+static int non_widelink_open(struct connection_struct *conn,
1166+ const char *conn_rootdir,
1167+ files_struct *fsp,
1168+ struct smb_filename *smb_fname,
1169+ int flags,
1170+ mode_t mode,
1171+ unsigned int link_depth)
1172+{
1173+ NTSTATUS status;
1174+ int fd = -1;
1175+ struct smb_filename *smb_fname_rel = NULL;
1176+ int saved_errno = 0;
1177+ char *oldwd = NULL;
1178+ char *parent_dir = NULL;
1179+ const char *final_component = NULL;
1180+
1181+ if (!parent_dirname(talloc_tos(),
1182+ smb_fname->base_name,
1183+ &parent_dir,
1184+ &final_component)) {
1185+ goto out;
1186+ }
1187+
1188+ oldwd = vfs_GetWd(talloc_tos(), conn);
1189+ if (oldwd == NULL) {
1190+ goto out;
1191+ }
1192+
1193+ /* Pin parent directory in place. */
1194+ if (vfs_ChDir(conn, parent_dir) == -1) {
1195+ goto out;
1196+ }
1197+
1198+ /* Ensure the relative path is below the share. */
1199+ status = check_reduced_name(conn, final_component);
1200+ if (!NT_STATUS_IS_OK(status)) {
1201+ saved_errno = map_errno_from_nt_status(status);
1202+ goto out;
1203+ }
1204+
1205+ status = create_synthetic_smb_fname(talloc_tos(),
1206+ final_component,
1207+ smb_fname->stream_name,
1208+ &smb_fname->st,
1209+ &smb_fname_rel);
1210+ if (!NT_STATUS_IS_OK(status)) {
1211+ saved_errno = map_errno_from_nt_status(status);
1212+ goto out;
1213+ }
1214+
1215+ flags |= O_NOFOLLOW;
1216+
1217+ {
1218+ struct smb_filename *tmp_name = fsp->fsp_name;
1219+ fsp->fsp_name = smb_fname_rel;
1220+ fd = SMB_VFS_OPEN(conn, smb_fname_rel, fsp, flags, mode);
1221+ fsp->fsp_name = tmp_name;
1222+ }
1223+
1224+ if (fd == -1) {
1225+ saved_errno = link_errno_convert(errno);
1226+ if (saved_errno == ELOOP) {
1227+ if (fsp->posix_open) {
1228+ /* Never follow symlinks on posix open. */
1229+ goto out;
1230+ }
1231+ if (!lp_symlinks(SNUM(conn))) {
1232+ /* Explicitly no symlinks. */
1233+ goto out;
1234+ }
1235+ /*
1236+ * We have a symlink. Follow in userspace
1237+ * to ensure it's under the share definition.
1238+ */
1239+ fd = process_symlink_open(conn,
1240+ conn_rootdir,
1241+ fsp,
1242+ smb_fname_rel,
1243+ flags,
1244+ mode,
1245+ link_depth);
1246+ if (fd == -1) {
1247+ saved_errno =
1248+ link_errno_convert(errno);
1249+ }
1250+ }
1251+ }
1252+
1253+ out:
1254+
1255+ TALLOC_FREE(parent_dir);
1256+ TALLOC_FREE(smb_fname_rel);
1257+
1258+ if (oldwd != NULL) {
1259+ int ret = vfs_ChDir(conn, oldwd);
1260+ if (ret == -1) {
1261+ smb_panic("unable to get back to old directory\n");
1262+ }
1263+ TALLOC_FREE(oldwd);
1264+ }
1265+ if (saved_errno != 0) {
1266+ errno = saved_errno;
1267+ }
1268+ return fd;
1269+}
1270+
1271 /****************************************************************************
1272 fd support routines - attempt to do a dos_open.
1273 ****************************************************************************/
1274--
12752.13.5
1276
1277
1278From 6a88d1cf3deb54a784f50c8eba3b9a24a65c1b34 Mon Sep 17 00:00:00 2001
1279From: Jeremy Allison <jra@samba.org>
1280Date: Thu, 15 Dec 2016 13:06:31 -0800
1281Subject: [PATCH 15/15] s3: smbd: Use the new non_widelink_open() function.
1282
1283CVE-2017-2619
1284
1285BUG: https://bugzilla.samba.org/show_bug.cgi?id=12496
1286
1287Signed-off-by: Jeremy Allison <jra@samba.org>
1288---
1289 source3/smbd/open.c | 23 ++++++++++++++++++++++-
1290 1 file changed, 22 insertions(+), 1 deletion(-)
1291
1292diff --git a/source3/smbd/open.c b/source3/smbd/open.c
1293index 0998adc416a..65ca14ec8b8 100644
1294--- a/source3/smbd/open.c
1295+++ b/source3/smbd/open.c
1296@@ -481,7 +481,28 @@ NTSTATUS fd_open(struct connection_struct *conn,
1297 flags |= O_NOFOLLOW;
1298 }
1299
1300- fsp->fh->fd = SMB_VFS_OPEN(conn, smb_fname, fsp, flags, mode);
1301+ /* Ensure path is below share definition. */
1302+ if (!lp_widelinks(SNUM(conn))) {
1303+ const char *conn_rootdir = SMB_VFS_CONNECTPATH(conn,
1304+ smb_fname->base_name);
1305+ if (conn_rootdir == NULL) {
1306+ return NT_STATUS_NO_MEMORY;
1307+ }
1308+ /*
1309+ * Only follow symlinks within a share
1310+ * definition.
1311+ */
1312+ fsp->fh->fd = non_widelink_open(conn,
1313+ conn_rootdir,
1314+ fsp,
1315+ smb_fname,
1316+ flags,
1317+ mode,
1318+ 0);
1319+ } else {
1320+ fsp->fh->fd = SMB_VFS_OPEN(conn, smb_fname, fsp, flags, mode);
1321+ }
1322+
1323 if (fsp->fh->fd == -1) {
1324 int posix_errno = link_errno_convert(errno);
1325 status = map_nt_error_from_unix(posix_errno);
1326--
13272.13.5
1328