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