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 * ----------------------------------------------------------------------------
10 #include <sys/cdefs.h>
11 __FBSDID("$FreeBSD$");
15 #include <sys/param.h>
16 #include <sys/types.h>
17 #include <sys/kernel.h>
18 #include <sys/systm.h>
19 #include <sys/errno.h>
20 #include <sys/sysproto.h>
21 #include <sys/malloc.h>
24 #include <sys/taskqueue.h>
25 #include <sys/fcntl.h>
28 #include <sys/mutex.h>
30 #include <sys/namei.h>
31 #include <sys/mount.h>
32 #include <sys/queue.h>
33 #include <sys/socket.h>
34 #include <sys/syscallsubr.h>
35 #include <sys/sysctl.h>
36 #include <sys/vnode.h>
37 #include <sys/vimage.h>
39 #include <netinet/in.h>
41 #include <security/mac/mac_framework.h>
43 MALLOC_DEFINE(M_PRISON
, "prison", "Prison structures");
45 SYSCTL_NODE(_security
, OID_AUTO
, jail
, CTLFLAG_RW
, 0,
48 int jail_set_hostname_allowed
= 1;
49 SYSCTL_INT(_security_jail
, OID_AUTO
, set_hostname_allowed
, CTLFLAG_RW
,
50 &jail_set_hostname_allowed
, 0,
51 "Processes in jail can set their hostnames");
53 int jail_socket_unixiproute_only
= 1;
54 SYSCTL_INT(_security_jail
, OID_AUTO
, socket_unixiproute_only
, CTLFLAG_RW
,
55 &jail_socket_unixiproute_only
, 0,
56 "Processes in jail are limited to creating UNIX/IPv4/route sockets only");
58 int jail_sysvipc_allowed
= 0;
59 SYSCTL_INT(_security_jail
, OID_AUTO
, sysvipc_allowed
, CTLFLAG_RW
,
60 &jail_sysvipc_allowed
, 0,
61 "Processes in jail can use System V IPC primitives");
63 static int jail_enforce_statfs
= 2;
64 SYSCTL_INT(_security_jail
, OID_AUTO
, enforce_statfs
, CTLFLAG_RW
,
65 &jail_enforce_statfs
, 0,
66 "Processes in jail cannot see all mounted file systems");
68 int jail_allow_raw_sockets
= 0;
69 SYSCTL_INT(_security_jail
, OID_AUTO
, allow_raw_sockets
, CTLFLAG_RW
,
70 &jail_allow_raw_sockets
, 0,
71 "Prison root can create raw sockets");
73 int jail_chflags_allowed
= 0;
74 SYSCTL_INT(_security_jail
, OID_AUTO
, chflags_allowed
, CTLFLAG_RW
,
75 &jail_chflags_allowed
, 0,
76 "Processes in jail can alter system file flags");
78 int jail_mount_allowed
= 0;
79 SYSCTL_INT(_security_jail
, OID_AUTO
, mount_allowed
, CTLFLAG_RW
,
80 &jail_mount_allowed
, 0,
81 "Processes in jail can mount/unmount jail-friendly file systems");
83 /* allprison, lastprid, and prisoncount are protected by allprison_lock. */
84 struct prisonlist allprison
;
85 struct sx allprison_lock
;
90 * List of jail services. Protected by allprison_lock.
92 TAILQ_HEAD(prison_services_head
, prison_service
);
93 static struct prison_services_head prison_services
=
94 TAILQ_HEAD_INITIALIZER(prison_services
);
95 static int prison_service_slots
= 0;
97 struct prison_service
{
98 prison_create_t ps_create
;
99 prison_destroy_t ps_destroy
;
101 TAILQ_ENTRY(prison_service
) ps_next
;
105 static void init_prison(void *);
106 static void prison_complete(void *context
, int pending
);
107 static int sysctl_jail_list(SYSCTL_HANDLER_ARGS
);
110 init_prison(void *data __unused
)
113 sx_init(&allprison_lock
, "allprison");
114 LIST_INIT(&allprison
);
117 SYSINIT(prison
, SI_SUB_INTRINSIC
, SI_ORDER_ANY
, init_prison
, NULL
);
125 jail(struct thread
*td
, struct jail_args
*uap
)
128 struct prison
*pr
, *tpr
;
129 struct prison_service
*psrv
;
131 struct jail_attach_args jaa
;
132 int vfslocked
, error
, tryprid
;
134 error
= copyin(uap
->jail
, &j
, sizeof(j
));
140 MALLOC(pr
, struct prison
*, sizeof(*pr
), M_PRISON
, M_WAITOK
| M_ZERO
);
141 mtx_init(&pr
->pr_mtx
, "jail mutex", NULL
, MTX_DEF
);
143 error
= copyinstr(j
.path
, &pr
->pr_path
, sizeof(pr
->pr_path
), 0);
146 NDINIT(&nd
, LOOKUP
, MPSAFE
| FOLLOW
| LOCKLEAF
, UIO_SYSSPACE
,
151 vfslocked
= NDHASGIANT(&nd
);
152 pr
->pr_root
= nd
.ni_vp
;
153 VOP_UNLOCK(nd
.ni_vp
, 0);
154 NDFREE(&nd
, NDF_ONLY_PNBUF
);
155 VFS_UNLOCK_GIANT(vfslocked
);
156 error
= copyinstr(j
.hostname
, &pr
->pr_host
, sizeof(pr
->pr_host
), 0);
159 pr
->pr_ip
= j
.ip_number
;
161 pr
->pr_securelevel
= securelevel
;
162 if (prison_service_slots
== 0)
165 pr
->pr_slots
= malloc(sizeof(*pr
->pr_slots
) * prison_service_slots
,
166 M_PRISON
, M_ZERO
| M_WAITOK
);
169 /* Determine next pr_id and add prison to allprison list. */
170 sx_xlock(&allprison_lock
);
171 tryprid
= lastprid
+ 1;
172 if (tryprid
== JAIL_MAX
)
175 LIST_FOREACH(tpr
, &allprison
, pr_list
) {
176 if (tpr
->pr_id
== tryprid
) {
178 if (tryprid
== JAIL_MAX
) {
179 sx_xunlock(&allprison_lock
);
186 pr
->pr_id
= jaa
.jid
= lastprid
= tryprid
;
187 LIST_INSERT_HEAD(&allprison
, pr
, pr_list
);
189 sx_downgrade(&allprison_lock
);
190 TAILQ_FOREACH(psrv
, &prison_services
, ps_next
) {
191 psrv
->ps_create(psrv
, pr
);
193 sx_sunlock(&allprison_lock
);
195 error
= jail_attach(td
, &jaa
);
198 mtx_lock(&pr
->pr_mtx
);
200 mtx_unlock(&pr
->pr_mtx
);
201 td
->td_retval
[0] = jaa
.jid
;
204 sx_xlock(&allprison_lock
);
205 LIST_REMOVE(pr
, pr_list
);
207 sx_downgrade(&allprison_lock
);
208 TAILQ_FOREACH(psrv
, &prison_services
, ps_next
) {
209 psrv
->ps_destroy(psrv
, pr
);
211 sx_sunlock(&allprison_lock
);
213 if (pr
->pr_slots
!= NULL
)
214 FREE(pr
->pr_slots
, M_PRISON
);
215 vfslocked
= VFS_LOCK_GIANT(pr
->pr_root
->v_mount
);
217 VFS_UNLOCK_GIANT(vfslocked
);
219 mtx_destroy(&pr
->pr_mtx
);
225 * struct jail_attach_args {
230 jail_attach(struct thread
*td
, struct jail_attach_args
*uap
)
233 struct ucred
*newcred
, *oldcred
;
235 int vfslocked
, error
;
238 * XXX: Note that there is a slight race here if two threads
239 * in the same privileged process attempt to attach to two
240 * different jails at the same time. It is important for
241 * user processes not to do this, or they might end up with
242 * a process root from one prison, but attached to the jail
245 error
= priv_check(td
, PRIV_JAIL_ATTACH
);
250 sx_slock(&allprison_lock
);
251 pr
= prison_find(uap
->jid
);
253 sx_sunlock(&allprison_lock
);
257 mtx_unlock(&pr
->pr_mtx
);
258 sx_sunlock(&allprison_lock
);
260 vfslocked
= VFS_LOCK_GIANT(pr
->pr_root
->v_mount
);
261 vn_lock(pr
->pr_root
, LK_EXCLUSIVE
| LK_RETRY
);
262 if ((error
= change_dir(pr
->pr_root
, td
)) != 0)
265 if ((error
= mac_vnode_check_chroot(td
->td_ucred
, pr
->pr_root
)))
268 VOP_UNLOCK(pr
->pr_root
, 0);
269 change_root(pr
->pr_root
, td
);
270 VFS_UNLOCK_GIANT(vfslocked
);
274 oldcred
= p
->p_ucred
;
276 crcopy(newcred
, oldcred
);
277 newcred
->cr_prison
= pr
;
278 p
->p_ucred
= newcred
;
283 VOP_UNLOCK(pr
->pr_root
, 0);
284 VFS_UNLOCK_GIANT(vfslocked
);
285 mtx_lock(&pr
->pr_mtx
);
287 mtx_unlock(&pr
->pr_mtx
);
292 * Returns a locked prison instance, or NULL on failure.
295 prison_find(int prid
)
299 sx_assert(&allprison_lock
, SX_LOCKED
);
300 LIST_FOREACH(pr
, &allprison
, pr_list
) {
301 if (pr
->pr_id
== prid
) {
302 mtx_lock(&pr
->pr_mtx
);
303 if (pr
->pr_ref
== 0) {
304 mtx_unlock(&pr
->pr_mtx
);
314 prison_free(struct prison
*pr
)
317 mtx_lock(&pr
->pr_mtx
);
319 if (pr
->pr_ref
== 0) {
320 mtx_unlock(&pr
->pr_mtx
);
321 TASK_INIT(&pr
->pr_task
, 0, prison_complete
, pr
);
322 taskqueue_enqueue(taskqueue_thread
, &pr
->pr_task
);
325 mtx_unlock(&pr
->pr_mtx
);
329 prison_complete(void *context
, int pending
)
331 struct prison_service
*psrv
;
335 pr
= (struct prison
*)context
;
337 sx_xlock(&allprison_lock
);
338 LIST_REMOVE(pr
, pr_list
);
340 sx_downgrade(&allprison_lock
);
341 TAILQ_FOREACH(psrv
, &prison_services
, ps_next
) {
342 psrv
->ps_destroy(psrv
, pr
);
344 sx_sunlock(&allprison_lock
);
345 if (pr
->pr_slots
!= NULL
)
346 FREE(pr
->pr_slots
, M_PRISON
);
348 vfslocked
= VFS_LOCK_GIANT(pr
->pr_root
->v_mount
);
350 VFS_UNLOCK_GIANT(vfslocked
);
352 mtx_destroy(&pr
->pr_mtx
);
353 if (pr
->pr_linux
!= NULL
)
354 FREE(pr
->pr_linux
, M_PRISON
);
359 prison_hold(struct prison
*pr
)
362 mtx_lock(&pr
->pr_mtx
);
363 KASSERT(pr
->pr_ref
> 0,
364 ("Trying to hold dead prison (id=%d).", pr
->pr_id
));
366 mtx_unlock(&pr
->pr_mtx
);
370 prison_getip(struct ucred
*cred
)
373 return (cred
->cr_prison
->pr_ip
);
377 prison_ip(struct ucred
*cred
, int flag
, u_int32_t
*ip
)
387 if (tmp
== INADDR_ANY
) {
389 *ip
= cred
->cr_prison
->pr_ip
;
391 *ip
= htonl(cred
->cr_prison
->pr_ip
);
394 if (tmp
== INADDR_LOOPBACK
) {
396 *ip
= cred
->cr_prison
->pr_ip
;
398 *ip
= htonl(cred
->cr_prison
->pr_ip
);
401 if (cred
->cr_prison
->pr_ip
!= tmp
)
407 prison_remote_ip(struct ucred
*cred
, int flag
, u_int32_t
*ip
)
417 if (tmp
== INADDR_LOOPBACK
) {
419 *ip
= cred
->cr_prison
->pr_ip
;
421 *ip
= htonl(cred
->cr_prison
->pr_ip
);
428 prison_if(struct ucred
*cred
, struct sockaddr
*sa
)
430 struct sockaddr_in
*sai
;
433 sai
= (struct sockaddr_in
*)sa
;
434 if ((sai
->sin_family
!= AF_INET
) && jail_socket_unixiproute_only
)
436 else if (sai
->sin_family
!= AF_INET
)
438 else if (cred
->cr_prison
->pr_ip
!= ntohl(sai
->sin_addr
.s_addr
))
446 * Return 0 if jails permit p1 to frob p2, otherwise ESRCH.
449 prison_check(struct ucred
*cred1
, struct ucred
*cred2
)
455 if (cred2
->cr_prison
!= cred1
->cr_prison
)
463 * Return 1 if the passed credential is in a jail, otherwise 0.
466 jailed(struct ucred
*cred
)
469 return (cred
->cr_prison
!= NULL
);
473 * Return the correct hostname for the passed credential.
476 getcredhostname(struct ucred
*cred
, char *buf
, size_t size
)
480 mtx_lock(&cred
->cr_prison
->pr_mtx
);
481 strlcpy(buf
, cred
->cr_prison
->pr_host
, size
);
482 mtx_unlock(&cred
->cr_prison
->pr_mtx
);
484 mtx_lock(&hostname_mtx
);
485 strlcpy(buf
, V_hostname
, size
);
486 mtx_unlock(&hostname_mtx
);
491 * Determine whether the subject represented by cred can "see"
492 * status of a mount point.
493 * Returns: 0 for permitted, ENOENT otherwise.
494 * XXX: This function should be called cr_canseemount() and should be
495 * placed in kern_prot.c.
498 prison_canseemount(struct ucred
*cred
, struct mount
*mp
)
504 if (!jailed(cred
) || jail_enforce_statfs
== 0)
506 pr
= cred
->cr_prison
;
507 if (pr
->pr_root
->v_mount
== mp
)
509 if (jail_enforce_statfs
== 2)
512 * If jail's chroot directory is set to "/" we should be able to see
513 * all mount-points from inside a jail.
514 * This is ugly check, but this is the only situation when jail's
515 * directory ends with '/'.
517 if (strcmp(pr
->pr_path
, "/") == 0)
519 len
= strlen(pr
->pr_path
);
521 if (strncmp(pr
->pr_path
, sp
->f_mntonname
, len
) != 0)
524 * Be sure that we don't have situation where jail's root directory
525 * is "/some/path" and mount point is "/some/pathpath".
527 if (sp
->f_mntonname
[len
] != '\0' && sp
->f_mntonname
[len
] != '/')
533 prison_enforce_statfs(struct ucred
*cred
, struct mount
*mp
, struct statfs
*sp
)
535 char jpath
[MAXPATHLEN
];
539 if (!jailed(cred
) || jail_enforce_statfs
== 0)
541 pr
= cred
->cr_prison
;
542 if (prison_canseemount(cred
, mp
) != 0) {
543 bzero(sp
->f_mntonname
, sizeof(sp
->f_mntonname
));
544 strlcpy(sp
->f_mntonname
, "[restricted]",
545 sizeof(sp
->f_mntonname
));
548 if (pr
->pr_root
->v_mount
== mp
) {
550 * Clear current buffer data, so we are sure nothing from
551 * the valid path left there.
553 bzero(sp
->f_mntonname
, sizeof(sp
->f_mntonname
));
554 *sp
->f_mntonname
= '/';
558 * If jail's chroot directory is set to "/" we should be able to see
559 * all mount-points from inside a jail.
561 if (strcmp(pr
->pr_path
, "/") == 0)
563 len
= strlen(pr
->pr_path
);
564 strlcpy(jpath
, sp
->f_mntonname
+ len
, sizeof(jpath
));
566 * Clear current buffer data, so we are sure nothing from
567 * the valid path left there.
569 bzero(sp
->f_mntonname
, sizeof(sp
->f_mntonname
));
570 if (*jpath
== '\0') {
571 /* Should never happen. */
572 *sp
->f_mntonname
= '/';
574 strlcpy(sp
->f_mntonname
, jpath
, sizeof(sp
->f_mntonname
));
579 * Check with permission for a specific privilege is granted within jail. We
580 * have a specific list of accepted privileges; the rest are denied.
583 prison_priv_check(struct ucred
*cred
, int priv
)
592 * Allow ktrace privileges for root in jail.
598 * Allow jailed processes to configure audit identity and
599 * submit audit records (login, etc). In the future we may
600 * want to further refine the relationship between audit and
603 case PRIV_AUDIT_GETAUDIT
:
604 case PRIV_AUDIT_SETAUDIT
:
605 case PRIV_AUDIT_SUBMIT
:
609 * Allow jailed processes to manipulate process UNIX
610 * credentials in any way they see fit.
612 case PRIV_CRED_SETUID
:
613 case PRIV_CRED_SETEUID
:
614 case PRIV_CRED_SETGID
:
615 case PRIV_CRED_SETEGID
:
616 case PRIV_CRED_SETGROUPS
:
617 case PRIV_CRED_SETREUID
:
618 case PRIV_CRED_SETREGID
:
619 case PRIV_CRED_SETRESUID
:
620 case PRIV_CRED_SETRESGID
:
623 * Jail implements visibility constraints already, so allow
624 * jailed root to override uid/gid-based constraints.
626 case PRIV_SEEOTHERGIDS
:
627 case PRIV_SEEOTHERUIDS
:
630 * Jail implements inter-process debugging limits already, so
631 * allow jailed root various debugging privileges.
633 case PRIV_DEBUG_DIFFCRED
:
634 case PRIV_DEBUG_SUGID
:
635 case PRIV_DEBUG_UNPRIV
:
638 * Allow jail to set various resource limits and login
639 * properties, and for now, exceed process resource limits.
641 case PRIV_PROC_LIMIT
:
642 case PRIV_PROC_SETLOGIN
:
643 case PRIV_PROC_SETRLIMIT
:
646 * System V and POSIX IPC privileges are granted in jail.
651 case PRIV_IPC_MSGSIZE
:
655 * Jail implements its own inter-process limits, so allow
656 * root processes in jail to change scheduling on other
657 * processes in the same jail. Likewise for signalling.
659 case PRIV_SCHED_DIFFCRED
:
660 case PRIV_SIGNAL_DIFFCRED
:
661 case PRIV_SIGNAL_SUGID
:
664 * Allow jailed processes to write to sysctls marked as jail
667 case PRIV_SYSCTL_WRITEJAIL
:
670 * Allow root in jail to manage a variety of quota
671 * properties. These should likely be conditional on a
672 * configuration option.
674 case PRIV_VFS_GETQUOTA
:
675 case PRIV_VFS_SETQUOTA
:
678 * Since Jail relies on chroot() to implement file system
679 * protections, grant many VFS privileges to root in jail.
680 * Be careful to exclude mount-related and NFS-related
687 case PRIV_VFS_LOOKUP
:
688 case PRIV_VFS_BLOCKRESERVE
: /* XXXRW: Slightly surprising. */
689 case PRIV_VFS_CHFLAGS_DEV
:
691 case PRIV_VFS_CHROOT
:
692 case PRIV_VFS_RETAINSUGID
:
693 case PRIV_VFS_FCHROOT
:
695 case PRIV_VFS_SETGID
:
697 case PRIV_VFS_STICKYFILE
:
701 * Depending on the global setting, allow privilege of
702 * setting system flags.
704 case PRIV_VFS_SYSFLAGS
:
705 if (jail_chflags_allowed
)
711 * Depending on the global setting, allow privilege of
712 * mounting/unmounting file systems.
715 case PRIV_VFS_UNMOUNT
:
716 case PRIV_VFS_MOUNT_NONUSER
:
717 case PRIV_VFS_MOUNT_OWNER
:
718 if (jail_mount_allowed
)
724 * Allow jailed root to bind reserved ports and reuse in-use
727 case PRIV_NETINET_RESERVEDPORT
:
728 case PRIV_NETINET_REUSEPORT
:
732 * Allow jailed root to set certian IPv4/6 (option) headers.
734 case PRIV_NETINET_SETHDROPTS
:
738 * Conditionally allow creating raw sockets in jail.
740 case PRIV_NETINET_RAW
:
741 if (jail_allow_raw_sockets
)
747 * Since jail implements its own visibility limits on netstat
748 * sysctls, allow getcred. This allows identd to work in
751 case PRIV_NETINET_GETCRED
:
756 * In all remaining cases, deny the privilege request. This
757 * includes almost all network privileges, many system
758 * configuration privileges.
765 * Register jail service. Provides 'create' and 'destroy' methods.
766 * 'create' method will be called for every existing jail and all
767 * jails in the future as they beeing created.
768 * 'destroy' method will be called for every jail going away and
769 * for all existing jails at the time of service deregistration.
771 struct prison_service
*
772 prison_service_register(const char *name
, prison_create_t create
,
773 prison_destroy_t destroy
)
775 struct prison_service
*psrv
, *psrv2
;
777 int reallocate
= 1, slotno
= 0;
778 void **slots
, **oldslots
;
780 psrv
= malloc(sizeof(*psrv
) + strlen(name
) + 1, M_PRISON
,
782 psrv
->ps_create
= create
;
783 psrv
->ps_destroy
= destroy
;
784 strcpy(psrv
->ps_name
, name
);
786 * Grab the allprison_lock here, so we won't miss any jail
787 * creation/destruction.
789 sx_xlock(&allprison_lock
);
792 * Verify if service is not already registered.
794 TAILQ_FOREACH(psrv2
, &prison_services
, ps_next
) {
795 KASSERT(strcmp(psrv2
->ps_name
, name
) != 0,
796 ("jail service %s already registered", name
));
800 * Find free slot. When there is no existing free slot available,
801 * allocate one at the end.
803 TAILQ_FOREACH(psrv2
, &prison_services
, ps_next
) {
804 if (psrv2
->ps_slotno
!= slotno
) {
805 KASSERT(slotno
< psrv2
->ps_slotno
,
806 ("Invalid slotno (slotno=%d >= ps_slotno=%d",
807 slotno
, psrv2
->ps_slotno
));
808 /* We found free slot. */
814 psrv
->ps_slotno
= slotno
;
816 * Keep the list sorted by slot number.
819 KASSERT(reallocate
== 0, ("psrv2 != NULL && reallocate != 0"));
820 TAILQ_INSERT_BEFORE(psrv2
, psrv
, ps_next
);
822 KASSERT(reallocate
== 1, ("psrv2 == NULL && reallocate == 0"));
823 TAILQ_INSERT_TAIL(&prison_services
, psrv
, ps_next
);
825 prison_service_slots
++;
826 sx_downgrade(&allprison_lock
);
828 * Allocate memory for new slot if we didn't found empty one.
829 * Do not use realloc(9), because pr_slots is protected with a mutex,
832 LIST_FOREACH(pr
, &allprison
, pr_list
) {
834 /* First allocate memory with M_WAITOK. */
835 slots
= malloc(sizeof(*slots
) * prison_service_slots
,
837 /* Now grab the mutex and replace pr_slots. */
838 mtx_lock(&pr
->pr_mtx
);
839 oldslots
= pr
->pr_slots
;
840 if (psrv
->ps_slotno
> 0) {
841 bcopy(oldslots
, slots
,
842 sizeof(*slots
) * (prison_service_slots
- 1));
844 slots
[psrv
->ps_slotno
] = NULL
;
845 pr
->pr_slots
= slots
;
846 mtx_unlock(&pr
->pr_mtx
);
847 if (oldslots
!= NULL
)
848 free(oldslots
, M_PRISON
);
851 * Call 'create' method for each existing jail.
853 psrv
->ps_create(psrv
, pr
);
855 sx_sunlock(&allprison_lock
);
861 prison_service_deregister(struct prison_service
*psrv
)
864 void **slots
, **oldslots
;
867 sx_xlock(&allprison_lock
);
868 if (TAILQ_LAST(&prison_services
, prison_services_head
) == psrv
)
870 TAILQ_REMOVE(&prison_services
, psrv
, ps_next
);
871 prison_service_slots
--;
872 sx_downgrade(&allprison_lock
);
873 LIST_FOREACH(pr
, &allprison
, pr_list
) {
875 * Call 'destroy' method for every currently existing jail.
877 psrv
->ps_destroy(psrv
, pr
);
879 * If this is the last slot, free the memory allocated for it.
882 if (prison_service_slots
== 0)
885 slots
= malloc(sizeof(*slots
) * prison_service_slots
,
888 mtx_lock(&pr
->pr_mtx
);
889 oldslots
= pr
->pr_slots
;
891 * We require setting slot to NULL after freeing it,
892 * this way we can check for memory leaks here.
894 KASSERT(oldslots
[psrv
->ps_slotno
] == NULL
,
895 ("Slot %d (service %s, jailid=%d) still contains data?",
896 psrv
->ps_slotno
, psrv
->ps_name
, pr
->pr_id
));
897 if (psrv
->ps_slotno
> 0) {
898 bcopy(oldslots
, slots
,
899 sizeof(*slots
) * prison_service_slots
);
901 pr
->pr_slots
= slots
;
902 mtx_unlock(&pr
->pr_mtx
);
903 KASSERT(oldslots
!= NULL
, ("oldslots == NULL"));
904 free(oldslots
, M_PRISON
);
907 sx_sunlock(&allprison_lock
);
908 free(psrv
, M_PRISON
);
912 * Function sets data for the given jail in slot assigned for the given
916 prison_service_data_set(struct prison_service
*psrv
, struct prison
*pr
,
920 mtx_assert(&pr
->pr_mtx
, MA_OWNED
);
921 pr
->pr_slots
[psrv
->ps_slotno
] = data
;
925 * Function clears slots assigned for the given jail service in the given
926 * prison structure and returns current slot data.
929 prison_service_data_del(struct prison_service
*psrv
, struct prison
*pr
)
933 mtx_assert(&pr
->pr_mtx
, MA_OWNED
);
934 data
= pr
->pr_slots
[psrv
->ps_slotno
];
935 pr
->pr_slots
[psrv
->ps_slotno
] = NULL
;
940 * Function returns current data from the slot assigned to the given jail
941 * service for the given jail.
944 prison_service_data_get(struct prison_service
*psrv
, struct prison
*pr
)
947 mtx_assert(&pr
->pr_mtx
, MA_OWNED
);
948 return (pr
->pr_slots
[psrv
->ps_slotno
]);
952 sysctl_jail_list(SYSCTL_HANDLER_ARGS
)
954 struct xprison
*xp
, *sxp
;
958 if (jailed(req
->td
->td_ucred
))
961 sx_slock(&allprison_lock
);
962 if ((count
= prisoncount
) == 0) {
963 sx_sunlock(&allprison_lock
);
967 sxp
= xp
= malloc(sizeof(*xp
) * count
, M_TEMP
, M_WAITOK
| M_ZERO
);
969 LIST_FOREACH(pr
, &allprison
, pr_list
) {
970 xp
->pr_version
= XPRISON_VERSION
;
971 xp
->pr_id
= pr
->pr_id
;
972 xp
->pr_ip
= pr
->pr_ip
;
973 strlcpy(xp
->pr_path
, pr
->pr_path
, sizeof(xp
->pr_path
));
974 mtx_lock(&pr
->pr_mtx
);
975 strlcpy(xp
->pr_host
, pr
->pr_host
, sizeof(xp
->pr_host
));
976 mtx_unlock(&pr
->pr_mtx
);
979 sx_sunlock(&allprison_lock
);
981 error
= SYSCTL_OUT(req
, sxp
, sizeof(*sxp
) * count
);
986 SYSCTL_OID(_security_jail
, OID_AUTO
, list
, CTLTYPE_STRUCT
| CTLFLAG_RD
,
987 NULL
, 0, sysctl_jail_list
, "S", "List of active jails");
990 sysctl_jail_jailed(SYSCTL_HANDLER_ARGS
)
994 injail
= jailed(req
->td
->td_ucred
);
995 error
= SYSCTL_OUT(req
, &injail
, sizeof(injail
));
999 SYSCTL_PROC(_security_jail
, OID_AUTO
, jailed
, CTLTYPE_INT
| CTLFLAG_RD
,
1000 NULL
, 0, sysctl_jail_jailed
, "I", "Process in jail?");