diff --git a/SOURCES/CVE-2015-7560-v4-2.patch b/SOURCES/CVE-2015-7560-v4-2.patch new file mode 100644 index 0000000..687ee8a --- /dev/null +++ b/SOURCES/CVE-2015-7560-v4-2.patch @@ -0,0 +1,1144 @@ +From a91cf9a5648184d39aa87e06d484b3d533aeefdb Mon Sep 17 00:00:00 2001 +From: Jeremy Allison +Date: Tue, 5 Jan 2016 11:18:12 -0800 +Subject: [PATCH 01/12] CVE-2015-7560: s3: smbd: Add refuse_symlink() function + that can be used to prevent operations on a symlink. + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=11648 + +Signed-off-by: Jeremy Allison +Reviewed-by: Volker Lendecke +--- + source3/smbd/trans2.c | 28 ++++++++++++++++++++++++++++ + 1 file changed, 28 insertions(+) + +diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c +index 41e1bb1..b9865fd 100644 +--- a/source3/smbd/trans2.c ++++ b/source3/smbd/trans2.c +@@ -54,6 +54,34 @@ static char *store_file_unix_basic_info2(connection_struct *conn, + files_struct *fsp, + const SMB_STRUCT_STAT *psbuf); + ++/**************************************************************************** ++ Check if an open file handle or pathname is a symlink. ++****************************************************************************/ ++ ++static NTSTATUS refuse_symlink(connection_struct *conn, ++ const files_struct *fsp, ++ const char *name) ++{ ++ SMB_STRUCT_STAT sbuf; ++ const SMB_STRUCT_STAT *pst = NULL; ++ ++ if (fsp) { ++ pst = &fsp->fsp_name->st; ++ } else { ++ int ret = vfs_stat_smb_basename(conn, ++ name, ++ &sbuf); ++ if (ret == -1) { ++ return map_nt_error_from_unix(errno); ++ } ++ pst = &sbuf; ++ } ++ if (S_ISLNK(pst->st_ex_mode)) { ++ return NT_STATUS_ACCESS_DENIED; ++ } ++ return NT_STATUS_OK; ++} ++ + /******************************************************************** + The canonical "check access" based on object handle or path function. + ********************************************************************/ +-- +1.9.1 + + +From cd950ca41df5076c8622cdf9be0e0db165b992f1 Mon Sep 17 00:00:00 2001 +From: Jeremy Allison +Date: Tue, 5 Jan 2016 10:38:28 -0800 +Subject: [PATCH 02/12] CVE-2015-7560: s3: smbd: Refuse to get an ACL from a + POSIX file handle on a symlink. + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=11648 + +Signed-off-by: Jeremy Allison +Reviewed-by: Volker Lendecke +--- + source3/smbd/nttrans.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/source3/smbd/nttrans.c b/source3/smbd/nttrans.c +index 4423a44..8113909 100644 +--- a/source3/smbd/nttrans.c ++++ b/source3/smbd/nttrans.c +@@ -1905,6 +1905,13 @@ NTSTATUS smbd_do_query_security_desc(connection_struct *conn, + return NT_STATUS_ACCESS_DENIED; + } + ++ if (S_ISLNK(fsp->fsp_name->st.st_ex_mode)) { ++ DEBUG(10, ("ACL get on symlink %s denied.\n", ++ fsp_str_dbg(fsp))); ++ TALLOC_FREE(frame); ++ return NT_STATUS_ACCESS_DENIED; ++ } ++ + if (security_info_wanted & (SECINFO_DACL|SECINFO_OWNER| + SECINFO_GROUP|SECINFO_SACL)) { + /* Don't return SECINFO_LABEL if anything else was +-- +1.9.1 + + +From b95ded07aec97c31c69f49f691d5f90fdee40f92 Mon Sep 17 00:00:00 2001 +From: Jeremy Allison +Date: Tue, 5 Jan 2016 10:52:50 -0800 +Subject: [PATCH 03/12] CVE-2015-7560: s3: smbd: Refuse to set an ACL from a + POSIX file handle on a symlink. + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=11648 + +Signed-off-by: Jeremy Allison +Reviewed-by: Volker Lendecke +--- + source3/smbd/nttrans.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/source3/smbd/nttrans.c b/source3/smbd/nttrans.c +index 8113909..372d420 100644 +--- a/source3/smbd/nttrans.c ++++ b/source3/smbd/nttrans.c +@@ -875,6 +875,12 @@ NTSTATUS set_sd(files_struct *fsp, struct security_descriptor *psd, + return NT_STATUS_OK; + } + ++ if (S_ISLNK(fsp->fsp_name->st.st_ex_mode)) { ++ DEBUG(10, ("ACL set on symlink %s denied.\n", ++ fsp_str_dbg(fsp))); ++ return NT_STATUS_ACCESS_DENIED; ++ } ++ + if (psd->owner_sid == NULL) { + security_info_sent &= ~SECINFO_OWNER; + } +-- +1.9.1 + + +From 35abb608ce57efea1bc197b7d65f9347f9533f23 Mon Sep 17 00:00:00 2001 +From: Jeremy Allison +Date: Tue, 5 Jan 2016 11:22:12 -0800 +Subject: [PATCH 04/12] CVE-2015-7560: s3: smbd: Refuse to set a POSIX ACL on a + symlink. + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=11648 + +Signed-off-by: Jeremy Allison +Reviewed-by: Volker Lendecke +--- + source3/smbd/trans2.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c +index b9865fd..a5eeda8 100644 +--- a/source3/smbd/trans2.c ++++ b/source3/smbd/trans2.c +@@ -6745,6 +6745,7 @@ static NTSTATUS smb_set_posix_acl(connection_struct *conn, + uint16 num_def_acls; + bool valid_file_acls = True; + bool valid_def_acls = True; ++ NTSTATUS status; + + if (total_data < SMB_POSIX_ACL_HEADER_SIZE) { + return NT_STATUS_INVALID_PARAMETER; +@@ -6772,6 +6773,11 @@ static NTSTATUS smb_set_posix_acl(connection_struct *conn, + return NT_STATUS_INVALID_PARAMETER; + } + ++ status = refuse_symlink(conn, fsp, smb_fname->base_name); ++ if (!NT_STATUS_IS_OK(status)) { ++ return status; ++ } ++ + DEBUG(10,("smb_set_posix_acl: file %s num_file_acls = %u, num_def_acls = %u\n", + smb_fname ? smb_fname_str_dbg(smb_fname) : fsp_str_dbg(fsp), + (unsigned int)num_file_acls, +-- +1.9.1 + + +From 95c3bf9102440cf299312acc0d0a89afebf0474e Mon Sep 17 00:00:00 2001 +From: Jeremy Allison +Date: Tue, 5 Jan 2016 11:24:36 -0800 +Subject: [PATCH 05/12] CVE-2015-7560: s3: smbd: Refuse to get a POSIX ACL on a + symlink. + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=11648 + +Signed-off-by: Jeremy Allison +Reviewed-by: Volker Lendecke +--- + source3/smbd/trans2.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c +index a5eeda8..8ea49f1e 100644 +--- a/source3/smbd/trans2.c ++++ b/source3/smbd/trans2.c +@@ -5248,6 +5248,13 @@ NTSTATUS smbd_do_qfilepathinfo(connection_struct *conn, + uint16 num_file_acls = 0; + uint16 num_def_acls = 0; + ++ status = refuse_symlink(conn, ++ fsp, ++ smb_fname->base_name); ++ if (!NT_STATUS_IS_OK(status)) { ++ return status; ++ } ++ + if (fsp && fsp->fh->fd != -1) { + file_acl = SMB_VFS_SYS_ACL_GET_FD(fsp, + talloc_tos()); +-- +1.9.1 + + +From c7ea0914d3b4a3deaf31a742c6edf4c6e7a91939 Mon Sep 17 00:00:00 2001 +From: Jeremy Allison +Date: Tue, 5 Jan 2016 11:05:48 -0800 +Subject: [PATCH 06/12] CVE-2015-7560: s3: smbd: Set return values early, + allows removal of code duplication. + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=11648 + +Signed-off-by: Jeremy Allison +Reviewed-by: Volker Lendecke +--- + source3/smbd/trans2.c | 13 +++++-------- + 1 file changed, 5 insertions(+), 8 deletions(-) + +diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c +index 8ea49f1e..35a0ba2 100644 +--- a/source3/smbd/trans2.c ++++ b/source3/smbd/trans2.c +@@ -238,11 +238,12 @@ NTSTATUS get_ea_names_from_file(TALLOC_CTX *mem_ctx, connection_struct *conn, + size_t num_names; + ssize_t sizeret = -1; + ++ if (pnames) { ++ *pnames = NULL; ++ } ++ *pnum_names = 0; ++ + if (!lp_ea_support(SNUM(conn))) { +- if (pnames) { +- *pnames = NULL; +- } +- *pnum_names = 0; + return NT_STATUS_OK; + } + +@@ -292,10 +293,6 @@ NTSTATUS get_ea_names_from_file(TALLOC_CTX *mem_ctx, connection_struct *conn, + + if (sizeret == 0) { + TALLOC_FREE(names); +- if (pnames) { +- *pnames = NULL; +- } +- *pnum_names = 0; + return NT_STATUS_OK; + } + +-- +1.9.1 + + +From 142a3050ec9875501b4f5693792d133bc5c3331a Mon Sep 17 00:00:00 2001 +From: Jeremy Allison +Date: Tue, 5 Jan 2016 11:29:38 -0800 +Subject: [PATCH 07/12] CVE-2015-7560: s3: smbd: Silently return no EA's + available on a symlink. + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=11648 + +Signed-off-by: Jeremy Allison +Reviewed-by: Volker Lendecke +--- + source3/smbd/trans2.c | 9 +++++++++ + 1 file changed, 9 insertions(+) + +diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c +index 35a0ba2..29e28bd 100644 +--- a/source3/smbd/trans2.c ++++ b/source3/smbd/trans2.c +@@ -237,6 +237,7 @@ NTSTATUS get_ea_names_from_file(TALLOC_CTX *mem_ctx, connection_struct *conn, + char **names, **tmp; + size_t num_names; + ssize_t sizeret = -1; ++ NTSTATUS status; + + if (pnames) { + *pnames = NULL; +@@ -247,6 +248,14 @@ NTSTATUS get_ea_names_from_file(TALLOC_CTX *mem_ctx, connection_struct *conn, + return NT_STATUS_OK; + } + ++ status = refuse_symlink(conn, fsp, fname); ++ if (!NT_STATUS_IS_OK(status)) { ++ /* ++ * Just return no EA's on a symlink. ++ */ ++ return NT_STATUS_OK; ++ } ++ + /* + * TALLOC the result early to get the talloc hierarchy right. + */ +-- +1.9.1 + + +From 08cf63d886b2f59f94a749089b73599330cee0e7 Mon Sep 17 00:00:00 2001 +From: Jeremy Allison +Date: Tue, 5 Jan 2016 11:33:48 -0800 +Subject: [PATCH 08/12] CVE-2015-7560: s3: smbd: Refuse to set EA's on a + symlink. + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=11648 + +Signed-off-by: Jeremy Allison +Reviewed-by: Volker Lendecke +--- + source3/smbd/trans2.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c +index 29e28bd..aaaa5f4 100644 +--- a/source3/smbd/trans2.c ++++ b/source3/smbd/trans2.c +@@ -659,6 +659,11 @@ NTSTATUS set_ea(connection_struct *conn, files_struct *fsp, + return NT_STATUS_EAS_NOT_SUPPORTED; + } + ++ status = refuse_symlink(conn, fsp, smb_fname->base_name); ++ if (!NT_STATUS_IS_OK(status)) { ++ return status; ++ } ++ + status = check_access(conn, fsp, smb_fname, FILE_WRITE_EA); + if (!NT_STATUS_IS_OK(status)) { + return status; +-- +1.9.1 + + +From 259fec336cee663044d7e107a3dfce6264f20e84 Mon Sep 17 00:00:00 2001 +From: Jeremy Allison +Date: Wed, 6 Jan 2016 17:17:24 -0800 +Subject: [PATCH 09/12] CVE-2015-7560: s3: libsmb: Rename cli_posix_getfaclXX() + functions to cli_posix_getacl() as they operate on pathnames. + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=11648 + +Signed-off-by: Jeremy Allison +Reviewed-by: Volker Lendecke +--- + source3/client/client.c | 2 +- + source3/libsmb/clifile.c | 30 +++++++++++++++--------------- + source3/libsmb/proto.h | 6 +++--- + 3 files changed, 19 insertions(+), 19 deletions(-) + +diff --git a/source3/client/client.c b/source3/client/client.c +index 67cc359..a8e5338 100644 +--- a/source3/client/client.c ++++ b/source3/client/client.c +@@ -3376,7 +3376,7 @@ static int cmd_getfacl(void) + return 1; + } + +- status = cli_posix_getfacl(targetcli, targetname, ctx, &rb_size, &retbuf); ++ status = cli_posix_getacl(targetcli, targetname, ctx, &rb_size, &retbuf); + if (!NT_STATUS_IS_OK(status)) { + d_printf("%s getfacl file %s\n", + nt_errstr(status), src); +diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c +index 61cb8b5..ff646e4 100644 +--- a/source3/libsmb/clifile.c ++++ b/source3/libsmb/clifile.c +@@ -590,25 +590,25 @@ NTSTATUS cli_posix_hardlink(struct cli_state *cli, + } + + /**************************************************************************** +- Do a POSIX getfacl (UNIX extensions). ++ Do a POSIX getacl - pathname based ACL get (UNIX extensions). + ****************************************************************************/ + +-struct getfacl_state { ++struct getacl_state { + uint32_t num_data; + uint8_t *data; + }; + +-static void cli_posix_getfacl_done(struct tevent_req *subreq); ++static void cli_posix_getacl_done(struct tevent_req *subreq); + +-struct tevent_req *cli_posix_getfacl_send(TALLOC_CTX *mem_ctx, ++struct tevent_req *cli_posix_getacl_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct cli_state *cli, + const char *fname) + { + struct tevent_req *req = NULL, *subreq = NULL; +- struct getfacl_state *state = NULL; ++ struct getacl_state *state = NULL; + +- req = tevent_req_create(mem_ctx, &state, struct getfacl_state); ++ req = tevent_req_create(mem_ctx, &state, struct getacl_state); + if (req == NULL) { + return NULL; + } +@@ -617,16 +617,16 @@ struct tevent_req *cli_posix_getfacl_send(TALLOC_CTX *mem_ctx, + if (tevent_req_nomem(subreq, req)) { + return tevent_req_post(req, ev); + } +- tevent_req_set_callback(subreq, cli_posix_getfacl_done, req); ++ tevent_req_set_callback(subreq, cli_posix_getacl_done, req); + return req; + } + +-static void cli_posix_getfacl_done(struct tevent_req *subreq) ++static void cli_posix_getacl_done(struct tevent_req *subreq) + { + struct tevent_req *req = tevent_req_callback_data( + subreq, struct tevent_req); +- struct getfacl_state *state = tevent_req_data( +- req, struct getfacl_state); ++ struct getacl_state *state = tevent_req_data( ++ req, struct getacl_state); + NTSTATUS status; + + status = cli_qpathinfo_recv(subreq, state, &state->data, +@@ -638,12 +638,12 @@ static void cli_posix_getfacl_done(struct tevent_req *subreq) + tevent_req_done(req); + } + +-NTSTATUS cli_posix_getfacl_recv(struct tevent_req *req, ++NTSTATUS cli_posix_getacl_recv(struct tevent_req *req, + TALLOC_CTX *mem_ctx, + size_t *prb_size, + char **retbuf) + { +- struct getfacl_state *state = tevent_req_data(req, struct getfacl_state); ++ struct getacl_state *state = tevent_req_data(req, struct getacl_state); + NTSTATUS status; + + if (tevent_req_is_nterror(req, &status)) { +@@ -654,7 +654,7 @@ NTSTATUS cli_posix_getfacl_recv(struct tevent_req *req, + return NT_STATUS_OK; + } + +-NTSTATUS cli_posix_getfacl(struct cli_state *cli, ++NTSTATUS cli_posix_getacl(struct cli_state *cli, + const char *fname, + TALLOC_CTX *mem_ctx, + size_t *prb_size, +@@ -679,7 +679,7 @@ NTSTATUS cli_posix_getfacl(struct cli_state *cli, + goto fail; + } + +- req = cli_posix_getfacl_send(frame, ++ req = cli_posix_getacl_send(frame, + ev, + cli, + fname); +@@ -693,7 +693,7 @@ NTSTATUS cli_posix_getfacl(struct cli_state *cli, + goto fail; + } + +- status = cli_posix_getfacl_recv(req, mem_ctx, prb_size, retbuf); ++ status = cli_posix_getacl_recv(req, mem_ctx, prb_size, retbuf); + + fail: + TALLOC_FREE(frame); +diff --git a/source3/libsmb/proto.h b/source3/libsmb/proto.h +index 2efb208..f5f35e0 100644 +--- a/source3/libsmb/proto.h ++++ b/source3/libsmb/proto.h +@@ -256,15 +256,15 @@ NTSTATUS cli_posix_hardlink(struct cli_state *cli, + const char *newname); + uint32_t unix_perms_to_wire(mode_t perms); + mode_t wire_perms_to_unix(uint32_t perms); +-struct tevent_req *cli_posix_getfacl_send(TALLOC_CTX *mem_ctx, ++struct tevent_req *cli_posix_getacl_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct cli_state *cli, + const char *fname); +-NTSTATUS cli_posix_getfacl_recv(struct tevent_req *req, ++NTSTATUS cli_posix_getacl_recv(struct tevent_req *req, + TALLOC_CTX *mem_ctx, + size_t *prb_size, + char **retbuf); +-NTSTATUS cli_posix_getfacl(struct cli_state *cli, ++NTSTATUS cli_posix_getacl(struct cli_state *cli, + const char *fname, + TALLOC_CTX *mem_ctx, + size_t *prb_size, +-- +1.9.1 + + +From d9054880d4bdbcb05c677e494906a26d62afa3a1 Mon Sep 17 00:00:00 2001 +From: Jeremy Allison +Date: Wed, 6 Jan 2016 17:02:52 -0800 +Subject: [PATCH 10/12] CVE-2015-7560: s3: libsmb: Add SMB1-only POSIX + cli_posix_setacl() functions. Needed for tests. + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=11648 + +Signed-off-by: Jeremy Allison +Reviewed-by: Volker Lendecke +--- + source3/libsmb/clifile.c | 100 +++++++++++++++++++++++++++++++++++++++++++++++ + source3/libsmb/proto.h | 11 ++++++ + 2 files changed, 111 insertions(+) + +diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c +index ff646e4..e4480c6 100644 +--- a/source3/libsmb/clifile.c ++++ b/source3/libsmb/clifile.c +@@ -701,6 +701,106 @@ NTSTATUS cli_posix_getacl(struct cli_state *cli, + } + + /**************************************************************************** ++ Do a POSIX setacl - pathname based ACL set (UNIX extensions). ++****************************************************************************/ ++ ++struct setacl_state { ++ uint8_t *data; ++}; ++ ++static void cli_posix_setacl_done(struct tevent_req *subreq); ++ ++struct tevent_req *cli_posix_setacl_send(TALLOC_CTX *mem_ctx, ++ struct tevent_context *ev, ++ struct cli_state *cli, ++ const char *fname, ++ const void *data, ++ size_t num_data) ++{ ++ struct tevent_req *req = NULL, *subreq = NULL; ++ struct setacl_state *state = NULL; ++ ++ req = tevent_req_create(mem_ctx, &state, struct setacl_state); ++ if (req == NULL) { ++ return NULL; ++ } ++ state->data = talloc_memdup(state, data, num_data); ++ if (tevent_req_nomem(state->data, req)) { ++ return tevent_req_post(req, ev); ++ } ++ ++ subreq = cli_setpathinfo_send(state, ++ ev, ++ cli, ++ SMB_SET_POSIX_ACL, ++ fname, ++ state->data, ++ num_data); ++ if (tevent_req_nomem(subreq, req)) { ++ return tevent_req_post(req, ev); ++ } ++ tevent_req_set_callback(subreq, cli_posix_setacl_done, req); ++ return req; ++} ++ ++static void cli_posix_setacl_done(struct tevent_req *subreq) ++{ ++ NTSTATUS status = cli_setpathinfo_recv(subreq); ++ tevent_req_simple_finish_ntstatus(subreq, status); ++} ++ ++NTSTATUS cli_posix_setacl_recv(struct tevent_req *req) ++{ ++ return tevent_req_simple_recv_ntstatus(req); ++} ++ ++NTSTATUS cli_posix_setacl(struct cli_state *cli, ++ const char *fname, ++ const void *acl_buf, ++ size_t acl_buf_size) ++{ ++ TALLOC_CTX *frame = talloc_stackframe(); ++ struct tevent_context *ev = NULL; ++ struct tevent_req *req = NULL; ++ NTSTATUS status = NT_STATUS_OK; ++ ++ if (smbXcli_conn_has_async_calls(cli->conn)) { ++ /* ++ * Can't use sync call while an async call is in flight ++ */ ++ status = NT_STATUS_INVALID_PARAMETER; ++ goto fail; ++ } ++ ++ ev = samba_tevent_context_init(frame); ++ if (ev == NULL) { ++ status = NT_STATUS_NO_MEMORY; ++ goto fail; ++ } ++ ++ req = cli_posix_setacl_send(frame, ++ ev, ++ cli, ++ fname, ++ acl_buf, ++ acl_buf_size); ++ if (req == NULL) { ++ status = NT_STATUS_NO_MEMORY; ++ goto fail; ++ } ++ ++ if (!tevent_req_poll_ntstatus(req, ev, &status)) { ++ goto fail; ++ } ++ ++ status = cli_posix_setacl_recv(req); ++ ++ fail: ++ TALLOC_FREE(frame); ++ return status; ++} ++ ++/**************************************************************************** + Stat a file (UNIX extensions). + ****************************************************************************/ + +diff --git a/source3/libsmb/proto.h b/source3/libsmb/proto.h +index f5f35e0..08dda96 100644 +--- a/source3/libsmb/proto.h ++++ b/source3/libsmb/proto.h +@@ -269,6 +269,17 @@ NTSTATUS cli_posix_getacl(struct cli_state *cli, + TALLOC_CTX *mem_ctx, + size_t *prb_size, + char **retbuf); ++struct tevent_req *cli_posix_setacl_send(TALLOC_CTX *mem_ctx, ++ struct tevent_context *ev, ++ struct cli_state *cli, ++ const char *fname, ++ const void *acl_buf, ++ size_t acl_buf_size); ++NTSTATUS cli_posix_setacl_recv(struct tevent_req *req); ++NTSTATUS cli_posix_setacl(struct cli_state *cli, ++ const char *fname, ++ const void *acl_buf, ++ size_t acl_buf_size); + struct tevent_req *cli_posix_stat_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct cli_state *cli, +-- +1.9.1 + + +From 5de774189a4e7be050c67d06f450a498d90d4368 Mon Sep 17 00:00:00 2001 +From: Jeremy Allison +Date: Thu, 7 Jan 2016 12:58:34 -0800 +Subject: [PATCH 11/12] CVE-2015-7560: s3: torture3: Add new POSIX-SYMLINK-ACL + test. + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=11648 + +Signed-off-by: Jeremy Allison +Reviewed-by: Volker Lendecke +--- + selftest/knownfail | 1 + + source3/selftest/tests.py | 2 +- + source3/torture/torture.c | 198 ++++++++++++++++++++++++++++++++++++++++++++++ + 3 files changed, 200 insertions(+), 1 deletion(-) + +diff --git a/selftest/knownfail b/selftest/knownfail +index fd41263..6696ba3 100644 +--- a/selftest/knownfail ++++ b/selftest/knownfail +@@ -16,6 +16,7 @@ + ^samba3.smbtorture_s3.plain\(dc\).UID-REGRESSION-TEST # Fails against the s4 ntvfs server + ^samba3.smbtorture_s3.plain\(dc\).SHORTNAME-TEST # Fails against the s4 ntvfs server + ^samba3.smbtorture_s3.plain\(dc\).POSIX-APPEND # Fails against the s4 ntvfs server ++^samba3.smbtorture_s3.plain\(ad_dc_ntvfs\).POSIX-SYMLINK-ACL # Fails against the s4 ntvfs server + ^samba3.smbtorture_s3.plain\(dc\).NTTRANS-FSCTL # Fails against the s4 ntvfs server + ^samba3.smbtorture_s3.plain\(dc\).SMB2-NEGPROT # Fails against the s4 ntvfs server + ^samba3.smbtorture_s3.plain\(dc\).BAD-NBT-SESSION # Fails against the s4 ntvfs server +diff --git a/source3/selftest/tests.py b/source3/selftest/tests.py +index 7279927..e66ddbc 100755 +--- a/source3/selftest/tests.py ++++ b/source3/selftest/tests.py +@@ -78,7 +78,7 @@ tests = ["RW1", "RW2", "RW3"] + for t in tests: + plantestsuite("samba3.smbtorture_s3.vfs_aio_fork(simpleserver).%s" % t, "simpleserver", [os.path.join(samba3srcdir, "script/tests/test_smbtorture_s3.sh"), t, '//$SERVER_IP/vfs_aio_fork', '$USERNAME', '$PASSWORD', smbtorture3, "", "-l $LOCAL_PATH"]) + +-posix_tests = ["POSIX", "POSIX-APPEND"] ++posix_tests = ["POSIX", "POSIX-APPEND", "POSIX-SYMLINK-ACL"] + + for t in posix_tests: + plantestsuite("samba3.smbtorture_s3.plain(s3dc).%s" % t, "s3dc", [os.path.join(samba3srcdir, "script/tests/test_smbtorture_s3.sh"), t, '//$SERVER_IP/posix_share', '$USERNAME', '$PASSWORD', smbtorture3, "", "-l $LOCAL_PATH"]) +diff --git a/source3/torture/torture.c b/source3/torture/torture.c +index 0b37e5c..6c0ab17 100644 +--- a/source3/torture/torture.c ++++ b/source3/torture/torture.c +@@ -5820,6 +5820,203 @@ static bool run_simple_posix_open_test(int dummy) + return correct; + } + ++/* ++ Test POSIX and Windows ACLs are rejected on symlinks. ++ */ ++static bool run_acl_symlink_test(int dummy) ++{ ++ static struct cli_state *cli; ++ const char *fname = "posix_file"; ++ const char *sname = "posix_symlink"; ++ uint16_t fnum = (uint16_t)-1; ++ bool correct = false; ++ NTSTATUS status; ++ char *posix_acl = NULL; ++ size_t posix_acl_len = 0; ++ char *posix_acl_sym = NULL; ++ size_t posix_acl_len_sym = 0; ++ struct security_descriptor *sd = NULL; ++ struct security_descriptor *sd_sym = NULL; ++ TALLOC_CTX *frame = NULL; ++ ++ frame = talloc_stackframe(); ++ ++ printf("Starting acl symlink test\n"); ++ ++ if (!torture_open_connection(&cli, 0)) { ++ TALLOC_FREE(frame); ++ return false; ++ } ++ ++ smbXcli_conn_set_sockopt(cli->conn, sockops); ++ ++ status = torture_setup_unix_extensions(cli); ++ if (!NT_STATUS_IS_OK(status)) { ++ TALLOC_FREE(frame); ++ return false; ++ } ++ ++ cli_setatr(cli, fname, 0, 0); ++ cli_posix_unlink(cli, fname); ++ cli_setatr(cli, sname, 0, 0); ++ cli_posix_unlink(cli, sname); ++ ++ status = cli_ntcreate(cli, ++ fname, ++ 0, ++ READ_CONTROL_ACCESS, ++ 0, ++ FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, ++ FILE_CREATE, ++ 0x0, ++ 0x0, ++ &fnum, ++ NULL); ++ ++ if (!NT_STATUS_IS_OK(status)) { ++ printf("cli_ntcreate of %s failed (%s)\n", ++ fname, ++ nt_errstr(status)); ++ goto out; ++ } ++ ++ /* Get the Windows ACL on the file. */ ++ status = cli_query_secdesc(cli, ++ fnum, ++ frame, ++ &sd); ++ if (!NT_STATUS_IS_OK(status)) { ++ printf("cli_query_secdesc failed (%s)\n", ++ nt_errstr(status)); ++ goto out; ++ } ++ ++ /* Get the POSIX ACL on the file. */ ++ status = cli_posix_getacl(cli, ++ fname, ++ frame, ++ &posix_acl_len, ++ &posix_acl); ++ ++ if (!NT_STATUS_IS_OK(status)) { ++ printf("cli_posix_getacl failed (%s)\n", ++ nt_errstr(status)); ++ goto out; ++ } ++ ++ status = cli_close(cli, fnum); ++ if (!NT_STATUS_IS_OK(status)) { ++ printf("close failed (%s)\n", nt_errstr(status)); ++ goto out; ++ } ++ fnum = (uint16_t)-1; ++ ++ /* Now create a symlink. */ ++ status = cli_posix_symlink(cli, fname, sname); ++ if (!NT_STATUS_IS_OK(status)) { ++ printf("cli_posix_symlink of %s -> %s failed (%s)\n", ++ sname, ++ fname, ++ nt_errstr(status)); ++ goto out; ++ } ++ ++ /* Open a handle on the symlink. */ ++ status = cli_ntcreate(cli, ++ sname, ++ 0, ++ READ_CONTROL_ACCESS|SEC_STD_WRITE_DAC, ++ 0, ++ FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, ++ FILE_OPEN, ++ 0x0, ++ 0x0, ++ &fnum, ++ NULL); ++ ++ if (!NT_STATUS_IS_OK(status)) { ++ printf("cli_posix_open of %s failed (%s)\n", ++ sname, ++ nt_errstr(status)); ++ goto out; ++ } ++ ++ /* Get the Windows ACL on the symlink handle. Should fail */ ++ status = cli_query_secdesc(cli, ++ fnum, ++ frame, ++ &sd_sym); ++ ++ if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) { ++ printf("cli_query_secdesc on a symlink gave %s. " ++ "Should be NT_STATUS_ACCESS_DENIED.\n", ++ nt_errstr(status)); ++ goto out; ++ } ++ ++ /* Get the POSIX ACL on the symlink pathname. Should fail. */ ++ status = cli_posix_getacl(cli, ++ sname, ++ frame, ++ &posix_acl_len_sym, ++ &posix_acl_sym); ++ ++ if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) { ++ printf("cli_posix_getacl on a symlink gave %s. " ++ "Should be NT_STATUS_ACCESS_DENIED.\n", ++ nt_errstr(status)); ++ goto out; ++ } ++ ++ /* Set the Windows ACL on the symlink handle. Should fail */ ++ status = cli_set_security_descriptor(cli, ++ fnum, ++ SECINFO_DACL, ++ sd); ++ ++ if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) { ++ printf("cli_query_secdesc on a symlink gave %s. " ++ "Should be NT_STATUS_ACCESS_DENIED.\n", ++ nt_errstr(status)); ++ goto out; ++ } ++ ++ /* Set the POSIX ACL on the symlink pathname. Should fail. */ ++ status = cli_posix_setacl(cli, ++ sname, ++ posix_acl, ++ posix_acl_len); ++ ++ if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) { ++ printf("cli_posix_getacl on a symlink gave %s. " ++ "Should be NT_STATUS_ACCESS_DENIED.\n", ++ nt_errstr(status)); ++ goto out; ++ } ++ ++ printf("ACL symlink test passed\n"); ++ correct = true; ++ ++ out: ++ ++ if (fnum != (uint16_t)-1) { ++ cli_close(cli, fnum); ++ fnum = (uint16_t)-1; ++ } ++ ++ cli_setatr(cli, sname, 0, 0); ++ cli_posix_unlink(cli, sname); ++ cli_setatr(cli, fname, 0, 0); ++ cli_posix_unlink(cli, fname); ++ ++ if (!torture_close_connection(cli)) { ++ correct = false; ++ } ++ ++ TALLOC_FREE(frame); ++ return correct; ++} ++ + + static uint32 open_attrs_table[] = { + FILE_ATTRIBUTE_NORMAL, +@@ -9647,6 +9844,7 @@ static struct { + {"OPEN", run_opentest, 0}, + {"POSIX", run_simple_posix_open_test, 0}, + {"POSIX-APPEND", run_posix_append, 0}, ++ {"POSIX-SYMLINK-ACL", run_acl_symlink_test, 0}, + {"CASE-INSENSITIVE-CREATE", run_case_insensitive_create, 0}, + {"ASYNC-ECHO", run_async_echo, 0}, + { "UID-REGRESSION-TEST", run_uid_regression_test, 0}, +-- +1.9.1 + + +From 6149e7297d9279df3b535e72eabbede7bd235925 Mon Sep 17 00:00:00 2001 +From: Jeremy Allison +Date: Thu, 7 Jan 2016 14:26:35 -0800 +Subject: [PATCH 12/12] CVE-2015-7560: s3: torture3: Add new POSIX-SYMLINK-EA + test. + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=11648 + +Signed-off-by: Jeremy Allison +Reviewed-by: Volker Lendecke +--- + selftest/knownfail | 1 + + source3/selftest/tests.py | 2 +- + source3/torture/torture.c | 179 ++++++++++++++++++++++++++++++++++++++++++++++ + 3 files changed, 181 insertions(+), 1 deletion(-) + +diff --git a/selftest/knownfail b/selftest/knownfail +index 6696ba3..c919a6a 100644 +--- a/selftest/knownfail ++++ b/selftest/knownfail +@@ -17,6 +17,7 @@ + ^samba3.smbtorture_s3.plain\(dc\).SHORTNAME-TEST # Fails against the s4 ntvfs server + ^samba3.smbtorture_s3.plain\(dc\).POSIX-APPEND # Fails against the s4 ntvfs server + ^samba3.smbtorture_s3.plain\(ad_dc_ntvfs\).POSIX-SYMLINK-ACL # Fails against the s4 ntvfs server ++^samba3.smbtorture_s3.plain\(ad_dc_ntvfs\).POSIX-SYMLINK-EA # Fails against the s4 ntvfs server + ^samba3.smbtorture_s3.plain\(dc\).NTTRANS-FSCTL # Fails against the s4 ntvfs server + ^samba3.smbtorture_s3.plain\(dc\).SMB2-NEGPROT # Fails against the s4 ntvfs server + ^samba3.smbtorture_s3.plain\(dc\).BAD-NBT-SESSION # Fails against the s4 ntvfs server +diff --git a/source3/selftest/tests.py b/source3/selftest/tests.py +index e66ddbc..830753c 100755 +--- a/source3/selftest/tests.py ++++ b/source3/selftest/tests.py +@@ -78,7 +78,7 @@ tests = ["RW1", "RW2", "RW3"] + for t in tests: + plantestsuite("samba3.smbtorture_s3.vfs_aio_fork(simpleserver).%s" % t, "simpleserver", [os.path.join(samba3srcdir, "script/tests/test_smbtorture_s3.sh"), t, '//$SERVER_IP/vfs_aio_fork', '$USERNAME', '$PASSWORD', smbtorture3, "", "-l $LOCAL_PATH"]) + +-posix_tests = ["POSIX", "POSIX-APPEND", "POSIX-SYMLINK-ACL"] ++posix_tests = ["POSIX", "POSIX-APPEND", "POSIX-SYMLINK-ACL", "POSIX-SYMLINK-EA"] + + for t in posix_tests: + plantestsuite("samba3.smbtorture_s3.plain(s3dc).%s" % t, "s3dc", [os.path.join(samba3srcdir, "script/tests/test_smbtorture_s3.sh"), t, '//$SERVER_IP/posix_share', '$USERNAME', '$PASSWORD', smbtorture3, "", "-l $LOCAL_PATH"]) +diff --git a/source3/torture/torture.c b/source3/torture/torture.c +index 6c0ab17..34c1a37 100644 +--- a/source3/torture/torture.c ++++ b/source3/torture/torture.c +@@ -6017,6 +6017,183 @@ static bool run_acl_symlink_test(int dummy) + return correct; + } + ++/* ++ Test setting EA's are rejected on symlinks. ++ */ ++static bool run_ea_symlink_test(int dummy) ++{ ++ static struct cli_state *cli; ++ const char *fname = "posix_file_ea"; ++ const char *sname = "posix_symlink_ea"; ++ const char *ea_name = "testea_name"; ++ const char *ea_value = "testea_value"; ++ uint16_t fnum = (uint16_t)-1; ++ bool correct = false; ++ NTSTATUS status; ++ size_t i, num_eas; ++ struct ea_struct *eas = NULL; ++ TALLOC_CTX *frame = NULL; ++ ++ frame = talloc_stackframe(); ++ ++ printf("Starting EA symlink test\n"); ++ ++ if (!torture_open_connection(&cli, 0)) { ++ TALLOC_FREE(frame); ++ return false; ++ } ++ ++ smbXcli_conn_set_sockopt(cli->conn, sockops); ++ ++ status = torture_setup_unix_extensions(cli); ++ if (!NT_STATUS_IS_OK(status)) { ++ TALLOC_FREE(frame); ++ return false; ++ } ++ ++ cli_setatr(cli, fname, 0, 0); ++ cli_posix_unlink(cli, fname); ++ cli_setatr(cli, sname, 0, 0); ++ cli_posix_unlink(cli, sname); ++ ++ status = cli_ntcreate(cli, ++ fname, ++ 0, ++ READ_CONTROL_ACCESS, ++ 0, ++ FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, ++ FILE_CREATE, ++ 0x0, ++ 0x0, ++ &fnum, ++ NULL); ++ ++ if (!NT_STATUS_IS_OK(status)) { ++ printf("cli_ntcreate of %s failed (%s)\n", ++ fname, ++ nt_errstr(status)); ++ goto out; ++ } ++ ++ status = cli_close(cli, fnum); ++ if (!NT_STATUS_IS_OK(status)) { ++ printf("close failed (%s)\n", ++ nt_errstr(status)); ++ goto out; ++ } ++ fnum = (uint16_t)-1; ++ ++ /* Set an EA on the path. */ ++ status = cli_set_ea_path(cli, ++ fname, ++ ea_name, ++ ea_value, ++ strlen(ea_value)+1); ++ ++ if (!NT_STATUS_IS_OK(status)) { ++ printf("cli_set_ea_path failed (%s)\n", ++ nt_errstr(status)); ++ goto out; ++ } ++ ++ /* Now create a symlink. */ ++ status = cli_posix_symlink(cli, fname, sname); ++ if (!NT_STATUS_IS_OK(status)) { ++ printf("cli_posix_symlink of %s -> %s failed (%s)\n", ++ sname, ++ fname, ++ nt_errstr(status)); ++ goto out; ++ } ++ ++ /* Get the EA list on the path. Should return value set. */ ++ status = cli_get_ea_list_path(cli, ++ fname, ++ frame, ++ &num_eas, ++ &eas); ++ ++ if (!NT_STATUS_IS_OK(status)) { ++ printf("cli_get_ea_list_path failed (%s)\n", ++ nt_errstr(status)); ++ goto out; ++ } ++ ++ /* Ensure the EA we set is there. */ ++ for (i=0; i - 4.2.3-12 +- resolves: #1314672 - Fix CVE-2015-7560 + * Fri Dec 11 2015 Guenther Deschner - 4.2.3-11 - resolves: #1290710 - CVE-2015-3223 Remote DoS in Samba (AD) LDAP server