OpenWrt – Blame information for rev 4
?pathlinks?
Rev | Author | Line No. | Line |
---|---|---|---|
4 | office | 1 | From eb27f9b7bf9c1dc902d9545eecf805831bd4e46c Mon Sep 17 00:00:00 2001 |
2 | From: Jeremy Allison <jra@samba.org> |
||
3 | Date: Tue, 5 Jan 2016 11:18:12 -0800 |
||
4 | Subject: [PATCH 1/8] CVE-2015-7560: s3: smbd: Add refuse_symlink() function |
||
5 | that can be used to prevent operations on a symlink. |
||
6 | |||
7 | BUG: https://bugzilla.samba.org/show_bug.cgi?id=11648 |
||
8 | |||
9 | Signed-off-by: Jeremy Allison <jra@samba.org> |
||
10 | Reviewed-by: Michael Adam <obnox@samba.org> |
||
11 | --- |
||
12 | source3/smbd/trans2.c | 28 ++++++++++++++++++++++++++++ |
||
13 | 1 file changed, 28 insertions(+) |
||
14 | |||
15 | --- a/source3/smbd/trans2.c |
||
16 | +++ b/source3/smbd/trans2.c |
||
17 | @@ -51,6 +51,34 @@ static char *store_file_unix_basic_info2 |
||
18 | files_struct *fsp, |
||
19 | const SMB_STRUCT_STAT *psbuf); |
||
20 | |||
21 | +/**************************************************************************** |
||
22 | + Check if an open file handle or pathname is a symlink. |
||
23 | +****************************************************************************/ |
||
24 | + |
||
25 | +static NTSTATUS refuse_symlink(connection_struct *conn, |
||
26 | + const files_struct *fsp, |
||
27 | + const char *name) |
||
28 | +{ |
||
29 | + SMB_STRUCT_STAT sbuf; |
||
30 | + const SMB_STRUCT_STAT *pst = NULL; |
||
31 | + |
||
32 | + if (fsp) { |
||
33 | + pst = &fsp->fsp_name->st; |
||
34 | + } else { |
||
35 | + int ret = vfs_stat_smb_fname(conn, |
||
36 | + name, |
||
37 | + &sbuf); |
||
38 | + if (ret == -1) { |
||
39 | + return map_nt_error_from_unix(errno); |
||
40 | + } |
||
41 | + pst = &sbuf; |
||
42 | + } |
||
43 | + if (S_ISLNK(pst->st_ex_mode)) { |
||
44 | + return NT_STATUS_ACCESS_DENIED; |
||
45 | + } |
||
46 | + return NT_STATUS_OK; |
||
47 | +} |
||
48 | + |
||
49 | /******************************************************************** |
||
50 | Roundup a value to the nearest allocation roundup size boundary. |
||
51 | Only do this for Windows clients. |
||
52 | @@ -181,12 +209,22 @@ NTSTATUS get_ea_names_from_file(TALLOC_C |
||
53 | char **names, **tmp; |
||
54 | size_t num_names; |
||
55 | ssize_t sizeret = -1; |
||
56 | + NTSTATUS status; |
||
57 | + |
||
58 | + if (pnames) { |
||
59 | + *pnames = NULL; |
||
60 | + } |
||
61 | + *pnum_names = 0; |
||
62 | |||
63 | if (!lp_ea_support(SNUM(conn))) { |
||
64 | - if (pnames) { |
||
65 | - *pnames = NULL; |
||
66 | - } |
||
67 | - *pnum_names = 0; |
||
68 | + return NT_STATUS_OK; |
||
69 | + } |
||
70 | + |
||
71 | + status = refuse_symlink(conn, fsp, fname); |
||
72 | + if (!NT_STATUS_IS_OK(status)) { |
||
73 | + /* |
||
74 | + * Just return no EA's on a symlink. |
||
75 | + */ |
||
76 | return NT_STATUS_OK; |
||
77 | } |
||
78 | |||
79 | @@ -236,10 +274,6 @@ NTSTATUS get_ea_names_from_file(TALLOC_C |
||
80 | |||
81 | if (sizeret == 0) { |
||
82 | TALLOC_FREE(names); |
||
83 | - if (pnames) { |
||
84 | - *pnames = NULL; |
||
85 | - } |
||
86 | - *pnum_names = 0; |
||
87 | return NT_STATUS_OK; |
||
88 | } |
||
89 | |||
90 | @@ -550,6 +584,7 @@ NTSTATUS set_ea(connection_struct *conn, |
||
91 | const struct smb_filename *smb_fname, struct ea_list *ea_list) |
||
92 | { |
||
93 | char *fname = NULL; |
||
94 | + NTSTATUS status; |
||
95 | |||
96 | if (!lp_ea_support(SNUM(conn))) { |
||
97 | return NT_STATUS_EAS_NOT_SUPPORTED; |
||
98 | @@ -559,6 +594,12 @@ NTSTATUS set_ea(connection_struct *conn, |
||
99 | return NT_STATUS_ACCESS_DENIED; |
||
100 | } |
||
101 | |||
102 | + status = refuse_symlink(conn, fsp, smb_fname->base_name); |
||
103 | + if (!NT_STATUS_IS_OK(status)) { |
||
104 | + return status; |
||
105 | + } |
||
106 | + |
||
107 | + |
||
108 | /* For now setting EAs on streams isn't supported. */ |
||
109 | fname = smb_fname->base_name; |
||
110 | |||
111 | @@ -4931,6 +4972,13 @@ NTSTATUS smbd_do_qfilepathinfo(connectio |
||
112 | uint16 num_file_acls = 0; |
||
113 | uint16 num_def_acls = 0; |
||
114 | |||
115 | + status = refuse_symlink(conn, |
||
116 | + fsp, |
||
117 | + smb_fname->base_name); |
||
118 | + if (!NT_STATUS_IS_OK(status)) { |
||
119 | + return status; |
||
120 | + } |
||
121 | + |
||
122 | if (fsp && fsp->fh->fd != -1) { |
||
123 | file_acl = SMB_VFS_SYS_ACL_GET_FD(fsp); |
||
124 | } else { |
||
125 | @@ -6452,6 +6500,7 @@ static NTSTATUS smb_set_posix_acl(connec |
||
126 | uint16 num_def_acls; |
||
127 | bool valid_file_acls = True; |
||
128 | bool valid_def_acls = True; |
||
129 | + NTSTATUS status; |
||
130 | |||
131 | if (total_data < SMB_POSIX_ACL_HEADER_SIZE) { |
||
132 | return NT_STATUS_INVALID_PARAMETER; |
||
133 | @@ -6479,6 +6528,11 @@ static NTSTATUS smb_set_posix_acl(connec |
||
134 | return NT_STATUS_INVALID_PARAMETER; |
||
135 | } |
||
136 | |||
137 | + status = refuse_symlink(conn, fsp, smb_fname->base_name); |
||
138 | + if (!NT_STATUS_IS_OK(status)) { |
||
139 | + return status; |
||
140 | + } |
||
141 | + |
||
142 | DEBUG(10,("smb_set_posix_acl: file %s num_file_acls = %u, num_def_acls = %u\n", |
||
143 | smb_fname ? smb_fname_str_dbg(smb_fname) : fsp_str_dbg(fsp), |
||
144 | (unsigned int)num_file_acls, |
||
145 | --- a/source3/smbd/nttrans.c |
||
146 | +++ b/source3/smbd/nttrans.c |
||
147 | @@ -877,6 +877,12 @@ NTSTATUS set_sd(files_struct *fsp, struc |
||
148 | return NT_STATUS_OK; |
||
149 | } |
||
150 | |||
151 | + if (S_ISLNK(fsp->fsp_name->st.st_ex_mode)) { |
||
152 | + DEBUG(10, ("ACL set on symlink %s denied.\n", |
||
153 | + fsp_str_dbg(fsp))); |
||
154 | + return NT_STATUS_ACCESS_DENIED; |
||
155 | + } |
||
156 | + |
||
157 | if (psd->owner_sid == NULL) { |
||
158 | security_info_sent &= ~SECINFO_OWNER; |
||
159 | } |
||
160 | @@ -1925,6 +1931,12 @@ NTSTATUS smbd_do_query_security_desc(con |
||
161 | return NT_STATUS_ACCESS_DENIED; |
||
162 | } |
||
163 | |||
164 | + if (S_ISLNK(fsp->fsp_name->st.st_ex_mode)) { |
||
165 | + DEBUG(10, ("ACL get on symlink %s denied.\n", |
||
166 | + fsp_str_dbg(fsp))); |
||
167 | + return NT_STATUS_ACCESS_DENIED; |
||
168 | + } |
||
169 | + |
||
170 | if (security_info_wanted & (SECINFO_DACL|SECINFO_OWNER| |
||
171 | SECINFO_GROUP|SECINFO_SACL)) { |
||
172 | /* Don't return SECINFO_LABEL if anything else was |