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 #include <sys/cdefs.h> 11 __FBSDID("$FreeBSD$"); 12 13 #include <sys/param.h> 14 #include <sys/types.h> 15 #include <sys/kernel.h> 16 #include <sys/systm.h> 17 #include <sys/errno.h> 18 #include <sys/sysproto.h> 19 #include <sys/malloc.h> 20 #include <sys/proc.h> 21 #include <sys/taskqueue.h> 22 #include <sys/jail.h> 23 #include <sys/lock.h> 24 #include <sys/mutex.h> 25 #include <sys/namei.h> 26 #include <sys/queue.h> 27 #include <sys/socket.h> 28 #include <sys/syscallsubr.h> 29 #include <sys/sysctl.h> 30 #include <sys/vnode.h> 31 #include <net/if.h> 32 #include <netinet/in.h> 33 34 MALLOC_DEFINE(M_PRISON, "prison", "Prison structures"); 35 36 SYSCTL_DECL(_security); 37 SYSCTL_NODE(_security, OID_AUTO, jail, CTLFLAG_RW, 0, 38 "Jail rules"); 39 40 mp_fixme("these variables need a lock") 41 42 int jail_set_hostname_allowed = 1; 43 SYSCTL_INT(_security_jail, OID_AUTO, set_hostname_allowed, CTLFLAG_RW, 44 &jail_set_hostname_allowed, 0, 45 "Processes in jail can set their hostnames"); 46 47 int jail_socket_unixiproute_only = 1; 48 SYSCTL_INT(_security_jail, OID_AUTO, socket_unixiproute_only, CTLFLAG_RW, 49 &jail_socket_unixiproute_only, 0, 50 "Processes in jail are limited to creating UNIX/IPv4/route sockets only"); 51 52 int jail_sysvipc_allowed = 0; 53 SYSCTL_INT(_security_jail, OID_AUTO, sysvipc_allowed, CTLFLAG_RW, 54 &jail_sysvipc_allowed, 0, 55 "Processes in jail can use System V IPC primitives"); 56 57 int jail_getfsstatroot_only = 1; 58 SYSCTL_INT(_security_jail, OID_AUTO, getfsstate_getfsstatroot_only, CTLFLAG_RW, 59 &jail_getfsstatroot_only, 0, 60 "Processes see only their root file system in getfsstat()"); 61 62 /* allprison, lastprid, and prisoncount are protected by allprison_mtx. */ 63 struct prisonlist allprison; 64 struct mtx allprison_mtx; 65 int lastprid = 0; 66 int prisoncount = 0; 67 68 static void init_prison(void *); 69 static void prison_complete(void *context, int pending); 70 static struct prison *prison_find(int); 71 static int sysctl_jail_list(SYSCTL_HANDLER_ARGS); 72 73 static void 74 init_prison(void *data __unused) 75 { 76 77 mtx_init(&allprison_mtx, "allprison", NULL, MTX_DEF); 78 LIST_INIT(&allprison); 79 } 80 81 SYSINIT(prison, SI_SUB_INTRINSIC, SI_ORDER_ANY, init_prison, NULL); 82 83 /* 84 * MPSAFE 85 * 86 * struct jail_args { 87 * struct jail *jail; 88 * }; 89 */ 90 int 91 jail(struct thread *td, struct jail_args *uap) 92 { 93 struct nameidata nd; 94 struct prison *pr, *tpr; 95 struct jail j; 96 struct jail_attach_args jaa; 97 int error, tryprid; 98 99 error = copyin(uap->jail, &j, sizeof(j)); 100 if (error) 101 return (error); 102 if (j.version != 0) 103 return (EINVAL); 104 105 MALLOC(pr, struct prison *, sizeof(*pr), M_PRISON, M_WAITOK | M_ZERO); 106 mtx_init(&pr->pr_mtx, "jail mutex", NULL, MTX_DEF); 107 pr->pr_ref = 1; 108 error = copyinstr(j.path, &pr->pr_path, sizeof(pr->pr_path), 0); 109 if (error) 110 goto e_killmtx; 111 mtx_lock(&Giant); 112 NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_SYSSPACE, pr->pr_path, td); 113 error = namei(&nd); 114 if (error) { 115 mtx_unlock(&Giant); 116 goto e_killmtx; 117 } 118 pr->pr_root = nd.ni_vp; 119 VOP_UNLOCK(nd.ni_vp, 0, td); 120 NDFREE(&nd, NDF_ONLY_PNBUF); 121 mtx_unlock(&Giant); 122 error = copyinstr(j.hostname, &pr->pr_host, sizeof(pr->pr_host), 0); 123 if (error) 124 goto e_dropvnref; 125 pr->pr_ip = j.ip_number; 126 pr->pr_linux = NULL; 127 pr->pr_securelevel = securelevel; 128 129 /* Determine next pr_id and add prison to allprison list. */ 130 mtx_lock(&allprison_mtx); 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 tryprid++; 138 if (tryprid == JAIL_MAX) { 139 mtx_unlock(&allprison_mtx); 140 error = EAGAIN; 141 goto e_dropvnref; 142 } 143 goto next; 144 } 145 } 146 pr->pr_id = jaa.jid = lastprid = tryprid; 147 LIST_INSERT_HEAD(&allprison, pr, pr_list); 148 prisoncount++; 149 mtx_unlock(&allprison_mtx); 150 151 error = jail_attach(td, &jaa); 152 if (error) 153 goto e_dropprref; 154 mtx_lock(&pr->pr_mtx); 155 pr->pr_ref--; 156 mtx_unlock(&pr->pr_mtx); 157 td->td_retval[0] = jaa.jid; 158 return (0); 159 e_dropprref: 160 mtx_lock(&allprison_mtx); 161 LIST_REMOVE(pr, pr_list); 162 prisoncount--; 163 mtx_unlock(&allprison_mtx); 164 e_dropvnref: 165 mtx_lock(&Giant); 166 vrele(pr->pr_root); 167 mtx_unlock(&Giant); 168 e_killmtx: 169 mtx_destroy(&pr->pr_mtx); 170 FREE(pr, M_PRISON); 171 return (error); 172 } 173 174 /* 175 * MPSAFE 176 * 177 * struct jail_attach_args { 178 * int jid; 179 * }; 180 */ 181 int 182 jail_attach(struct thread *td, struct jail_attach_args *uap) 183 { 184 struct proc *p; 185 struct ucred *newcred, *oldcred; 186 struct prison *pr; 187 int error; 188 189 /* 190 * XXX: Note that there is a slight race here if two threads 191 * in the same privileged process attempt to attach to two 192 * different jails at the same time. It is important for 193 * user processes not to do this, or they might end up with 194 * a process root from one prison, but attached to the jail 195 * of another. 196 */ 197 error = suser(td); 198 if (error) 199 return (error); 200 201 p = td->td_proc; 202 mtx_lock(&allprison_mtx); 203 pr = prison_find(uap->jid); 204 if (pr == NULL) { 205 mtx_unlock(&allprison_mtx); 206 return (EINVAL); 207 } 208 pr->pr_ref++; 209 mtx_unlock(&pr->pr_mtx); 210 mtx_unlock(&allprison_mtx); 211 212 mtx_lock(&Giant); 213 vn_lock(pr->pr_root, LK_EXCLUSIVE | LK_RETRY, td); 214 if ((error = change_dir(pr->pr_root, td)) != 0) 215 goto e_unlock; 216 #ifdef MAC 217 if ((error = mac_check_vnode_chroot(td->td_ucred, pr->pr_root))) 218 goto e_unlock; 219 #endif 220 VOP_UNLOCK(pr->pr_root, 0, td); 221 change_root(pr->pr_root, td); 222 mtx_unlock(&Giant); 223 224 newcred = crget(); 225 PROC_LOCK(p); 226 oldcred = p->p_ucred; 227 setsugid(p); 228 crcopy(newcred, oldcred); 229 newcred->cr_prison = pr; 230 p->p_ucred = newcred; 231 PROC_UNLOCK(p); 232 crfree(oldcred); 233 return (0); 234 e_unlock: 235 VOP_UNLOCK(pr->pr_root, 0, td); 236 mtx_unlock(&Giant); 237 mtx_lock(&pr->pr_mtx); 238 pr->pr_ref--; 239 mtx_unlock(&pr->pr_mtx); 240 return (error); 241 } 242 243 /* 244 * Returns a locked prison instance, or NULL on failure. 245 */ 246 static struct prison * 247 prison_find(int prid) 248 { 249 struct prison *pr; 250 251 mtx_assert(&allprison_mtx, MA_OWNED); 252 LIST_FOREACH(pr, &allprison, pr_list) { 253 if (pr->pr_id == prid) { 254 mtx_lock(&pr->pr_mtx); 255 return (pr); 256 } 257 } 258 return (NULL); 259 } 260 261 void 262 prison_free(struct prison *pr) 263 { 264 265 mtx_lock(&allprison_mtx); 266 mtx_lock(&pr->pr_mtx); 267 pr->pr_ref--; 268 if (pr->pr_ref == 0) { 269 LIST_REMOVE(pr, pr_list); 270 mtx_unlock(&pr->pr_mtx); 271 prisoncount--; 272 mtx_unlock(&allprison_mtx); 273 274 TASK_INIT(&pr->pr_task, 0, prison_complete, pr); 275 taskqueue_enqueue(taskqueue_swi, &pr->pr_task); 276 return; 277 } 278 mtx_unlock(&pr->pr_mtx); 279 mtx_unlock(&allprison_mtx); 280 } 281 282 static void 283 prison_complete(void *context, int pending) 284 { 285 struct prison *pr; 286 287 pr = (struct prison *)context; 288 289 mtx_lock(&Giant); 290 vrele(pr->pr_root); 291 mtx_unlock(&Giant); 292 293 mtx_destroy(&pr->pr_mtx); 294 if (pr->pr_linux != NULL) 295 FREE(pr->pr_linux, M_PRISON); 296 FREE(pr, M_PRISON); 297 } 298 299 void 300 prison_hold(struct prison *pr) 301 { 302 303 mtx_lock(&pr->pr_mtx); 304 pr->pr_ref++; 305 mtx_unlock(&pr->pr_mtx); 306 } 307 308 u_int32_t 309 prison_getip(struct ucred *cred) 310 { 311 312 return (cred->cr_prison->pr_ip); 313 } 314 315 int 316 prison_ip(struct ucred *cred, int flag, u_int32_t *ip) 317 { 318 u_int32_t tmp; 319 320 if (!jailed(cred)) 321 return (0); 322 if (flag) 323 tmp = *ip; 324 else 325 tmp = ntohl(*ip); 326 if (tmp == INADDR_ANY) { 327 if (flag) 328 *ip = cred->cr_prison->pr_ip; 329 else 330 *ip = htonl(cred->cr_prison->pr_ip); 331 return (0); 332 } 333 if (tmp == INADDR_LOOPBACK) { 334 if (flag) 335 *ip = cred->cr_prison->pr_ip; 336 else 337 *ip = htonl(cred->cr_prison->pr_ip); 338 return (0); 339 } 340 if (cred->cr_prison->pr_ip != tmp) 341 return (1); 342 return (0); 343 } 344 345 void 346 prison_remote_ip(struct ucred *cred, int flag, u_int32_t *ip) 347 { 348 u_int32_t tmp; 349 350 if (!jailed(cred)) 351 return; 352 if (flag) 353 tmp = *ip; 354 else 355 tmp = ntohl(*ip); 356 if (tmp == INADDR_LOOPBACK) { 357 if (flag) 358 *ip = cred->cr_prison->pr_ip; 359 else 360 *ip = htonl(cred->cr_prison->pr_ip); 361 return; 362 } 363 return; 364 } 365 366 int 367 prison_if(struct ucred *cred, struct sockaddr *sa) 368 { 369 struct sockaddr_in *sai; 370 int ok; 371 372 sai = (struct sockaddr_in *)sa; 373 if ((sai->sin_family != AF_INET) && jail_socket_unixiproute_only) 374 ok = 1; 375 else if (sai->sin_family != AF_INET) 376 ok = 0; 377 else if (cred->cr_prison->pr_ip != ntohl(sai->sin_addr.s_addr)) 378 ok = 1; 379 else 380 ok = 0; 381 return (ok); 382 } 383 384 /* 385 * Return 0 if jails permit p1 to frob p2, otherwise ESRCH. 386 */ 387 int 388 prison_check(struct ucred *cred1, struct ucred *cred2) 389 { 390 391 if (jailed(cred1)) { 392 if (!jailed(cred2)) 393 return (ESRCH); 394 if (cred2->cr_prison != cred1->cr_prison) 395 return (ESRCH); 396 } 397 398 return (0); 399 } 400 401 /* 402 * Return 1 if the passed credential is in a jail, otherwise 0. 403 */ 404 int 405 jailed(struct ucred *cred) 406 { 407 408 return (cred->cr_prison != NULL); 409 } 410 411 /* 412 * Return the correct hostname for the passed credential. 413 */ 414 void 415 getcredhostname(struct ucred *cred, char *buf, size_t size) 416 { 417 418 if (jailed(cred)) { 419 mtx_lock(&cred->cr_prison->pr_mtx); 420 strlcpy(buf, cred->cr_prison->pr_host, size); 421 mtx_unlock(&cred->cr_prison->pr_mtx); 422 } else 423 strlcpy(buf, hostname, size); 424 } 425 426 /* 427 * Return 1 if the passed credential can "see" the passed mountpoint 428 * when performing a getfsstat(); otherwise, 0. 429 */ 430 int 431 prison_check_mount(struct ucred *cred, struct mount *mp) 432 { 433 434 if (jail_getfsstatroot_only && cred->cr_prison != NULL) { 435 if (cred->cr_prison->pr_root->v_mount != mp) 436 return (0); 437 } 438 return (1); 439 } 440 441 static int 442 sysctl_jail_list(SYSCTL_HANDLER_ARGS) 443 { 444 struct xprison *xp, *sxp; 445 struct prison *pr; 446 int count, error; 447 448 mtx_assert(&Giant, MA_OWNED); 449 if (jailed(req->td->td_ucred)) 450 return (0); 451 retry: 452 mtx_lock(&allprison_mtx); 453 count = prisoncount; 454 mtx_unlock(&allprison_mtx); 455 456 if (count == 0) 457 return (0); 458 459 sxp = xp = malloc(sizeof(*xp) * count, M_TEMP, M_WAITOK | M_ZERO); 460 mtx_lock(&allprison_mtx); 461 if (count != prisoncount) { 462 mtx_unlock(&allprison_mtx); 463 free(sxp, M_TEMP); 464 goto retry; 465 } 466 467 LIST_FOREACH(pr, &allprison, pr_list) { 468 mtx_lock(&pr->pr_mtx); 469 xp->pr_version = XPRISON_VERSION; 470 xp->pr_id = pr->pr_id; 471 strlcpy(xp->pr_path, pr->pr_path, sizeof(xp->pr_path)); 472 strlcpy(xp->pr_host, pr->pr_host, sizeof(xp->pr_host)); 473 xp->pr_ip = pr->pr_ip; 474 mtx_unlock(&pr->pr_mtx); 475 xp++; 476 } 477 mtx_unlock(&allprison_mtx); 478 479 error = SYSCTL_OUT(req, sxp, sizeof(*sxp) * count); 480 free(sxp, M_TEMP); 481 if (error) 482 return (error); 483 return (0); 484 } 485 486 SYSCTL_OID(_security_jail, OID_AUTO, list, CTLTYPE_STRUCT | CTLFLAG_RD, 487 NULL, 0, sysctl_jail_list, "S", "List of active jails"); 488 489 static int 490 sysctl_jail_jailed(SYSCTL_HANDLER_ARGS) 491 { 492 int error, injail; 493 494 injail = jailed(req->td->td_ucred); 495 error = SYSCTL_OUT(req, &injail, sizeof(injail)); 496 497 return (error); 498 } 499 SYSCTL_PROC(_security_jail, OID_AUTO, jailed, CTLTYPE_INT | CTLFLAG_RD, 500 NULL, 0, sysctl_jail_jailed, "I", "Process in jail?"); 501