Fri Aug 28 18:17:13 2020 UTC ()
Pull up following revision(s) (requested by hannken in ticket #1066):

	external/cddl/osnet/sys/kern/policy.c: revision 1.9

Glue operation secpolicy_fs_mount() passes wrong arguments to
operation kauth_authorize_system().

KAUTH_SYSTEM_MOUNT / KAUTH_REQ_SYSTEM_MOUNT_NEW wants the to be
covered vnode and the mount flags, not the mount structure.

Fix for PR kern/55602: zpool panic on mounting zfs filesystem


(martin)
diff -r1.7 -r1.7.4.1 src/external/cddl/osnet/sys/kern/policy.c

cvs diff -r1.7 -r1.7.4.1 src/external/cddl/osnet/sys/kern/policy.c (switch to unified diff)

--- src/external/cddl/osnet/sys/kern/policy.c 2018/05/28 21:05:09 1.7
+++ src/external/cddl/osnet/sys/kern/policy.c 2020/08/28 18:17:13 1.7.4.1
@@ -1,438 +1,438 @@ @@ -1,438 +1,438 @@
1/* $NetBSD: policy.c,v 1.7 2018/05/28 21:05:09 chs Exp $ */ 1/* $NetBSD: policy.c,v 1.7.4.1 2020/08/28 18:17:13 martin Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2009 The NetBSD Foundation, Inc. 4 * Copyright (c) 2009 The NetBSD Foundation, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to The NetBSD Foundation 7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Andrew Doran. 8 * by Andrew Doran.
9 * 9 *
10 * Redistribution and use in source and binary forms, with or without 10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions 11 * modification, are permitted provided that the following conditions
12 * are met: 12 * are met:
13 * 1. Redistributions of source code must retain the above copyright 13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer. 14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright 15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the 16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution. 17 * documentation and/or other materials provided with the distribution.
18 * 18 *
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE. 29 * POSSIBILITY OF SUCH DAMAGE.
30 */ 30 */
31 31
32/*- 32/*-
33 * Copyright (c) 2007 Pawel Jakub Dawidek <pjd@FreeBSD.org> 33 * Copyright (c) 2007 Pawel Jakub Dawidek <pjd@FreeBSD.org>
34 * All rights reserved. 34 * All rights reserved.
35 * 35 *
36 * Redistribution and use in source and binary forms, with or without 36 * Redistribution and use in source and binary forms, with or without
37 * modification, are permitted provided that the following conditions 37 * modification, are permitted provided that the following conditions
38 * are met: 38 * are met:
39 * 1. Redistributions of source code must retain the above copyright 39 * 1. Redistributions of source code must retain the above copyright
40 * notice, this list of conditions and the following disclaimer. 40 * notice, this list of conditions and the following disclaimer.
41 * 2. Redistributions in binary form must reproduce the above copyright 41 * 2. Redistributions in binary form must reproduce the above copyright
42 * notice, this list of conditions and the following disclaimer in the 42 * notice, this list of conditions and the following disclaimer in the
43 * documentation and/or other materials provided with the distribution. 43 * documentation and/or other materials provided with the distribution.
44 * 44 *
45 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND 45 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
46 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 46 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
47 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 47 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
48 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE 48 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
49 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 49 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
50 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 50 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
51 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 51 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
52 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 52 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
53 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 53 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
54 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 54 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
55 * SUCH DAMAGE. 55 * SUCH DAMAGE.
56 */ 56 */
57 57
58/* 58/*
59 * CDDL HEADER START 59 * CDDL HEADER START
60 * 60 *
61 * The contents of this file are subject to the terms of the 61 * The contents of this file are subject to the terms of the
62 * Common Development and Distribution License (the "License"). 62 * Common Development and Distribution License (the "License").
63 * You may not use this file except in compliance with the License. 63 * You may not use this file except in compliance with the License.
64 * 64 *
65 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 65 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
66 * or http://www.opensolaris.org/os/licensing. 66 * or http://www.opensolaris.org/os/licensing.
67 * See the License for the specific language governing permissions 67 * See the License for the specific language governing permissions
68 * and limitations under the License. 68 * and limitations under the License.
69 * 69 *
70 * When distributing Covered Code, include this CDDL HEADER in each 70 * When distributing Covered Code, include this CDDL HEADER in each
71 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 71 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
72 * If applicable, add the following below this CDDL HEADER, with the 72 * If applicable, add the following below this CDDL HEADER, with the
73 * fields enclosed by brackets "[]" replaced with your own identifying 73 * fields enclosed by brackets "[]" replaced with your own identifying
74 * information: Portions Copyright [yyyy] [name of copyright owner] 74 * information: Portions Copyright [yyyy] [name of copyright owner]
75 * 75 *
76 * CDDL HEADER END 76 * CDDL HEADER END
77 */ 77 */
78/* 78/*
79 * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. 79 * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
80 * Copyright 2012, Joyent, Inc. All rights reserved. 80 * Copyright 2012, Joyent, Inc. All rights reserved.
81 */ 81 */
82 82
83#include <sys/param.h> 83#include <sys/param.h>
84#include <sys/vnode.h> 84#include <sys/vnode.h>
85#include <sys/mount.h> 85#include <sys/mount.h>
86#include <sys/stat.h> 86#include <sys/stat.h>
87#include <sys/policy.h> 87#include <sys/policy.h>
88 88
89int 89int
90secpolicy_nfs(cred_t *cr) 90secpolicy_nfs(cred_t *cr)
91{ 91{
92 92
93 return kauth_authorize_generic(cr, KAUTH_GENERIC_ISSUSER, NULL); 93 return kauth_authorize_generic(cr, KAUTH_GENERIC_ISSUSER, NULL);
94} 94}
95 95
96int 96int
97secpolicy_zfs(cred_t *cred) 97secpolicy_zfs(cred_t *cred)
98{ 98{
99 99
100 return kauth_authorize_generic(cred, KAUTH_GENERIC_ISSUSER, NULL); 100 return kauth_authorize_generic(cred, KAUTH_GENERIC_ISSUSER, NULL);
101} 101}
102 102
103int 103int
104secpolicy_sys_config(cred_t *cred, int checkonly __unused) 104secpolicy_sys_config(cred_t *cred, int checkonly __unused)
105{ 105{
106 106
107 return kauth_authorize_generic(cred, KAUTH_GENERIC_ISSUSER, NULL); 107 return kauth_authorize_generic(cred, KAUTH_GENERIC_ISSUSER, NULL);
108} 108}
109 109
110int 110int
111secpolicy_zinject(cred_t *cred) 111secpolicy_zinject(cred_t *cred)
112{ 112{
113 113
114 return kauth_authorize_generic(cred, KAUTH_GENERIC_ISSUSER, NULL); 114 return kauth_authorize_generic(cred, KAUTH_GENERIC_ISSUSER, NULL);
115} 115}
116 116
117int 117int
118secpolicy_fs_mount(cred_t *cred, vnode_t *mvp, struct mount *vfsp) 118secpolicy_fs_mount(cred_t *cred, vnode_t *mvp, struct mount *vfsp)
119{ 119{
120 120
121 return kauth_authorize_system(cred, KAUTH_SYSTEM_MOUNT, 121 return kauth_authorize_system(cred, KAUTH_SYSTEM_MOUNT,
122 KAUTH_REQ_SYSTEM_MOUNT_NEW, vfsp, NULL, NULL); 122 KAUTH_REQ_SYSTEM_MOUNT_NEW, mvp, KAUTH_ARG(vfsp->mnt_flag), NULL);
123} 123}
124 124
125int 125int
126secpolicy_fs_unmount(cred_t *cred, struct mount *vfsp) 126secpolicy_fs_unmount(cred_t *cred, struct mount *vfsp)
127{ 127{
128 128
129 return kauth_authorize_system(cred, KAUTH_SYSTEM_MOUNT, 129 return kauth_authorize_system(cred, KAUTH_SYSTEM_MOUNT,
130 KAUTH_REQ_SYSTEM_MOUNT_UNMOUNT, vfsp, NULL, NULL); 130 KAUTH_REQ_SYSTEM_MOUNT_UNMOUNT, vfsp, NULL, NULL);
131} 131}
132 132
133int 133int
134secpolicy_fs_owner(struct mount *mp, cred_t *cr) 134secpolicy_fs_owner(struct mount *mp, cred_t *cr)
135{ 135{
136 136
137 return (EPERM); 137 return (EPERM);
138} 138}
139 139
140/* 140/*
141 * This check is done in kern_link(), so we could just return 0 here. 141 * This check is done in kern_link(), so we could just return 0 here.
142 */ 142 */
143int 143int
144secpolicy_basic_link(vnode_t *vp, cred_t *cred) 144secpolicy_basic_link(vnode_t *vp, cred_t *cred)
145{ 145{
146 146
147 return kauth_authorize_generic(cred, KAUTH_GENERIC_ISSUSER, NULL); 147 return kauth_authorize_generic(cred, KAUTH_GENERIC_ISSUSER, NULL);
148} 148}
149 149
150int 150int
151secpolicy_vnode_stky_modify(cred_t *cred) 151secpolicy_vnode_stky_modify(cred_t *cred)
152{ 152{
153 153
154 return kauth_authorize_generic(cred, KAUTH_GENERIC_ISSUSER, NULL); 154 return kauth_authorize_generic(cred, KAUTH_GENERIC_ISSUSER, NULL);
155} 155}
156 156
157int 157int
158secpolicy_vnode_remove(vnode_t *vp, cred_t *cred) 158secpolicy_vnode_remove(vnode_t *vp, cred_t *cred)
159{ 159{
160 160
161 return kauth_authorize_generic(cred, KAUTH_GENERIC_ISSUSER, NULL); 161 return kauth_authorize_generic(cred, KAUTH_GENERIC_ISSUSER, NULL);
162} 162}
163 163
164 164
165int 165int
166secpolicy_vnode_owner(vnode_t *vp, cred_t *cred, uid_t owner) 166secpolicy_vnode_owner(vnode_t *vp, cred_t *cred, uid_t owner)
167{ 167{
168 168
169 if (owner == kauth_cred_getuid(cred)) 169 if (owner == kauth_cred_getuid(cred))
170 return (0); 170 return (0);
171 171
172 if (secpolicy_fs_owner(vp->v_mount, cred) == 0) 172 if (secpolicy_fs_owner(vp->v_mount, cred) == 0)
173 return (0); 173 return (0);
174 174
175 return kauth_authorize_generic(cred, KAUTH_GENERIC_ISSUSER, NULL); 175 return kauth_authorize_generic(cred, KAUTH_GENERIC_ISSUSER, NULL);
176} 176}
177 177
178int 178int
179secpolicy_vnode_access(cred_t *cred, vnode_t *vp, uid_t owner, 179secpolicy_vnode_access(cred_t *cred, vnode_t *vp, uid_t owner,
180 int mode) 180 int mode)
181{ 181{
182 182
183 return kauth_authorize_generic(cred, KAUTH_GENERIC_ISSUSER, NULL); 183 return kauth_authorize_generic(cred, KAUTH_GENERIC_ISSUSER, NULL);
184} 184}
185 185
186/* 186/*
187 * Like secpolicy_vnode_access() but we get the actual wanted mode and the 187 * Like secpolicy_vnode_access() but we get the actual wanted mode and the
188 * current mode of the file, not the missing bits. 188 * current mode of the file, not the missing bits.
189 */ 189 */
190int 190int
191secpolicy_vnode_access2(cred_t *cr, vnode_t *vp, uid_t owner, 191secpolicy_vnode_access2(cred_t *cr, vnode_t *vp, uid_t owner,
192 accmode_t curmode, accmode_t wantmode) 192 accmode_t curmode, accmode_t wantmode)
193{ 193{
194 accmode_t mode; 194 accmode_t mode;
195 195
196 mode = ~curmode & wantmode; 196 mode = ~curmode & wantmode;
197 197
198 if (mode == 0) 198 if (mode == 0)
199 return (0); 199 return (0);
200 200
201 return (secpolicy_vnode_access(cr, vp, owner, mode)); 201 return (secpolicy_vnode_access(cr, vp, owner, mode));
202} 202}
203 203
204int 204int
205secpolicy_vnode_any_access(cred_t *cr, vnode_t *vp, uid_t owner) 205secpolicy_vnode_any_access(cred_t *cr, vnode_t *vp, uid_t owner)
206{ 206{
207 207
208 return kauth_authorize_generic(cr, KAUTH_GENERIC_ISSUSER, NULL); 208 return kauth_authorize_generic(cr, KAUTH_GENERIC_ISSUSER, NULL);
209} 209}
210 210
211int 211int
212secpolicy_xvattr(vnode_t *vp, xvattr_t *xvap, uid_t owner, cred_t *cred, vtype_t vtype) 212secpolicy_xvattr(vnode_t *vp, xvattr_t *xvap, uid_t owner, cred_t *cred, vtype_t vtype)
213{ 213{
214 214
215 return kauth_authorize_generic(cred, KAUTH_GENERIC_ISSUSER, NULL); 215 return kauth_authorize_generic(cred, KAUTH_GENERIC_ISSUSER, NULL);
216} 216}
217 217
218int 218int
219secpolicy_vnode_setid_retain(vnode_t *vp, cred_t *cred, boolean_t issuidroot __unused) 219secpolicy_vnode_setid_retain(vnode_t *vp, cred_t *cred, boolean_t issuidroot __unused)
220{ 220{
221 221
222 return kauth_authorize_generic(cred, KAUTH_GENERIC_ISSUSER, NULL); 222 return kauth_authorize_generic(cred, KAUTH_GENERIC_ISSUSER, NULL);
223} 223}
224 224
225int 225int
226secpolicy_vnode_setids_setgids(vnode_t *vp, cred_t *cred, gid_t gid) 226secpolicy_vnode_setids_setgids(vnode_t *vp, cred_t *cred, gid_t gid)
227{ 227{
228 228
229 if (groupmember(gid, cred)) 229 if (groupmember(gid, cred))
230 return (0); 230 return (0);
231 231
232 return kauth_authorize_generic(cred, KAUTH_GENERIC_ISSUSER, NULL); 232 return kauth_authorize_generic(cred, KAUTH_GENERIC_ISSUSER, NULL);
233} 233}
234 234
235int 235int
236secpolicy_vnode_chown(vnode_t *vp, cred_t *cred, uid_t owner) 236secpolicy_vnode_chown(vnode_t *vp, cred_t *cred, uid_t owner)
237{ 237{
238 238
239 return kauth_authorize_generic(cred, KAUTH_GENERIC_ISSUSER, NULL); 239 return kauth_authorize_generic(cred, KAUTH_GENERIC_ISSUSER, NULL);
240} 240}
241 241
242int 242int
243secpolicy_vnode_create_gid(cred_t *cred) 243secpolicy_vnode_create_gid(cred_t *cred)
244{ 244{
245 245
246 return kauth_authorize_generic(cred, KAUTH_GENERIC_ISSUSER, NULL); 246 return kauth_authorize_generic(cred, KAUTH_GENERIC_ISSUSER, NULL);
247} 247}
248 248
249int 249int
250secpolicy_vnode_utime_modify(cred_t *cred) 250secpolicy_vnode_utime_modify(cred_t *cred)
251{ 251{
252 252
253 return kauth_authorize_generic(cred, KAUTH_GENERIC_ISSUSER, NULL); 253 return kauth_authorize_generic(cred, KAUTH_GENERIC_ISSUSER, NULL);
254} 254}
255 255
256int 256int
257secpolicy_vnode_setdac(vnode_t *vp, cred_t *cred, uid_t owner) 257secpolicy_vnode_setdac(vnode_t *vp, cred_t *cred, uid_t owner)
258{ 258{
259 259
260 if (owner == kauth_cred_getuid(cred)) 260 if (owner == kauth_cred_getuid(cred))
261 return (0); 261 return (0);
262 262
263 return kauth_authorize_generic(cred, KAUTH_GENERIC_ISSUSER, NULL); 263 return kauth_authorize_generic(cred, KAUTH_GENERIC_ISSUSER, NULL);
264} 264}
265 265
266int 266int
267secpolicy_setid_setsticky_clear(vnode_t *vp, struct vattr *vap, 267secpolicy_setid_setsticky_clear(vnode_t *vp, struct vattr *vap,
268 const struct vattr *ovap, cred_t *cred) 268 const struct vattr *ovap, cred_t *cred)
269{ 269{
270 /* 270 /*
271 * Privileged processes may set the sticky bit on non-directories, 271 * Privileged processes may set the sticky bit on non-directories,
272 * as well as set the setgid bit on a file with a group that the process 272 * as well as set the setgid bit on a file with a group that the process
273 * is not a member of. Both of these are allowed in jail(8). 273 * is not a member of. Both of these are allowed in jail(8).
274 */ 274 */
275 if (vp->v_type != VDIR && (vap->va_mode & S_ISTXT)) { 275 if (vp->v_type != VDIR && (vap->va_mode & S_ISTXT)) {
276 if (kauth_authorize_generic(cred, KAUTH_GENERIC_ISSUSER, NULL)) 276 if (kauth_authorize_generic(cred, KAUTH_GENERIC_ISSUSER, NULL))
277 return (EFTYPE); 277 return (EFTYPE);
278 } 278 }
279 /* 279 /*
280 * Check for privilege if attempting to set the 280 * Check for privilege if attempting to set the
281 * group-id bit. 281 * group-id bit.
282 */ 282 */
283 if ((vap->va_mode & S_ISGID) != 0) 283 if ((vap->va_mode & S_ISGID) != 0)
284 return (secpolicy_vnode_setids_setgids(vp, cred, ovap->va_gid)); 284 return (secpolicy_vnode_setids_setgids(vp, cred, ovap->va_gid));
285 285
286 return (0); 286 return (0);
287} 287}
288 288
289/* 289/*
290 * XXX Copied from illumos. Should not be here; should be under 290 * XXX Copied from illumos. Should not be here; should be under
291 * external/cddl/osnet/dist. Not sure why it is even in illumos's 291 * external/cddl/osnet/dist. Not sure why it is even in illumos's
292 * policy.c rather than somewhere in vnode.c or something. 292 * policy.c rather than somewhere in vnode.c or something.
293 */ 293 */
294int 294int
295secpolicy_vnode_setattr(cred_t *cred, vnode_t *vp, struct vattr *vap, 295secpolicy_vnode_setattr(cred_t *cred, vnode_t *vp, struct vattr *vap,
296 const struct vattr *ovap, int flags, 296 const struct vattr *ovap, int flags,
297 int unlocked_access(void *, int, cred_t *), void *node) 297 int unlocked_access(void *, int, cred_t *), void *node)
298{ 298{
299 int mask = vap->va_mask; 299 int mask = vap->va_mask;
300 int error = 0; 300 int error = 0;
301 boolean_t skipaclchk = (flags & ATTR_NOACLCHECK) ? B_TRUE : B_FALSE; 301 boolean_t skipaclchk = (flags & ATTR_NOACLCHECK) ? B_TRUE : B_FALSE;
302 302
303 if (mask & AT_SIZE) { 303 if (mask & AT_SIZE) {
304 if (vp->v_type == VDIR) { 304 if (vp->v_type == VDIR) {
305 error = EISDIR; 305 error = EISDIR;
306 goto out; 306 goto out;
307 } 307 }
308 308
309 /* 309 /*
310 * If ATTR_NOACLCHECK is set in the flags, then we don't 310 * If ATTR_NOACLCHECK is set in the flags, then we don't
311 * perform the secondary unlocked_access() call since the 311 * perform the secondary unlocked_access() call since the
312 * ACL (if any) is being checked there. 312 * ACL (if any) is being checked there.
313 */ 313 */
314 if (skipaclchk == B_FALSE) { 314 if (skipaclchk == B_FALSE) {
315 error = unlocked_access(node, VWRITE, cred); 315 error = unlocked_access(node, VWRITE, cred);
316 if (error) 316 if (error)
317 goto out; 317 goto out;
318 } 318 }
319 } 319 }
320 if (mask & AT_MODE) { 320 if (mask & AT_MODE) {
321 /* 321 /*
322 * If not the owner of the file then check privilege 322 * If not the owner of the file then check privilege
323 * for two things: the privilege to set the mode at all 323 * for two things: the privilege to set the mode at all
324 * and, if we're setting setuid, we also need permissions 324 * and, if we're setting setuid, we also need permissions
325 * to add the set-uid bit, if we're not the owner. 325 * to add the set-uid bit, if we're not the owner.
326 * In the specific case of creating a set-uid root 326 * In the specific case of creating a set-uid root
327 * file, we need even more permissions. 327 * file, we need even more permissions.
328 */ 328 */
329 if ((error = secpolicy_vnode_setdac(vp, cred, ovap->va_uid)) != 0) 329 if ((error = secpolicy_vnode_setdac(vp, cred, ovap->va_uid)) != 0)
330 goto out; 330 goto out;
331 331
332 if ((error = secpolicy_setid_setsticky_clear(vp, vap, 332 if ((error = secpolicy_setid_setsticky_clear(vp, vap,
333 ovap, cred)) != 0) 333 ovap, cred)) != 0)
334 goto out; 334 goto out;
335 } else 335 } else
336 vap->va_mode = ovap->va_mode; 336 vap->va_mode = ovap->va_mode;
337 337
338 if (mask & (AT_UID|AT_GID)) { 338 if (mask & (AT_UID|AT_GID)) {
339 boolean_t checkpriv = B_FALSE; 339 boolean_t checkpriv = B_FALSE;
340 340
341 /* 341 /*
342 * Chowning files. 342 * Chowning files.
343 * 343 *
344 * If you are the file owner: 344 * If you are the file owner:
345 * chown to other uid FILE_CHOWN_SELF 345 * chown to other uid FILE_CHOWN_SELF
346 * chown to gid (non-member) FILE_CHOWN_SELF 346 * chown to gid (non-member) FILE_CHOWN_SELF
347 * chown to gid (member) <none> 347 * chown to gid (member) <none>
348 * 348 *
349 * Instead of PRIV_FILE_CHOWN_SELF, FILE_CHOWN is also 349 * Instead of PRIV_FILE_CHOWN_SELF, FILE_CHOWN is also
350 * acceptable but the first one is reported when debugging. 350 * acceptable but the first one is reported when debugging.
351 * 351 *
352 * If you are not the file owner: 352 * If you are not the file owner:
353 * chown from root PRIV_FILE_CHOWN + zone 353 * chown from root PRIV_FILE_CHOWN + zone
354 * chown from other to any PRIV_FILE_CHOWN 354 * chown from other to any PRIV_FILE_CHOWN
355 * 355 *
356 */ 356 */
357 if (kauth_cred_getuid(cred) != ovap->va_uid) { 357 if (kauth_cred_getuid(cred) != ovap->va_uid) {
358 checkpriv = B_TRUE; 358 checkpriv = B_TRUE;
359 } else { 359 } else {
360 if (((mask & AT_UID) && vap->va_uid != ovap->va_uid) || 360 if (((mask & AT_UID) && vap->va_uid != ovap->va_uid) ||
361 ((mask & AT_GID) && vap->va_gid != ovap->va_gid && 361 ((mask & AT_GID) && vap->va_gid != ovap->va_gid &&
362 !groupmember(vap->va_gid, cred))) { 362 !groupmember(vap->va_gid, cred))) {
363 checkpriv = B_TRUE; 363 checkpriv = B_TRUE;
364 } 364 }
365 } 365 }
366 /* 366 /*
367 * If necessary, check privilege to see if update can be done. 367 * If necessary, check privilege to see if update can be done.
368 */ 368 */
369 if (checkpriv && 369 if (checkpriv &&
370 (error = secpolicy_vnode_chown(vp, cred, ovap->va_uid)) != 0) { 370 (error = secpolicy_vnode_chown(vp, cred, ovap->va_uid)) != 0) {
371 goto out; 371 goto out;
372 } 372 }
373 373
374 /* 374 /*
375 * If the file has either the set UID or set GID bits 375 * If the file has either the set UID or set GID bits
376 * set and the caller can set the bits, then leave them. 376 * set and the caller can set the bits, then leave them.
377 */ 377 */
378 secpolicy_setid_clear(vap, vp, cred); 378 secpolicy_setid_clear(vap, vp, cred);
379 } 379 }
380 if (mask & (AT_ATIME|AT_MTIME)) { 380 if (mask & (AT_ATIME|AT_MTIME)) {
381 /* 381 /*
382 * If not the file owner and not otherwise privileged, 382 * If not the file owner and not otherwise privileged,
383 * always return an error when setting the 383 * always return an error when setting the
384 * time other than the current (ATTR_UTIME flag set). 384 * time other than the current (ATTR_UTIME flag set).
385 * If setting the current time (ATTR_UTIME not set) then 385 * If setting the current time (ATTR_UTIME not set) then
386 * unlocked_access will check permissions according to policy. 386 * unlocked_access will check permissions according to policy.
387 */ 387 */
388 if (kauth_cred_getuid(cred) != ovap->va_uid) { 388 if (kauth_cred_getuid(cred) != ovap->va_uid) {
389 if (flags & ATTR_UTIME) 389 if (flags & ATTR_UTIME)
390 error = secpolicy_vnode_utime_modify(cred); 390 error = secpolicy_vnode_utime_modify(cred);
391 else if (skipaclchk == B_FALSE) { 391 else if (skipaclchk == B_FALSE) {
392 error = unlocked_access(node, VWRITE, cred); 392 error = unlocked_access(node, VWRITE, cred);
393 if (error == EACCES && 393 if (error == EACCES &&
394 secpolicy_vnode_utime_modify(cred) == 0) 394 secpolicy_vnode_utime_modify(cred) == 0)
395 error = 0; 395 error = 0;
396 } 396 }
397 if (error) 397 if (error)
398 goto out; 398 goto out;
399 } 399 }
400 } 400 }
401 401
402 /* 402 /*
403 * Check for optional attributes here by checking the following: 403 * Check for optional attributes here by checking the following:
404 */ 404 */
405 if (mask & AT_XVATTR) 405 if (mask & AT_XVATTR)
406 error = secpolicy_xvattr(vp, (xvattr_t *)vap, ovap->va_uid, 406 error = secpolicy_xvattr(vp, (xvattr_t *)vap, ovap->va_uid,
407 cred, vp->v_type); 407 cred, vp->v_type);
408out: 408out:
409 return (error); 409 return (error);
410} 410}
411 411
412void 412void
413secpolicy_setid_clear(struct vattr *vap, vnode_t *vp, cred_t *cred) 413secpolicy_setid_clear(struct vattr *vap, vnode_t *vp, cred_t *cred)
414{ 414{
415 if (kauth_authorize_generic(cred, KAUTH_GENERIC_ISSUSER, NULL) != 0) 415 if (kauth_authorize_generic(cred, KAUTH_GENERIC_ISSUSER, NULL) != 0)
416 return; 416 return;
417 417
418 if ((vap->va_mode & (S_ISUID | S_ISGID)) != 0) { 418 if ((vap->va_mode & (S_ISUID | S_ISGID)) != 0) {
419 vap->va_mask |= AT_MODE; 419 vap->va_mask |= AT_MODE;
420 vap->va_mode &= ~(S_ISUID|S_ISGID); 420 vap->va_mode &= ~(S_ISUID|S_ISGID);
421 } 421 }
422 422
423 return; 423 return;
424} 424}
425 425
426int 426int
427secpolicy_smb(cred_t *cr) 427secpolicy_smb(cred_t *cr)
428{ 428{
429 429
430 return kauth_authorize_generic(cr, KAUTH_GENERIC_ISSUSER, NULL); 430 return kauth_authorize_generic(cr, KAUTH_GENERIC_ISSUSER, NULL);
431} 431}
432 432
433void 433void
434secpolicy_fs_mount_clearopts(cred_t *cr, struct mount *vfsp) 434secpolicy_fs_mount_clearopts(cred_t *cr, struct mount *vfsp)
435{ 435{
436 436
437 printf("%s writeme\n", __func__); 437 printf("%s writeme\n", __func__);
438} 438}