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 /* 126 * jail() 127 * 128 * jail_args(syscallarg(struct jail *) jail) 129 */ 130 int 131 sys_jail(struct jail_args *uap) 132 { 133 struct prison *pr, *tpr; 134 struct jail j; 135 struct jail_v0 jv0; 136 struct thread *td = curthread; 137 int error, tryprid, i; 138 uint32_t jversion; 139 struct nlookupdata nd; 140 /* Multiip */ 141 struct sockaddr_storage *uips; /* Userland ips */ 142 struct sockaddr_in ip4addr; 143 struct jail_ip_storage *jip; 144 /* Multiip */ 145 146 error = priv_check(td, PRIV_ROOT); 147 if (error) { 148 uap->sysmsg_result = -1; 149 return (error); 150 } 151 error = copyin(uap->jail, &jversion, sizeof(jversion)); 152 if (error) { 153 uap->sysmsg_result = -1; 154 return (error); 155 } 156 pr = kmalloc(sizeof(*pr), M_PRISON, M_WAITOK | M_ZERO); 157 SLIST_INIT(&pr->pr_ips); 158 159 switch (jversion) { 160 case 0: 161 /* Single IPv4 jails. */ 162 163 error = copyin(uap->jail, &jv0, sizeof(jv0)); 164 if (error) 165 goto bail; 166 jip = kmalloc(sizeof(*jip), M_PRISON, M_WAITOK | M_ZERO); 167 ip4addr.sin_family = AF_INET; 168 ip4addr.sin_addr.s_addr = htonl(jv0.ip_number); 169 memcpy(&jip->ip, &ip4addr, sizeof(ip4addr)); 170 SLIST_INSERT_HEAD(&pr->pr_ips, jip, entries); 171 break; 172 case 1: 173 /* 174 * DragonFly multi noIP/IPv4/IPv6 jails 175 * 176 * NOTE: This version is unsupported by FreeBSD 177 * (which uses version 2 instead). 178 */ 179 180 error = copyin(uap->jail, &j, sizeof(j)); 181 if (error) 182 goto bail; 183 uips = kmalloc((sizeof(*uips) * j.n_ips), M_PRISON, 184 M_WAITOK | M_ZERO); 185 error = copyin(j.ips, uips, (sizeof(*uips) * j.n_ips)); 186 if (error) { 187 kfree(uips, M_PRISON); 188 goto bail; 189 } 190 for (i = 0; i < j.n_ips; i++) { 191 jip = kmalloc(sizeof(*jip), M_PRISON, 192 M_WAITOK | M_ZERO); 193 memcpy(&jip->ip, &uips[i], sizeof(*uips)); 194 SLIST_INSERT_HEAD(&pr->pr_ips, jip, entries); 195 } 196 kfree(uips, M_PRISON); 197 break; 198 default: 199 error = EINVAL; 200 goto bail; 201 } 202 203 error = copyinstr(j.hostname, &pr->pr_host, sizeof(pr->pr_host), 0); 204 if (error) 205 goto bail; 206 error = nlookup_init(&nd, j.path, UIO_USERSPACE, NLC_FOLLOW); 207 if (error) 208 goto nlookup_init_clean; 209 error = nlookup(&nd); 210 if (error) 211 goto nlookup_init_clean; 212 cache_copy(&nd.nl_nch, &pr->pr_root); 213 214 varsymset_init(&pr->pr_varsymset, NULL); 215 prison_ipcache_init(pr); 216 217 tryprid = lastprid + 1; 218 if (tryprid == JAIL_MAX) 219 tryprid = 1; 220 next: 221 LIST_FOREACH(tpr, &allprison, pr_list) { 222 if (tpr->pr_id != tryprid) 223 continue; 224 tryprid++; 225 if (tryprid == JAIL_MAX) { 226 error = ERANGE; 227 goto varsym_clean; 228 } 229 goto next; 230 } 231 pr->pr_id = lastprid = tryprid; 232 LIST_INSERT_HEAD(&allprison, pr, pr_list); 233 prisoncount++; 234 235 error = kern_jail_attach(pr->pr_id); 236 if (error) 237 goto jail_attach_clean; 238 239 nlookup_done(&nd); 240 uap->sysmsg_result = pr->pr_id; 241 return (0); 242 243 jail_attach_clean: 244 LIST_REMOVE(pr, pr_list); 245 varsym_clean: 246 varsymset_clean(&pr->pr_varsymset); 247 nlookup_init_clean: 248 nlookup_done(&nd); 249 bail: 250 /* Delete all ips */ 251 while (!SLIST_EMPTY(&pr->pr_ips)) { 252 jip = SLIST_FIRST(&pr->pr_ips); 253 SLIST_REMOVE_HEAD(&pr->pr_ips, entries); 254 kfree(jip, M_PRISON); 255 } 256 kfree(pr, M_PRISON); 257 return(error); 258 } 259 260 /* 261 * int jail_attach(int jid); 262 */ 263 int 264 sys_jail_attach(struct jail_attach_args *uap) 265 { 266 struct thread *td = curthread; 267 int error; 268 269 error = priv_check(td, PRIV_ROOT); 270 if (error) 271 return(error); 272 273 return(kern_jail_attach(uap->jid)); 274 } 275 276 static void 277 prison_ipcache_init(struct prison *pr) 278 { 279 struct jail_ip_storage *jis; 280 struct sockaddr_in *ip4; 281 struct sockaddr_in6 *ip6; 282 283 SLIST_FOREACH(jis, &pr->pr_ips, entries) { 284 switch (jis->ip.ss_family) { 285 case AF_INET: 286 ip4 = (struct sockaddr_in *)&jis->ip; 287 if ((ntohl(ip4->sin_addr.s_addr) >> IN_CLASSA_NSHIFT) == 288 IN_LOOPBACKNET) { 289 /* loopback address */ 290 if (pr->local_ip4 == NULL) 291 pr->local_ip4 = ip4; 292 } else { 293 /* public address */ 294 if (pr->nonlocal_ip4 == NULL) 295 pr->nonlocal_ip4 = ip4; 296 } 297 break; 298 299 case AF_INET6: 300 ip6 = (struct sockaddr_in6 *)&jis->ip; 301 if (IN6_IS_ADDR_LOOPBACK(&ip6->sin6_addr)) { 302 /* loopback address */ 303 if (pr->local_ip6 == NULL) 304 pr->local_ip6 = ip6; 305 } else { 306 /* public address */ 307 if (pr->nonlocal_ip6 == NULL) 308 pr->nonlocal_ip6 = ip6; 309 } 310 break; 311 } 312 } 313 } 314 315 /* 316 * Changes INADDR_LOOPBACK for a valid jail address. 317 * ip is in network byte order. 318 * Returns 1 if the ip is among jail valid ips. 319 * Returns 0 if is not among jail valid ips or 320 * if couldn't replace INADDR_LOOPBACK for a valid 321 * IP. 322 */ 323 int 324 prison_replace_wildcards(struct thread *td, struct sockaddr *ip) 325 { 326 struct sockaddr_in *ip4 = (struct sockaddr_in *)ip; 327 struct sockaddr_in6 *ip6 = (struct sockaddr_in6 *)ip; 328 struct prison *pr; 329 330 if (td->td_proc == NULL) 331 return (1); 332 if ((pr = td->td_proc->p_ucred->cr_prison) == NULL) 333 return (1); 334 335 if ((ip->sa_family == AF_INET && 336 ip4->sin_addr.s_addr == htonl(INADDR_ANY)) || 337 (ip->sa_family == AF_INET6 && 338 IN6_IS_ADDR_UNSPECIFIED(&ip6->sin6_addr))) 339 return (1); 340 if ((ip->sa_family == AF_INET && 341 ip4->sin_addr.s_addr == htonl(INADDR_LOOPBACK)) || 342 (ip->sa_family == AF_INET6 && 343 IN6_IS_ADDR_LOOPBACK(&ip6->sin6_addr))) { 344 if (!prison_get_local(pr, ip->sa_family, ip) && 345 !prison_get_nonlocal(pr, ip->sa_family, ip)) 346 return(0); 347 else 348 return(1); 349 } 350 if (jailed_ip(pr, ip)) 351 return(1); 352 return(0); 353 } 354 355 int 356 prison_remote_ip(struct thread *td, struct sockaddr *ip) 357 { 358 struct sockaddr_in *ip4 = (struct sockaddr_in *)ip; 359 struct sockaddr_in6 *ip6 = (struct sockaddr_in6 *)ip; 360 struct prison *pr; 361 362 if (td == NULL || td->td_proc == NULL) 363 return(1); 364 if ((pr = td->td_proc->p_ucred->cr_prison) == NULL) 365 return(1); 366 if ((ip->sa_family == AF_INET && 367 ip4->sin_addr.s_addr == htonl(INADDR_LOOPBACK)) || 368 (ip->sa_family == AF_INET6 && 369 IN6_IS_ADDR_LOOPBACK(&ip6->sin6_addr))) { 370 if (!prison_get_local(pr, ip->sa_family, ip) && 371 !prison_get_nonlocal(pr, ip->sa_family, ip)) 372 return(0); 373 else 374 return(1); 375 } 376 return(1); 377 } 378 379 /* 380 * Prison get non loopback ip: 381 * - af is the address family of the ip we want (AF_INET|AF_INET6). 382 * - If ip != NULL, put the first IP address that is not a loopback address 383 * into *ip. 384 * 385 * ip is in network by order and we don't touch it unless we find a valid ip. 386 * No matter if ip == NULL or not, we return either a valid struct sockaddr *, 387 * or NULL. This struct may not be modified. 388 */ 389 struct sockaddr * 390 prison_get_nonlocal(struct prison *pr, sa_family_t af, struct sockaddr *ip) 391 { 392 struct sockaddr_in *ip4 = (struct sockaddr_in *)ip; 393 struct sockaddr_in6 *ip6 = (struct sockaddr_in6 *)ip; 394 395 /* Check if it is cached */ 396 switch(af) { 397 case AF_INET: 398 if (ip4 != NULL && pr->nonlocal_ip4 != NULL) 399 ip4->sin_addr.s_addr = pr->nonlocal_ip4->sin_addr.s_addr; 400 return (struct sockaddr *)pr->nonlocal_ip4; 401 402 case AF_INET6: 403 if (ip6 != NULL && pr->nonlocal_ip6 != NULL) 404 ip6->sin6_addr = pr->nonlocal_ip6->sin6_addr; 405 return (struct sockaddr *)pr->nonlocal_ip6; 406 } 407 408 /* NOTREACHED */ 409 return NULL; 410 } 411 412 /* 413 * Prison get loopback ip. 414 * - af is the address family of the ip we want (AF_INET|AF_INET6). 415 * - If ip != NULL, put the first IP address that is not a loopback address 416 * into *ip. 417 * 418 * ip is in network by order and we don't touch it unless we find a valid ip. 419 * No matter if ip == NULL or not, we return either a valid struct sockaddr *, 420 * or NULL. This struct may not be modified. 421 */ 422 struct sockaddr * 423 prison_get_local(struct prison *pr, sa_family_t af, struct sockaddr *ip) 424 { 425 struct sockaddr_in *ip4 = (struct sockaddr_in *)ip; 426 struct sockaddr_in6 *ip6 = (struct sockaddr_in6 *)ip; 427 428 /* Check if it is cached */ 429 switch(af) { 430 case AF_INET: 431 if (ip4 != NULL && pr->local_ip4 != NULL) 432 ip4->sin_addr.s_addr = pr->local_ip4->sin_addr.s_addr; 433 return (struct sockaddr *)pr->local_ip4; 434 435 case AF_INET6: 436 if (ip6 != NULL && pr->local_ip6 != NULL) 437 ip6->sin6_addr = pr->local_ip6->sin6_addr; 438 return (struct sockaddr *)pr->local_ip6; 439 } 440 441 /* NOTREACHED */ 442 return NULL; 443 } 444 445 /* Check if the IP is among ours, if it is return 1, else 0 */ 446 int 447 jailed_ip(struct prison *pr, struct sockaddr *ip) 448 { 449 struct jail_ip_storage *jis; 450 struct sockaddr_in *jip4, *ip4; 451 struct sockaddr_in6 *jip6, *ip6; 452 453 if (pr == NULL) 454 return(0); 455 ip4 = (struct sockaddr_in *)ip; 456 ip6 = (struct sockaddr_in6 *)ip; 457 SLIST_FOREACH(jis, &pr->pr_ips, entries) { 458 switch (ip->sa_family) { 459 case AF_INET: 460 jip4 = (struct sockaddr_in *) &jis->ip; 461 if (jip4->sin_family == AF_INET && 462 ip4->sin_addr.s_addr == jip4->sin_addr.s_addr) 463 return(1); 464 break; 465 case AF_INET6: 466 jip6 = (struct sockaddr_in6 *) &jis->ip; 467 if (jip6->sin6_family == AF_INET6 && 468 IN6_ARE_ADDR_EQUAL(&ip6->sin6_addr, 469 &jip6->sin6_addr)) 470 return(1); 471 break; 472 } 473 } 474 /* Ip not in list */ 475 return(0); 476 } 477 478 int 479 prison_if(struct ucred *cred, struct sockaddr *sa) 480 { 481 struct prison *pr; 482 struct sockaddr_in *sai = (struct sockaddr_in*) sa; 483 484 pr = cred->cr_prison; 485 486 if (((sai->sin_family != AF_INET) && (sai->sin_family != AF_INET6)) 487 && jail_socket_unixiproute_only) 488 return(1); 489 else if ((sai->sin_family != AF_INET) && (sai->sin_family != AF_INET6)) 490 return(0); 491 else if (jailed_ip(pr, sa)) 492 return(0); 493 return(1); 494 } 495 496 /* 497 * Returns a prison instance, or NULL on failure. 498 */ 499 static struct prison * 500 prison_find(int prid) 501 { 502 struct prison *pr; 503 504 LIST_FOREACH(pr, &allprison, pr_list) { 505 if (pr->pr_id == prid) 506 break; 507 } 508 return(pr); 509 } 510 511 static int 512 sysctl_jail_list(SYSCTL_HANDLER_ARGS) 513 { 514 struct jail_ip_storage *jip; 515 #ifdef INET6 516 struct sockaddr_in6 *jsin6; 517 #endif 518 struct sockaddr_in *jsin; 519 struct proc *p; 520 struct prison *pr; 521 unsigned int jlssize, jlsused; 522 int count, error; 523 char *jls; /* Jail list */ 524 char *oip; /* Output ip */ 525 char *fullpath, *freepath; 526 527 jlsused = 0; 528 p = curthread->td_proc; 529 530 if (jailed(p->p_ucred)) 531 return (0); 532 retry: 533 count = prisoncount; 534 535 if (count == 0) 536 return(0); 537 538 jlssize = (count * 1024); 539 jls = kmalloc(jlssize + 1, M_TEMP, M_WAITOK | M_ZERO); 540 if (count < prisoncount) { 541 kfree(jls, M_TEMP); 542 goto retry; 543 } 544 count = prisoncount; 545 546 LIST_FOREACH(pr, &allprison, pr_list) { 547 error = cache_fullpath(p, &pr->pr_root, &fullpath, &freepath); 548 if (error) 549 continue; 550 if (jlsused && jlsused < jlssize) 551 jls[jlsused++] = '\n'; 552 count = ksnprintf(jls + jlsused, (jlssize - jlsused), 553 "%d %s %s", 554 pr->pr_id, pr->pr_host, fullpath); 555 kfree(freepath, M_TEMP); 556 if (count < 0) 557 goto end; 558 jlsused += count; 559 560 /* Copy the IPS */ 561 SLIST_FOREACH(jip, &pr->pr_ips, entries) { 562 jsin = (struct sockaddr_in *)&jip->ip; 563 564 switch(jsin->sin_family) { 565 case AF_INET: 566 oip = inet_ntoa(jsin->sin_addr); 567 break; 568 #ifdef INET6 569 case AF_INET6: 570 jsin6 = (struct sockaddr_in6 *)&jip->ip; 571 oip = ip6_sprintf(&jsin6->sin6_addr); 572 break; 573 #endif 574 default: 575 oip = "?family?"; 576 break; 577 } 578 579 if ((jlssize - jlsused) < (strlen(oip) + 1)) { 580 error = ERANGE; 581 goto end; 582 } 583 count = ksnprintf(jls + jlsused, (jlssize - jlsused), 584 " %s", oip); 585 if (count < 0) 586 goto end; 587 jlsused += count; 588 } 589 } 590 591 /* 592 * The format is: 593 * pr_id <SPC> hostname1 <SPC> PATH1 <SPC> IP1 <SPC> IP2\npr_id... 594 */ 595 error = SYSCTL_OUT(req, jls, jlsused); 596 end: 597 kfree(jls, M_TEMP); 598 return(error); 599 } 600 601 SYSCTL_OID(_jail, OID_AUTO, list, CTLTYPE_STRING | CTLFLAG_RD, NULL, 0, 602 sysctl_jail_list, "A", "List of active jails"); 603 604 void 605 prison_hold(struct prison *pr) 606 { 607 pr->pr_ref++; 608 } 609 610 void 611 prison_free(struct prison *pr) 612 { 613 struct jail_ip_storage *jls; 614 KKASSERT(pr->pr_ref >= 1); 615 616 if (--pr->pr_ref > 0) 617 return; 618 619 /* Delete all ips */ 620 while (!SLIST_EMPTY(&pr->pr_ips)) { 621 jls = SLIST_FIRST(&pr->pr_ips); 622 SLIST_REMOVE_HEAD(&pr->pr_ips, entries); 623 kfree(jls, M_PRISON); 624 } 625 LIST_REMOVE(pr, pr_list); 626 prisoncount--; 627 628 if (pr->pr_linux != NULL) 629 kfree(pr->pr_linux, M_PRISON); 630 varsymset_clean(&pr->pr_varsymset); 631 cache_drop(&pr->pr_root); 632 kfree(pr, M_PRISON); 633 } 634