kern_jail.c revision 185404
1/*- 2 * Copyright (c) 1999 Poul-Henning Kamp. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * 2. Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 13 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 14 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 16 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 17 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 18 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 19 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 20 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 21 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 22 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 23 * SUCH DAMAGE. 24 */ 25 26#include <sys/cdefs.h> 27__FBSDID("$FreeBSD: head/sys/kern/kern_jail.c 185404 2008-11-28 19:23:46Z bz $"); 28 29#include "opt_mac.h" 30 31#include <sys/param.h> 32#include <sys/types.h> 33#include <sys/kernel.h> 34#include <sys/systm.h> 35#include <sys/errno.h> 36#include <sys/sysproto.h> 37#include <sys/malloc.h> 38#include <sys/priv.h> 39#include <sys/proc.h> 40#include <sys/taskqueue.h> 41#include <sys/fcntl.h> 42#include <sys/jail.h> 43#include <sys/lock.h> 44#include <sys/mutex.h> 45#include <sys/sx.h> 46#include <sys/namei.h> 47#include <sys/mount.h> 48#include <sys/queue.h> 49#include <sys/socket.h> 50#include <sys/syscallsubr.h> 51#include <sys/sysctl.h> 52#include <sys/vnode.h> 53#include <sys/vimage.h> 54#include <sys/osd.h> 55#include <net/if.h> 56#include <netinet/in.h> 57 58#include <security/mac/mac_framework.h> 59 60MALLOC_DEFINE(M_PRISON, "prison", "Prison structures"); 61 62SYSCTL_NODE(_security, OID_AUTO, jail, CTLFLAG_RW, 0, 63 "Jail rules"); 64 65int jail_set_hostname_allowed = 1; 66SYSCTL_INT(_security_jail, OID_AUTO, set_hostname_allowed, CTLFLAG_RW, 67 &jail_set_hostname_allowed, 0, 68 "Processes in jail can set their hostnames"); 69 70int jail_socket_unixiproute_only = 1; 71SYSCTL_INT(_security_jail, OID_AUTO, socket_unixiproute_only, CTLFLAG_RW, 72 &jail_socket_unixiproute_only, 0, 73 "Processes in jail are limited to creating UNIX/IPv4/route sockets only"); 74 75int jail_sysvipc_allowed = 0; 76SYSCTL_INT(_security_jail, OID_AUTO, sysvipc_allowed, CTLFLAG_RW, 77 &jail_sysvipc_allowed, 0, 78 "Processes in jail can use System V IPC primitives"); 79 80static int jail_enforce_statfs = 2; 81SYSCTL_INT(_security_jail, OID_AUTO, enforce_statfs, CTLFLAG_RW, 82 &jail_enforce_statfs, 0, 83 "Processes in jail cannot see all mounted file systems"); 84 85int jail_allow_raw_sockets = 0; 86SYSCTL_INT(_security_jail, OID_AUTO, allow_raw_sockets, CTLFLAG_RW, 87 &jail_allow_raw_sockets, 0, 88 "Prison root can create raw sockets"); 89 90int jail_chflags_allowed = 0; 91SYSCTL_INT(_security_jail, OID_AUTO, chflags_allowed, CTLFLAG_RW, 92 &jail_chflags_allowed, 0, 93 "Processes in jail can alter system file flags"); 94 95int jail_mount_allowed = 0; 96SYSCTL_INT(_security_jail, OID_AUTO, mount_allowed, CTLFLAG_RW, 97 &jail_mount_allowed, 0, 98 "Processes in jail can mount/unmount jail-friendly file systems"); 99 100/* allprison, lastprid, and prisoncount are protected by allprison_lock. */ 101struct prisonlist allprison; 102struct sx allprison_lock; 103int lastprid = 0; 104int prisoncount = 0; 105 106static void init_prison(void *); 107static void prison_complete(void *context, int pending); 108static int sysctl_jail_list(SYSCTL_HANDLER_ARGS); 109 110static void 111init_prison(void *data __unused) 112{ 113 114 sx_init(&allprison_lock, "allprison"); 115 LIST_INIT(&allprison); 116} 117 118SYSINIT(prison, SI_SUB_INTRINSIC, SI_ORDER_ANY, init_prison, NULL); 119 120/* 121 * struct jail_args { 122 * struct jail *jail; 123 * }; 124 */ 125int 126jail(struct thread *td, struct jail_args *uap) 127{ 128 struct nameidata nd; 129 struct prison *pr, *tpr; 130 struct jail j; 131 struct jail_attach_args jaa; 132 int vfslocked, error, tryprid; 133 134 error = copyin(uap->jail, &j, sizeof(j)); 135 if (error) 136 return (error); 137 if (j.version != 0) 138 return (EINVAL); 139 140 pr = malloc(sizeof(*pr), M_PRISON, M_WAITOK | M_ZERO); 141 mtx_init(&pr->pr_mtx, "jail mutex", NULL, MTX_DEF); 142 pr->pr_ref = 1; 143 error = copyinstr(j.path, &pr->pr_path, sizeof(pr->pr_path), 0); 144 if (error) 145 goto e_killmtx; 146 NDINIT(&nd, LOOKUP, MPSAFE | FOLLOW | LOCKLEAF, UIO_SYSSPACE, 147 pr->pr_path, td); 148 error = namei(&nd); 149 if (error) 150 goto e_killmtx; 151 vfslocked = NDHASGIANT(&nd); 152 pr->pr_root = nd.ni_vp; 153 VOP_UNLOCK(nd.ni_vp, 0); 154 NDFREE(&nd, NDF_ONLY_PNBUF); 155 VFS_UNLOCK_GIANT(vfslocked); 156 error = copyinstr(j.hostname, &pr->pr_host, sizeof(pr->pr_host), 0); 157 if (error) 158 goto e_dropvnref; 159 pr->pr_ip = j.ip_number; 160 pr->pr_linux = NULL; 161 pr->pr_securelevel = securelevel; 162 bzero(&pr->pr_osd, sizeof(pr->pr_osd)); 163 164 /* Determine next pr_id and add prison to allprison list. */ 165 sx_xlock(&allprison_lock); 166 tryprid = lastprid + 1; 167 if (tryprid == JAIL_MAX) 168 tryprid = 1; 169next: 170 LIST_FOREACH(tpr, &allprison, pr_list) { 171 if (tpr->pr_id == tryprid) { 172 tryprid++; 173 if (tryprid == JAIL_MAX) { 174 sx_xunlock(&allprison_lock); 175 error = EAGAIN; 176 goto e_dropvnref; 177 } 178 goto next; 179 } 180 } 181 pr->pr_id = jaa.jid = lastprid = tryprid; 182 LIST_INSERT_HEAD(&allprison, pr, pr_list); 183 prisoncount++; 184 sx_xunlock(&allprison_lock); 185 186 error = jail_attach(td, &jaa); 187 if (error) 188 goto e_dropprref; 189 mtx_lock(&pr->pr_mtx); 190 pr->pr_ref--; 191 mtx_unlock(&pr->pr_mtx); 192 td->td_retval[0] = jaa.jid; 193 return (0); 194e_dropprref: 195 sx_xlock(&allprison_lock); 196 LIST_REMOVE(pr, pr_list); 197 prisoncount--; 198 sx_xunlock(&allprison_lock); 199e_dropvnref: 200 vfslocked = VFS_LOCK_GIANT(pr->pr_root->v_mount); 201 vrele(pr->pr_root); 202 VFS_UNLOCK_GIANT(vfslocked); 203e_killmtx: 204 mtx_destroy(&pr->pr_mtx); 205 free(pr, M_PRISON); 206 return (error); 207} 208 209/* 210 * struct jail_attach_args { 211 * int jid; 212 * }; 213 */ 214int 215jail_attach(struct thread *td, struct jail_attach_args *uap) 216{ 217 struct proc *p; 218 struct ucred *newcred, *oldcred; 219 struct prison *pr; 220 int vfslocked, error; 221 222 /* 223 * XXX: Note that there is a slight race here if two threads 224 * in the same privileged process attempt to attach to two 225 * different jails at the same time. It is important for 226 * user processes not to do this, or they might end up with 227 * a process root from one prison, but attached to the jail 228 * of another. 229 */ 230 error = priv_check(td, PRIV_JAIL_ATTACH); 231 if (error) 232 return (error); 233 234 p = td->td_proc; 235 sx_slock(&allprison_lock); 236 pr = prison_find(uap->jid); 237 if (pr == NULL) { 238 sx_sunlock(&allprison_lock); 239 return (EINVAL); 240 } 241 pr->pr_ref++; 242 mtx_unlock(&pr->pr_mtx); 243 sx_sunlock(&allprison_lock); 244 245 vfslocked = VFS_LOCK_GIANT(pr->pr_root->v_mount); 246 vn_lock(pr->pr_root, LK_EXCLUSIVE | LK_RETRY); 247 if ((error = change_dir(pr->pr_root, td)) != 0) 248 goto e_unlock; 249#ifdef MAC 250 if ((error = mac_vnode_check_chroot(td->td_ucred, pr->pr_root))) 251 goto e_unlock; 252#endif 253 VOP_UNLOCK(pr->pr_root, 0); 254 change_root(pr->pr_root, td); 255 VFS_UNLOCK_GIANT(vfslocked); 256 257 newcred = crget(); 258 PROC_LOCK(p); 259 oldcred = p->p_ucred; 260 setsugid(p); 261 crcopy(newcred, oldcred); 262 newcred->cr_prison = pr; 263 p->p_ucred = newcred; 264 PROC_UNLOCK(p); 265 crfree(oldcred); 266 return (0); 267e_unlock: 268 VOP_UNLOCK(pr->pr_root, 0); 269 VFS_UNLOCK_GIANT(vfslocked); 270 mtx_lock(&pr->pr_mtx); 271 pr->pr_ref--; 272 mtx_unlock(&pr->pr_mtx); 273 return (error); 274} 275 276/* 277 * Returns a locked prison instance, or NULL on failure. 278 */ 279struct prison * 280prison_find(int prid) 281{ 282 struct prison *pr; 283 284 sx_assert(&allprison_lock, SX_LOCKED); 285 LIST_FOREACH(pr, &allprison, pr_list) { 286 if (pr->pr_id == prid) { 287 mtx_lock(&pr->pr_mtx); 288 if (pr->pr_ref == 0) { 289 mtx_unlock(&pr->pr_mtx); 290 break; 291 } 292 return (pr); 293 } 294 } 295 return (NULL); 296} 297 298void 299prison_free_locked(struct prison *pr) 300{ 301 302 mtx_assert(&pr->pr_mtx, MA_OWNED); 303 pr->pr_ref--; 304 if (pr->pr_ref == 0) { 305 mtx_unlock(&pr->pr_mtx); 306 TASK_INIT(&pr->pr_task, 0, prison_complete, pr); 307 taskqueue_enqueue(taskqueue_thread, &pr->pr_task); 308 return; 309 } 310 mtx_unlock(&pr->pr_mtx); 311} 312 313void 314prison_free(struct prison *pr) 315{ 316 317 mtx_lock(&pr->pr_mtx); 318 prison_free_locked(pr); 319} 320 321static void 322prison_complete(void *context, int pending) 323{ 324 struct prison *pr; 325 int vfslocked; 326 327 pr = (struct prison *)context; 328 329 sx_xlock(&allprison_lock); 330 LIST_REMOVE(pr, pr_list); 331 prisoncount--; 332 sx_xunlock(&allprison_lock); 333 334 /* Free all OSD associated to this jail. */ 335 osd_jail_exit(pr); 336 337 vfslocked = VFS_LOCK_GIANT(pr->pr_root->v_mount); 338 vrele(pr->pr_root); 339 VFS_UNLOCK_GIANT(vfslocked); 340 341 mtx_destroy(&pr->pr_mtx); 342 if (pr->pr_linux != NULL) 343 free(pr->pr_linux, M_PRISON); 344 free(pr, M_PRISON); 345} 346 347void 348prison_hold_locked(struct prison *pr) 349{ 350 351 mtx_assert(&pr->pr_mtx, MA_OWNED); 352 KASSERT(pr->pr_ref > 0, 353 ("Trying to hold dead prison (id=%d).", pr->pr_id)); 354 pr->pr_ref++; 355} 356 357void 358prison_hold(struct prison *pr) 359{ 360 361 mtx_lock(&pr->pr_mtx); 362 prison_hold_locked(pr); 363 mtx_unlock(&pr->pr_mtx); 364} 365 366u_int32_t 367prison_getip(struct ucred *cred) 368{ 369 370 return (cred->cr_prison->pr_ip); 371} 372 373int 374prison_ip(struct ucred *cred, int flag, u_int32_t *ip) 375{ 376 u_int32_t tmp; 377 378 if (!jailed(cred)) 379 return (0); 380 if (flag) 381 tmp = *ip; 382 else 383 tmp = ntohl(*ip); 384 if (tmp == INADDR_ANY) { 385 if (flag) 386 *ip = cred->cr_prison->pr_ip; 387 else 388 *ip = htonl(cred->cr_prison->pr_ip); 389 return (0); 390 } 391 if (tmp == INADDR_LOOPBACK) { 392 if (flag) 393 *ip = cred->cr_prison->pr_ip; 394 else 395 *ip = htonl(cred->cr_prison->pr_ip); 396 return (0); 397 } 398 if (cred->cr_prison->pr_ip != tmp) 399 return (1); 400 return (0); 401} 402 403void 404prison_remote_ip(struct ucred *cred, int flag, u_int32_t *ip) 405{ 406 u_int32_t tmp; 407 408 if (!jailed(cred)) 409 return; 410 if (flag) 411 tmp = *ip; 412 else 413 tmp = ntohl(*ip); 414 if (tmp == INADDR_LOOPBACK) { 415 if (flag) 416 *ip = cred->cr_prison->pr_ip; 417 else 418 *ip = htonl(cred->cr_prison->pr_ip); 419 return; 420 } 421 return; 422} 423 424int 425prison_if(struct ucred *cred, struct sockaddr *sa) 426{ 427 struct sockaddr_in *sai; 428 int ok; 429 430 sai = (struct sockaddr_in *)sa; 431 if ((sai->sin_family != AF_INET) && jail_socket_unixiproute_only) 432 ok = 1; 433 else if (sai->sin_family != AF_INET) 434 ok = 0; 435 else if (cred->cr_prison->pr_ip != ntohl(sai->sin_addr.s_addr)) 436 ok = 1; 437 else 438 ok = 0; 439 return (ok); 440} 441 442/* 443 * Return 0 if jails permit p1 to frob p2, otherwise ESRCH. 444 */ 445int 446prison_check(struct ucred *cred1, struct ucred *cred2) 447{ 448 449 if (jailed(cred1)) { 450 if (!jailed(cred2)) 451 return (ESRCH); 452 if (cred2->cr_prison != cred1->cr_prison) 453 return (ESRCH); 454 } 455 456 return (0); 457} 458 459/* 460 * Return 1 if the passed credential is in a jail, otherwise 0. 461 */ 462int 463jailed(struct ucred *cred) 464{ 465 466 return (cred->cr_prison != NULL); 467} 468 469/* 470 * Return the correct hostname for the passed credential. 471 */ 472void 473getcredhostname(struct ucred *cred, char *buf, size_t size) 474{ 475 INIT_VPROCG(cred->cr_vimage->v_procg); 476 477 if (jailed(cred)) { 478 mtx_lock(&cred->cr_prison->pr_mtx); 479 strlcpy(buf, cred->cr_prison->pr_host, size); 480 mtx_unlock(&cred->cr_prison->pr_mtx); 481 } else { 482 mtx_lock(&hostname_mtx); 483 strlcpy(buf, V_hostname, size); 484 mtx_unlock(&hostname_mtx); 485 } 486} 487 488/* 489 * Determine whether the subject represented by cred can "see" 490 * status of a mount point. 491 * Returns: 0 for permitted, ENOENT otherwise. 492 * XXX: This function should be called cr_canseemount() and should be 493 * placed in kern_prot.c. 494 */ 495int 496prison_canseemount(struct ucred *cred, struct mount *mp) 497{ 498 struct prison *pr; 499 struct statfs *sp; 500 size_t len; 501 502 if (!jailed(cred) || jail_enforce_statfs == 0) 503 return (0); 504 pr = cred->cr_prison; 505 if (pr->pr_root->v_mount == mp) 506 return (0); 507 if (jail_enforce_statfs == 2) 508 return (ENOENT); 509 /* 510 * If jail's chroot directory is set to "/" we should be able to see 511 * all mount-points from inside a jail. 512 * This is ugly check, but this is the only situation when jail's 513 * directory ends with '/'. 514 */ 515 if (strcmp(pr->pr_path, "/") == 0) 516 return (0); 517 len = strlen(pr->pr_path); 518 sp = &mp->mnt_stat; 519 if (strncmp(pr->pr_path, sp->f_mntonname, len) != 0) 520 return (ENOENT); 521 /* 522 * Be sure that we don't have situation where jail's root directory 523 * is "/some/path" and mount point is "/some/pathpath". 524 */ 525 if (sp->f_mntonname[len] != '\0' && sp->f_mntonname[len] != '/') 526 return (ENOENT); 527 return (0); 528} 529 530void 531prison_enforce_statfs(struct ucred *cred, struct mount *mp, struct statfs *sp) 532{ 533 char jpath[MAXPATHLEN]; 534 struct prison *pr; 535 size_t len; 536 537 if (!jailed(cred) || jail_enforce_statfs == 0) 538 return; 539 pr = cred->cr_prison; 540 if (prison_canseemount(cred, mp) != 0) { 541 bzero(sp->f_mntonname, sizeof(sp->f_mntonname)); 542 strlcpy(sp->f_mntonname, "[restricted]", 543 sizeof(sp->f_mntonname)); 544 return; 545 } 546 if (pr->pr_root->v_mount == mp) { 547 /* 548 * Clear current buffer data, so we are sure nothing from 549 * the valid path left there. 550 */ 551 bzero(sp->f_mntonname, sizeof(sp->f_mntonname)); 552 *sp->f_mntonname = '/'; 553 return; 554 } 555 /* 556 * If jail's chroot directory is set to "/" we should be able to see 557 * all mount-points from inside a jail. 558 */ 559 if (strcmp(pr->pr_path, "/") == 0) 560 return; 561 len = strlen(pr->pr_path); 562 strlcpy(jpath, sp->f_mntonname + len, sizeof(jpath)); 563 /* 564 * Clear current buffer data, so we are sure nothing from 565 * the valid path left there. 566 */ 567 bzero(sp->f_mntonname, sizeof(sp->f_mntonname)); 568 if (*jpath == '\0') { 569 /* Should never happen. */ 570 *sp->f_mntonname = '/'; 571 } else { 572 strlcpy(sp->f_mntonname, jpath, sizeof(sp->f_mntonname)); 573 } 574} 575 576/* 577 * Check with permission for a specific privilege is granted within jail. We 578 * have a specific list of accepted privileges; the rest are denied. 579 */ 580int 581prison_priv_check(struct ucred *cred, int priv) 582{ 583 584 if (!jailed(cred)) 585 return (0); 586 587 switch (priv) { 588 589 /* 590 * Allow ktrace privileges for root in jail. 591 */ 592 case PRIV_KTRACE: 593 594#if 0 595 /* 596 * Allow jailed processes to configure audit identity and 597 * submit audit records (login, etc). In the future we may 598 * want to further refine the relationship between audit and 599 * jail. 600 */ 601 case PRIV_AUDIT_GETAUDIT: 602 case PRIV_AUDIT_SETAUDIT: 603 case PRIV_AUDIT_SUBMIT: 604#endif 605 606 /* 607 * Allow jailed processes to manipulate process UNIX 608 * credentials in any way they see fit. 609 */ 610 case PRIV_CRED_SETUID: 611 case PRIV_CRED_SETEUID: 612 case PRIV_CRED_SETGID: 613 case PRIV_CRED_SETEGID: 614 case PRIV_CRED_SETGROUPS: 615 case PRIV_CRED_SETREUID: 616 case PRIV_CRED_SETREGID: 617 case PRIV_CRED_SETRESUID: 618 case PRIV_CRED_SETRESGID: 619 620 /* 621 * Jail implements visibility constraints already, so allow 622 * jailed root to override uid/gid-based constraints. 623 */ 624 case PRIV_SEEOTHERGIDS: 625 case PRIV_SEEOTHERUIDS: 626 627 /* 628 * Jail implements inter-process debugging limits already, so 629 * allow jailed root various debugging privileges. 630 */ 631 case PRIV_DEBUG_DIFFCRED: 632 case PRIV_DEBUG_SUGID: 633 case PRIV_DEBUG_UNPRIV: 634 635 /* 636 * Allow jail to set various resource limits and login 637 * properties, and for now, exceed process resource limits. 638 */ 639 case PRIV_PROC_LIMIT: 640 case PRIV_PROC_SETLOGIN: 641 case PRIV_PROC_SETRLIMIT: 642 643 /* 644 * System V and POSIX IPC privileges are granted in jail. 645 */ 646 case PRIV_IPC_READ: 647 case PRIV_IPC_WRITE: 648 case PRIV_IPC_ADMIN: 649 case PRIV_IPC_MSGSIZE: 650 case PRIV_MQ_ADMIN: 651 652 /* 653 * Jail implements its own inter-process limits, so allow 654 * root processes in jail to change scheduling on other 655 * processes in the same jail. Likewise for signalling. 656 */ 657 case PRIV_SCHED_DIFFCRED: 658 case PRIV_SIGNAL_DIFFCRED: 659 case PRIV_SIGNAL_SUGID: 660 661 /* 662 * Allow jailed processes to write to sysctls marked as jail 663 * writable. 664 */ 665 case PRIV_SYSCTL_WRITEJAIL: 666 667 /* 668 * Allow root in jail to manage a variety of quota 669 * properties. These should likely be conditional on a 670 * configuration option. 671 */ 672 case PRIV_VFS_GETQUOTA: 673 case PRIV_VFS_SETQUOTA: 674 675 /* 676 * Since Jail relies on chroot() to implement file system 677 * protections, grant many VFS privileges to root in jail. 678 * Be careful to exclude mount-related and NFS-related 679 * privileges. 680 */ 681 case PRIV_VFS_READ: 682 case PRIV_VFS_WRITE: 683 case PRIV_VFS_ADMIN: 684 case PRIV_VFS_EXEC: 685 case PRIV_VFS_LOOKUP: 686 case PRIV_VFS_BLOCKRESERVE: /* XXXRW: Slightly surprising. */ 687 case PRIV_VFS_CHFLAGS_DEV: 688 case PRIV_VFS_CHOWN: 689 case PRIV_VFS_CHROOT: 690 case PRIV_VFS_RETAINSUGID: 691 case PRIV_VFS_FCHROOT: 692 case PRIV_VFS_LINK: 693 case PRIV_VFS_SETGID: 694 case PRIV_VFS_STAT: 695 case PRIV_VFS_STICKYFILE: 696 return (0); 697 698 /* 699 * Depending on the global setting, allow privilege of 700 * setting system flags. 701 */ 702 case PRIV_VFS_SYSFLAGS: 703 if (jail_chflags_allowed) 704 return (0); 705 else 706 return (EPERM); 707 708 /* 709 * Depending on the global setting, allow privilege of 710 * mounting/unmounting file systems. 711 */ 712 case PRIV_VFS_MOUNT: 713 case PRIV_VFS_UNMOUNT: 714 case PRIV_VFS_MOUNT_NONUSER: 715 case PRIV_VFS_MOUNT_OWNER: 716 if (jail_mount_allowed) 717 return (0); 718 else 719 return (EPERM); 720 721 /* 722 * Allow jailed root to bind reserved ports and reuse in-use 723 * ports. 724 */ 725 case PRIV_NETINET_RESERVEDPORT: 726 case PRIV_NETINET_REUSEPORT: 727 return (0); 728 729 /* 730 * Allow jailed root to set certian IPv4/6 (option) headers. 731 */ 732 case PRIV_NETINET_SETHDROPTS: 733 return (0); 734 735 /* 736 * Conditionally allow creating raw sockets in jail. 737 */ 738 case PRIV_NETINET_RAW: 739 if (jail_allow_raw_sockets) 740 return (0); 741 else 742 return (EPERM); 743 744 /* 745 * Since jail implements its own visibility limits on netstat 746 * sysctls, allow getcred. This allows identd to work in 747 * jail. 748 */ 749 case PRIV_NETINET_GETCRED: 750 return (0); 751 752 default: 753 /* 754 * In all remaining cases, deny the privilege request. This 755 * includes almost all network privileges, many system 756 * configuration privileges. 757 */ 758 return (EPERM); 759 } 760} 761 762static int 763sysctl_jail_list(SYSCTL_HANDLER_ARGS) 764{ 765 struct xprison *xp, *sxp; 766 struct prison *pr; 767 int count, error; 768 769 if (jailed(req->td->td_ucred)) 770 return (0); 771 772 sx_slock(&allprison_lock); 773 if ((count = prisoncount) == 0) { 774 sx_sunlock(&allprison_lock); 775 return (0); 776 } 777 778 sxp = xp = malloc(sizeof(*xp) * count, M_TEMP, M_WAITOK | M_ZERO); 779 780 LIST_FOREACH(pr, &allprison, pr_list) { 781 xp->pr_version = XPRISON_VERSION; 782 xp->pr_id = pr->pr_id; 783 xp->pr_ip = pr->pr_ip; 784 strlcpy(xp->pr_path, pr->pr_path, sizeof(xp->pr_path)); 785 mtx_lock(&pr->pr_mtx); 786 strlcpy(xp->pr_host, pr->pr_host, sizeof(xp->pr_host)); 787 mtx_unlock(&pr->pr_mtx); 788 xp++; 789 } 790 sx_sunlock(&allprison_lock); 791 792 error = SYSCTL_OUT(req, sxp, sizeof(*sxp) * count); 793 free(sxp, M_TEMP); 794 return (error); 795} 796 797SYSCTL_OID(_security_jail, OID_AUTO, list, CTLTYPE_STRUCT | CTLFLAG_RD, 798 NULL, 0, sysctl_jail_list, "S", "List of active jails"); 799 800static int 801sysctl_jail_jailed(SYSCTL_HANDLER_ARGS) 802{ 803 int error, injail; 804 805 injail = jailed(req->td->td_ucred); 806 error = SYSCTL_OUT(req, &injail, sizeof(injail)); 807 808 return (error); 809} 810SYSCTL_PROC(_security_jail, OID_AUTO, jailed, CTLTYPE_INT | CTLFLAG_RD, 811 NULL, 0, sysctl_jail_jailed, "I", "Process in jail?"); 812