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