diff options
author | Jeremy Allison <jra@samba.org> | 2015-07-09 10:58:11 -0700 |
---|---|---|
committer | Karolin Seeger <kseeger@samba.org> | 2015-12-10 11:10:54 +0100 |
commit | f0cb216f6385460d4d3c728257baaaa26a95c5d1 (patch) | |
tree | b9475793377c67cc459b008c5e6ca515bfcc0799 | |
parent | 9d989c9dd7a5b92d0c5d65287935471b83b6e884 (diff) | |
download | samba-f0cb216f6385460d4d3c728257baaaa26a95c5d1.tar.gz |
CVE-2015-5252: s3: smbd: Fix symlink verification (file access outside the share).
Ensure matching component ends in '/' or '\0'.
BUG: https://bugzilla.samba.org/show_bug.cgi?id=11395
Signed-off-by: Jeremy Allison <jra@samba.org>
Reviewed-by: Volker Lendecke <vl@samba.org>
-rw-r--r-- | source3/smbd/vfs.c | 13 |
1 files changed, 10 insertions, 3 deletions
diff --git a/source3/smbd/vfs.c b/source3/smbd/vfs.c index 118f6c90b2b..edf4ee15df8 100644 --- a/source3/smbd/vfs.c +++ b/source3/smbd/vfs.c @@ -976,6 +976,7 @@ NTSTATUS check_reduced_name_with_privilege(connection_struct *conn, struct smb_filename *smb_fname_cwd = NULL; struct privilege_paths *priv_paths = NULL; int ret; + bool matched; DEBUG(3,("check_reduced_name_with_privilege [%s] [%s]\n", fname, @@ -1070,7 +1071,10 @@ NTSTATUS check_reduced_name_with_privilege(connection_struct *conn, } rootdir_len = strlen(conn_rootdir); - if (strncmp(conn_rootdir, resolved_name, rootdir_len) != 0) { + matched = (strncmp(conn_rootdir, resolved_name, rootdir_len) == 0); + + if (!matched || (resolved_name[rootdir_len] != '/' && + resolved_name[rootdir_len] != '\0')) { DEBUG(2, ("check_reduced_name_with_privilege: Bad access " "attempt: %s is a symlink outside the " "share path\n", @@ -1210,6 +1214,7 @@ NTSTATUS check_reduced_name(connection_struct *conn, const char *fname) if (!allow_widelinks || !allow_symlinks) { const char *conn_rootdir; size_t rootdir_len; + bool matched; conn_rootdir = SMB_VFS_CONNECTPATH(conn, fname); if (conn_rootdir == NULL) { @@ -1220,8 +1225,10 @@ NTSTATUS check_reduced_name(connection_struct *conn, const char *fname) } rootdir_len = strlen(conn_rootdir); - if (strncmp(conn_rootdir, resolved_name, - rootdir_len) != 0) { + matched = (strncmp(conn_rootdir, resolved_name, + rootdir_len) == 0); + if (!matched || (resolved_name[rootdir_len] != '/' && + resolved_name[rootdir_len] != '\0')) { DEBUG(2, ("check_reduced_name: Bad access " "attempt: %s is a symlink outside the " "share path\n", fname)); |