1 0 stevel /* 2 0 stevel * CDDL HEADER START 3 0 stevel * 4 0 stevel * The contents of this file are subject to the terms of the 5 1544 eschrock * Common Development and Distribution License (the "License"). 6 1544 eschrock * You may not use this file except in compliance with the License. 7 0 stevel * 8 0 stevel * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 0 stevel * or http://www.opensolaris.org/os/licensing. 10 0 stevel * See the License for the specific language governing permissions 11 0 stevel * and limitations under the License. 12 0 stevel * 13 0 stevel * When distributing Covered Code, include this CDDL HEADER in each 14 0 stevel * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 0 stevel * If applicable, add the following below this CDDL HEADER, with the 16 0 stevel * fields enclosed by brackets "[]" replaced with your own identifying 17 0 stevel * information: Portions Copyright [yyyy] [name of copyright owner] 18 0 stevel * 19 0 stevel * CDDL HEADER END 20 0 stevel */ 21 0 stevel /* 22 9751 james * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 23 0 stevel * Use is subject to license terms. 24 0 stevel */ 25 0 stevel 26 0 stevel #include <sys/types.h> 27 0 stevel #include <sys/sysmacros.h> 28 0 stevel #include <sys/param.h> 29 0 stevel #include <sys/systm.h> 30 0 stevel #include <sys/cred_impl.h> 31 0 stevel #include <sys/vnode.h> 32 0 stevel #include <sys/vfs.h> 33 0 stevel #include <sys/stat.h> 34 0 stevel #include <sys/errno.h> 35 0 stevel #include <sys/kmem.h> 36 0 stevel #include <sys/user.h> 37 0 stevel #include <sys/proc.h> 38 0 stevel #include <sys/acct.h> 39 0 stevel #include <sys/ipc_impl.h> 40 0 stevel #include <sys/cmn_err.h> 41 0 stevel #include <sys/debug.h> 42 0 stevel #include <sys/policy.h> 43 0 stevel #include <sys/kobj.h> 44 0 stevel #include <sys/msg.h> 45 0 stevel #include <sys/devpolicy.h> 46 0 stevel #include <c2/audit.h> 47 0 stevel #include <sys/varargs.h> 48 6134 casper #include <sys/klpd.h> 49 0 stevel #include <sys/modctl.h> 50 0 stevel #include <sys/disp.h> 51 0 stevel #include <sys/zone.h> 52 0 stevel #include <inet/optcom.h> 53 0 stevel #include <sys/sdt.h> 54 0 stevel #include <sys/vfs.h> 55 0 stevel #include <sys/mntent.h> 56 0 stevel #include <sys/contract_impl.h> 57 8275 Eric #include <sys/dld_ioc.h> 58 0 stevel 59 0 stevel /* 60 0 stevel * There are two possible layers of privilege routines and two possible 61 0 stevel * levels of secpolicy. Plus one other we may not be interested in, so 62 0 stevel * we may need as many as 6 but no more. 63 0 stevel */ 64 0 stevel #define MAXPRIVSTACK 6 65 0 stevel 66 0 stevel int priv_debug = 0; 67 0 stevel 68 0 stevel /* 69 0 stevel * This file contains the majority of the policy routines. 70 0 stevel * Since the policy routines are defined by function and not 71 0 stevel * by privilege, there is quite a bit of duplication of 72 0 stevel * functions. 73 0 stevel * 74 5331 amw * The secpolicy functions must not make assumptions about 75 0 stevel * locks held or not held as any lock can be held while they're 76 0 stevel * being called. 77 0 stevel * 78 0 stevel * Credentials are read-only so no special precautions need to 79 0 stevel * be taken while locking them. 80 0 stevel * 81 0 stevel * When a new policy check needs to be added to the system the 82 0 stevel * following procedure should be followed: 83 0 stevel * 84 0 stevel * Pick an appropriate secpolicy_*() function 85 0 stevel * -> done if one exists. 86 0 stevel * Create a new secpolicy function, preferably with 87 0 stevel * a descriptive name using the standard template. 88 0 stevel * Pick an appropriate privilege for the policy. 89 0 stevel * If no appropraite privilege exists, define new one 90 0 stevel * (this should be done with extreme care; in most cases 91 0 stevel * little is gained by adding another privilege) 92 0 stevel * 93 0 stevel * WHY ROOT IS STILL SPECIAL. 94 0 stevel * 95 0 stevel * In a number of the policy functions, there are still explicit 96 0 stevel * checks for uid 0. The rationale behind these is that many root 97 0 stevel * owned files/objects hold configuration information which can give full 98 0 stevel * privileges to the user once written to. To prevent escalation 99 0 stevel * of privilege by allowing just a single privilege to modify root owned 100 0 stevel * objects, we've added these root specific checks where we considered 101 0 stevel * them necessary: modifying root owned files, changing uids to 0, etc. 102 0 stevel * 103 0 stevel * PRIVILEGE ESCALATION AND ZONES. 104 0 stevel * 105 0 stevel * A number of operations potentially allow the caller to achieve 106 0 stevel * privileges beyond the ones normally required to perform the operation. 107 0 stevel * For example, if allowed to create a setuid 0 executable, a process can 108 0 stevel * gain privileges beyond PRIV_FILE_SETID. Zones, however, place 109 0 stevel * restrictions on the ability to gain privileges beyond those available 110 0 stevel * within the zone through file and process manipulation. Hence, such 111 0 stevel * operations require that the caller have an effective set that includes 112 0 stevel * all privileges available within the current zone, or all privileges 113 0 stevel * if executing in the global zone. 114 0 stevel * 115 0 stevel * This is indicated in the priv_policy* policy checking functions 116 0 stevel * through a combination of parameters. The "priv" parameter indicates 117 0 stevel * the privilege that is required, and the "allzone" parameter indicates 118 0 stevel * whether or not all privileges in the zone are required. In addition, 119 0 stevel * priv can be set to PRIV_ALL to indicate that all privileges are 120 0 stevel * required (regardless of zone). There are three scenarios of interest: 121 0 stevel * (1) operation requires a specific privilege 122 0 stevel * (2) operation requires a specific privilege, and requires all 123 0 stevel * privileges available within the zone (or all privileges if in 124 0 stevel * the global zone) 125 0 stevel * (3) operation requires all privileges, regardless of zone 126 0 stevel * 127 0 stevel * For (1), priv should be set to the specific privilege, and allzone 128 0 stevel * should be set to B_FALSE. 129 0 stevel * For (2), priv should be set to the specific privilege, and allzone 130 0 stevel * should be set to B_TRUE. 131 0 stevel * For (3), priv should be set to PRIV_ALL, and allzone should be set 132 0 stevel * to B_FALSE. 133 0 stevel * 134 0 stevel */ 135 0 stevel 136 0 stevel /* 137 0 stevel * The privileges are checked against the Effective set for 138 0 stevel * ordinary processes and checked against the Limit set 139 0 stevel * for euid 0 processes that haven't manipulated their privilege 140 0 stevel * sets. 141 0 stevel */ 142 0 stevel #define HAS_ALLPRIVS(cr) priv_isfullset(&CR_OEPRIV(cr)) 143 0 stevel #define ZONEPRIVS(cr) ((cr)->cr_zone->zone_privset) 144 0 stevel #define HAS_ALLZONEPRIVS(cr) priv_issubset(ZONEPRIVS(cr), &CR_OEPRIV(cr)) 145 0 stevel #define HAS_PRIVILEGE(cr, pr) ((pr) == PRIV_ALL ? \ 146 0 stevel HAS_ALLPRIVS(cr) : \ 147 0 stevel PRIV_ISASSERT(&CR_OEPRIV(cr), pr)) 148 0 stevel 149 0 stevel /* 150 6134 casper * Policy checking functions. 151 0 stevel * 152 6134 casper * All of the system's policy should be implemented here. 153 0 stevel */ 154 6134 casper 155 6134 casper /* 156 6134 casper * Private functions which take an additional va_list argument to 157 6134 casper * implement an object specific policy override. 158 6134 casper */ 159 6134 casper static int priv_policy_ap(const cred_t *, int, boolean_t, int, 160 6134 casper const char *, va_list); 161 6134 casper static int priv_policy_va(const cred_t *, int, boolean_t, int, 162 6134 casper const char *, ...); 163 0 stevel 164 0 stevel /* 165 0 stevel * Generic policy calls 166 0 stevel * 167 0 stevel * The "bottom" functions of policy control 168 0 stevel */ 169 0 stevel static char * 170 0 stevel mprintf(const char *fmt, ...) 171 0 stevel { 172 0 stevel va_list args; 173 0 stevel char *buf; 174 0 stevel size_t len; 175 0 stevel 176 0 stevel va_start(args, fmt); 177 0 stevel len = vsnprintf(NULL, 0, fmt, args) + 1; 178 0 stevel va_end(args); 179 0 stevel 180 0 stevel buf = kmem_alloc(len, KM_NOSLEEP); 181 0 stevel 182 0 stevel if (buf == NULL) 183 0 stevel return (NULL); 184 0 stevel 185 0 stevel va_start(args, fmt); 186 0 stevel (void) vsnprintf(buf, len, fmt, args); 187 0 stevel va_end(args); 188 0 stevel 189 0 stevel return (buf); 190 0 stevel } 191 0 stevel 192 0 stevel /* 193 0 stevel * priv_policy_errmsg() 194 0 stevel * 195 0 stevel * Generate an error message if privilege debugging is enabled system wide 196 0 stevel * or for this particular process. 197 0 stevel */ 198 0 stevel 199 0 stevel #define FMTHDR "%s[%d]: missing privilege \"%s\" (euid = %d, syscall = %d)" 200 0 stevel #define FMTMSG " for \"%s\"" 201 0 stevel #define FMTFUN " needed at %s+0x%lx" 202 0 stevel 203 0 stevel /* The maximum size privilege format: the concatenation of the above */ 204 0 stevel #define FMTMAX FMTHDR FMTMSG FMTFUN "\n" 205 0 stevel 206 0 stevel static void 207 0 stevel priv_policy_errmsg(const cred_t *cr, int priv, const char *msg) 208 0 stevel { 209 0 stevel struct proc *me; 210 0 stevel pc_t stack[MAXPRIVSTACK]; 211 0 stevel int depth; 212 0 stevel int i; 213 0 stevel char *sym; 214 0 stevel ulong_t off; 215 0 stevel const char *pname; 216 0 stevel 217 0 stevel char *cmd; 218 0 stevel char fmt[sizeof (FMTMAX)]; 219 0 stevel 220 0 stevel if ((me = curproc) == &p0) 221 0 stevel return; 222 0 stevel 223 0 stevel /* Privileges must be defined */ 224 0 stevel ASSERT(priv == PRIV_ALL || priv == PRIV_MULTIPLE || 225 0 stevel priv == PRIV_ALLZONE || priv == PRIV_GLOBAL || 226 0 stevel priv_getbynum(priv) != NULL); 227 0 stevel 228 0 stevel if (priv == PRIV_ALLZONE && INGLOBALZONE(me)) 229 0 stevel priv = PRIV_ALL; 230 0 stevel 231 0 stevel if (curthread->t_pre_sys) 232 0 stevel ttolwp(curthread)->lwp_badpriv = (short)priv; 233 0 stevel 234 0 stevel if (priv_debug == 0 && (CR_FLAGS(cr) & PRIV_DEBUG) == 0) 235 0 stevel return; 236 0 stevel 237 0 stevel (void) strcpy(fmt, FMTHDR); 238 0 stevel 239 0 stevel if (me->p_user.u_comm[0]) 240 0 stevel cmd = &me->p_user.u_comm[0]; 241 0 stevel else 242 0 stevel cmd = "priv_policy"; 243 0 stevel 244 0 stevel if (msg != NULL && *msg != '\0') { 245 0 stevel (void) strcat(fmt, FMTMSG); 246 0 stevel } else { 247 0 stevel (void) strcat(fmt, "%s"); 248 0 stevel msg = ""; 249 0 stevel } 250 0 stevel 251 0 stevel sym = NULL; 252 0 stevel 253 0 stevel depth = getpcstack(stack, MAXPRIVSTACK); 254 0 stevel 255 0 stevel /* 256 0 stevel * Try to find the first interesting function on the stack. 257 0 stevel * priv_policy* that's us, so completely uninteresting. 258 0 stevel * suser(), drv_priv(), secpolicy_* are also called from 259 0 stevel * too many locations to convey useful information. 260 0 stevel */ 261 0 stevel for (i = 0; i < depth; i++) { 262 0 stevel sym = kobj_getsymname((uintptr_t)stack[i], &off); 263 0 stevel if (sym != NULL && 264 0 stevel strstr(sym, "hasprocperm") == 0 && 265 0 stevel strcmp("suser", sym) != 0 && 266 0 stevel strcmp("ipcaccess", sym) != 0 && 267 0 stevel strcmp("drv_priv", sym) != 0 && 268 0 stevel strncmp("secpolicy_", sym, 10) != 0 && 269 0 stevel strncmp("priv_policy", sym, 11) != 0) 270 0 stevel break; 271 0 stevel } 272 0 stevel 273 0 stevel if (sym != NULL) 274 0 stevel (void) strcat(fmt, FMTFUN); 275 0 stevel 276 0 stevel (void) strcat(fmt, "\n"); 277 0 stevel 278 0 stevel switch (priv) { 279 0 stevel case PRIV_ALL: 280 0 stevel pname = "ALL"; 281 0 stevel break; 282 0 stevel case PRIV_MULTIPLE: 283 0 stevel pname = "MULTIPLE"; 284 0 stevel break; 285 0 stevel case PRIV_ALLZONE: 286 0 stevel pname = "ZONE"; 287 0 stevel break; 288 0 stevel case PRIV_GLOBAL: 289 0 stevel pname = "GLOBAL"; 290 0 stevel break; 291 0 stevel default: 292 0 stevel pname = priv_getbynum(priv); 293 0 stevel break; 294 0 stevel } 295 0 stevel 296 0 stevel if (CR_FLAGS(cr) & PRIV_DEBUG) { 297 0 stevel /* Remember last message, just like lwp_badpriv. */ 298 0 stevel if (curthread->t_pdmsg != NULL) { 299 0 stevel kmem_free(curthread->t_pdmsg, 300 0 stevel strlen(curthread->t_pdmsg) + 1); 301 0 stevel } 302 0 stevel 303 0 stevel curthread->t_pdmsg = mprintf(fmt, cmd, me->p_pid, pname, 304 4543 marks cr->cr_uid, curthread->t_sysnum, msg, sym, off); 305 0 stevel 306 0 stevel curthread->t_post_sys = 1; 307 6134 casper } 308 6134 casper if (priv_debug) { 309 0 stevel cmn_err(CE_NOTE, fmt, cmd, me->p_pid, pname, cr->cr_uid, 310 0 stevel curthread->t_sysnum, msg, sym, off); 311 0 stevel } 312 6134 casper } 313 6134 casper 314 6134 casper /* 315 6134 casper * Override the policy, if appropriate. Return 0 if the external 316 6134 casper * policy engine approves. 317 6134 casper */ 318 6134 casper static int 319 6134 casper priv_policy_override(const cred_t *cr, int priv, boolean_t allzone, va_list ap) 320 6134 casper { 321 6134 casper priv_set_t set; 322 6134 casper int ret; 323 6134 casper 324 6134 casper if (!(CR_FLAGS(cr) & PRIV_XPOLICY)) 325 6134 casper return (-1); 326 6134 casper 327 6134 casper if (priv == PRIV_ALL) { 328 6134 casper priv_fillset(&set); 329 6134 casper } else if (allzone) { 330 6134 casper set = *ZONEPRIVS(cr); 331 6134 casper } else { 332 6134 casper priv_emptyset(&set); 333 6134 casper priv_addset(&set, priv); 334 6134 casper } 335 6134 casper ret = klpd_call(cr, &set, ap); 336 6134 casper return (ret); 337 6134 casper } 338 6134 casper 339 6134 casper static int 340 6134 casper priv_policy_override_set(const cred_t *cr, const priv_set_t *req, ...) 341 6134 casper { 342 6134 casper va_list ap; 343 6134 casper 344 6134 casper if (CR_FLAGS(cr) & PRIV_XPOLICY) { 345 6134 casper va_start(ap, req); 346 6134 casper return (klpd_call(cr, req, ap)); 347 6134 casper } 348 6134 casper return (-1); 349 0 stevel } 350 0 stevel 351 0 stevel /* 352 0 stevel * Audit failure, log error message. 353 0 stevel */ 354 0 stevel static void 355 0 stevel priv_policy_err(const cred_t *cr, int priv, boolean_t allzone, const char *msg) 356 0 stevel { 357 0 stevel 358 0 stevel if (audit_active) 359 0 stevel audit_priv(priv, allzone ? ZONEPRIVS(cr) : NULL, 0); 360 0 stevel DTRACE_PROBE2(priv__err, int, priv, boolean_t, allzone); 361 0 stevel 362 0 stevel if (priv_debug || (CR_FLAGS(cr) & PRIV_DEBUG) || 363 0 stevel curthread->t_pre_sys) { 364 0 stevel if (allzone && !HAS_ALLZONEPRIVS(cr)) { 365 0 stevel priv_policy_errmsg(cr, PRIV_ALLZONE, msg); 366 0 stevel } else { 367 0 stevel ASSERT(!HAS_PRIVILEGE(cr, priv)); 368 0 stevel priv_policy_errmsg(cr, priv, msg); 369 0 stevel } 370 0 stevel } 371 0 stevel } 372 0 stevel 373 0 stevel /* 374 6134 casper * priv_policy_ap() 375 0 stevel * return 0 or error. 376 0 stevel * See block comment above for a description of "priv" and "allzone" usage. 377 0 stevel */ 378 6134 casper static int 379 6134 casper priv_policy_ap(const cred_t *cr, int priv, boolean_t allzone, int err, 380 6134 casper const char *msg, va_list ap) 381 0 stevel { 382 6134 casper if ((HAS_PRIVILEGE(cr, priv) && (!allzone || HAS_ALLZONEPRIVS(cr))) || 383 6134 casper (!servicing_interrupt() && 384 6134 casper priv_policy_override(cr, priv, allzone, ap) == 0)) { 385 0 stevel if ((allzone || priv == PRIV_ALL || 386 0 stevel !PRIV_ISASSERT(priv_basic, priv)) && 387 0 stevel !servicing_interrupt()) { 388 3446 mrj PTOU(curproc)->u_acflag |= ASU; /* Needed for SVVS */ 389 0 stevel if (audit_active) 390 0 stevel audit_priv(priv, 391 0 stevel allzone ? ZONEPRIVS(cr) : NULL, 1); 392 0 stevel } 393 0 stevel err = 0; 394 0 stevel DTRACE_PROBE2(priv__ok, int, priv, boolean_t, allzone); 395 0 stevel } else if (!servicing_interrupt()) { 396 0 stevel /* Failure audited in this procedure */ 397 0 stevel priv_policy_err(cr, priv, allzone, msg); 398 0 stevel } 399 6134 casper return (err); 400 6134 casper } 401 0 stevel 402 6134 casper int 403 6134 casper priv_policy_va(const cred_t *cr, int priv, boolean_t allzone, int err, 404 6134 casper const char *msg, ...) 405 6134 casper { 406 6134 casper int ret; 407 6134 casper va_list ap; 408 6134 casper 409 6134 casper va_start(ap, msg); 410 6134 casper ret = priv_policy_ap(cr, priv, allzone, err, msg, ap); 411 6134 casper va_end(ap); 412 6134 casper 413 6134 casper return (ret); 414 6134 casper } 415 6134 casper 416 6134 casper int 417 6134 casper priv_policy(const cred_t *cr, int priv, boolean_t allzone, int err, 418 6134 casper const char *msg) 419 6134 casper { 420 6134 casper return (priv_policy_va(cr, priv, allzone, err, msg, KLPDARG_NOMORE)); 421 0 stevel } 422 0 stevel 423 0 stevel /* 424 0 stevel * Return B_TRUE for sufficient privileges, B_FALSE for insufficient privileges. 425 0 stevel */ 426 0 stevel boolean_t 427 0 stevel priv_policy_choice(const cred_t *cr, int priv, boolean_t allzone) 428 0 stevel { 429 0 stevel boolean_t res = HAS_PRIVILEGE(cr, priv) && 430 0 stevel (!allzone || HAS_ALLZONEPRIVS(cr)); 431 0 stevel 432 0 stevel /* Audit success only */ 433 0 stevel if (res && audit_active && 434 0 stevel (allzone || priv == PRIV_ALL || !PRIV_ISASSERT(priv_basic, priv)) && 435 0 stevel !servicing_interrupt()) { 436 0 stevel audit_priv(priv, allzone ? ZONEPRIVS(cr) : NULL, 1); 437 0 stevel } 438 0 stevel if (res) { 439 0 stevel DTRACE_PROBE2(priv__ok, int, priv, boolean_t, allzone); 440 0 stevel } else { 441 0 stevel DTRACE_PROBE2(priv__err, int, priv, boolean_t, allzone); 442 0 stevel } 443 0 stevel return (res); 444 0 stevel } 445 0 stevel 446 0 stevel /* 447 0 stevel * Non-auditing variant of priv_policy_choice(). 448 0 stevel */ 449 0 stevel boolean_t 450 0 stevel priv_policy_only(const cred_t *cr, int priv, boolean_t allzone) 451 0 stevel { 452 0 stevel boolean_t res = HAS_PRIVILEGE(cr, priv) && 453 0 stevel (!allzone || HAS_ALLZONEPRIVS(cr)); 454 0 stevel 455 0 stevel if (res) { 456 0 stevel DTRACE_PROBE2(priv__ok, int, priv, boolean_t, allzone); 457 0 stevel } else { 458 0 stevel DTRACE_PROBE2(priv__err, int, priv, boolean_t, allzone); 459 0 stevel } 460 0 stevel return (res); 461 0 stevel } 462 0 stevel 463 0 stevel /* 464 0 stevel * Check whether all privileges in the required set are present. 465 0 stevel */ 466 0 stevel static int 467 0 stevel secpolicy_require_set(const cred_t *cr, const priv_set_t *req, const char *msg) 468 0 stevel { 469 0 stevel int priv; 470 0 stevel int pfound = -1; 471 0 stevel priv_set_t pset; 472 0 stevel 473 0 stevel if (req == PRIV_FULLSET ? HAS_ALLPRIVS(cr) : priv_issubset(req, 474 4543 marks &CR_OEPRIV(cr))) { 475 0 stevel return (0); 476 0 stevel } 477 6134 casper 478 6134 casper if (priv_policy_override_set(cr, req, KLPDARG_NOMORE) == 0) 479 6134 casper return (0); 480 0 stevel 481 0 stevel if (req == PRIV_FULLSET || priv_isfullset(req)) { 482 0 stevel priv_policy_err(cr, PRIV_ALL, B_FALSE, msg); 483 0 stevel return (EACCES); 484 0 stevel } 485 0 stevel 486 0 stevel pset = CR_OEPRIV(cr); /* present privileges */ 487 0 stevel priv_inverse(&pset); /* all non present privileges */ 488 0 stevel priv_intersect(req, &pset); /* the actual missing privs */ 489 0 stevel 490 0 stevel if (audit_active) 491 0 stevel audit_priv(PRIV_NONE, &pset, 0); 492 0 stevel /* 493 0 stevel * Privilege debugging; special case "one privilege in set". 494 0 stevel */ 495 0 stevel if (priv_debug || (CR_FLAGS(cr) & PRIV_DEBUG) || curthread->t_pre_sys) { 496 0 stevel for (priv = 0; priv < nprivs; priv++) { 497 0 stevel if (priv_ismember(&pset, priv)) { 498 0 stevel if (pfound != -1) { 499 0 stevel /* Multiple missing privs */ 500 0 stevel priv_policy_errmsg(cr, PRIV_MULTIPLE, 501 4543 marks msg); 502 0 stevel return (EACCES); 503 0 stevel } 504 0 stevel pfound = priv; 505 0 stevel } 506 0 stevel } 507 0 stevel ASSERT(pfound != -1); 508 0 stevel /* Just the one missing privilege */ 509 0 stevel priv_policy_errmsg(cr, pfound, msg); 510 0 stevel } 511 0 stevel 512 0 stevel return (EACCES); 513 0 stevel } 514 0 stevel 515 0 stevel /* 516 0 stevel * Called when an operation requires that the caller be in the 517 0 stevel * global zone, regardless of privilege. 518 0 stevel */ 519 0 stevel static int 520 0 stevel priv_policy_global(const cred_t *cr) 521 0 stevel { 522 0 stevel if (crgetzoneid(cr) == GLOBAL_ZONEID) 523 0 stevel return (0); /* success */ 524 0 stevel 525 0 stevel if (priv_debug || (CR_FLAGS(cr) & PRIV_DEBUG) || 526 0 stevel curthread->t_pre_sys) { 527 0 stevel priv_policy_errmsg(cr, PRIV_GLOBAL, NULL); 528 0 stevel } 529 0 stevel return (EPERM); 530 0 stevel } 531 0 stevel 532 0 stevel /* 533 0 stevel * Changing process priority 534 0 stevel */ 535 0 stevel int 536 0 stevel secpolicy_setpriority(const cred_t *cr) 537 0 stevel { 538 0 stevel return (PRIV_POLICY(cr, PRIV_PROC_PRIOCNTL, B_FALSE, EPERM, NULL)); 539 0 stevel } 540 0 stevel 541 0 stevel /* 542 0 stevel * Binding to a privileged port, port must be specified in host byte 543 0 stevel * order. 544 0 stevel */ 545 0 stevel int 546 6134 casper secpolicy_net_privaddr(const cred_t *cr, in_port_t port, int proto) 547 0 stevel { 548 5331 amw char *reason; 549 5331 amw int priv; 550 5331 amw 551 5331 amw switch (port) { 552 5331 amw case 137: 553 5331 amw case 138: 554 5331 amw case 139: 555 5331 amw case 445: 556 5331 amw /* 557 5331 amw * NBT and SMB ports, these are extra privileged ports, 558 5331 amw * allow bind only if the SYS_SMB privilege is present. 559 5331 amw */ 560 5331 amw priv = PRIV_SYS_SMB; 561 5331 amw reason = "NBT or SMB port"; 562 5331 amw break; 563 5331 amw 564 5331 amw case 2049: 565 5331 amw case 4045: 566 5331 amw /* 567 5331 amw * NFS ports, these are extra privileged ports, allow bind 568 5331 amw * only if the SYS_NFS privilege is present. 569 5331 amw */ 570 5331 amw priv = PRIV_SYS_NFS; 571 5331 amw reason = "NFS port"; 572 5331 amw break; 573 5331 amw 574 5331 amw default: 575 5331 amw priv = PRIV_NET_PRIVADDR; 576 5331 amw reason = NULL; 577 5331 amw break; 578 5331 amw 579 5331 amw } 580 5331 amw 581 6134 casper return (priv_policy_va(cr, priv, B_FALSE, EACCES, reason, 582 6134 casper KLPDARG_PORT, (int)proto, (int)port, KLPDARG_NOMORE)); 583 0 stevel } 584 0 stevel 585 0 stevel /* 586 1676 jpk * Binding to a multilevel port on a trusted (labeled) system. 587 1676 jpk */ 588 1676 jpk int 589 1676 jpk secpolicy_net_bindmlp(const cred_t *cr) 590 1676 jpk { 591 6134 casper return (PRIV_POLICY(cr, PRIV_NET_BINDMLP, B_FALSE, EACCES, NULL)); 592 1676 jpk } 593 1676 jpk 594 1676 jpk /* 595 1676 jpk * Allow a communication between a zone and an unlabeled host when their 596 1676 jpk * labels don't match. 597 1676 jpk */ 598 1676 jpk int 599 1676 jpk secpolicy_net_mac_aware(const cred_t *cr) 600 1676 jpk { 601 6134 casper return (PRIV_POLICY(cr, PRIV_NET_MAC_AWARE, B_FALSE, EACCES, NULL)); 602 1676 jpk } 603 1676 jpk 604 1676 jpk /* 605 10934 sommerfeld * Allow a privileged process to transmit traffic without explicit labels 606 10934 sommerfeld */ 607 10934 sommerfeld int 608 10934 sommerfeld secpolicy_net_mac_implicit(const cred_t *cr) 609 10934 sommerfeld { 610 10934 sommerfeld return (PRIV_POLICY(cr, PRIV_NET_MAC_IMPLICIT, B_FALSE, EACCES, NULL)); 611 10934 sommerfeld } 612 10934 sommerfeld 613 10934 sommerfeld /* 614 0 stevel * Common routine which determines whether a given credential can 615 0 stevel * act on a given mount. 616 0 stevel * When called through mount, the parameter needoptcheck is a pointer 617 0 stevel * to a boolean variable which will be set to either true or false, 618 0 stevel * depending on whether the mount policy should change the mount options. 619 0 stevel * In all other cases, needoptcheck should be a NULL pointer. 620 0 stevel */ 621 0 stevel static int 622 0 stevel secpolicy_fs_common(cred_t *cr, vnode_t *mvp, const vfs_t *vfsp, 623 0 stevel boolean_t *needoptcheck) 624 0 stevel { 625 0 stevel boolean_t allzone = B_FALSE; 626 0 stevel boolean_t mounting = needoptcheck != NULL; 627 0 stevel 628 0 stevel /* 629 0 stevel * Short circuit the following cases: 630 0 stevel * vfsp == NULL or mvp == NULL (pure privilege check) 631 0 stevel * have all privileges - no further checks required 632 0 stevel * and no mount options need to be set. 633 0 stevel */ 634 0 stevel if (vfsp == NULL || mvp == NULL || HAS_ALLPRIVS(cr)) { 635 0 stevel if (mounting) 636 0 stevel *needoptcheck = B_FALSE; 637 0 stevel 638 6134 casper return (priv_policy_va(cr, PRIV_SYS_MOUNT, allzone, EPERM, 639 6134 casper NULL, KLPDARG_VNODE, mvp, (char *)NULL, KLPDARG_NOMORE)); 640 0 stevel } 641 0 stevel 642 0 stevel /* 643 0 stevel * When operating on an existing mount (either we're not mounting 644 0 stevel * or we're doing a remount and VFS_REMOUNT will be set), zones 645 0 stevel * can operate only on mounts established by the zone itself. 646 0 stevel */ 647 0 stevel if (!mounting || (vfsp->vfs_flag & VFS_REMOUNT) != 0) { 648 0 stevel zoneid_t zoneid = crgetzoneid(cr); 649 0 stevel 650 0 stevel if (zoneid != GLOBAL_ZONEID && 651 0 stevel vfsp->vfs_zone->zone_id != zoneid) { 652 0 stevel return (EPERM); 653 0 stevel } 654 0 stevel } 655 0 stevel 656 0 stevel if (mounting) 657 0 stevel *needoptcheck = B_TRUE; 658 0 stevel 659 0 stevel /* 660 0 stevel * Overlay mounts may hide important stuff; if you can't write to a 661 0 stevel * mount point but would be able to mount on top of it, you can 662 0 stevel * escalate your privileges. 663 0 stevel * So we go about asking the same questions namefs does when it 664 0 stevel * decides whether you can mount over a file or not but with the 665 0 stevel * added restriction that you can only mount on top of a regular 666 0 stevel * file or directory. 667 0 stevel * If we have all the zone's privileges, we skip all other checks, 668 0 stevel * or else we may actually get in trouble inside the automounter. 669 0 stevel */ 670 0 stevel if ((mvp->v_flag & VROOT) != 0 || 671 0 stevel (mvp->v_type != VDIR && mvp->v_type != VREG) || 672 0 stevel HAS_ALLZONEPRIVS(cr)) { 673 0 stevel allzone = B_TRUE; 674 0 stevel } else { 675 0 stevel vattr_t va; 676 0 stevel int err; 677 0 stevel 678 0 stevel va.va_mask = AT_UID|AT_MODE; 679 5331 amw err = VOP_GETATTR(mvp, &va, 0, cr, NULL); 680 0 stevel if (err != 0) 681 0 stevel return (err); 682 0 stevel 683 0 stevel if ((err = secpolicy_vnode_owner(cr, va.va_uid)) != 0) 684 0 stevel return (err); 685 0 stevel 686 0 stevel if ((va.va_mode & VWRITE) == 0 && 687 0 stevel secpolicy_vnode_access(cr, mvp, va.va_uid, VWRITE) != 0) { 688 0 stevel return (EACCES); 689 0 stevel } 690 0 stevel } 691 6134 casper return (priv_policy_va(cr, PRIV_SYS_MOUNT, allzone, EPERM, 692 6134 casper NULL, KLPDARG_VNODE, mvp, (char *)NULL, KLPDARG_NOMORE)); 693 0 stevel } 694 0 stevel 695 4543 marks void 696 4543 marks secpolicy_fs_mount_clearopts(cred_t *cr, struct vfs *vfsp) 697 4543 marks { 698 4543 marks boolean_t amsuper = HAS_ALLZONEPRIVS(cr); 699 4543 marks 700 4543 marks /* 701 4543 marks * check; if we don't have either "nosuid" or 702 4543 marks * both "nosetuid" and "nodevices", then we add 703 4543 marks * "nosuid"; this depends on how the current 704 4543 marks * implementation works (it first checks nosuid). In a 705 4543 marks * zone, a user with all zone privileges can mount with 706 4543 marks * "setuid" but never with "devices". 707 4543 marks */ 708 4543 marks if (!vfs_optionisset(vfsp, MNTOPT_NOSUID, NULL) && 709 4543 marks (!vfs_optionisset(vfsp, MNTOPT_NODEVICES, NULL) || 710 4543 marks !vfs_optionisset(vfsp, MNTOPT_NOSETUID, NULL))) { 711 4543 marks if (crgetzoneid(cr) == GLOBAL_ZONEID || !amsuper) 712 4543 marks vfs_setmntopt(vfsp, MNTOPT_NOSUID, NULL, 0); 713 4543 marks else 714 4543 marks vfs_setmntopt(vfsp, MNTOPT_NODEVICES, NULL, 0); 715 4543 marks } 716 4543 marks /* 717 4543 marks * If we're not the local super user, we set the "restrict" 718 4543 marks * option to indicate to automountd that this mount should 719 4543 marks * be handled with care. 720 4543 marks */ 721 4543 marks if (!amsuper) 722 4543 marks vfs_setmntopt(vfsp, MNTOPT_RESTRICT, NULL, 0); 723 4543 marks 724 4543 marks } 725 4543 marks 726 148 casper extern vnode_t *rootvp; 727 148 casper extern vfs_t *rootvfs; 728 148 casper 729 0 stevel int 730 0 stevel secpolicy_fs_mount(cred_t *cr, vnode_t *mvp, struct vfs *vfsp) 731 0 stevel { 732 0 stevel boolean_t needoptchk; 733 0 stevel int error; 734 148 casper 735 148 casper /* 736 148 casper * If it's a remount, get the underlying mount point, 737 148 casper * except for the root where we use the rootvp. 738 148 casper */ 739 148 casper if ((vfsp->vfs_flag & VFS_REMOUNT) != 0) { 740 148 casper if (vfsp == rootvfs) 741 148 casper mvp = rootvp; 742 148 casper else 743 148 casper mvp = vfsp->vfs_vnodecovered; 744 148 casper } 745 0 stevel 746 0 stevel error = secpolicy_fs_common(cr, mvp, vfsp, &needoptchk); 747 0 stevel 748 0 stevel if (error == 0 && needoptchk) { 749 4543 marks secpolicy_fs_mount_clearopts(cr, vfsp); 750 4543 marks } 751 0 stevel 752 0 stevel return (error); 753 0 stevel } 754 0 stevel 755 0 stevel /* 756 0 stevel * Does the policy computations for "ownership" of a mount; 757 0 stevel * here ownership is defined as the ability to "mount" 758 0 stevel * the filesystem originally. The rootvfs doesn't cover any 759 0 stevel * vnodes; we attribute its ownership to the rootvp. 760 0 stevel */ 761 0 stevel static int 762 0 stevel secpolicy_fs_owner(cred_t *cr, const struct vfs *vfsp) 763 0 stevel { 764 0 stevel vnode_t *mvp; 765 0 stevel 766 0 stevel if (vfsp == NULL) 767 0 stevel mvp = NULL; 768 0 stevel else if (vfsp == rootvfs) 769 0 stevel mvp = rootvp; 770 0 stevel else 771 0 stevel mvp = vfsp->vfs_vnodecovered; 772 0 stevel 773 0 stevel return (secpolicy_fs_common(cr, mvp, vfsp, NULL)); 774 0 stevel } 775 0 stevel 776 0 stevel int 777 0 stevel secpolicy_fs_unmount(cred_t *cr, struct vfs *vfsp) 778 0 stevel { 779 0 stevel return (secpolicy_fs_owner(cr, vfsp)); 780 0 stevel } 781 0 stevel 782 0 stevel /* 783 0 stevel * Quotas are a resource, but if one has the ability to mount a filesystem, he 784 0 stevel * should be able to modify quotas on it. 785 0 stevel */ 786 0 stevel int 787 0 stevel secpolicy_fs_quota(const cred_t *cr, const vfs_t *vfsp) 788 0 stevel { 789 0 stevel return (secpolicy_fs_owner((cred_t *)cr, vfsp)); 790 0 stevel } 791 0 stevel 792 0 stevel /* 793 0 stevel * Exceeding minfree: also a per-mount resource constraint. 794 0 stevel */ 795 0 stevel int 796 0 stevel secpolicy_fs_minfree(const cred_t *cr, const vfs_t *vfsp) 797 0 stevel { 798 0 stevel return (secpolicy_fs_owner((cred_t *)cr, vfsp)); 799 0 stevel } 800 0 stevel 801 0 stevel int 802 0 stevel secpolicy_fs_config(const cred_t *cr, const vfs_t *vfsp) 803 0 stevel { 804 0 stevel return (secpolicy_fs_owner((cred_t *)cr, vfsp)); 805 0 stevel } 806 0 stevel 807 0 stevel /* ARGSUSED */ 808 0 stevel int 809 0 stevel secpolicy_fs_linkdir(const cred_t *cr, const vfs_t *vfsp) 810 0 stevel { 811 0 stevel return (PRIV_POLICY(cr, PRIV_SYS_LINKDIR, B_FALSE, EPERM, NULL)); 812 0 stevel } 813 0 stevel 814 0 stevel /* 815 0 stevel * Name: secpolicy_vnode_access() 816 0 stevel * 817 0 stevel * Parameters: Process credential 818 0 stevel * vnode 819 0 stevel * uid of owner of vnode 820 0 stevel * permission bits not granted to the caller when examining 821 0 stevel * file mode bits (i.e., when a process wants to open a 822 0 stevel * mode 444 file for VREAD|VWRITE, this function should be 823 0 stevel * called only with a VWRITE argument). 824 0 stevel * 825 0 stevel * Normal: Verifies that cred has the appropriate privileges to 826 0 stevel * override the mode bits that were denied. 827 0 stevel * 828 0 stevel * Override: file_dac_execute - if VEXEC bit was denied and vnode is 829 0 stevel * not a directory. 830 0 stevel * file_dac_read - if VREAD bit was denied. 831 0 stevel * file_dac_search - if VEXEC bit was denied and vnode is 832 0 stevel * a directory. 833 0 stevel * file_dac_write - if VWRITE bit was denied. 834 0 stevel * 835 0 stevel * Root owned files are special cased to protect system 836 0 stevel * configuration files and such. 837 0 stevel * 838 0 stevel * Output: EACCES - if privilege check fails. 839 0 stevel */ 840 0 stevel 841 0 stevel /* ARGSUSED */ 842 0 stevel int 843 0 stevel secpolicy_vnode_access(const cred_t *cr, vnode_t *vp, uid_t owner, mode_t mode) 844 0 stevel { 845 6134 casper if ((mode & VREAD) && priv_policy_va(cr, PRIV_FILE_DAC_READ, B_FALSE, 846 6134 casper EACCES, NULL, KLPDARG_VNODE, vp, (char *)NULL, 847 6134 casper KLPDARG_NOMORE) != 0) { 848 0 stevel return (EACCES); 849 6134 casper } 850 0 stevel 851 0 stevel if (mode & VWRITE) { 852 0 stevel boolean_t allzone; 853 0 stevel 854 0 stevel if (owner == 0 && cr->cr_uid != 0) 855 0 stevel allzone = B_TRUE; 856 0 stevel else 857 0 stevel allzone = B_FALSE; 858 6134 casper if (priv_policy_va(cr, PRIV_FILE_DAC_WRITE, allzone, EACCES, 859 6134 casper NULL, KLPDARG_VNODE, vp, (char *)NULL, 860 6134 casper KLPDARG_NOMORE) != 0) { 861 0 stevel return (EACCES); 862 6134 casper } 863 0 stevel } 864 0 stevel 865 0 stevel if (mode & VEXEC) { 866 0 stevel /* 867 0 stevel * Directories use file_dac_search to override the execute bit. 868 0 stevel */ 869 6134 casper int p = vp->v_type == VDIR ? PRIV_FILE_DAC_SEARCH : 870 6134 casper PRIV_FILE_DAC_EXECUTE; 871 0 stevel 872 6134 casper return (priv_policy_va(cr, p, B_FALSE, EACCES, NULL, 873 6134 casper KLPDARG_VNODE, vp, (char *)NULL, KLPDARG_NOMORE)); 874 0 stevel } 875 0 stevel return (0); 876 0 stevel } 877 0 stevel 878 0 stevel /* 879 0 stevel * Name: secpolicy_vnode_setid_modify() 880 0 stevel * 881 0 stevel * Normal: verify that subject can set the file setid flags. 882 0 stevel * 883 0 stevel * Output: EPERM - if not privileged. 884 0 stevel */ 885 0 stevel 886 0 stevel static int 887 0 stevel secpolicy_vnode_setid_modify(const cred_t *cr, uid_t owner) 888 0 stevel { 889 0 stevel /* If changing to suid root, must have all zone privs */ 890 0 stevel boolean_t allzone = B_TRUE; 891 0 stevel 892 0 stevel if (owner != 0) { 893 0 stevel if (owner == cr->cr_uid) 894 0 stevel return (0); 895 0 stevel allzone = B_FALSE; 896 0 stevel } 897 0 stevel return (PRIV_POLICY(cr, PRIV_FILE_SETID, allzone, EPERM, NULL)); 898 0 stevel } 899 0 stevel 900 0 stevel /* 901 0 stevel * Are we allowed to retain the set-uid/set-gid bits when 902 0 stevel * changing ownership or when writing to a file? 903 0 stevel * "issuid" should be true when set-uid; only in that case 904 0 stevel * root ownership is checked (setgid is assumed). 905 0 stevel */ 906 0 stevel int 907 0 stevel secpolicy_vnode_setid_retain(const cred_t *cred, boolean_t issuidroot) 908 0 stevel { 909 0 stevel if (issuidroot && !HAS_ALLZONEPRIVS(cred)) 910 0 stevel return (EPERM); 911 0 stevel 912 0 stevel return (!PRIV_POLICY_CHOICE(cred, PRIV_FILE_SETID, B_FALSE)); 913 0 stevel } 914 0 stevel 915 0 stevel /* 916 0 stevel * Name: secpolicy_vnode_setids_setgids() 917 0 stevel * 918 0 stevel * Normal: verify that subject can set the file setgid flag. 919 0 stevel * 920 0 stevel * Output: EPERM - if not privileged 921 0 stevel */ 922 0 stevel 923 0 stevel int 924 0 stevel secpolicy_vnode_setids_setgids(const cred_t *cred, gid_t gid) 925 0 stevel { 926 0 stevel if (!groupmember(gid, cred)) 927 0 stevel return (PRIV_POLICY(cred, PRIV_FILE_SETID, B_FALSE, EPERM, 928 0 stevel NULL)); 929 0 stevel return (0); 930 0 stevel } 931 0 stevel 932 0 stevel /* 933 7624 Mark * Name: secpolicy_vnode_chown 934 7624 Mark * 935 7624 Mark * Normal: Determine if subject can chown owner of a file. 936 7624 Mark * 937 7624 Mark * Output: EPERM - if access denied 938 7624 Mark */ 939 7624 Mark 940 7624 Mark int 941 9866 Mark secpolicy_vnode_chown(const cred_t *cred, uid_t owner) 942 7624 Mark { 943 9866 Mark boolean_t is_owner = (owner == crgetuid(cred)); 944 9866 Mark boolean_t allzone = B_FALSE; 945 9866 Mark int priv; 946 9866 Mark 947 9866 Mark if (!is_owner) { 948 9866 Mark allzone = (owner == 0); 949 9866 Mark priv = PRIV_FILE_CHOWN; 950 9866 Mark } else { 951 9866 Mark priv = HAS_PRIVILEGE(cred, PRIV_FILE_CHOWN) ? 952 9866 Mark PRIV_FILE_CHOWN : PRIV_FILE_CHOWN_SELF; 953 9866 Mark } 954 9866 Mark 955 9866 Mark return (PRIV_POLICY(cred, priv, allzone, EPERM, NULL)); 956 7624 Mark } 957 7624 Mark 958 7624 Mark /* 959 7624 Mark * Name: secpolicy_vnode_create_gid 960 7624 Mark * 961 7624 Mark * Normal: Determine if subject can change group ownership of a file. 962 7624 Mark * 963 7624 Mark * Output: EPERM - if access denied 964 0 stevel */ 965 0 stevel int 966 0 stevel secpolicy_vnode_create_gid(const cred_t *cred) 967 0 stevel { 968 9866 Mark if (HAS_PRIVILEGE(cred, PRIV_FILE_CHOWN)) 969 9866 Mark return (PRIV_POLICY(cred, PRIV_FILE_CHOWN, B_FALSE, EPERM, 970 9866 Mark NULL)); 971 9866 Mark else 972 9866 Mark return (PRIV_POLICY(cred, PRIV_FILE_CHOWN_SELF, B_FALSE, EPERM, 973 9866 Mark NULL)); 974 0 stevel } 975 0 stevel 976 0 stevel /* 977 0 stevel * Name: secpolicy_vnode_utime_modify() 978 0 stevel * 979 0 stevel * Normal: verify that subject can modify the utime on a file. 980 0 stevel * 981 0 stevel * Output: EPERM - if access denied. 982 0 stevel */ 983 0 stevel 984 0 stevel static int 985 0 stevel secpolicy_vnode_utime_modify(const cred_t *cred) 986 0 stevel { 987 0 stevel return (PRIV_POLICY(cred, PRIV_FILE_OWNER, B_FALSE, EPERM, 988 0 stevel "modify file times")); 989 0 stevel } 990 0 stevel 991 0 stevel 992 0 stevel /* 993 0 stevel * Name: secpolicy_vnode_setdac() 994 0 stevel * 995 0 stevel * Normal: verify that subject can modify the mode of a file. 996 0 stevel * allzone privilege needed when modifying root owned object. 997 0 stevel * 998 0 stevel * Output: EPERM - if access denied. 999 0 stevel */ 1000 0 stevel 1001 0 stevel int 1002 0 stevel secpolicy_vnode_setdac(const cred_t *cred, uid_t owner) 1003 0 stevel { 1004 0 stevel if (owner == cred->cr_uid) 1005 0 stevel return (0); 1006 0 stevel 1007 0 stevel return (PRIV_POLICY(cred, PRIV_FILE_OWNER, owner == 0, EPERM, NULL)); 1008 0 stevel } 1009 0 stevel /* 1010 0 stevel * Name: secpolicy_vnode_stky_modify() 1011 0 stevel * 1012 0 stevel * Normal: verify that subject can make a file a "sticky". 1013 0 stevel * 1014 0 stevel * Output: EPERM - if access denied. 1015 0 stevel */ 1016 0 stevel 1017 0 stevel int 1018 0 stevel secpolicy_vnode_stky_modify(const cred_t *cred) 1019 0 stevel { 1020 0 stevel return (PRIV_POLICY(cred, PRIV_SYS_CONFIG, B_FALSE, EPERM, 1021 0 stevel "set file sticky")); 1022 0 stevel } 1023 0 stevel 1024 0 stevel /* 1025 0 stevel * Policy determines whether we can remove an entry from a directory, 1026 0 stevel * regardless of permission bits. 1027 0 stevel */ 1028 0 stevel int 1029 0 stevel secpolicy_vnode_remove(const cred_t *cr) 1030 0 stevel { 1031 0 stevel return (PRIV_POLICY(cr, PRIV_FILE_OWNER, B_FALSE, EACCES, 1032 0 stevel "sticky directory")); 1033 0 stevel } 1034 0 stevel 1035 0 stevel int 1036 0 stevel secpolicy_vnode_owner(const cred_t *cr, uid_t owner) 1037 0 stevel { 1038 0 stevel boolean_t allzone = (owner == 0); 1039 0 stevel 1040 0 stevel if (owner == cr->cr_uid) 1041 0 stevel return (0); 1042 0 stevel 1043 0 stevel return (PRIV_POLICY(cr, PRIV_FILE_OWNER, allzone, EPERM, NULL)); 1044 0 stevel } 1045 0 stevel 1046 1115 marks void 1047 1115 marks secpolicy_setid_clear(vattr_t *vap, cred_t *cr) 1048 1115 marks { 1049 1115 marks if ((vap->va_mode & (S_ISUID | S_ISGID)) != 0 && 1050 1115 marks secpolicy_vnode_setid_retain(cr, 1051 1115 marks (vap->va_mode & S_ISUID) != 0 && 1052 1115 marks (vap->va_mask & AT_UID) != 0 && vap->va_uid == 0) != 0) { 1053 1115 marks vap->va_mask |= AT_MODE; 1054 1115 marks vap->va_mode &= ~(S_ISUID|S_ISGID); 1055 1115 marks } 1056 1115 marks } 1057 1115 marks 1058 2796 marks int 1059 2796 marks secpolicy_setid_setsticky_clear(vnode_t *vp, vattr_t *vap, const vattr_t *ovap, 1060 2796 marks cred_t *cr) 1061 2796 marks { 1062 2796 marks int error; 1063 2796 marks 1064 2796 marks if ((vap->va_mode & S_ISUID) != 0 && 1065 2796 marks (error = secpolicy_vnode_setid_modify(cr, 1066 2796 marks ovap->va_uid)) != 0) { 1067 2796 marks return (error); 1068 2796 marks } 1069 2796 marks 1070 2796 marks /* 1071 2796 marks * Check privilege if attempting to set the 1072 2796 marks * sticky bit on a non-directory. 1073 2796 marks */ 1074 2796 marks if (vp->v_type != VDIR && (vap->va_mode & S_ISVTX) != 0 && 1075 2796 marks secpolicy_vnode_stky_modify(cr) != 0) { 1076 4543 marks vap->va_mode &= ~S_ISVTX; 1077 2796 marks } 1078 2796 marks 1079 2796 marks /* 1080 2796 marks * Check for privilege if attempting to set the 1081 2796 marks * group-id bit. 1082 2796 marks */ 1083 2796 marks if ((vap->va_mode & S_ISGID) != 0 && 1084 2796 marks secpolicy_vnode_setids_setgids(cr, ovap->va_gid) != 0) { 1085 4543 marks vap->va_mode &= ~S_ISGID; 1086 2796 marks } 1087 2796 marks 1088 2796 marks return (0); 1089 2796 marks } 1090 2796 marks 1091 5331 amw #define ATTR_FLAG_PRIV(attr, value, cr) \ 1092 5331 amw PRIV_POLICY(cr, value ? PRIV_FILE_FLAG_SET : PRIV_ALL, \ 1093 5331 amw B_FALSE, EPERM, NULL) 1094 5331 amw 1095 5331 amw /* 1096 5331 amw * Check privileges for setting xvattr attributes 1097 5331 amw */ 1098 5331 amw int 1099 5331 amw secpolicy_xvattr(xvattr_t *xvap, uid_t owner, cred_t *cr, vtype_t vtype) 1100 5331 amw { 1101 5331 amw xoptattr_t *xoap; 1102 5331 amw int error = 0; 1103 5331 amw 1104 5331 amw if ((xoap = xva_getxoptattr(xvap)) == NULL) 1105 5331 amw return (EINVAL); 1106 5331 amw 1107 5331 amw /* 1108 5331 amw * First process the DOS bits 1109 5331 amw */ 1110 5331 amw if (XVA_ISSET_REQ(xvap, XAT_ARCHIVE) || 1111 5331 amw XVA_ISSET_REQ(xvap, XAT_HIDDEN) || 1112 5331 amw XVA_ISSET_REQ(xvap, XAT_READONLY) || 1113 5331 amw XVA_ISSET_REQ(xvap, XAT_SYSTEM) || 1114 5331 amw XVA_ISSET_REQ(xvap, XAT_CREATETIME)) { 1115 5331 amw if ((error = secpolicy_vnode_owner(cr, owner)) != 0) 1116 5331 amw return (error); 1117 5331 amw } 1118 5331 amw 1119 5331 amw /* 1120 5331 amw * Now handle special attributes 1121 5331 amw */ 1122 5331 amw 1123 5331 amw if (XVA_ISSET_REQ(xvap, XAT_IMMUTABLE)) 1124 5331 amw error = ATTR_FLAG_PRIV(XAT_IMMUTABLE, 1125 5331 amw xoap->xoa_immutable, cr); 1126 5331 amw if (error == 0 && XVA_ISSET_REQ(xvap, XAT_NOUNLINK)) 1127 5331 amw error = ATTR_FLAG_PRIV(XAT_NOUNLINK, 1128 5331 amw xoap->xoa_nounlink, cr); 1129 5331 amw if (error == 0 && XVA_ISSET_REQ(xvap, XAT_APPENDONLY)) 1130 5331 amw error = ATTR_FLAG_PRIV(XAT_APPENDONLY, 1131 5331 amw xoap->xoa_appendonly, cr); 1132 5331 amw if (error == 0 && XVA_ISSET_REQ(xvap, XAT_NODUMP)) 1133 5331 amw error = ATTR_FLAG_PRIV(XAT_NODUMP, 1134 5331 amw xoap->xoa_nodump, cr); 1135 5331 amw if (error == 0 && XVA_ISSET_REQ(xvap, XAT_OPAQUE)) 1136 5331 amw error = EPERM; 1137 5331 amw if (error == 0 && XVA_ISSET_REQ(xvap, XAT_AV_QUARANTINED)) { 1138 5331 amw error = ATTR_FLAG_PRIV(XAT_AV_QUARANTINED, 1139 5331 amw xoap->xoa_av_quarantined, cr); 1140 5545 marks if (error == 0 && vtype != VREG && xoap->xoa_av_quarantined) 1141 5331 amw error = EINVAL; 1142 5331 amw } 1143 5331 amw if (error == 0 && XVA_ISSET_REQ(xvap, XAT_AV_MODIFIED)) 1144 5331 amw error = ATTR_FLAG_PRIV(XAT_AV_MODIFIED, 1145 5331 amw xoap->xoa_av_modified, cr); 1146 5331 amw if (error == 0 && XVA_ISSET_REQ(xvap, XAT_AV_SCANSTAMP)) { 1147 5331 amw error = ATTR_FLAG_PRIV(XAT_AV_SCANSTAMP, 1148 5331 amw xoap->xoa_av_scanstamp, cr); 1149 5331 amw if (error == 0 && vtype != VREG) 1150 5331 amw error = EINVAL; 1151 5331 amw } 1152 5331 amw return (error); 1153 5331 amw } 1154 5331 amw 1155 0 stevel /* 1156 0 stevel * This function checks the policy decisions surrounding the 1157 0 stevel * vop setattr call. 1158 0 stevel * 1159 0 stevel * It should be called after sufficient locks have been established 1160 0 stevel * on the underlying data structures. No concurrent modifications 1161 0 stevel * should be allowed. 1162 0 stevel * 1163 0 stevel * The caller must pass in unlocked version of its vaccess function 1164 0 stevel * this is required because vop_access function should lock the 1165 0 stevel * node for reading. A three argument function should be defined 1166 0 stevel * which accepts the following argument: 1167 0 stevel * A pointer to the internal "node" type (inode *) 1168 0 stevel * vnode access bits (VREAD|VWRITE|VEXEC) 1169 0 stevel * a pointer to the credential 1170 0 stevel * 1171 0 stevel * This function makes the following policy decisions: 1172 0 stevel * 1173 0 stevel * - change permissions 1174 0 stevel * - permission to change file mode if not owner 1175 0 stevel * - permission to add sticky bit to non-directory 1176 0 stevel * - permission to add set-gid bit 1177 0 stevel * 1178 0 stevel * The ovap argument should include AT_MODE|AT_UID|AT_GID. 1179 0 stevel * 1180 0 stevel * If the vap argument does not include AT_MODE, the mode will be copied from 1181 0 stevel * ovap. In certain situations set-uid/set-gid bits need to be removed; 1182 0 stevel * this is done by marking vap->va_mask to include AT_MODE and va_mode 1183 0 stevel * is updated to the newly computed mode. 1184 0 stevel */ 1185 0 stevel 1186 0 stevel int 1187 0 stevel secpolicy_vnode_setattr(cred_t *cr, struct vnode *vp, struct vattr *vap, 1188 0 stevel const struct vattr *ovap, int flags, 1189 0 stevel int unlocked_access(void *, int, cred_t *), 1190 0 stevel void *node) 1191 0 stevel { 1192 0 stevel int mask = vap->va_mask; 1193 0 stevel int error = 0; 1194 5331 amw boolean_t skipaclchk = (flags & ATTR_NOACLCHECK) ? B_TRUE : B_FALSE; 1195 0 stevel 1196 0 stevel if (mask & AT_SIZE) { 1197 0 stevel if (vp->v_type == VDIR) { 1198 0 stevel error = EISDIR; 1199 0 stevel goto out; 1200 0 stevel } 1201 5331 amw 1202 5331 amw /* 1203 5331 amw * If ATTR_NOACLCHECK is set in the flags, then we don't 1204 5331 amw * perform the secondary unlocked_access() call since the 1205 5331 amw * ACL (if any) is being checked there. 1206 5331 amw */ 1207 5331 amw if (skipaclchk == B_FALSE) { 1208 5331 amw error = unlocked_access(node, VWRITE, cr); 1209 5331 amw if (error) 1210 5331 amw goto out; 1211 5331 amw } 1212 0 stevel } 1213 0 stevel if (mask & AT_MODE) { 1214 0 stevel /* 1215 0 stevel * If not the owner of the file then check privilege 1216 0 stevel * for two things: the privilege to set the mode at all 1217 0 stevel * and, if we're setting setuid, we also need permissions 1218 0 stevel * to add the set-uid bit, if we're not the owner. 1219 0 stevel * In the specific case of creating a set-uid root 1220 0 stevel * file, we need even more permissions. 1221 0 stevel */ 1222 0 stevel if ((error = secpolicy_vnode_setdac(cr, ovap->va_uid)) != 0) 1223 0 stevel goto out; 1224 0 stevel 1225 2796 marks if ((error = secpolicy_setid_setsticky_clear(vp, vap, 1226 2796 marks ovap, cr)) != 0) 1227 0 stevel goto out; 1228 0 stevel } else 1229 0 stevel vap->va_mode = ovap->va_mode; 1230 0 stevel 1231 0 stevel if (mask & (AT_UID|AT_GID)) { 1232 0 stevel boolean_t checkpriv = B_FALSE; 1233 0 stevel 1234 0 stevel /* 1235 0 stevel * Chowning files. 1236 0 stevel * 1237 0 stevel * If you are the file owner: 1238 0 stevel * chown to other uid FILE_CHOWN_SELF 1239 0 stevel * chown to gid (non-member) FILE_CHOWN_SELF 1240 0 stevel * chown to gid (member) <none> 1241 0 stevel * 1242 0 stevel * Instead of PRIV_FILE_CHOWN_SELF, FILE_CHOWN is also 1243 0 stevel * acceptable but the first one is reported when debugging. 1244 0 stevel * 1245 0 stevel * If you are not the file owner: 1246 0 stevel * chown from root PRIV_FILE_CHOWN + zone 1247 0 stevel * chown from other to any PRIV_FILE_CHOWN 1248 0 stevel * 1249 0 stevel */ 1250 0 stevel if (cr->cr_uid != ovap->va_uid) { 1251 0 stevel checkpriv = B_TRUE; 1252 0 stevel } else { 1253 0 stevel if (((mask & AT_UID) && vap->va_uid != ovap->va_uid) || 1254 0 stevel ((mask & AT_GID) && vap->va_gid != ovap->va_gid && 1255 0 stevel !groupmember(vap->va_gid, cr))) { 1256 0 stevel checkpriv = B_TRUE; 1257 0 stevel } 1258 0 stevel } 1259 0 stevel /* 1260 0 stevel * If necessary, check privilege to see if update can be done. 1261 0 stevel */ 1262 0 stevel if (checkpriv && 1263 9866 Mark (error = secpolicy_vnode_chown(cr, ovap->va_uid)) != 0) { 1264 0 stevel goto out; 1265 0 stevel } 1266 0 stevel 1267 0 stevel /* 1268 0 stevel * If the file has either the set UID or set GID bits 1269 0 stevel * set and the caller can set the bits, then leave them. 1270 0 stevel */ 1271 1115 marks secpolicy_setid_clear(vap, cr); 1272 0 stevel } 1273 0 stevel if (mask & (AT_ATIME|AT_MTIME)) { 1274 0 stevel /* 1275 0 stevel * If not the file owner and not otherwise privileged, 1276 0 stevel * always return an error when setting the 1277 0 stevel * time other than the current (ATTR_UTIME flag set). 1278 0 stevel * If setting the current time (ATTR_UTIME not set) then 1279 0 stevel * unlocked_access will check permissions according to policy. 1280 0 stevel */ 1281 0 stevel if (cr->cr_uid != ovap->va_uid) { 1282 0 stevel if (flags & ATTR_UTIME) 1283 0 stevel error = secpolicy_vnode_utime_modify(cr); 1284 5331 amw else if (skipaclchk == B_FALSE) { 1285 0 stevel error = unlocked_access(node, VWRITE, cr); 1286 0 stevel if (error == EACCES && 1287 0 stevel secpolicy_vnode_utime_modify(cr) == 0) 1288 0 stevel error = 0; 1289 0 stevel } 1290 0 stevel if (error) 1291 0 stevel goto out; 1292 0 stevel } 1293 0 stevel } 1294 5331 amw 1295 5331 amw /* 1296 5331 amw * Check for optional attributes here by checking the following: 1297 5331 amw */ 1298 5331 amw if (mask & AT_XVATTR) 1299 5331 amw error = secpolicy_xvattr((xvattr_t *)vap, ovap->va_uid, cr, 1300 5331 amw vp->v_type); 1301 0 stevel out: 1302 0 stevel return (error); 1303 0 stevel } 1304 0 stevel 1305 0 stevel /* 1306 0 stevel * Name: secpolicy_pcfs_modify_bootpartition() 1307 0 stevel * 1308 0 stevel * Normal: verify that subject can modify a pcfs boot partition. 1309 0 stevel * 1310 0 stevel * Output: EACCES - if privilege check failed. 1311 0 stevel */ 1312 0 stevel /*ARGSUSED*/ 1313 0 stevel int 1314 0 stevel secpolicy_pcfs_modify_bootpartition(const cred_t *cred) 1315 0 stevel { 1316 0 stevel return (PRIV_POLICY(cred, PRIV_ALL, B_FALSE, EACCES, 1317 0 stevel "modify pcfs boot partition")); 1318 0 stevel } 1319 0 stevel 1320 0 stevel /* 1321 0 stevel * System V IPC routines 1322 0 stevel */ 1323 0 stevel int 1324 0 stevel secpolicy_ipc_owner(const cred_t *cr, const struct kipc_perm *ip) 1325 0 stevel { 1326 0 stevel if (crgetzoneid(cr) != ip->ipc_zoneid || 1327 0 stevel (cr->cr_uid != ip->ipc_uid && cr->cr_uid != ip->ipc_cuid)) { 1328 0 stevel boolean_t allzone = B_FALSE; 1329 0 stevel if (ip->ipc_uid == 0 || ip->ipc_cuid == 0) 1330 0 stevel allzone = B_TRUE; 1331 0 stevel return (PRIV_POLICY(cr, PRIV_IPC_OWNER, allzone, EPERM, NULL)); 1332 0 stevel } 1333 0 stevel return (0); 1334 0 stevel } 1335 0 stevel 1336 0 stevel int 1337 0 stevel secpolicy_ipc_config(const cred_t *cr) 1338 0 stevel { 1339 0 stevel return (PRIV_POLICY(cr, PRIV_SYS_IPC_CONFIG, B_FALSE, EPERM, NULL)); 1340 0 stevel } 1341 0 stevel 1342 0 stevel int 1343 0 stevel secpolicy_ipc_access(const cred_t *cr, const struct kipc_perm *ip, mode_t mode) 1344 0 stevel { 1345 0 stevel 1346 0 stevel boolean_t allzone = B_FALSE; 1347 0 stevel 1348 0 stevel ASSERT((mode & (MSG_R|MSG_W)) != 0); 1349 0 stevel 1350 0 stevel if ((mode & MSG_R) && 1351 0 stevel PRIV_POLICY(cr, PRIV_IPC_DAC_READ, allzone, EACCES, NULL) != 0) 1352 0 stevel return (EACCES); 1353 0 stevel 1354 0 stevel if (mode & MSG_W) { 1355 0 stevel if (cr->cr_uid != 0 && (ip->ipc_uid == 0 || ip->ipc_cuid == 0)) 1356 0 stevel allzone = B_TRUE; 1357 0 stevel 1358 0 stevel return (PRIV_POLICY(cr, PRIV_IPC_DAC_WRITE, allzone, EACCES, 1359 0 stevel NULL)); 1360 0 stevel } 1361 0 stevel return (0); 1362 0 stevel } 1363 0 stevel 1364 0 stevel int 1365 0 stevel secpolicy_rsm_access(const cred_t *cr, uid_t owner, mode_t mode) 1366 0 stevel { 1367 0 stevel boolean_t allzone = B_FALSE; 1368 0 stevel 1369 0 stevel ASSERT((mode & (MSG_R|MSG_W)) != 0); 1370 0 stevel 1371 0 stevel if ((mode & MSG_R) && 1372 0 stevel PRIV_POLICY(cr, PRIV_IPC_DAC_READ, allzone, EACCES, NULL) != 0) 1373 0 stevel return (EACCES); 1374 0 stevel 1375 0 stevel if (mode & MSG_W) { 1376 0 stevel if (cr->cr_uid != 0 && owner == 0) 1377 0 stevel allzone = B_TRUE; 1378 0 stevel 1379 0 stevel return (PRIV_POLICY(cr, PRIV_IPC_DAC_WRITE, allzone, EACCES, 1380 0 stevel NULL)); 1381 0 stevel } 1382 0 stevel return (0); 1383 0 stevel } 1384 0 stevel 1385 0 stevel /* 1386 0 stevel * Audit configuration. 1387 0 stevel */ 1388 0 stevel int 1389 0 stevel secpolicy_audit_config(const cred_t *cr) 1390 0 stevel { 1391 0 stevel return (PRIV_POLICY(cr, PRIV_SYS_AUDIT, B_FALSE, EPERM, NULL)); 1392 0 stevel } 1393 0 stevel 1394 0 stevel /* 1395 0 stevel * Audit record generation. 1396 0 stevel */ 1397 0 stevel int 1398 0 stevel secpolicy_audit_modify(const cred_t *cr) 1399 0 stevel { 1400 0 stevel return (PRIV_POLICY(cr, PRIV_PROC_AUDIT, B_FALSE, EPERM, NULL)); 1401 0 stevel } 1402 0 stevel 1403 0 stevel /* 1404 0 stevel * Get audit attributes. 1405 0 stevel * Either PRIV_SYS_AUDIT or PRIV_PROC_AUDIT required; report the 1406 0 stevel * "Least" of the two privileges on error. 1407 0 stevel */ 1408 0 stevel int 1409 0 stevel secpolicy_audit_getattr(const cred_t *cr) 1410 0 stevel { 1411 0 stevel if (!PRIV_POLICY_ONLY(cr, PRIV_SYS_AUDIT, B_FALSE)) { 1412 0 stevel return (PRIV_POLICY(cr, PRIV_PROC_AUDIT, B_FALSE, EPERM, 1413 0 stevel NULL)); 1414 0 stevel } else { 1415 0 stevel return (PRIV_POLICY(cr, PRIV_SYS_AUDIT, B_FALSE, EPERM, NULL)); 1416 0 stevel } 1417 0 stevel } 1418 0 stevel 1419 0 stevel 1420 0 stevel /* 1421 0 stevel * Locking physical memory 1422 0 stevel */ 1423 0 stevel int 1424 0 stevel secpolicy_lock_memory(const cred_t *cr) 1425 0 stevel { 1426 0 stevel return (PRIV_POLICY(cr, PRIV_PROC_LOCK_MEMORY, B_FALSE, EPERM, NULL)); 1427 0 stevel } 1428 0 stevel 1429 0 stevel /* 1430 0 stevel * Accounting (both acct(2) and exacct). 1431 0 stevel */ 1432 0 stevel int 1433 0 stevel secpolicy_acct(const cred_t *cr) 1434 0 stevel { 1435 0 stevel return (PRIV_POLICY(cr, PRIV_SYS_ACCT, B_FALSE, EPERM, NULL)); 1436 0 stevel } 1437 0 stevel 1438 0 stevel /* 1439 0 stevel * Is this process privileged to change its uids at will? 1440 0 stevel * Uid 0 is still considered "special" and having the SETID 1441 0 stevel * privilege is not sufficient to get uid 0. 1442 0 stevel * Files are owned by root, so the privilege would give 1443 0 stevel * full access and euid 0 is still effective. 1444 0 stevel * 1445 0 stevel * If you have the privilege and euid 0 only then do you 1446 0 stevel * get the powers of root wrt uid 0. 1447 0 stevel * 1448 0 stevel * For gid manipulations, this is should be called with an 1449 0 stevel * uid of -1. 1450 0 stevel * 1451 0 stevel */ 1452 0 stevel int 1453 0 stevel secpolicy_allow_setid(const cred_t *cr, uid_t newuid, boolean_t checkonly) 1454 0 stevel { 1455 0 stevel boolean_t allzone = B_FALSE; 1456 0 stevel 1457 0 stevel if (newuid == 0 && cr->cr_uid != 0 && cr->cr_suid != 0 && 1458 0 stevel cr->cr_ruid != 0) { 1459 0 stevel allzone = B_TRUE; 1460 0 stevel } 1461 0 stevel 1462 0 stevel return (checkonly ? !PRIV_POLICY_ONLY(cr, PRIV_PROC_SETID, allzone) : 1463 0 stevel PRIV_POLICY(cr, PRIV_PROC_SETID, allzone, EPERM, NULL)); 1464 0 stevel } 1465 0 stevel 1466 0 stevel 1467 0 stevel /* 1468 0 stevel * Acting on a different process: if the mode is for writing, 1469 0 stevel * the restrictions are more severe. This is called after 1470 0 stevel * we've verified that the uids do not match. 1471 0 stevel */ 1472 0 stevel int 1473 0 stevel secpolicy_proc_owner(const cred_t *scr, const cred_t *tcr, int mode) 1474 0 stevel { 1475 0 stevel boolean_t allzone = B_FALSE; 1476 0 stevel 1477 0 stevel if ((mode & VWRITE) && scr->cr_uid != 0 && 1478 0 stevel (tcr->cr_uid == 0 || tcr->cr_ruid == 0 || tcr->cr_suid == 0)) 1479 0 stevel allzone = B_TRUE; 1480 0 stevel 1481 0 stevel return (PRIV_POLICY(scr, PRIV_PROC_OWNER, allzone, EPERM, NULL)); 1482 0 stevel } 1483 0 stevel 1484 0 stevel int 1485 0 stevel secpolicy_proc_access(const cred_t *scr) 1486 0 stevel { 1487 0 stevel return (PRIV_POLICY(scr, PRIV_PROC_OWNER, B_FALSE, EACCES, NULL)); 1488 0 stevel } 1489 0 stevel 1490 0 stevel int 1491 0 stevel secpolicy_proc_excl_open(const cred_t *scr) 1492 0 stevel { 1493 0 stevel return (PRIV_POLICY(scr, PRIV_PROC_OWNER, B_FALSE, EBUSY, NULL)); 1494 0 stevel } 1495 0 stevel 1496 0 stevel int 1497 0 stevel secpolicy_proc_zone(const cred_t *scr) 1498 0 stevel { 1499 0 stevel return (PRIV_POLICY(scr, PRIV_PROC_ZONE, B_FALSE, EPERM, NULL)); 1500 0 stevel } 1501 0 stevel 1502 0 stevel /* 1503 0 stevel * Destroying the system 1504 0 stevel */ 1505 0 stevel 1506 0 stevel int 1507 0 stevel secpolicy_kmdb(const cred_t *scr) 1508 0 stevel { 1509 0 stevel return (PRIV_POLICY(scr, PRIV_ALL, B_FALSE, EPERM, NULL)); 1510 0 stevel } 1511 0 stevel 1512 1414 cindi int 1513 1414 cindi secpolicy_error_inject(const cred_t *scr) 1514 1414 cindi { 1515 1414 cindi return (PRIV_POLICY(scr, PRIV_ALL, B_FALSE, EPERM, NULL)); 1516 1414 cindi } 1517 1414 cindi 1518 0 stevel /* 1519 0 stevel * Processor sets, cpu configuration, resource pools. 1520 0 stevel */ 1521 0 stevel int 1522 0 stevel secpolicy_pset(const cred_t *cr) 1523 0 stevel { 1524 0 stevel return (PRIV_POLICY(cr, PRIV_SYS_RES_CONFIG, B_FALSE, EPERM, NULL)); 1525 0 stevel } 1526 0 stevel 1527 0 stevel int 1528 0 stevel secpolicy_ponline(const cred_t *cr) 1529 0 stevel { 1530 0 stevel return (PRIV_POLICY(cr, PRIV_SYS_RES_CONFIG, B_FALSE, EPERM, NULL)); 1531 0 stevel } 1532 0 stevel 1533 0 stevel int 1534 0 stevel secpolicy_pool(const cred_t *cr) 1535 0 stevel { 1536 0 stevel return (PRIV_POLICY(cr, PRIV_SYS_RES_CONFIG, B_FALSE, EPERM, NULL)); 1537 0 stevel } 1538 0 stevel 1539 0 stevel int 1540 0 stevel secpolicy_blacklist(const cred_t *cr) 1541 0 stevel { 1542 0 stevel return (PRIV_POLICY(cr, PRIV_SYS_RES_CONFIG, B_FALSE, EPERM, NULL)); 1543 0 stevel } 1544 0 stevel 1545 0 stevel /* 1546 0 stevel * Catch all system configuration. 1547 0 stevel */ 1548 0 stevel int 1549 0 stevel secpolicy_sys_config(const cred_t *cr, boolean_t checkonly) 1550 0 stevel { 1551 0 stevel if (checkonly) { 1552 0 stevel return (PRIV_POLICY_ONLY(cr, PRIV_SYS_CONFIG, B_FALSE) ? 0 : 1553 0 stevel EPERM); 1554 0 stevel } else { 1555 0 stevel return (PRIV_POLICY(cr, PRIV_SYS_CONFIG, B_FALSE, EPERM, NULL)); 1556 0 stevel } 1557 0 stevel } 1558 0 stevel 1559 0 stevel /* 1560 0 stevel * Zone administration (halt, reboot, etc.) from within zone. 1561 0 stevel */ 1562 0 stevel int 1563 0 stevel secpolicy_zone_admin(const cred_t *cr, boolean_t checkonly) 1564 0 stevel { 1565 0 stevel if (checkonly) { 1566 0 stevel return (PRIV_POLICY_ONLY(cr, PRIV_SYS_ADMIN, B_FALSE) ? 0 : 1567 0 stevel EPERM); 1568 0 stevel } else { 1569 0 stevel return (PRIV_POLICY(cr, PRIV_SYS_ADMIN, B_FALSE, EPERM, 1570 0 stevel NULL)); 1571 0 stevel } 1572 0 stevel } 1573 0 stevel 1574 0 stevel /* 1575 0 stevel * Zone configuration (create, halt, enter). 1576 0 stevel */ 1577 0 stevel int 1578 0 stevel secpolicy_zone_config(const cred_t *cr) 1579 0 stevel { 1580 0 stevel /* 1581 0 stevel * Require all privileges to avoid possibility of privilege 1582 0 stevel * escalation. 1583 0 stevel */ 1584 0 stevel return (secpolicy_require_set(cr, PRIV_FULLSET, NULL)); 1585 0 stevel } 1586 0 stevel 1587 0 stevel /* 1588 0 stevel * Various other system configuration calls 1589 0 stevel */ 1590 0 stevel int 1591 0 stevel secpolicy_coreadm(const cred_t *cr) 1592 0 stevel { 1593 0 stevel return (PRIV_POLICY(cr, PRIV_SYS_ADMIN, B_FALSE, EPERM, NULL)); 1594 0 stevel } 1595 0 stevel 1596 0 stevel int 1597 0 stevel secpolicy_systeminfo(const cred_t *cr) 1598 0 stevel { 1599 0 stevel return (PRIV_POLICY(cr, PRIV_SYS_ADMIN, B_FALSE, EPERM, NULL)); 1600 0 stevel } 1601 0 stevel 1602 0 stevel int 1603 0 stevel secpolicy_dispadm(const cred_t *cr) 1604 0 stevel { 1605 0 stevel return (PRIV_POLICY(cr, PRIV_SYS_CONFIG, B_FALSE, EPERM, NULL)); 1606 0 stevel } 1607 0 stevel 1608 0 stevel int 1609 0 stevel secpolicy_settime(const cred_t *cr) 1610 0 stevel { 1611 0 stevel return (PRIV_POLICY(cr, PRIV_SYS_TIME, B_FALSE, EPERM, NULL)); 1612 0 stevel } 1613 0 stevel 1614 0 stevel /* 1615 0 stevel * For realtime users: high resolution clock. 1616 0 stevel */ 1617 0 stevel int 1618 0 stevel secpolicy_clock_highres(const cred_t *cr) 1619 0 stevel { 1620 0 stevel return (PRIV_POLICY(cr, PRIV_PROC_CLOCK_HIGHRES, B_FALSE, EPERM, 1621 0 stevel NULL)); 1622 0 stevel } 1623 0 stevel 1624 0 stevel /* 1625 0 stevel * drv_priv() is documented as callable from interrupt context, not that 1626 0 stevel * anyone ever does, but still. No debugging or auditing can be done when 1627 0 stevel * it is called from interrupt context. 1628 0 stevel * returns 0 on succes, EPERM on failure. 1629 0 stevel */ 1630 0 stevel int 1631 0 stevel drv_priv(cred_t *cr) 1632 0 stevel { 1633 0 stevel return (PRIV_POLICY(cr, PRIV_SYS_DEVICES, B_FALSE, EPERM, NULL)); 1634 0 stevel } 1635 0 stevel 1636 0 stevel int 1637 0 stevel secpolicy_sys_devices(const cred_t *cr) 1638 0 stevel { 1639 0 stevel return (PRIV_POLICY(cr, PRIV_SYS_DEVICES, B_FALSE, EPERM, NULL)); 1640 0 stevel } 1641 0 stevel 1642 0 stevel int 1643 0 stevel secpolicy_excl_open(const cred_t *cr) 1644 0 stevel { 1645 0 stevel return (PRIV_POLICY(cr, PRIV_SYS_DEVICES, B_FALSE, EBUSY, NULL)); 1646 0 stevel } 1647 0 stevel 1648 0 stevel int 1649 0 stevel secpolicy_rctlsys(const cred_t *cr, boolean_t is_zone_rctl) 1650 0 stevel { 1651 0 stevel /* zone.* rctls can only be set from the global zone */ 1652 0 stevel if (is_zone_rctl && priv_policy_global(cr) != 0) 1653 0 stevel return (EPERM); 1654 0 stevel return (PRIV_POLICY(cr, PRIV_SYS_RESOURCE, B_FALSE, EPERM, NULL)); 1655 0 stevel } 1656 0 stevel 1657 0 stevel int 1658 0 stevel secpolicy_resource(const cred_t *cr) 1659 0 stevel { 1660 0 stevel return (PRIV_POLICY(cr, PRIV_SYS_RESOURCE, B_FALSE, EPERM, NULL)); 1661 0 stevel } 1662 0 stevel 1663 10154 Stan int 1664 10154 Stan secpolicy_resource_anon_mem(const cred_t *cr) 1665 10154 Stan { 1666 10154 Stan return (PRIV_POLICY_ONLY(cr, PRIV_SYS_RESOURCE, B_FALSE)); 1667 10154 Stan } 1668 10154 Stan 1669 0 stevel /* 1670 0 stevel * Processes with a real uid of 0 escape any form of accounting, much 1671 0 stevel * like before. 1672 0 stevel */ 1673 0 stevel int 1674 0 stevel secpolicy_newproc(const cred_t *cr) 1675 0 stevel { 1676 0 stevel if (cr->cr_ruid == 0) 1677 0 stevel return (0); 1678 0 stevel 1679 0 stevel return (PRIV_POLICY(cr, PRIV_SYS_RESOURCE, B_FALSE, EPERM, NULL)); 1680 0 stevel } 1681 0 stevel 1682 0 stevel /* 1683 0 stevel * Networking 1684 0 stevel */ 1685 0 stevel int 1686 0 stevel secpolicy_net_rawaccess(const cred_t *cr) 1687 0 stevel { 1688 0 stevel return (PRIV_POLICY(cr, PRIV_NET_RAWACCESS, B_FALSE, EACCES, NULL)); 1689 0 stevel } 1690 0 stevel 1691 10639 Darren int 1692 10639 Darren secpolicy_net_observability(const cred_t *cr) 1693 10639 Darren { 1694 10639 Darren return (PRIV_POLICY(cr, PRIV_NET_OBSERVABILITY, B_FALSE, EACCES, NULL)); 1695 10639 Darren } 1696 10639 Darren 1697 0 stevel /* 1698 0 stevel * Need this privilege for accessing the ICMP device 1699 0 stevel */ 1700 0 stevel int 1701 0 stevel secpolicy_net_icmpaccess(const cred_t *cr) 1702 0 stevel { 1703 0 stevel return (PRIV_POLICY(cr, PRIV_NET_ICMPACCESS, B_FALSE, EACCES, NULL)); 1704 0 stevel } 1705 0 stevel 1706 0 stevel /* 1707 0 stevel * There are a few rare cases where the kernel generates ioctls() from 1708 0 stevel * interrupt context with a credential of kcred rather than NULL. 1709 0 stevel * In those cases, we take the safe and cheap test. 1710 0 stevel */ 1711 0 stevel int 1712 0 stevel secpolicy_net_config(const cred_t *cr, boolean_t checkonly) 1713 0 stevel { 1714 0 stevel if (checkonly) { 1715 0 stevel return (PRIV_POLICY_ONLY(cr, PRIV_SYS_NET_CONFIG, B_FALSE) ? 1716 0 stevel 0 : EPERM); 1717 0 stevel } else { 1718 0 stevel return (PRIV_POLICY(cr, PRIV_SYS_NET_CONFIG, B_FALSE, EPERM, 1719 0 stevel NULL)); 1720 0 stevel } 1721 0 stevel } 1722 0 stevel 1723 0 stevel 1724 0 stevel /* 1725 4962 dh155122 * PRIV_SYS_NET_CONFIG is a superset of PRIV_SYS_IP_CONFIG. 1726 3448 dh155122 * 1727 3448 dh155122 * There are a few rare cases where the kernel generates ioctls() from 1728 3448 dh155122 * interrupt context with a credential of kcred rather than NULL. 1729 3448 dh155122 * In those cases, we take the safe and cheap test. 1730 3448 dh155122 */ 1731 3448 dh155122 int 1732 3448 dh155122 secpolicy_ip_config(const cred_t *cr, boolean_t checkonly) 1733 3448 dh155122 { 1734 3448 dh155122 if (PRIV_POLICY_ONLY(cr, PRIV_SYS_NET_CONFIG, B_FALSE)) 1735 3448 dh155122 return (secpolicy_net_config(cr, checkonly)); 1736 3448 dh155122 1737 3448 dh155122 if (checkonly) { 1738 3448 dh155122 return (PRIV_POLICY_ONLY(cr, PRIV_SYS_IP_CONFIG, B_FALSE) ? 1739 3448 dh155122 0 : EPERM); 1740 3448 dh155122 } else { 1741 3448 dh155122 return (PRIV_POLICY(cr, PRIV_SYS_IP_CONFIG, B_FALSE, EPERM, 1742 3448 dh155122 NULL)); 1743 3448 dh155122 } 1744 3448 dh155122 } 1745 3448 dh155122 1746 7408 Sebastien /* 1747 7408 Sebastien * PRIV_SYS_NET_CONFIG is a superset of PRIV_SYS_DL_CONFIG. 1748 7408 Sebastien */ 1749 7408 Sebastien int 1750 7408 Sebastien secpolicy_dl_config(const cred_t *cr) 1751 7408 Sebastien { 1752 7408 Sebastien if (PRIV_POLICY_ONLY(cr, PRIV_SYS_NET_CONFIG, B_FALSE)) 1753 7408 Sebastien return (secpolicy_net_config(cr, B_FALSE)); 1754 10616 Sebastien return (PRIV_POLICY(cr, PRIV_SYS_DL_CONFIG, B_FALSE, EPERM, NULL)); 1755 7408 Sebastien } 1756 7408 Sebastien 1757 10616 Sebastien /* 1758 10616 Sebastien * PRIV_SYS_DL_CONFIG is a superset of PRIV_SYS_IPTUN_CONFIG. 1759 10616 Sebastien */ 1760 10616 Sebastien int 1761 10616 Sebastien secpolicy_iptun_config(const cred_t *cr) 1762 10616 Sebastien { 1763 10616 Sebastien if (PRIV_POLICY_ONLY(cr, PRIV_SYS_NET_CONFIG, B_FALSE)) 1764 10616 Sebastien return (secpolicy_net_config(cr, B_FALSE)); 1765 10616 Sebastien if (PRIV_POLICY_ONLY(cr, PRIV_SYS_DL_CONFIG, B_FALSE)) 1766 10616 Sebastien return (secpolicy_dl_config(cr)); 1767 10616 Sebastien return (PRIV_POLICY(cr, PRIV_SYS_IPTUN_CONFIG, B_FALSE, EPERM, NULL)); 1768 10616 Sebastien } 1769 3448 dh155122 1770 3448 dh155122 /* 1771 3448 dh155122 * Map IP pseudo privileges to actual privileges. 1772 3448 dh155122 * So we don't need to recompile IP when we change the privileges. 1773 3448 dh155122 */ 1774 3448 dh155122 int 1775 3448 dh155122 secpolicy_ip(const cred_t *cr, int netpriv, boolean_t checkonly) 1776 3448 dh155122 { 1777 3448 dh155122 int priv = PRIV_ALL; 1778 3448 dh155122 1779 3448 dh155122 switch (netpriv) { 1780 3448 dh155122 case OP_CONFIG: 1781 3448 dh155122 priv = PRIV_SYS_IP_CONFIG; 1782 3448 dh155122 break; 1783 3448 dh155122 case OP_RAW: 1784 3448 dh155122 priv = PRIV_NET_RAWACCESS; 1785 3448 dh155122 break; 1786 3448 dh155122 case OP_PRIVPORT: 1787 3448 dh155122 priv = PRIV_NET_PRIVADDR; 1788 3448 dh155122 break; 1789 3448 dh155122 } 1790 3448 dh155122 ASSERT(priv != PRIV_ALL); 1791 3448 dh155122 if (checkonly) 1792 3448 dh155122 return (PRIV_POLICY_ONLY(cr, priv, B_FALSE) ? 0 : EPERM); 1793 3448 dh155122 else 1794 3448 dh155122 return (PRIV_POLICY(cr, priv, B_FALSE, EPERM, NULL)); 1795 3448 dh155122 } 1796 3448 dh155122 1797 3448 dh155122 /* 1798 0 stevel * Map network pseudo privileges to actual privileges. 1799 0 stevel * So we don't need to recompile IP when we change the privileges. 1800 0 stevel */ 1801 0 stevel int 1802 0 stevel secpolicy_net(const cred_t *cr, int netpriv, boolean_t checkonly) 1803 0 stevel { 1804 0 stevel int priv = PRIV_ALL; 1805 0 stevel 1806 0 stevel switch (netpriv) { 1807 0 stevel case OP_CONFIG: 1808 0 stevel priv = PRIV_SYS_NET_CONFIG; 1809 0 stevel break; 1810 0 stevel case OP_RAW: 1811 0 stevel priv = PRIV_NET_RAWACCESS; 1812 0 stevel break; 1813 0 stevel case OP_PRIVPORT: 1814 0 stevel priv = PRIV_NET_PRIVADDR; 1815 0 stevel break; 1816 0 stevel } 1817 0 stevel ASSERT(priv != PRIV_ALL); 1818 0 stevel if (checkonly) 1819 0 stevel return (PRIV_POLICY_ONLY(cr, priv, B_FALSE) ? 0 : EPERM); 1820 0 stevel else 1821 0 stevel return (PRIV_POLICY(cr, priv, B_FALSE, EPERM, NULL)); 1822 0 stevel } 1823 0 stevel 1824 0 stevel /* 1825 0 stevel * Checks for operations that are either client-only or are used by 1826 0 stevel * both clients and servers. 1827 0 stevel */ 1828 0 stevel int 1829 0 stevel secpolicy_nfs(const cred_t *cr) 1830 0 stevel { 1831 0 stevel return (PRIV_POLICY(cr, PRIV_SYS_NFS, B_FALSE, EPERM, NULL)); 1832 0 stevel } 1833 0 stevel 1834 0 stevel /* 1835 0 stevel * Special case for opening rpcmod: have NFS privileges or network 1836 0 stevel * config privileges. 1837 0 stevel */ 1838 0 stevel int 1839 0 stevel secpolicy_rpcmod_open(const cred_t *cr) 1840 0 stevel { 1841 0 stevel if (PRIV_POLICY_ONLY(cr, PRIV_SYS_NFS, B_FALSE)) 1842 0 stevel return (secpolicy_nfs(cr)); 1843 0 stevel else 1844 0 stevel return (secpolicy_net_config(cr, NULL)); 1845 0 stevel } 1846 0 stevel 1847 0 stevel int 1848 0 stevel secpolicy_chroot(const cred_t *cr) 1849 0 stevel { 1850 0 stevel return (PRIV_POLICY(cr, PRIV_PROC_CHROOT, B_FALSE, EPERM, NULL)); 1851 0 stevel } 1852 0 stevel 1853 0 stevel int 1854 0 stevel secpolicy_tasksys(const cred_t *cr) 1855 0 stevel { 1856 0 stevel return (PRIV_POLICY(cr, PRIV_PROC_TASKID, B_FALSE, EPERM, NULL)); 1857 0 stevel } 1858 0 stevel 1859 0 stevel /* 1860 0 stevel * Basic privilege checks. 1861 0 stevel */ 1862 0 stevel int 1863 6134 casper secpolicy_basic_exec(const cred_t *cr, vnode_t *vp) 1864 0 stevel { 1865 6134 casper return (priv_policy_va(cr, PRIV_PROC_EXEC, B_FALSE, EPERM, NULL, 1866 6134 casper KLPDARG_VNODE, vp, (char *)NULL, KLPDARG_NOMORE)); 1867 0 stevel } 1868 0 stevel 1869 0 stevel int 1870 0 stevel secpolicy_basic_fork(const cred_t *cr) 1871 0 stevel { 1872 0 stevel return (PRIV_POLICY(cr, PRIV_PROC_FORK, B_FALSE, EPERM, NULL)); 1873 0 stevel } 1874 0 stevel 1875 0 stevel int 1876 0 stevel secpolicy_basic_proc(const cred_t *cr) 1877 0 stevel { 1878 0 stevel return (PRIV_POLICY(cr, PRIV_PROC_SESSION, B_FALSE, EPERM, NULL)); 1879 0 stevel } 1880 0 stevel 1881 0 stevel /* 1882 0 stevel * Slightly complicated because we don't want to trigger the policy too 1883 0 stevel * often. First we shortcircuit access to "self" (tp == sp) or if 1884 0 stevel * we don't have the privilege but if we have permission 1885 0 stevel * just return (0) and we don't flag the privilege as needed. 1886 0 stevel * Else, we test for the privilege because we either have it or need it. 1887 0 stevel */ 1888 0 stevel int 1889 0 stevel secpolicy_basic_procinfo(const cred_t *cr, proc_t *tp, proc_t *sp) 1890 0 stevel { 1891 0 stevel if (tp == sp || 1892 0 stevel !HAS_PRIVILEGE(cr, PRIV_PROC_INFO) && prochasprocperm(tp, sp, cr)) { 1893 0 stevel return (0); 1894 0 stevel } else { 1895 0 stevel return (PRIV_POLICY(cr, PRIV_PROC_INFO, B_FALSE, EPERM, NULL)); 1896 0 stevel } 1897 0 stevel } 1898 0 stevel 1899 0 stevel int 1900 0 stevel secpolicy_basic_link(const cred_t *cr) 1901 0 stevel { 1902 0 stevel return (PRIV_POLICY(cr, PRIV_FILE_LINK_ANY, B_FALSE, EPERM, NULL)); 1903 0 stevel } 1904 0 stevel 1905 0 stevel /* 1906 0 stevel * Additional device protection. 1907 0 stevel * 1908 0 stevel * Traditionally, a device has specific permissions on the node in 1909 0 stevel * the filesystem which govern which devices can be opened by what 1910 0 stevel * processes. In certain cases, it is desirable to add extra 1911 0 stevel * restrictions, as writing to certain devices is identical to 1912 0 stevel * having a complete run of the system. 1913 0 stevel * 1914 0 stevel * This mechanism is called the device policy. 1915 0 stevel * 1916 0 stevel * When a device is opened, its policy entry is looked up in the 1917 0 stevel * policy cache and checked. 1918 0 stevel */ 1919 0 stevel int 1920 0 stevel secpolicy_spec_open(const cred_t *cr, struct vnode *vp, int oflag) 1921 0 stevel { 1922 0 stevel devplcy_t *plcy; 1923 0 stevel int err; 1924 0 stevel struct snode *csp = VTOS(common_specvp(vp)); 1925 4962 dh155122 priv_set_t pset; 1926 0 stevel 1927 0 stevel mutex_enter(&csp->s_lock); 1928 0 stevel 1929 0 stevel if (csp->s_plcy == NULL || csp->s_plcy->dp_gen != devplcy_gen) { 1930 0 stevel plcy = devpolicy_find(vp); 1931 0 stevel if (csp->s_plcy) 1932 0 stevel dpfree(csp->s_plcy); 1933 0 stevel csp->s_plcy = plcy; 1934 0 stevel ASSERT(plcy != NULL); 1935 0 stevel } else 1936 0 stevel plcy = csp->s_plcy; 1937 0 stevel 1938 0 stevel if (plcy == nullpolicy) { 1939 0 stevel mutex_exit(&csp->s_lock); 1940 0 stevel return (0); 1941 0 stevel } 1942 0 stevel 1943 0 stevel dphold(plcy); 1944 0 stevel 1945 0 stevel mutex_exit(&csp->s_lock); 1946 0 stevel 1947 4962 dh155122 if (oflag & FWRITE) 1948 4962 dh155122 pset = plcy->dp_wrp; 1949 4962 dh155122 else 1950 4962 dh155122 pset = plcy->dp_rdp; 1951 4962 dh155122 /* 1952 4962 dh155122 * Special case: 1953 4962 dh155122 * PRIV_SYS_NET_CONFIG is a superset of PRIV_SYS_IP_CONFIG. 1954 4962 dh155122 * If PRIV_SYS_NET_CONFIG is present and PRIV_SYS_IP_CONFIG is 1955 4962 dh155122 * required, replace PRIV_SYS_IP_CONFIG with PRIV_SYS_NET_CONFIG 1956 4962 dh155122 * in the required privilege set before doing the check. 1957 4962 dh155122 */ 1958 4962 dh155122 if (priv_ismember(&pset, PRIV_SYS_IP_CONFIG) && 1959 4962 dh155122 priv_ismember(&CR_OEPRIV(cr), PRIV_SYS_NET_CONFIG) && 1960 4962 dh155122 !priv_ismember(&CR_OEPRIV(cr), PRIV_SYS_IP_CONFIG)) { 1961 4962 dh155122 priv_delset(&pset, PRIV_SYS_IP_CONFIG); 1962 4962 dh155122 priv_addset(&pset, PRIV_SYS_NET_CONFIG); 1963 4962 dh155122 } 1964 4962 dh155122 1965 4962 dh155122 err = secpolicy_require_set(cr, &pset, "devpolicy"); 1966 0 stevel dpfree(plcy); 1967 0 stevel 1968 0 stevel return (err); 1969 0 stevel } 1970 0 stevel 1971 0 stevel int 1972 0 stevel secpolicy_modctl(const cred_t *cr, int cmd) 1973 0 stevel { 1974 0 stevel switch (cmd) { 1975 0 stevel case MODINFO: 1976 2723 cth case MODGETMAJBIND: 1977 0 stevel case MODGETPATH: 1978 0 stevel case MODGETPATHLEN: 1979 2723 cth case MODGETNAME: 1980 0 stevel case MODGETFBNAME: 1981 0 stevel case MODGETDEVPOLICY: 1982 0 stevel case MODGETDEVPOLICYBYNAME: 1983 2723 cth case MODDEVT2INSTANCE: 1984 2723 cth case MODSIZEOF_DEVID: 1985 2723 cth case MODGETDEVID: 1986 2723 cth case MODSIZEOF_MINORNAME: 1987 2723 cth case MODGETMINORNAME: 1988 2723 cth case MODGETDEVFSPATH_LEN: 1989 2723 cth case MODGETDEVFSPATH: 1990 2723 cth case MODGETDEVFSPATH_MI_LEN: 1991 2723 cth case MODGETDEVFSPATH_MI: 1992 0 stevel /* Unprivileged */ 1993 0 stevel return (0); 1994 0 stevel case MODLOAD: 1995 0 stevel case MODSETDEVPOLICY: 1996 0 stevel return (secpolicy_require_set(cr, PRIV_FULLSET, NULL)); 1997 0 stevel default: 1998 0 stevel return (secpolicy_sys_config(cr, B_FALSE)); 1999 0 stevel } 2000 0 stevel } 2001 0 stevel 2002 0 stevel int 2003 0 stevel secpolicy_console(const cred_t *cr) 2004 0 stevel { 2005 0 stevel return (PRIV_POLICY(cr, PRIV_SYS_DEVICES, B_FALSE, EPERM, NULL)); 2006 0 stevel } 2007 0 stevel 2008 0 stevel int 2009 0 stevel secpolicy_power_mgmt(const cred_t *cr) 2010 0 stevel { 2011 0 stevel return (PRIV_POLICY(cr, PRIV_SYS_DEVICES, B_FALSE, EPERM, NULL)); 2012 0 stevel } 2013 0 stevel 2014 0 stevel /* 2015 0 stevel * Simulate terminal input; another escalation of privileges avenue. 2016 0 stevel */ 2017 0 stevel 2018 0 stevel int 2019 0 stevel secpolicy_sti(const cred_t *cr) 2020 0 stevel { 2021 0 stevel return (secpolicy_require_set(cr, PRIV_FULLSET, NULL)); 2022 0 stevel } 2023 0 stevel 2024 1676 jpk boolean_t 2025 1676 jpk secpolicy_net_reply_equal(const cred_t *cr) 2026 1676 jpk { 2027 1676 jpk return (PRIV_POLICY(cr, PRIV_SYS_CONFIG, B_FALSE, EPERM, NULL)); 2028 1676 jpk } 2029 1676 jpk 2030 0 stevel int 2031 0 stevel secpolicy_swapctl(const cred_t *cr) 2032 0 stevel { 2033 0 stevel return (PRIV_POLICY(cr, PRIV_SYS_CONFIG, B_FALSE, EPERM, NULL)); 2034 0 stevel } 2035 0 stevel 2036 0 stevel int 2037 0 stevel secpolicy_cpc_cpu(const cred_t *cr) 2038 0 stevel { 2039 0 stevel return (PRIV_POLICY(cr, PRIV_CPC_CPU, B_FALSE, EACCES, NULL)); 2040 0 stevel } 2041 0 stevel 2042 0 stevel /* 2043 6073 acruz * secpolicy_contract_identity 2044 6073 acruz * 2045 6073 acruz * Determine if the subject may set the process contract FMRI value 2046 6073 acruz */ 2047 6073 acruz int 2048 6073 acruz secpolicy_contract_identity(const cred_t *cr) 2049 6073 acruz { 2050 6073 acruz return (PRIV_POLICY(cr, PRIV_CONTRACT_IDENTITY, B_FALSE, EPERM, NULL)); 2051 6073 acruz } 2052 6073 acruz 2053 6073 acruz /* 2054 0 stevel * secpolicy_contract_observer 2055 0 stevel * 2056 0 stevel * Determine if the subject may observe a specific contract's events. 2057 0 stevel */ 2058 0 stevel int 2059 0 stevel secpolicy_contract_observer(const cred_t *cr, struct contract *ct) 2060 0 stevel { 2061 0 stevel if (contract_owned(ct, cr, B_FALSE)) 2062 0 stevel return (0); 2063 0 stevel return (PRIV_POLICY(cr, PRIV_CONTRACT_OBSERVER, B_FALSE, EPERM, NULL)); 2064 0 stevel } 2065 0 stevel 2066 0 stevel /* 2067 0 stevel * secpolicy_contract_observer_choice 2068 0 stevel * 2069 0 stevel * Determine if the subject may observe any contract's events. Just 2070 0 stevel * tests privilege and audits on success. 2071 0 stevel */ 2072 0 stevel boolean_t 2073 0 stevel secpolicy_contract_observer_choice(const cred_t *cr) 2074 0 stevel { 2075 0 stevel return (PRIV_POLICY_CHOICE(cr, PRIV_CONTRACT_OBSERVER, B_FALSE)); 2076 0 stevel } 2077 0 stevel 2078 0 stevel /* 2079 0 stevel * secpolicy_contract_event 2080 0 stevel * 2081 0 stevel * Determine if the subject may request critical contract events or 2082 0 stevel * reliable contract event delivery. 2083 0 stevel */ 2084 0 stevel int 2085 0 stevel secpolicy_contract_event(const cred_t *cr) 2086 0 stevel { 2087 0 stevel return (PRIV_POLICY(cr, PRIV_CONTRACT_EVENT, B_FALSE, EPERM, NULL)); 2088 0 stevel } 2089 0 stevel 2090 0 stevel /* 2091 0 stevel * secpolicy_contract_event_choice 2092 0 stevel * 2093 0 stevel * Determine if the subject may retain contract events in its critical 2094 0 stevel * set when a change in other terms would normally require a change in 2095 0 stevel * the critical set. Just tests privilege and audits on success. 2096 0 stevel */ 2097 0 stevel boolean_t 2098 0 stevel secpolicy_contract_event_choice(const cred_t *cr) 2099 0 stevel { 2100 0 stevel return (PRIV_POLICY_CHOICE(cr, PRIV_CONTRACT_EVENT, B_FALSE)); 2101 0 stevel } 2102 0 stevel 2103 0 stevel /* 2104 1544 eschrock * secpolicy_gart_access 2105 0 stevel * 2106 1544 eschrock * Determine if the subject has sufficient priveleges to make ioctls to agpgart 2107 1544 eschrock * device. 2108 0 stevel */ 2109 0 stevel int 2110 0 stevel secpolicy_gart_access(const cred_t *cr) 2111 0 stevel { 2112 1862 casper return (PRIV_POLICY(cr, PRIV_GRAPHICS_ACCESS, B_FALSE, EPERM, NULL)); 2113 0 stevel } 2114 0 stevel 2115 0 stevel /* 2116 1544 eschrock * secpolicy_gart_map 2117 0 stevel * 2118 1544 eschrock * Determine if the subject has sufficient priveleges to map aperture range 2119 1544 eschrock * through agpgart driver. 2120 0 stevel */ 2121 0 stevel int 2122 0 stevel secpolicy_gart_map(const cred_t *cr) 2123 0 stevel { 2124 1862 casper if (PRIV_POLICY_ONLY(cr, PRIV_GRAPHICS_ACCESS, B_FALSE)) { 2125 1862 casper return (PRIV_POLICY(cr, PRIV_GRAPHICS_ACCESS, B_FALSE, EPERM, 2126 1862 casper NULL)); 2127 1862 casper } else { 2128 1862 casper return (PRIV_POLICY(cr, PRIV_GRAPHICS_MAP, B_FALSE, EPERM, 2129 1862 casper NULL)); 2130 0 stevel } 2131 0 stevel } 2132 789 ahrens 2133 789 ahrens /* 2134 1544 eschrock * secpolicy_zinject 2135 1544 eschrock * 2136 1544 eschrock * Determine if the subject can inject faults in the ZFS fault injection 2137 1544 eschrock * framework. Requires all privileges. 2138 1544 eschrock */ 2139 1544 eschrock int 2140 1544 eschrock secpolicy_zinject(const cred_t *cr) 2141 1544 eschrock { 2142 1544 eschrock return (secpolicy_require_set(cr, PRIV_FULLSET, NULL)); 2143 1544 eschrock } 2144 1544 eschrock 2145 1544 eschrock /* 2146 789 ahrens * secpolicy_zfs 2147 789 ahrens * 2148 1544 eschrock * Determine if the subject has permission to manipulate ZFS datasets 2149 1544 eschrock * (not pools). Equivalent to the SYS_MOUNT privilege. 2150 789 ahrens */ 2151 789 ahrens int 2152 789 ahrens secpolicy_zfs(const cred_t *cr) 2153 789 ahrens { 2154 789 ahrens return (PRIV_POLICY(cr, PRIV_SYS_MOUNT, B_FALSE, EPERM, NULL)); 2155 789 ahrens } 2156 4321 casper 2157 4321 casper /* 2158 4321 casper * secpolicy_idmap 2159 4321 casper * 2160 4321 casper * Determine if the calling process has permissions to register an SID 2161 4321 casper * mapping daemon and allocate ephemeral IDs. 2162 4321 casper */ 2163 4321 casper int 2164 4321 casper secpolicy_idmap(const cred_t *cr) 2165 4321 casper { 2166 5771 jp151216 return (PRIV_POLICY(cr, PRIV_FILE_SETID, B_TRUE, EPERM, NULL)); 2167 4321 casper } 2168 4581 sherrym 2169 4581 sherrym /* 2170 4581 sherrym * secpolicy_ucode_update 2171 4581 sherrym * 2172 4581 sherrym * Determine if the subject has sufficient privilege to update microcode. 2173 4581 sherrym */ 2174 4581 sherrym int 2175 4581 sherrym secpolicy_ucode_update(const cred_t *scr) 2176 4581 sherrym { 2177 4581 sherrym return (PRIV_POLICY(scr, PRIV_ALL, B_FALSE, EPERM, NULL)); 2178 4581 sherrym } 2179 4962 dh155122 2180 4962 dh155122 /* 2181 4962 dh155122 * secpolicy_sadopen 2182 4962 dh155122 * 2183 4962 dh155122 * Determine if the subject has sufficient privilege to access /dev/sad/admin. 2184 4962 dh155122 * /dev/sad/admin appear in global zone and exclusive-IP zones only. 2185 4962 dh155122 * In global zone, sys_config is required. 2186 4962 dh155122 * In exclusive-IP zones, sys_ip_config is required. 2187 4962 dh155122 * Note that sys_config is prohibited in non-global zones. 2188 4962 dh155122 */ 2189 4962 dh155122 int 2190 4962 dh155122 secpolicy_sadopen(const cred_t *credp) 2191 4962 dh155122 { 2192 4962 dh155122 priv_set_t pset; 2193 4962 dh155122 2194 4962 dh155122 priv_emptyset(&pset); 2195 4962 dh155122 2196 4962 dh155122 if (crgetzoneid(credp) == GLOBAL_ZONEID) 2197 4962 dh155122 priv_addset(&pset, PRIV_SYS_CONFIG); 2198 4962 dh155122 else 2199 4962 dh155122 priv_addset(&pset, PRIV_SYS_IP_CONFIG); 2200 4962 dh155122 2201 4962 dh155122 return (secpolicy_require_set(credp, &pset, "devpolicy")); 2202 4962 dh155122 } 2203 5331 amw 2204 6134 casper 2205 6134 casper /* 2206 6134 casper * Add privileges to a particular privilege set; this is called when the 2207 6134 casper * current sets of privileges are not sufficient. I.e., we should always 2208 6134 casper * call the policy override functions from here. 2209 6134 casper * What we are allowed to have is in the Observed Permitted set; so 2210 6134 casper * we compute the difference between that and the newset. 2211 6134 casper */ 2212 6134 casper int 2213 6134 casper secpolicy_require_privs(const cred_t *cr, const priv_set_t *nset) 2214 6134 casper { 2215 6134 casper priv_set_t rqd; 2216 6134 casper 2217 6134 casper rqd = CR_OPPRIV(cr); 2218 6134 casper 2219 6134 casper priv_inverse(&rqd); 2220 6134 casper priv_intersect(nset, &rqd); 2221 6134 casper 2222 6134 casper return (secpolicy_require_set(cr, &rqd, NULL)); 2223 6134 casper } 2224 6134 casper 2225 5331 amw /* 2226 5331 amw * secpolicy_smb 2227 5331 amw * 2228 5331 amw * Determine if the cred_t has PRIV_SYS_SMB privilege, indicating 2229 5331 amw * that it has permission to access the smbsrv kernel driver. 2230 5331 amw * PRIV_POLICY checks the privilege and audits the check. 2231 5331 amw * 2232 5331 amw * Returns: 2233 5331 amw * 0 Driver access is allowed. 2234 5331 amw * EPERM Driver access is NOT permitted. 2235 5331 amw */ 2236 5331 amw int 2237 5331 amw secpolicy_smb(const cred_t *cr) 2238 5331 amw { 2239 5331 amw return (PRIV_POLICY(cr, PRIV_SYS_SMB, B_FALSE, EPERM, NULL)); 2240 5331 amw } 2241 5440 jm199354 2242 5440 jm199354 /* 2243 5440 jm199354 * secpolicy_vscan 2244 5440 jm199354 * 2245 5440 jm199354 * Determine if cred_t has the necessary privileges to access a file 2246 5440 jm199354 * for virus scanning and update its extended system attributes. 2247 5440 jm199354 * PRIV_FILE_DAC_SEARCH, PRIV_FILE_DAC_READ - file access 2248 5440 jm199354 * PRIV_FILE_FLAG_SET - set extended system attributes 2249 5440 jm199354 * 2250 5440 jm199354 * PRIV_POLICY checks the privilege and audits the check. 2251 5440 jm199354 * 2252 5440 jm199354 * Returns: 2253 5440 jm199354 * 0 file access for virus scanning allowed. 2254 5440 jm199354 * EPERM file access for virus scanning is NOT permitted. 2255 5440 jm199354 */ 2256 5440 jm199354 int 2257 5440 jm199354 secpolicy_vscan(const cred_t *cr) 2258 5440 jm199354 { 2259 5440 jm199354 if ((PRIV_POLICY(cr, PRIV_FILE_DAC_SEARCH, B_FALSE, EPERM, NULL)) || 2260 5440 jm199354 (PRIV_POLICY(cr, PRIV_FILE_DAC_READ, B_FALSE, EPERM, NULL)) || 2261 5440 jm199354 (PRIV_POLICY(cr, PRIV_FILE_FLAG_SET, B_FALSE, EPERM, NULL))) { 2262 5440 jm199354 return (EPERM); 2263 5440 jm199354 } 2264 5440 jm199354 2265 5440 jm199354 return (0); 2266 5440 jm199354 } 2267 6007 thurlow 2268 6007 thurlow /* 2269 6007 thurlow * secpolicy_smbfs_login 2270 6007 thurlow * 2271 6007 thurlow * Determines if the caller can add and delete the smbfs login 2272 6007 thurlow * password in the the nsmb kernel module for the CIFS client. 2273 6007 thurlow * 2274 6007 thurlow * Returns: 2275 6007 thurlow * 0 access is allowed. 2276 6007 thurlow * EPERM access is NOT allowed. 2277 6007 thurlow */ 2278 6007 thurlow int 2279 6007 thurlow secpolicy_smbfs_login(const cred_t *cr, uid_t uid) 2280 6007 thurlow { 2281 6007 thurlow uid_t cruid = crgetruid(cr); 2282 6007 thurlow 2283 6007 thurlow if (cruid == uid) 2284 6007 thurlow return (0); 2285 6007 thurlow return (PRIV_POLICY(cr, PRIV_PROC_OWNER, B_FALSE, 2286 6007 thurlow EPERM, NULL)); 2287 6007 thurlow } 2288 6784 johnlev 2289 6784 johnlev /* 2290 6784 johnlev * secpolicy_xvm_control 2291 6784 johnlev * 2292 6784 johnlev * Determines if a caller can control the xVM hypervisor and/or running 2293 6784 johnlev * domains (x86 specific). 2294 6784 johnlev * 2295 6784 johnlev * Returns: 2296 6784 johnlev * 0 access is allowed. 2297 6784 johnlev * EPERM access is NOT allowed. 2298 6784 johnlev */ 2299 6784 johnlev int 2300 6784 johnlev secpolicy_xvm_control(const cred_t *cr) 2301 6784 johnlev { 2302 6784 johnlev if (PRIV_POLICY(cr, PRIV_XVM_CONTROL, B_FALSE, EPERM, NULL)) 2303 6784 johnlev return (EPERM); 2304 6784 johnlev return (0); 2305 6784 johnlev } 2306 8275 Eric 2307 8275 Eric /* 2308 9751 james * secpolicy_ppp_config 2309 9751 james * 2310 9751 james * Determine if the subject has sufficient privileges to configure PPP and 2311 9751 james * PPP-related devices. 2312 9751 james */ 2313 9751 james int 2314 9751 james secpolicy_ppp_config(const cred_t *cr) 2315 9751 james { 2316 9751 james if (PRIV_POLICY_ONLY(cr, PRIV_SYS_NET_CONFIG, B_FALSE)) 2317 9751 james return (secpolicy_net_config(cr, B_FALSE)); 2318 9751 james return (PRIV_POLICY(cr, PRIV_SYS_PPP_CONFIG, B_FALSE, EPERM, NULL)); 2319 9751 james } 2320