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