summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeremy Allison <jra@samba.org>2015-07-09 10:58:11 -0700
committerKarolin Seeger <kseeger@samba.org>2015-12-10 11:10:54 +0100
commitf0cb216f6385460d4d3c728257baaaa26a95c5d1 (patch)
treeb9475793377c67cc459b008c5e6ca515bfcc0799
parent9d989c9dd7a5b92d0c5d65287935471b83b6e884 (diff)
downloadsamba-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.c13
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));