mirror of
https://github.com/samba-team/samba.git
synced 2025-02-03 13:47:25 +03:00
CVE-2021-44141: s3: smbd: Fix a subtle bug in the error returns from filename_convert().
If filename_convert() fails to convert the path, we never call check_name(). This means we can return an incorrect error code (NT_STATUS_ACCESS_DENIED) if we ran into a symlink that points outside the share to a non-readable directory. We need to make sure in this case we always call check_name(). Remove knownfail.d/symlink_traversal. BUG: https://bugzilla.samba.org/show_bug.cgi?id=14911 Signed-off-by: Jeremy Allison <jra@samba.org>
This commit is contained in:
parent
43455edd29
commit
be13892020
@ -1,2 +0,0 @@
|
||||
^samba3.blackbox.test_symlink_traversal.SMB2.symlink_traversal_SMB2\(fileserver\)
|
||||
^samba3.blackbox.test_symlink_traversal.SMB1.symlink_traversal_SMB1\(fileserver_smb1_done\)
|
@ -36,6 +36,9 @@ static int get_real_filename(connection_struct *conn,
|
||||
TALLOC_CTX *mem_ctx,
|
||||
char **found_name);
|
||||
|
||||
static NTSTATUS check_name(connection_struct *conn,
|
||||
const struct smb_filename *smb_fname);
|
||||
|
||||
uint32_t ucf_flags_from_smb_request(struct smb_request *req)
|
||||
{
|
||||
uint32_t ucf_flags = 0;
|
||||
@ -542,6 +545,39 @@ static NTSTATUS unix_convert_step_search_fail(struct uc_state *state)
|
||||
|
||||
if (errno == EACCES) {
|
||||
if ((state->ucf_flags & UCF_PREP_CREATEFILE) == 0) {
|
||||
/*
|
||||
* Could be a symlink pointing to
|
||||
* a directory outside the share
|
||||
* to which we don't have access.
|
||||
* If so, we need to know that here
|
||||
* so we can return the correct error code.
|
||||
* check_name() is never called if we
|
||||
* error out of filename_convert().
|
||||
*/
|
||||
int ret;
|
||||
NTSTATUS status;
|
||||
struct smb_filename dname = (struct smb_filename) {
|
||||
.base_name = state->dirpath,
|
||||
.twrp = state->smb_fname->twrp,
|
||||
};
|
||||
|
||||
/* handle null paths */
|
||||
if ((dname.base_name == NULL) ||
|
||||
(dname.base_name[0] == '\0')) {
|
||||
return NT_STATUS_ACCESS_DENIED;
|
||||
}
|
||||
ret = SMB_VFS_LSTAT(state->conn, &dname);
|
||||
if (ret != 0) {
|
||||
return NT_STATUS_ACCESS_DENIED;
|
||||
}
|
||||
if (!S_ISLNK(dname.st.st_ex_mode)) {
|
||||
return NT_STATUS_ACCESS_DENIED;
|
||||
}
|
||||
status = check_name(state->conn, &dname);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
/* We know this is an intermediate path. */
|
||||
return NT_STATUS_OBJECT_PATH_NOT_FOUND;
|
||||
}
|
||||
return NT_STATUS_ACCESS_DENIED;
|
||||
} else {
|
||||
/*
|
||||
|
Loading…
x
Reference in New Issue
Block a user