1 /* 2 * ---------------------------------------------------------------------------- 3 * "THE BEER-WARE LICENSE" (Revision 42): 4 * <phk@FreeBSD.ORG> wrote this file. As long as you retain this notice you 5 * can do whatever you want with this stuff. If we meet some day, and you think 6 * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp 7 * ---------------------------------------------------------------------------- 8 * 9 */ 10 /*- 11 * Copyright (c) 2006 Victor Balada Diaz <victor@bsdes.net> 12 * All rights reserved. 13 * 14 * Redistribution and use in source and binary forms, with or without 15 * modification, are permitted provided that the following conditions 16 * are met: 17 * 1. Redistributions of source code must retain the above copyright 18 * notice, this list of conditions and the following disclaimer. 19 * 2. Redistributions in binary form must reproduce the above copyright 20 * notice, this list of conditions and the following disclaimer in the 21 * documentation and/or other materials provided with the distribution. 22 * 23 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 26 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 33 * SUCH DAMAGE. 34 */ 35 36 37 /* 38 * $FreeBSD: src/sys/kern/kern_jail.c,v 1.6.2.3 2001/08/17 01:00:26 rwatson Exp $ 39 * $DragonFly: src/sys/kern/kern_jail.c,v 1.19 2008/05/17 18:20:33 dillon Exp $ 40 */ 41 42 #include "opt_inet6.h" 43 44 #include <sys/param.h> 45 #include <sys/types.h> 46 #include <sys/kernel.h> 47 #include <sys/systm.h> 48 #include <sys/errno.h> 49 #include <sys/sysproto.h> 50 #include <sys/malloc.h> 51 #include <sys/nlookup.h> 52 #include <sys/namecache.h> 53 #include <sys/proc.h> 54 #include <sys/priv.h> 55 #include <sys/jail.h> 56 #include <sys/socket.h> 57 #include <sys/sysctl.h> 58 #include <sys/kern_syscall.h> 59 #include <net/if.h> 60 #include <netinet/in.h> 61 #include <netinet6/in6_var.h> 62 63 static struct prison *prison_find(int); 64 static void prison_ipcache_init(struct prison *); 65 66 MALLOC_DEFINE(M_PRISON, "prison", "Prison structures"); 67 68 SYSCTL_NODE(, OID_AUTO, jail, CTLFLAG_RW, 0, 69 "Jail rules"); 70 71 int jail_set_hostname_allowed = 1; 72 SYSCTL_INT(_jail, OID_AUTO, set_hostname_allowed, CTLFLAG_RW, 73 &jail_set_hostname_allowed, 0, 74 "Processes in jail can set their hostnames"); 75 76 int jail_socket_unixiproute_only = 1; 77 SYSCTL_INT(_jail, OID_AUTO, socket_unixiproute_only, CTLFLAG_RW, 78 &jail_socket_unixiproute_only, 0, 79 "Processes in jail are limited to creating UNIX/IPv[46]/route sockets only"); 80 81 int jail_sysvipc_allowed = 0; 82 SYSCTL_INT(_jail, OID_AUTO, sysvipc_allowed, CTLFLAG_RW, 83 &jail_sysvipc_allowed, 0, 84 "Processes in jail can use System V IPC primitives"); 85 86 int jail_chflags_allowed = 0; 87 SYSCTL_INT(_jail, OID_AUTO, chflags_allowed, CTLFLAG_RW, 88 &jail_chflags_allowed, 0, 89 "Process in jail can set chflags(1)"); 90 91 int jail_allow_raw_sockets = 0; 92 SYSCTL_INT(_jail, OID_AUTO, allow_raw_sockets, CTLFLAG_RW, 93 &jail_allow_raw_sockets, 0, 94 "Process in jail can create raw sockets"); 95 96 int lastprid = 0; 97 int prisoncount = 0; 98 99 LIST_HEAD(prisonlist, prison); 100 struct prisonlist allprison = LIST_HEAD_INITIALIZER(&allprison); 101 102 static int 103 kern_jail_attach(int jid) 104 { 105 struct proc *p = curthread->td_proc; 106 struct prison *pr; 107 int error; 108 109 pr = prison_find(jid); 110 if (pr == NULL) 111 return(EINVAL); 112 113 error = kern_chroot(&pr->pr_root); 114 if (error) 115 return(error); 116 117 prison_hold(pr); 118 cratom(&p->p_ucred); 119 p->p_ucred->cr_prison = pr; 120 p->p_flag |= P_JAILED; 121 122 return(0); 123 } 124 125 static int 126 assign_prison_id(struct prison *pr) 127 { 128 int tryprid; 129 struct prison *tpr; 130 131 tryprid = lastprid + 1; 132 if (tryprid == JAIL_MAX) 133 tryprid = 1; 134 next: 135 LIST_FOREACH(tpr, &allprison, pr_list) { 136 if (tpr->pr_id != tryprid) 137 continue; 138 tryprid++; 139 if (tryprid == JAIL_MAX) { 140 return (ERANGE); 141 } 142 goto next; 143 } 144 pr->pr_id = lastprid = tryprid; 145 146 return (0); 147 } 148 149 static int 150 kern_jail(struct prison *pr, struct jail *j) 151 { 152 int error; 153 struct nlookupdata nd; 154 155 error = nlookup_init(&nd, j->path, UIO_USERSPACE, NLC_FOLLOW); 156 if (error) { 157 nlookup_done(&nd); 158 return (error); 159 } 160 error = nlookup(&nd); 161 if (error) { 162 nlookup_done(&nd); 163 return (error); 164 } 165 cache_copy(&nd.nl_nch, &pr->pr_root); 166 167 varsymset_init(&pr->pr_varsymset, NULL); 168 prison_ipcache_init(pr); 169 170 error = assign_prison_id(pr); 171 if (error) { 172 varsymset_clean(&pr->pr_varsymset); 173 nlookup_done(&nd); 174 return (error); 175 } 176 177 LIST_INSERT_HEAD(&allprison, pr, pr_list); 178 prisoncount++; 179 180 error = kern_jail_attach(pr->pr_id); 181 if (error) { 182 LIST_REMOVE(pr, pr_list); 183 varsymset_clean(&pr->pr_varsymset); 184 } 185 nlookup_done(&nd); 186 return (error); 187 } 188 189 /* 190 * jail() 191 * 192 * jail_args(syscallarg(struct jail *) jail) 193 * 194 * MPALMOSTSAFE 195 */ 196 int 197 sys_jail(struct jail_args *uap) 198 { 199 struct thread *td = curthread; 200 struct prison *pr; 201 struct jail_ip_storage *jip; 202 struct jail j; 203 int error; 204 uint32_t jversion; 205 206 uap->sysmsg_result = -1; 207 208 error = priv_check(td, PRIV_JAIL_CREATE); 209 if (error) 210 return (error); 211 212 error = copyin(uap->jail, &jversion, sizeof(jversion)); 213 if (error) 214 return (error); 215 216 pr = kmalloc(sizeof(*pr), M_PRISON, M_WAITOK | M_ZERO); 217 SLIST_INIT(&pr->pr_ips); 218 get_mplock(); 219 220 switch (jversion) { 221 case 0: 222 /* Single IPv4 jails. */ 223 { 224 struct jail_v0 jv0; 225 struct sockaddr_in ip4addr; 226 227 error = copyin(uap->jail, &jv0, sizeof(jv0)); 228 if (error) 229 goto out; 230 231 j.path = jv0.path; 232 j.hostname = jv0.hostname; 233 234 jip = kmalloc(sizeof(*jip), M_PRISON, M_WAITOK | M_ZERO); 235 ip4addr.sin_family = AF_INET; 236 ip4addr.sin_addr.s_addr = htonl(jv0.ip_number); 237 memcpy(&jip->ip, &ip4addr, sizeof(ip4addr)); 238 SLIST_INSERT_HEAD(&pr->pr_ips, jip, entries); 239 break; 240 } 241 242 case 1: 243 /* 244 * DragonFly multi noIP/IPv4/IPv6 jails 245 * 246 * NOTE: This version is unsupported by FreeBSD 247 * (which uses version 2 instead). 248 */ 249 250 error = copyin(uap->jail, &j, sizeof(j)); 251 if (error) 252 goto out; 253 254 for (int i = 0; i < j.n_ips; i++) { 255 jip = kmalloc(sizeof(*jip), M_PRISON, 256 M_WAITOK | M_ZERO); 257 SLIST_INSERT_HEAD(&pr->pr_ips, jip, entries); 258 error = copyin(&j.ips[i], &jip->ip, 259 sizeof(struct sockaddr_storage)); 260 if (error) 261 goto out; 262 } 263 break; 264 default: 265 error = EINVAL; 266 goto out; 267 } 268 269 error = copyinstr(j.hostname, &pr->pr_host, sizeof(pr->pr_host), 0); 270 if (error) 271 goto out; 272 273 error = kern_jail(pr, &j); 274 if (error) 275 goto out; 276 277 uap->sysmsg_result = pr->pr_id; 278 rel_mplock(); 279 return (0); 280 281 out: 282 /* Delete all ips */ 283 while (!SLIST_EMPTY(&pr->pr_ips)) { 284 jip = SLIST_FIRST(&pr->pr_ips); 285 SLIST_REMOVE_HEAD(&pr->pr_ips, entries); 286 kfree(jip, M_PRISON); 287 } 288 rel_mplock(); 289 kfree(pr, M_PRISON); 290 return (error); 291 } 292 293 /* 294 * int jail_attach(int jid); 295 * 296 * MPALMOSTSAFE 297 */ 298 int 299 sys_jail_attach(struct jail_attach_args *uap) 300 { 301 struct thread *td = curthread; 302 int error; 303 304 error = priv_check(td, PRIV_JAIL_ATTACH); 305 if (error) 306 return(error); 307 get_mplock(); 308 error = kern_jail_attach(uap->jid); 309 rel_mplock(); 310 return (error); 311 } 312 313 static void 314 prison_ipcache_init(struct prison *pr) 315 { 316 struct jail_ip_storage *jis; 317 struct sockaddr_in *ip4; 318 struct sockaddr_in6 *ip6; 319 320 SLIST_FOREACH(jis, &pr->pr_ips, entries) { 321 switch (jis->ip.ss_family) { 322 case AF_INET: 323 ip4 = (struct sockaddr_in *)&jis->ip; 324 if ((ntohl(ip4->sin_addr.s_addr) >> IN_CLASSA_NSHIFT) == 325 IN_LOOPBACKNET) { 326 /* loopback address */ 327 if (pr->local_ip4 == NULL) 328 pr->local_ip4 = ip4; 329 } else { 330 /* public address */ 331 if (pr->nonlocal_ip4 == NULL) 332 pr->nonlocal_ip4 = ip4; 333 } 334 break; 335 336 case AF_INET6: 337 ip6 = (struct sockaddr_in6 *)&jis->ip; 338 if (IN6_IS_ADDR_LOOPBACK(&ip6->sin6_addr)) { 339 /* loopback address */ 340 if (pr->local_ip6 == NULL) 341 pr->local_ip6 = ip6; 342 } else { 343 /* public address */ 344 if (pr->nonlocal_ip6 == NULL) 345 pr->nonlocal_ip6 = ip6; 346 } 347 break; 348 } 349 } 350 } 351 352 /* 353 * Changes INADDR_LOOPBACK for a valid jail address. 354 * ip is in network byte order. 355 * Returns 1 if the ip is among jail valid ips. 356 * Returns 0 if is not among jail valid ips or 357 * if couldn't replace INADDR_LOOPBACK for a valid 358 * IP. 359 */ 360 int 361 prison_replace_wildcards(struct thread *td, struct sockaddr *ip) 362 { 363 struct sockaddr_in *ip4 = (struct sockaddr_in *)ip; 364 struct sockaddr_in6 *ip6 = (struct sockaddr_in6 *)ip; 365 struct prison *pr; 366 367 if (td->td_proc == NULL) 368 return (1); 369 if ((pr = td->td_proc->p_ucred->cr_prison) == NULL) 370 return (1); 371 372 if ((ip->sa_family == AF_INET && 373 ip4->sin_addr.s_addr == htonl(INADDR_ANY)) || 374 (ip->sa_family == AF_INET6 && 375 IN6_IS_ADDR_UNSPECIFIED(&ip6->sin6_addr))) 376 return (1); 377 if ((ip->sa_family == AF_INET && 378 ip4->sin_addr.s_addr == htonl(INADDR_LOOPBACK)) || 379 (ip->sa_family == AF_INET6 && 380 IN6_IS_ADDR_LOOPBACK(&ip6->sin6_addr))) { 381 if (!prison_get_local(pr, ip->sa_family, ip) && 382 !prison_get_nonlocal(pr, ip->sa_family, ip)) 383 return(0); 384 else 385 return(1); 386 } 387 if (jailed_ip(pr, ip)) 388 return(1); 389 return(0); 390 } 391 392 int 393 prison_remote_ip(struct thread *td, struct sockaddr *ip) 394 { 395 struct sockaddr_in *ip4 = (struct sockaddr_in *)ip; 396 struct sockaddr_in6 *ip6 = (struct sockaddr_in6 *)ip; 397 struct prison *pr; 398 399 if (td == NULL || td->td_proc == NULL) 400 return(1); 401 if ((pr = td->td_proc->p_ucred->cr_prison) == NULL) 402 return(1); 403 if ((ip->sa_family == AF_INET && 404 ip4->sin_addr.s_addr == htonl(INADDR_LOOPBACK)) || 405 (ip->sa_family == AF_INET6 && 406 IN6_IS_ADDR_LOOPBACK(&ip6->sin6_addr))) { 407 if (!prison_get_local(pr, ip->sa_family, ip) && 408 !prison_get_nonlocal(pr, ip->sa_family, ip)) 409 return(0); 410 else 411 return(1); 412 } 413 return(1); 414 } 415 416 /* 417 * Prison get non loopback ip: 418 * - af is the address family of the ip we want (AF_INET|AF_INET6). 419 * - If ip != NULL, put the first IP address that is not a loopback address 420 * into *ip. 421 * 422 * ip is in network by order and we don't touch it unless we find a valid ip. 423 * No matter if ip == NULL or not, we return either a valid struct sockaddr *, 424 * or NULL. This struct may not be modified. 425 */ 426 struct sockaddr * 427 prison_get_nonlocal(struct prison *pr, sa_family_t af, struct sockaddr *ip) 428 { 429 struct sockaddr_in *ip4 = (struct sockaddr_in *)ip; 430 struct sockaddr_in6 *ip6 = (struct sockaddr_in6 *)ip; 431 432 /* Check if it is cached */ 433 switch(af) { 434 case AF_INET: 435 if (ip4 != NULL && pr->nonlocal_ip4 != NULL) 436 ip4->sin_addr.s_addr = pr->nonlocal_ip4->sin_addr.s_addr; 437 return (struct sockaddr *)pr->nonlocal_ip4; 438 439 case AF_INET6: 440 if (ip6 != NULL && pr->nonlocal_ip6 != NULL) 441 ip6->sin6_addr = pr->nonlocal_ip6->sin6_addr; 442 return (struct sockaddr *)pr->nonlocal_ip6; 443 } 444 445 /* NOTREACHED */ 446 return NULL; 447 } 448 449 /* 450 * Prison get loopback ip. 451 * - af is the address family of the ip we want (AF_INET|AF_INET6). 452 * - If ip != NULL, put the first IP address that is not a loopback address 453 * into *ip. 454 * 455 * ip is in network by order and we don't touch it unless we find a valid ip. 456 * No matter if ip == NULL or not, we return either a valid struct sockaddr *, 457 * or NULL. This struct may not be modified. 458 */ 459 struct sockaddr * 460 prison_get_local(struct prison *pr, sa_family_t af, struct sockaddr *ip) 461 { 462 struct sockaddr_in *ip4 = (struct sockaddr_in *)ip; 463 struct sockaddr_in6 *ip6 = (struct sockaddr_in6 *)ip; 464 465 /* Check if it is cached */ 466 switch(af) { 467 case AF_INET: 468 if (ip4 != NULL && pr->local_ip4 != NULL) 469 ip4->sin_addr.s_addr = pr->local_ip4->sin_addr.s_addr; 470 return (struct sockaddr *)pr->local_ip4; 471 472 case AF_INET6: 473 if (ip6 != NULL && pr->local_ip6 != NULL) 474 ip6->sin6_addr = pr->local_ip6->sin6_addr; 475 return (struct sockaddr *)pr->local_ip6; 476 } 477 478 /* NOTREACHED */ 479 return NULL; 480 } 481 482 /* Check if the IP is among ours, if it is return 1, else 0 */ 483 int 484 jailed_ip(struct prison *pr, struct sockaddr *ip) 485 { 486 struct jail_ip_storage *jis; 487 struct sockaddr_in *jip4, *ip4; 488 struct sockaddr_in6 *jip6, *ip6; 489 490 if (pr == NULL) 491 return(0); 492 ip4 = (struct sockaddr_in *)ip; 493 ip6 = (struct sockaddr_in6 *)ip; 494 SLIST_FOREACH(jis, &pr->pr_ips, entries) { 495 switch (ip->sa_family) { 496 case AF_INET: 497 jip4 = (struct sockaddr_in *) &jis->ip; 498 if (jip4->sin_family == AF_INET && 499 ip4->sin_addr.s_addr == jip4->sin_addr.s_addr) 500 return(1); 501 break; 502 case AF_INET6: 503 jip6 = (struct sockaddr_in6 *) &jis->ip; 504 if (jip6->sin6_family == AF_INET6 && 505 IN6_ARE_ADDR_EQUAL(&ip6->sin6_addr, 506 &jip6->sin6_addr)) 507 return(1); 508 break; 509 } 510 } 511 /* Ip not in list */ 512 return(0); 513 } 514 515 int 516 prison_if(struct ucred *cred, struct sockaddr *sa) 517 { 518 struct prison *pr; 519 struct sockaddr_in *sai = (struct sockaddr_in*) sa; 520 521 pr = cred->cr_prison; 522 523 if (((sai->sin_family != AF_INET) && (sai->sin_family != AF_INET6)) 524 && jail_socket_unixiproute_only) 525 return(1); 526 else if ((sai->sin_family != AF_INET) && (sai->sin_family != AF_INET6)) 527 return(0); 528 else if (jailed_ip(pr, sa)) 529 return(0); 530 return(1); 531 } 532 533 /* 534 * Returns a prison instance, or NULL on failure. 535 */ 536 static struct prison * 537 prison_find(int prid) 538 { 539 struct prison *pr; 540 541 LIST_FOREACH(pr, &allprison, pr_list) { 542 if (pr->pr_id == prid) 543 break; 544 } 545 return(pr); 546 } 547 548 static int 549 sysctl_jail_list(SYSCTL_HANDLER_ARGS) 550 { 551 struct jail_ip_storage *jip; 552 #ifdef INET6 553 struct sockaddr_in6 *jsin6; 554 #endif 555 struct sockaddr_in *jsin; 556 struct proc *p; 557 struct prison *pr; 558 unsigned int jlssize, jlsused; 559 int count, error; 560 char *jls; /* Jail list */ 561 char *oip; /* Output ip */ 562 char *fullpath, *freepath; 563 564 jlsused = 0; 565 p = curthread->td_proc; 566 567 if (jailed(p->p_ucred)) 568 return (0); 569 retry: 570 count = prisoncount; 571 572 if (count == 0) 573 return(0); 574 575 jlssize = (count * 1024); 576 jls = kmalloc(jlssize + 1, M_TEMP, M_WAITOK | M_ZERO); 577 if (count < prisoncount) { 578 kfree(jls, M_TEMP); 579 goto retry; 580 } 581 count = prisoncount; 582 583 LIST_FOREACH(pr, &allprison, pr_list) { 584 error = cache_fullpath(p, &pr->pr_root, &fullpath, &freepath); 585 if (error) 586 continue; 587 if (jlsused && jlsused < jlssize) 588 jls[jlsused++] = '\n'; 589 count = ksnprintf(jls + jlsused, (jlssize - jlsused), 590 "%d %s %s", 591 pr->pr_id, pr->pr_host, fullpath); 592 kfree(freepath, M_TEMP); 593 if (count < 0) 594 goto end; 595 jlsused += count; 596 597 /* Copy the IPS */ 598 SLIST_FOREACH(jip, &pr->pr_ips, entries) { 599 jsin = (struct sockaddr_in *)&jip->ip; 600 601 switch(jsin->sin_family) { 602 case AF_INET: 603 oip = inet_ntoa(jsin->sin_addr); 604 break; 605 #ifdef INET6 606 case AF_INET6: 607 jsin6 = (struct sockaddr_in6 *)&jip->ip; 608 oip = ip6_sprintf(&jsin6->sin6_addr); 609 break; 610 #endif 611 default: 612 oip = "?family?"; 613 break; 614 } 615 616 if ((jlssize - jlsused) < (strlen(oip) + 1)) { 617 error = ERANGE; 618 goto end; 619 } 620 count = ksnprintf(jls + jlsused, (jlssize - jlsused), 621 " %s", oip); 622 if (count < 0) 623 goto end; 624 jlsused += count; 625 } 626 } 627 628 /* 629 * The format is: 630 * pr_id <SPC> hostname1 <SPC> PATH1 <SPC> IP1 <SPC> IP2\npr_id... 631 */ 632 error = SYSCTL_OUT(req, jls, jlsused); 633 end: 634 kfree(jls, M_TEMP); 635 return(error); 636 } 637 638 SYSCTL_OID(_jail, OID_AUTO, list, CTLTYPE_STRING | CTLFLAG_RD, NULL, 0, 639 sysctl_jail_list, "A", "List of active jails"); 640 641 void 642 prison_hold(struct prison *pr) 643 { 644 pr->pr_ref++; 645 } 646 647 void 648 prison_free(struct prison *pr) 649 { 650 struct jail_ip_storage *jls; 651 KKASSERT(pr->pr_ref >= 1); 652 653 if (--pr->pr_ref > 0) 654 return; 655 656 /* Delete all ips */ 657 while (!SLIST_EMPTY(&pr->pr_ips)) { 658 jls = SLIST_FIRST(&pr->pr_ips); 659 SLIST_REMOVE_HEAD(&pr->pr_ips, entries); 660 kfree(jls, M_PRISON); 661 } 662 LIST_REMOVE(pr, pr_list); 663 prisoncount--; 664 665 if (pr->pr_linux != NULL) 666 kfree(pr->pr_linux, M_PRISON); 667 varsymset_clean(&pr->pr_varsymset); 668 cache_drop(&pr->pr_root); 669 kfree(pr, M_PRISON); 670 } 671 672 /* 673 * Check if permisson for a specific privilege is granted within jail. 674 * 675 * MPSAFE 676 */ 677 int 678 prison_priv_check(struct ucred *cred, int priv) 679 { 680 if (!jailed(cred)) 681 return (0); 682 683 switch (priv) { 684 case PRIV_CRED_SETUID: 685 case PRIV_CRED_SETEUID: 686 case PRIV_CRED_SETGID: 687 case PRIV_CRED_SETEGID: 688 case PRIV_CRED_SETGROUPS: 689 case PRIV_CRED_SETREUID: 690 case PRIV_CRED_SETREGID: 691 case PRIV_CRED_SETRESUID: 692 case PRIV_CRED_SETRESGID: 693 694 case PRIV_VFS_SYSFLAGS: 695 case PRIV_VFS_CHOWN: 696 case PRIV_VFS_CHMOD: 697 case PRIV_VFS_CHROOT: 698 case PRIV_VFS_LINK: 699 case PRIV_VFS_CHFLAGS_DEV: 700 case PRIV_VFS_REVOKE: 701 case PRIV_VFS_MKNOD_BAD: 702 case PRIV_VFS_MKNOD_WHT: 703 case PRIV_VFS_MKNOD_DIR: 704 case PRIV_VFS_SETATTR: 705 case PRIV_VFS_SETGID: 706 707 case PRIV_PROC_SETRLIMIT: 708 case PRIV_PROC_SETLOGIN: 709 710 case PRIV_SYSCTL_WRITEJAIL: 711 712 case PRIV_VARSYM_SYS: 713 714 case PRIV_SETHOSTNAME: 715 716 case PRIV_PROC_TRESPASS: 717 718 return (0); 719 720 case PRIV_UFS_QUOTAON: 721 case PRIV_UFS_QUOTAOFF: 722 case PRIV_VFS_SETQUOTA: 723 case PRIV_UFS_SETUSE: 724 case PRIV_VFS_GETQUOTA: 725 return (0); 726 727 728 case PRIV_DEBUG_UNPRIV: 729 return (0); 730 731 732 /* 733 * Allow jailed root to bind reserved ports. 734 */ 735 case PRIV_NETINET_RESERVEDPORT: 736 return (0); 737 738 739 /* 740 * Conditionally allow creating raw sockets in jail. 741 */ 742 case PRIV_NETINET_RAW: 743 if (jail_allow_raw_sockets) 744 return (0); 745 else 746 return (EPERM); 747 748 case PRIV_HAMMER_IOCTL: 749 return (0); 750 751 default: 752 753 return (EPERM); 754 } 755 } 756