FreeBSD Bugzilla – Attachment 28925 Details for
Bug 48471
[jail] Private IPC for every jail
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
file.diff
file.diff (text/plain), 68.32 KB, created by
Pawel Jakub Dawidek
on 2003-02-19 22:00:11 UTC
(
hide
)
Description:
file.diff
Filename:
MIME Type:
Creator:
Pawel Jakub Dawidek
Created:
2003-02-19 22:00:11 UTC
Size:
68.32 KB
patch
obsolete
>diff -ru /sys/compat/linux/linux_ipc.c sys/compat/linux/linux_ipc.c >--- /sys/compat/linux/linux_ipc.c Wed Feb 19 19:29:13 2003 >+++ sys/compat/linux/linux_ipc.c Wed Feb 19 18:02:21 2003 >@@ -25,7 +25,7 @@ > * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF > * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. > * >- * $FreeBSD: src/sys/compat/linux/linux_ipc.c,v 1.17.2.3 2001/11/05 19:08:22 marcel Exp $ >+ * $FreeBSD$ > */ > > #include <sys/param.h> >@@ -34,6 +34,7 @@ > #include <sys/proc.h> > #include <sys/sem.h> > #include <sys/shm.h> >+#include <sys/jail.h> > > #include <machine/../linux/linux.h> > #include <machine/../linux/linux_proto.h> >@@ -222,6 +223,12 @@ > int error; > union semun *unptr; > caddr_t sg; >+ struct sempriv *sp; >+ >+ if (p->p_prison == NULL) >+ sp = &mainsem; >+ else >+ sp = &p->p_prison->pr_sem; > > sg = stackgap_init(); > >@@ -278,7 +285,7 @@ > sizeof(linux_seminfo) ); > if (error) > return error; >- bcopy(&seminfo, &linux_seminfo, sizeof(linux_seminfo) ); >+ bcopy(&sp->seminfo, &linux_seminfo, sizeof(linux_seminfo) ); > /* XXX BSD equivalent? > #define used_semids 10 > #define used_sems 10 >@@ -289,7 +296,7 @@ > sizeof(linux_seminfo) ); > if (error) > return error; >- p->p_retval[0] = seminfo.semmni; >+ p->p_retval[0] = sp->seminfo.semmni; > return 0; /* No need for __semctl call */ > case LINUX_GETALL: > /* FALLTHROUGH */ >diff -ru /sys/kern/kern_exit.c sys/kern/kern_exit.c >--- /sys/kern/kern_exit.c Wed Feb 19 19:29:13 2003 >+++ sys/kern/kern_exit.c Wed Feb 19 18:38:38 2003 >@@ -36,11 +36,12 @@ > * SUCH DAMAGE. > * > * @(#)kern_exit.c 8.7 (Berkeley) 2/12/94 >- * $FreeBSD: src/sys/kern/kern_exit.c,v 1.92.2.11 2003/01/13 22:51:16 dillon Exp $ >+ * $FreeBSD$ > */ > > #include "opt_compat.h" > #include "opt_ktrace.h" >+#include "opt_sysvipc.h" > > #include <sys/param.h> > #include <sys/systm.h> >@@ -57,6 +58,7 @@ > #include <sys/ptrace.h> > #include <sys/acct.h> /* for acct_process() function prototype */ > #include <sys/filedesc.h> >+#include <sys/msg.h> > #include <sys/shm.h> > #include <sys/sem.h> > #include <sys/aio.h> >@@ -510,6 +512,15 @@ > if (p->p_prison && !--p->p_prison->pr_ref) { > if (p->p_prison->pr_linux != NULL) > FREE(p->p_prison->pr_linux, M_PRISON); >+#ifdef SYSVMSG >+ msgclear(p->p_prison); >+#endif >+#ifdef SYSVSEM >+ semclear(p->p_prison); >+#endif >+#ifdef SYSVSHM >+ shmclear(p->p_prison); >+#endif > FREE(p->p_prison, M_PRISON); > } > >diff -ru /sys/kern/kern_jail.c sys/kern/kern_jail.c >--- /sys/kern/kern_jail.c Wed Feb 19 19:29:13 2003 >+++ sys/kern/kern_jail.c Wed Feb 19 19:29:09 2003 >@@ -6,10 +6,12 @@ > * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp > * ---------------------------------------------------------------------------- > * >- * $FreeBSD: src/sys/kern/kern_jail.c,v 1.6.2.3 2001/08/17 01:00:26 rwatson Exp $ >+ * $FreeBSD$ > * > */ > >+#include "opt_sysvipc.h" >+ > #include <sys/param.h> > #include <sys/types.h> > #include <sys/kernel.h> >@@ -21,6 +23,9 @@ > #include <sys/jail.h> > #include <sys/socket.h> > #include <sys/sysctl.h> >+#include <sys/msg.h> >+#include <sys/sem.h> >+#include <sys/shm.h> > #include <net/if.h> > #include <netinet/in.h> > >@@ -39,10 +44,12 @@ > &jail_socket_unixiproute_only, 0, > "Processes in jail are limited to creating UNIX/IPv4/route sockets only"); > >-int jail_sysvipc_allowed = 0; >+#if defined(SYSVMSG) || defined(SYSVSEM) || defined(SYSVSHM) >+int jail_sysvipc_allowed = 1; > SYSCTL_INT(_jail, OID_AUTO, sysvipc_allowed, CTLFLAG_RW, > &jail_sysvipc_allowed, 0, > "Processes in jail can use System V IPC primitives"); >+#endif > > int > jail(p, uap) >@@ -75,7 +82,32 @@ > error = chroot(p, &ca); > if (error) > goto bail; >- >+#ifdef SYSVMSG >+ error = msginit(pr); >+ if (error != 0) >+ goto bail; >+#endif >+#ifdef SYSVSEM >+ error = seminit(pr); >+ if (error != 0) { >+#ifdef SYSVMSG >+ msgclear(pr); >+#endif >+ goto bail; >+ } >+#endif >+#ifdef SYSVSHM >+ error = shminit(pr); >+ if (error != 0) { >+#ifdef SYSVMSG >+ msgclear(pr); >+#endif >+#ifdef SYSVSEM >+ semclear(pr); >+#endif >+ goto bail; >+ } >+#endif > pr->pr_ref++; > p->p_prison = pr; > p->p_flag |= P_JAILED; >diff -ru /sys/kern/sysv_msg.c sys/kern/sysv_msg.c >--- /sys/kern/sysv_msg.c Wed Feb 19 19:29:13 2003 >+++ sys/kern/sysv_msg.c Wed Feb 19 18:27:23 2003 >@@ -1,9 +1,10 @@ >-/* $FreeBSD: src/sys/kern/sysv_msg.c,v 1.23.2.5 2002/12/31 08:54:53 maxim Exp $ */ >+/* $FreeBSD$ */ > > /* > * Implementation of SVID messages > * > * Author: Daniel Boulet >+ * Jailed by: Pawel Jakub Dawidek <nick@garage.freebsd.pl> > * > * Copyright 1993 Daniel Boulet and RTMX Inc. > * >@@ -34,8 +35,6 @@ > > static MALLOC_DEFINE(M_MSG, "msg", "SVID compatible message queues"); > >-static void msginit __P((void *)); >- > #define MSG_DEBUG > #undef MSG_DEBUG_OK > >@@ -47,15 +46,6 @@ > (sy_call_t *)msgsnd, (sy_call_t *)msgrcv > }; > >-struct msg { >- struct msg *msg_next; /* next msg in the chain */ >- long msg_type; /* type of this message */ >- /* >0 -> type of this message */ >- /* 0 -> free header */ >- u_short msg_ts; /* size of this message */ >- short msg_spot; /* location of start of msg in buffer */ >-}; >- > > #ifndef MSGSSZ > #define MSGSSZ 8 /* Each segment must be 2^N long */ >@@ -75,26 +65,6 @@ > #endif > > /* >- * Based on the configuration parameters described in an SVR2 (yes, two) >- * config(1m) man page. >- * >- * Each message is broken up and stored in segments that are msgssz bytes >- * long. For efficiency reasons, this should be a power of two. Also, >- * it doesn't make sense if it is less than 8 or greater than about 256. >- * Consequently, msginit in kern/sysv_msg.c checks that msgssz is a power of >- * two between 8 and 1024 inclusive (and panic's if it isn't). >- */ >-struct msginfo msginfo = { >- MSGMAX, /* max chars in a message */ >- MSGMNI, /* # of message queue identifiers */ >- MSGMNB, /* max chars in a queue */ >- MSGTQL, /* max messages in system */ >- MSGSSZ, /* size of a message segment */ >- /* (must be small power of 2 greater than 4) */ >- MSGSEG /* number of message segments */ >-}; >- >-/* > * macros to convert between msqid_ds's and msqid's. > * (specific to this implementation) > */ >@@ -106,41 +76,68 @@ > * The rest of this file is specific to this particular implementation. > */ > >-struct msgmap { >- short next; /* next segment in buffer */ >- /* -1 -> available */ >- /* 0..(MSGSEG-1) -> index of next segment */ >-}; >- > #define MSG_LOCKED 01000 /* Is this msqid_ds locked? */ > >-static int nfree_msgmaps; /* # of free map entries */ >-static short free_msgmaps; /* head of linked list of free map entries */ >-static struct msg *free_msghdrs;/* list of free msg headers */ >-static char *msgpool; /* MSGMAX byte long msg buffer pool */ >-static struct msgmap *msgmaps; /* MSGSEG msgmap structures */ >-static struct msg *msghdrs; /* MSGTQL msg headers */ >-static struct msqid_ds *msqids; /* MSGMNI msqid_ds struct's */ >+/* Global struct for main system, all jails have its own. */ >+struct msgpriv mainmsg; > >-static void >-msginit(dummy) >- void *dummy; >+int >+msginit(struct prison *pr) > { > register int i; >+ struct msgpriv *mp; >+ int error; > >- msginfo.msgmax = msginfo.msgseg * msginfo.msgssz; >- msgpool = malloc(msginfo.msgmax, M_MSG, M_WAITOK); >- if (msgpool == NULL) >- panic("msgpool is NULL"); >- msgmaps = malloc(sizeof(struct msgmap) * msginfo.msgseg, M_MSG, M_WAITOK); >- if (msgmaps == NULL) >- panic("msgmaps is NULL"); >- msghdrs = malloc(sizeof(struct msg) * msginfo.msgtql, M_MSG, M_WAITOK); >- if (msghdrs == NULL) >- panic("msghdrs is NULL"); >- msqids = malloc(sizeof(struct msqid_ds) * msginfo.msgmni, M_MSG, M_WAITOK); >- if (msqids == NULL) >- panic("msqids is NULL"); >+ if (pr == NULL) >+ mp = &mainmsg; >+ else >+ mp = &pr->pr_msg; >+ >+ mp->msginfo.msgmax = MSGMAX; >+ mp->msginfo.msgmni = MSGMNI; >+ mp->msginfo.msgmnb = MSGMNB; >+ mp->msginfo.msgtql = MSGTQL; >+ mp->msginfo.msgssz = MSGSSZ; >+ mp->msginfo.msgseg = MSGSEG; >+ >+ mp->msginfo.msgmax = mp->msginfo.msgseg * mp->msginfo.msgssz; >+ mp->msgpool = malloc(mp->msginfo.msgmax, M_MSG, M_WAITOK); >+ if (mp->msgpool == NULL) { >+ if (pr == NULL) >+ panic("msgpool is NULL"); >+ else >+ return (ENOMEM); >+ } >+ mp->msgmaps = malloc(sizeof(struct msgmap) * mp->msginfo.msgseg, M_MSG, >+ M_WAITOK); >+ if (mp->msgmaps == NULL) { >+ if (pr == NULL) >+ panic("msgmaps is NULL"); >+ else { >+ error = ENOMEM; >+ goto fail_msgmaps; >+ } >+ } >+ mp->msghdrs = malloc(sizeof(struct msg) * mp->msginfo.msgtql, M_MSG, >+ M_WAITOK); >+ if (mp->msghdrs == NULL) { >+ if (pr == NULL) >+ panic("msghdrs is NULL"); >+ else { >+ error = ENOMEM; >+ goto fail_msghdrs; >+ } >+ } >+ mp->msqids = malloc(sizeof(struct msqid_ds) * mp->msginfo.msgmni, M_MSG, >+ M_WAITOK); >+ if (mp->msqids == NULL) { >+ if (pr == NULL) >+ panic("msqids is NULL"); >+ else { >+ error = ENOMEM; >+ goto fail_msqids; >+ } >+ } > > /* > * msginfo.msgssz should be a power of two for efficiency reasons. >@@ -149,49 +146,88 @@ > */ > > i = 8; >- while (i < 1024 && i != msginfo.msgssz) >+ while (i < 1024 && i != mp->msginfo.msgssz) > i <<= 1; >- if (i != msginfo.msgssz) { >- printf("msginfo.msgssz=%d (0x%x)\n", msginfo.msgssz, >- msginfo.msgssz); >- panic("msginfo.msgssz not a small power of 2"); >+ if (i != mp->msginfo.msgssz) { >+ printf("msginfo.msgssz=%d (0x%x)\n", mp->msginfo.msgssz, >+ mp->msginfo.msgssz); >+ if (pr == NULL) >+ panic("msginfo.msgssz not a small power of 2"); >+ else { >+ error = EINVAL; >+ goto all; >+ } > } > >- if (msginfo.msgseg > 32767) { >- printf("msginfo.msgseg=%d\n", msginfo.msgseg); >- panic("msginfo.msgseg > 32767"); >+ if (mp->msginfo.msgseg > 32767) { >+ printf("msginfo.msgseg=%d\n", mp->msginfo.msgseg); >+ if (pr == NULL) >+ panic("msginfo.msgseg > 32767"); >+ else { >+ error = EINVAL; >+ goto all; >+ } > } > >- if (msgmaps == NULL) >- panic("msgmaps is NULL"); >+ if (mp->msgmaps == NULL) { >+ if (pr == NULL) >+ panic("msgmaps is NULL"); >+ else { >+ error = EFAULT; >+ goto all; >+ } >+ } > >- for (i = 0; i < msginfo.msgseg; i++) { >+ for (i = 0; i < mp->msginfo.msgseg; i++) { > if (i > 0) >- msgmaps[i-1].next = i; >- msgmaps[i].next = -1; /* implies entry is available */ >+ mp->msgmaps[i-1].next = i; >+ mp->msgmaps[i].next = -1; /* implies entry is available */ > } >- free_msgmaps = 0; >- nfree_msgmaps = msginfo.msgseg; >+ mp->free_msgmaps = 0; >+ mp->nfree_msgmaps = mp->msginfo.msgseg; > >- if (msghdrs == NULL) >- panic("msghdrs is NULL"); >+ if (mp->msghdrs == NULL) { >+ if (pr == NULL) >+ panic("msghdrs is NULL"); >+ else { >+ error = EFAULT; >+ goto all; >+ } >+ } > >- for (i = 0; i < msginfo.msgtql; i++) { >- msghdrs[i].msg_type = 0; >+ for (i = 0; i < mp->msginfo.msgtql; i++) { >+ mp->msghdrs[i].msg_type = 0; > if (i > 0) >- msghdrs[i-1].msg_next = &msghdrs[i]; >- msghdrs[i].msg_next = NULL; >+ mp->msghdrs[i-1].msg_next = &mp->msghdrs[i]; >+ mp->msghdrs[i].msg_next = NULL; > } >- free_msghdrs = &msghdrs[0]; >+ mp->free_msghdrs = &mp->msghdrs[0]; > >- if (msqids == NULL) >- panic("msqids is NULL"); >+ if (mp->msqids == NULL) { >+ if (pr == NULL) >+ panic("msqids is NULL"); >+ else { >+ error = EFAULT; >+ goto all; >+ } >+ } > >- for (i = 0; i < msginfo.msgmni; i++) { >- msqids[i].msg_qbytes = 0; /* implies entry is available */ >- msqids[i].msg_perm.seq = 0; /* reset to a known value */ >- msqids[i].msg_perm.mode = 0; >+ for (i = 0; i < mp->msginfo.msgmni; i++) { >+ mp->msqids[i].msg_qbytes = 0; /* implies entry is available */ >+ mp->msqids[i].msg_perm.seq = 0; /* reset to a known value */ >+ mp->msqids[i].msg_perm.mode = 0; > } >+ >+ return (0); >+all: >+fail_msqids: >+ free(mp->msghdrs, M_MSG); >+fail_msghdrs: >+ free(mp->msgmaps, M_MSG); >+fail_msgmaps: >+ free(mp->msgpool, M_MSG); >+ >+ return (error); > } > SYSINIT(sysv_msg, SI_SUB_SYSV_MSG, SI_ORDER_FIRST, msginit, NULL) > >@@ -224,24 +260,34 @@ > msg_freehdr(msghdr) > struct msg *msghdr; > { >+ struct msgpriv *mp; >+ >+ KASSERT(curproc != NULL, ("msg_freehdr: curproc is NULL")); >+ if (curproc->p_prison == NULL) >+ mp = &mainmsg; >+ else >+ mp = &curproc->p_prison->pr_msg; >+ > while (msghdr->msg_ts > 0) { > short next; >- if (msghdr->msg_spot < 0 || msghdr->msg_spot >= msginfo.msgseg) >+ if (msghdr->msg_spot < 0 || >+ msghdr->msg_spot >= mp->msginfo.msgseg) { > panic("msghdr->msg_spot out of range"); >- next = msgmaps[msghdr->msg_spot].next; >- msgmaps[msghdr->msg_spot].next = free_msgmaps; >- free_msgmaps = msghdr->msg_spot; >- nfree_msgmaps++; >+ } >+ next = mp->msgmaps[msghdr->msg_spot].next; >+ mp->msgmaps[msghdr->msg_spot].next = mp->free_msgmaps; >+ mp->free_msgmaps = msghdr->msg_spot; >+ mp->nfree_msgmaps++; > msghdr->msg_spot = next; >- if (msghdr->msg_ts >= msginfo.msgssz) >- msghdr->msg_ts -= msginfo.msgssz; >+ if (msghdr->msg_ts >= mp->msginfo.msgssz) >+ msghdr->msg_ts -= mp->msginfo.msgssz; > else > msghdr->msg_ts = 0; > } > if (msghdr->msg_spot != -1) > panic("msghdr->msg_spot != -1"); >- msghdr->msg_next = free_msghdrs; >- free_msghdrs = msghdr; >+ msghdr->msg_next = mp->free_msghdrs; >+ mp->free_msghdrs = msghdr; > } > > #ifndef _SYS_SYSPROTO_H_ >@@ -263,6 +309,7 @@ > int rval, eval; > struct msqid_ds msqbuf; > register struct msqid_ds *msqptr; >+ struct msgpriv *mp; > > #ifdef MSG_DEBUG_OK > printf("call to msgctl(%d, %d, 0x%x)\n", msqid, cmd, user_msqptr); >@@ -271,17 +318,22 @@ > if (!jail_sysvipc_allowed && p->p_prison != NULL) > return (ENOSYS); > >+ if (p->p_prison == NULL) >+ mp = &mainmsg; >+ else >+ mp = &p->p_prison->pr_msg; >+ > msqid = IPCID_TO_IX(msqid); > >- if (msqid < 0 || msqid >= msginfo.msgmni) { >+ if (msqid < 0 || msqid >= mp->msginfo.msgmni) { > #ifdef MSG_DEBUG_OK > printf("msqid (%d) out of range (0<=msqid<%d)\n", msqid, >- msginfo.msgmni); >+ mp->msginfo.msgmni); > #endif > return(EINVAL); > } > >- msqptr = &msqids[msqid]; >+ msqptr = &mp->msqids[msqid]; > > if (msqptr->msg_qbytes == 0) { > #ifdef MSG_DEBUG_OK >@@ -341,12 +393,13 @@ > if (eval) > return(eval); > } >- if (msqbuf.msg_qbytes > msginfo.msgmnb) { >+ if (msqbuf.msg_qbytes > mp->msginfo.msgmnb) { > #ifdef MSG_DEBUG_OK > printf("can't increase msg_qbytes beyond %d (truncating)\n", >- msginfo.msgmnb); >+ mp->msginfo.msgmnb); > #endif >- msqbuf.msg_qbytes = msginfo.msgmnb; /* silently restrict qbytes to system limit */ >+ /* silently restrict qbytes to system limit */ >+ msqbuf.msg_qbytes = mp->msginfo.msgmnb; > } > if (msqbuf.msg_qbytes == 0) { > #ifdef MSG_DEBUG_OK >@@ -402,6 +455,7 @@ > int msgflg = uap->msgflg; > struct ucred *cred = p->p_ucred; > register struct msqid_ds *msqptr = NULL; >+ struct msgpriv *mp; > > #ifdef MSG_DEBUG_OK > printf("msgget(0x%x, 0%o)\n", key, msgflg); >@@ -410,14 +464,19 @@ > if (!jail_sysvipc_allowed && p->p_prison != NULL) > return (ENOSYS); > >+ if (p->p_prison == NULL) >+ mp = &mainmsg; >+ else >+ mp = &p->p_prison->pr_msg; >+ > if (key != IPC_PRIVATE) { >- for (msqid = 0; msqid < msginfo.msgmni; msqid++) { >- msqptr = &msqids[msqid]; >+ for (msqid = 0; msqid < mp->msginfo.msgmni; msqid++) { >+ msqptr = &mp->msqids[msqid]; > if (msqptr->msg_qbytes != 0 && > msqptr->msg_perm.key == key) > break; > } >- if (msqid < msginfo.msgmni) { >+ if (msqid < mp->msginfo.msgmni) { > #ifdef MSG_DEBUG_OK > printf("found public key\n"); > #endif >@@ -442,19 +501,19 @@ > printf("need to allocate the msqid_ds\n"); > #endif > if (key == IPC_PRIVATE || (msgflg & IPC_CREAT)) { >- for (msqid = 0; msqid < msginfo.msgmni; msqid++) { >+ for (msqid = 0; msqid < mp->msginfo.msgmni; msqid++) { > /* > * Look for an unallocated and unlocked msqid_ds. > * msqid_ds's can be locked by msgsnd or msgrcv while > * they are copying the message in/out. We can't > * re-use the entry until they release it. > */ >- msqptr = &msqids[msqid]; >+ msqptr = &mp->msqids[msqid]; > if (msqptr->msg_qbytes == 0 && > (msqptr->msg_perm.mode & MSG_LOCKED) == 0) > break; > } >- if (msqid == msginfo.msgmni) { >+ if (msqid == mp->msginfo.msgmni) { > #ifdef MSG_DEBUG_OK > printf("no more msqid_ds's available\n"); > #endif >@@ -475,7 +534,7 @@ > msqptr->msg_last = NULL; > msqptr->msg_cbytes = 0; > msqptr->msg_qnum = 0; >- msqptr->msg_qbytes = msginfo.msgmnb; >+ msqptr->msg_qbytes = mp->msginfo.msgmnb; > msqptr->msg_lspid = 0; > msqptr->msg_lrpid = 0; > msqptr->msg_stime = 0; >@@ -516,6 +575,7 @@ > register struct msqid_ds *msqptr; > register struct msg *msghdr; > short next; >+ struct msgpriv *mp; > > #ifdef MSG_DEBUG_OK > printf("call to msgsnd(%d, 0x%x, %d, %d)\n", msqid, user_msgp, msgsz, >@@ -525,17 +585,22 @@ > if (!jail_sysvipc_allowed && p->p_prison != NULL) > return (ENOSYS); > >+ if (p->p_prison == NULL) >+ mp = &mainmsg; >+ else >+ mp = &p->p_prison->pr_msg; >+ > msqid = IPCID_TO_IX(msqid); > >- if (msqid < 0 || msqid >= msginfo.msgmni) { >+ if (msqid < 0 || msqid >= mp->msginfo.msgmni) { > #ifdef MSG_DEBUG_OK > printf("msqid (%d) out of range (0<=msqid<%d)\n", msqid, >- msginfo.msgmni); >+ mp->msginfo.msgmni); > #endif > return(EINVAL); > } > >- msqptr = &msqids[msqid]; >+ msqptr = &mp->msqids[msqid]; > if (msqptr->msg_qbytes == 0) { > #ifdef MSG_DEBUG_OK > printf("no such message queue id\n"); >@@ -556,10 +621,10 @@ > return(eval); > } > >- segs_needed = (msgsz + msginfo.msgssz - 1) / msginfo.msgssz; >+ segs_needed = (msgsz + mp->msginfo.msgssz - 1) / mp->msginfo.msgssz; > #ifdef MSG_DEBUG_OK >- printf("msgsz=%d, msgssz=%d, segs_needed=%d\n", msgsz, msginfo.msgssz, >- segs_needed); >+ printf("msgsz=%d, msgssz=%d, segs_needed=%d\n", msgsz, >+ mp->msginfo.msgssz, segs_needed); > #endif > for (;;) { > int need_more_resources = 0; >@@ -588,13 +653,13 @@ > #endif > need_more_resources = 1; > } >- if (segs_needed > nfree_msgmaps) { >+ if (segs_needed > mp->nfree_msgmaps) { > #ifdef MSG_DEBUG_OK > printf("segs_needed > nfree_msgmaps\n"); > #endif > need_more_resources = 1; > } >- if (free_msghdrs == NULL) { >+ if (mp->free_msghdrs == NULL) { > #ifdef MSG_DEBUG_OK > printf("no more msghdrs\n"); > #endif >@@ -668,11 +733,11 @@ > > if (msqptr->msg_perm.mode & MSG_LOCKED) > panic("msg_perm.mode & MSG_LOCKED"); >- if (segs_needed > nfree_msgmaps) >+ if (segs_needed > mp->nfree_msgmaps) > panic("segs_needed > nfree_msgmaps"); > if (msgsz + msqptr->msg_cbytes > msqptr->msg_qbytes) > panic("msgsz + msg_cbytes > msg_qbytes"); >- if (free_msghdrs == NULL) >+ if (mp->free_msghdrs == NULL) > panic("no more msghdrs"); > > /* >@@ -688,8 +753,8 @@ > * Allocate a message header > */ > >- msghdr = free_msghdrs; >- free_msghdrs = msghdr->msg_next; >+ msghdr = mp->free_msghdrs; >+ mp->free_msghdrs = msghdr->msg_next; > msghdr->msg_spot = -1; > msghdr->msg_ts = msgsz; > >@@ -698,21 +763,21 @@ > */ > > while (segs_needed > 0) { >- if (nfree_msgmaps <= 0) >+ if (mp->nfree_msgmaps <= 0) > panic("not enough msgmaps"); >- if (free_msgmaps == -1) >+ if (mp->free_msgmaps == -1) > panic("nil free_msgmaps"); >- next = free_msgmaps; >+ next = mp->free_msgmaps; > if (next <= -1) > panic("next too low #1"); >- if (next >= msginfo.msgseg) >+ if (next >= mp->msginfo.msgseg) > panic("next out of range #1"); > #ifdef MSG_DEBUG_OK > printf("allocating segment %d to message\n", next); > #endif >- free_msgmaps = msgmaps[next].next; >- nfree_msgmaps--; >- msgmaps[next].next = msghdr->msg_spot; >+ mp->free_msgmaps = mp->msgmaps[next].next; >+ mp->nfree_msgmaps--; >+ mp->msgmaps[next].next = msghdr->msg_spot; > msghdr->msg_spot = next; > segs_needed--; > } >@@ -754,16 +819,16 @@ > next = msghdr->msg_spot; > while (msgsz > 0) { > size_t tlen; >- if (msgsz > msginfo.msgssz) >- tlen = msginfo.msgssz; >+ if (msgsz > mp->msginfo.msgssz) >+ tlen = mp->msginfo.msgssz; > else > tlen = msgsz; > if (next <= -1) > panic("next too low #2"); >- if (next >= msginfo.msgseg) >+ if (next >= mp->msginfo.msgseg) > panic("next out of range #2"); >- if ((eval = copyin(user_msgp, &msgpool[next * msginfo.msgssz], >- tlen)) != 0) { >+ if ((eval = copyin(user_msgp, >+ &mp->msgpool[next * mp->msginfo.msgssz], tlen)) != 0) { > #ifdef MSG_DEBUG_OK > printf("error %d copying in message segment\n", eval); > #endif >@@ -774,7 +839,7 @@ > } > msgsz -= tlen; > user_msgp = (char *)user_msgp + tlen; >- next = msgmaps[next].next; >+ next = mp->msgmaps[next].next; > } > if (next != -1) > panic("didn't use all the msg segments"); >@@ -843,6 +908,7 @@ > register struct msg *msghdr; > int eval; > short next; >+ struct msgpriv *mp; > > #ifdef MSG_DEBUG_OK > printf("call to msgrcv(%d, 0x%x, %d, %ld, %d)\n", msqid, user_msgp, >@@ -852,17 +918,22 @@ > if (!jail_sysvipc_allowed && p->p_prison != NULL) > return (ENOSYS); > >+ if (p->p_prison == NULL) >+ mp = &mainmsg; >+ else >+ mp = &p->p_prison->pr_msg; >+ > msqid = IPCID_TO_IX(msqid); > >- if (msqid < 0 || msqid >= msginfo.msgmni) { >+ if (msqid < 0 || msqid >= mp->msginfo.msgmni) { > #ifdef MSG_DEBUG_OK > printf("msqid (%d) out of range (0<=msqid<%d)\n", msqid, >- msginfo.msgmni); >+ mp->msginfo.msgmni); > #endif > return(EINVAL); > } > >- msqptr = &msqids[msqid]; >+ msqptr = &mp->msqids[msqid]; > if (msqptr->msg_qbytes == 0) { > #ifdef MSG_DEBUG_OK > printf("no such message queue id\n"); >@@ -1065,18 +1136,18 @@ > */ > > next = msghdr->msg_spot; >- for (len = 0; len < msgsz; len += msginfo.msgssz) { >+ for (len = 0; len < msgsz; len += mp->msginfo.msgssz) { > size_t tlen; > >- if (msgsz - len > msginfo.msgssz) >- tlen = msginfo.msgssz; >+ if (msgsz - len > mp->msginfo.msgssz) >+ tlen = mp->msginfo.msgssz; > else > tlen = msgsz - len; > if (next <= -1) > panic("next too low #3"); >- if (next >= msginfo.msgseg) >+ if (next >= mp->msginfo.msgseg) > panic("next out of range #3"); >- eval = copyout((caddr_t)&msgpool[next * msginfo.msgssz], >+ eval = copyout((caddr_t)&mp->msgpool[next * mp->msginfo.msgssz], > user_msgp, tlen); > if (eval != 0) { > #ifdef MSG_DEBUG_OK >@@ -1088,7 +1159,7 @@ > return(eval); > } > user_msgp = (char *)user_msgp + tlen; >- next = msgmaps[next].next; >+ next = mp->msgmaps[next].next; > } > > /* >@@ -1101,24 +1172,155 @@ > return(0); > } > >-static int >-sysctl_msqids(SYSCTL_HANDLER_ARGS) >+void >+msgclear(struct prison *pr) > { >+ struct msgpriv *mp; > >- return (SYSCTL_OUT(req, msqids, >- sizeof(struct msqid_ds) * msginfo.msgmni)); >+ if (pr == NULL) >+ mp = &mainmsg; >+ else >+ mp = &pr->pr_msg; >+ >+ free(mp->msgpool, M_MSG); >+ free(mp->msgmaps, M_MSG); >+ free(mp->msghdrs, M_MSG); >+ free(mp->msqids, M_MSG); > } > >-TUNABLE_INT("kern.ipc.msgseg", &msginfo.msgseg); >-TUNABLE_INT("kern.ipc.msgssz", &msginfo.msgssz); >-TUNABLE_INT("kern.ipc.msgmni", &msginfo.msgmni); >+/* XXX: Should it stay? */ >+TUNABLE_INT("kern.ipc.msgseg", &mainmsg.msginfo.msgseg); >+TUNABLE_INT("kern.ipc.msgssz", &mainmsg.msginfo.msgssz); >+TUNABLE_INT("kern.ipc.msgmni", &mainmsg.msginfo.msgmni); > > SYSCTL_DECL(_kern_ipc); >-SYSCTL_INT(_kern_ipc, OID_AUTO, msgmax, CTLFLAG_RD, &msginfo.msgmax, 0, ""); >-SYSCTL_INT(_kern_ipc, OID_AUTO, msgmni, CTLFLAG_RD, &msginfo.msgmni, 0, ""); >-SYSCTL_INT(_kern_ipc, OID_AUTO, msgmnb, CTLFLAG_RD, &msginfo.msgmnb, 0, ""); >-SYSCTL_INT(_kern_ipc, OID_AUTO, msgtql, CTLFLAG_RD, &msginfo.msgtql, 0, ""); >-SYSCTL_INT(_kern_ipc, OID_AUTO, msgssz, CTLFLAG_RD, &msginfo.msgssz, 0, ""); >-SYSCTL_INT(_kern_ipc, OID_AUTO, msgseg, CTLFLAG_RD, &msginfo.msgseg, 0, ""); >+ >+static int >+sysctl_msqids(SYSCTL_HANDLER_ARGS) >+{ >+ struct msgpriv *mp; >+ >+ if (req->p->p_prison == NULL) >+ mp = &mainmsg; >+ else >+ mp = &req->p->p_prison->pr_msg; >+ >+ return (SYSCTL_OUT(req, mp->msqids, >+ sizeof(struct msqid_ds) * mp->msginfo.msgmni)); >+} > SYSCTL_PROC(_kern_ipc, OID_AUTO, msqids, CTLFLAG_RD, > NULL, 0, sysctl_msqids, "", "Message queue IDs"); >+ >+static int >+sysctl_msginfo(SYSCTL_HANDLER_ARGS) >+{ >+ struct msgpriv *mp; >+ >+ if (req->p->p_prison == NULL) >+ mp = &mainmsg; >+ else >+ mp = &req->p->p_prison->pr_msg; >+ >+ return (sysctl_handle_opaque(oidp, &mp->msginfo, sizeof(struct msginfo), >+ req)); >+} >+SYSCTL_PROC(_kern_ipc, OID_AUTO, msginfo, CTLTYPE_STRUCT | CTLFLAG_RD, 0, 0, >+ sysctl_msginfo, "S,msginfo",""); >+ >+#define IPC_MSGMAX 0 >+#define IPC_MSGMNI 1 >+#define IPC_MSGMNB 2 >+#define IPC_MSGTQL 3 >+#define IPC_MSGSSZ 4 >+#define IPC_MSGSEG 5 >+ >+static int >+sysctl_msginfo_val(struct sysctl_oid *oidp, struct sysctl_req *req, u_int type) >+{ >+ int *msginfo; >+ struct msgpriv *mp; >+ >+ if (req->p->p_prison == NULL) >+ mp = &mainmsg; >+ else >+ mp = &req->p->p_prison->pr_msg; >+ >+ switch (type) { >+ case IPC_MSGMAX: >+ msginfo = &mp->msginfo.msgmax; >+ break; >+ case IPC_MSGMNI: >+ msginfo = &mp->msginfo.msgmni; >+ break; >+ case IPC_MSGMNB: >+ msginfo = &mp->msginfo.msgmnb; >+ break; >+ case IPC_MSGTQL: >+ msginfo = &mp->msginfo.msgtql; >+ break; >+ case IPC_MSGSSZ: >+ msginfo = &mp->msginfo.msgssz; >+ break; >+ case IPC_MSGSEG: >+ msginfo = &mp->msginfo.msgseg; >+ break; >+ default: >+ panic("unknown msg type"); >+ } >+ >+ return (sysctl_handle_int(oidp, msginfo, 0, req)); >+} >+ >+static int >+sysctl_msginfo_msgmax(SYSCTL_HANDLER_ARGS) >+{ >+ >+ return (sysctl_msginfo_val(oidp, req, IPC_MSGMAX)); >+} >+SYSCTL_PROC(_kern_ipc, OID_AUTO, msgmax, CTLTYPE_INT|CTLFLAG_RD, 0, 0, >+ sysctl_msginfo_msgmax, "IU", ""); >+ >+static int >+sysctl_msginfo_msgmni(SYSCTL_HANDLER_ARGS) >+{ >+ >+ return (sysctl_msginfo_val(oidp, req, IPC_MSGMNI)); >+} >+SYSCTL_PROC(_kern_ipc, OID_AUTO, msgmni, CTLTYPE_INT|CTLFLAG_RD, 0, 0, >+ sysctl_msginfo_msgmni, "IU", ""); >+ >+static int >+sysctl_msginfo_msgmnb(SYSCTL_HANDLER_ARGS) >+{ >+ >+ return (sysctl_msginfo_val(oidp, req, IPC_MSGMNB)); >+} >+SYSCTL_PROC(_kern_ipc, OID_AUTO, msgmnb, CTLTYPE_INT|CTLFLAG_RD, 0, 0, >+ sysctl_msginfo_msgmnb, "IU", ""); >+ >+static int >+sysctl_msginfo_msgtql(SYSCTL_HANDLER_ARGS) >+{ >+ >+ return (sysctl_msginfo_val(oidp, req, IPC_MSGTQL)); >+} >+SYSCTL_PROC(_kern_ipc, OID_AUTO, msgtql, CTLTYPE_INT|CTLFLAG_RD, 0, 0, >+ sysctl_msginfo_msgtql, "IU", ""); >+ >+static int >+sysctl_msginfo_msgssz(SYSCTL_HANDLER_ARGS) >+{ >+ >+ return (sysctl_msginfo_val(oidp, req, IPC_MSGSSZ)); >+} >+SYSCTL_PROC(_kern_ipc, OID_AUTO, msgssz, CTLTYPE_INT|CTLFLAG_RD, 0, 0, >+ sysctl_msginfo_msgssz, "IU", ""); >+ >+static int >+sysctl_msginfo_msgseg(SYSCTL_HANDLER_ARGS) >+{ >+ >+ return (sysctl_msginfo_val(oidp, req, IPC_MSGSEG)); >+} >+SYSCTL_PROC(_kern_ipc, OID_AUTO, msgseg, CTLTYPE_INT|CTLFLAG_RD, 0, 0, >+ sysctl_msginfo_msgseg, "IU", ""); >diff -ru /sys/kern/sysv_sem.c sys/kern/sysv_sem.c >--- /sys/kern/sysv_sem.c Wed Feb 19 19:29:13 2003 >+++ sys/kern/sysv_sem.c Wed Feb 19 18:27:06 2003 >@@ -1,9 +1,10 @@ >-/* $FreeBSD: src/sys/kern/sysv_sem.c,v 1.24.2.8 2002/10/22 20:45:03 fjoe Exp $ */ >+/* $FreeBSD$ */ > > /* > * Implementation of SVID semaphores > * > * Author: Daniel Boulet >+ * Jailed by: Pawel Jakub Dawidek <nick@garage.freebsd.pl> > * > * This software is provided ``AS IS'' without any warranties of any kind. > */ >@@ -23,8 +24,6 @@ > > static MALLOC_DEFINE(M_SEM, "sem", "SVID compatible semaphores"); > >-static void seminit __P((void *)); >- > #ifndef _SYS_SYSPROTO_H_ > struct __semctl_args; > int __semctl __P((struct proc *p, struct __semctl_args *uap)); >@@ -45,33 +44,6 @@ > (sy_call_t *)semop > }; > >-static int semtot = 0; >-static struct semid_ds *sema; /* semaphore id pool */ >-static struct sem *sem; /* semaphore pool */ >-static struct sem_undo *semu_list; /* list of active undo structures */ >-static int *semu; /* undo structure pool */ >- >-struct sem { >- u_short semval; /* semaphore value */ >- pid_t sempid; /* pid of last operation */ >- u_short semncnt; /* # awaiting semval > cval */ >- u_short semzcnt; /* # awaiting semval = 0 */ >-}; >- >-/* >- * Undo structure (one per process) >- */ >-struct sem_undo { >- struct sem_undo *un_next; /* ptr to next active undo structure */ >- struct proc *un_proc; /* owner of this structure */ >- short un_cnt; /* # of active entries */ >- struct undo { >- short un_adjval; /* adjust on exit values */ >- short un_num; /* semaphore # */ >- int un_id; /* semid */ >- } un_ent[1]; /* undo entries */ >-}; >- > /* > * Configuration parameters > */ >@@ -115,46 +87,7 @@ > /* > * Macro to find a particular sem_undo vector > */ >-#define SEMU(ix) ((struct sem_undo *)(((intptr_t)semu)+ix * seminfo.semusz)) >- >-/* >- * semaphore info struct >- */ >-struct seminfo seminfo = { >- SEMMAP, /* # of entries in semaphore map */ >- SEMMNI, /* # of semaphore identifiers */ >- SEMMNS, /* # of semaphores in system */ >- SEMMNU, /* # of undo structures in system */ >- SEMMSL, /* max # of semaphores per id */ >- SEMOPM, /* max # of operations per semop call */ >- SEMUME, /* max # of undo entries per process */ >- SEMUSZ, /* size in bytes of undo structure */ >- SEMVMX, /* semaphore maximum value */ >- SEMAEM /* adjust on exit max value */ >-}; >- >-TUNABLE_INT("kern.ipc.semmap", &seminfo.semmap); >-TUNABLE_INT("kern.ipc.semmni", &seminfo.semmni); >-TUNABLE_INT("kern.ipc.semmns", &seminfo.semmns); >-TUNABLE_INT("kern.ipc.semmnu", &seminfo.semmnu); >-TUNABLE_INT("kern.ipc.semmsl", &seminfo.semmsl); >-TUNABLE_INT("kern.ipc.semopm", &seminfo.semopm); >-TUNABLE_INT("kern.ipc.semume", &seminfo.semume); >-TUNABLE_INT("kern.ipc.semusz", &seminfo.semusz); >-TUNABLE_INT("kern.ipc.semvmx", &seminfo.semvmx); >-TUNABLE_INT("kern.ipc.semaem", &seminfo.semaem); >- >-SYSCTL_DECL(_kern_ipc); >-SYSCTL_INT(_kern_ipc, OID_AUTO, semmap, CTLFLAG_RW, &seminfo.semmap, 0, ""); >-SYSCTL_INT(_kern_ipc, OID_AUTO, semmni, CTLFLAG_RD, &seminfo.semmni, 0, ""); >-SYSCTL_INT(_kern_ipc, OID_AUTO, semmns, CTLFLAG_RD, &seminfo.semmns, 0, ""); >-SYSCTL_INT(_kern_ipc, OID_AUTO, semmnu, CTLFLAG_RD, &seminfo.semmnu, 0, ""); >-SYSCTL_INT(_kern_ipc, OID_AUTO, semmsl, CTLFLAG_RW, &seminfo.semmsl, 0, ""); >-SYSCTL_INT(_kern_ipc, OID_AUTO, semopm, CTLFLAG_RD, &seminfo.semopm, 0, ""); >-SYSCTL_INT(_kern_ipc, OID_AUTO, semume, CTLFLAG_RD, &seminfo.semume, 0, ""); >-SYSCTL_INT(_kern_ipc, OID_AUTO, semusz, CTLFLAG_RD, &seminfo.semusz, 0, ""); >-SYSCTL_INT(_kern_ipc, OID_AUTO, semvmx, CTLFLAG_RW, &seminfo.semvmx, 0, ""); >-SYSCTL_INT(_kern_ipc, OID_AUTO, semaem, CTLFLAG_RW, &seminfo.semaem, 0, ""); >+#define SEMU(ix) ((struct sem_undo *)(((intptr_t)sp->semu)+ix * sp->seminfo.semusz)) > > #if 0 > RO seminfo.semmap /* SEMMAP unused */ >@@ -169,31 +102,79 @@ > RO seminfo.semaem /* SEMAEM unused - user param */ > #endif > >-static void >-seminit(dummy) >- void *dummy; >+/* Global struct for main system, all jails have its own. */ >+struct sempriv mainsem; >+ >+int >+seminit(struct prison *pr) > { > register int i; >+ struct sempriv *sp; >+ int error; >+ >+ if (pr == NULL) >+ sp = &mainsem; >+ else >+ sp = &pr->pr_sem; >+ >+ sp->semtot = 0; >+ >+ sp->seminfo.semmap = SEMMAP; >+ sp->seminfo.semmni = SEMMNI; >+ sp->seminfo.semmns = SEMMNS; >+ sp->seminfo.semmnu = SEMMNU; >+ sp->seminfo.semmsl = SEMMSL; >+ sp->seminfo.semopm = SEMOPM; >+ sp->seminfo.semume = SEMUME; >+ sp->seminfo.semusz = SEMUSZ; >+ sp->seminfo.semvmx = SEMVMX; >+ sp->seminfo.semaem = SEMAEM; >+ >+ sp->sem = malloc(sizeof(struct sem) * sp->seminfo.semmns, M_SEM, M_WAITOK); >+ if (sp->sem == NULL) { >+ if (pr == NULL) >+ panic("sem is NULL"); >+ else >+ return (ENOMEM); >+ } > >- sem = malloc(sizeof(struct sem) * seminfo.semmns, M_SEM, M_WAITOK); >- if (sem == NULL) >- panic("sem is NULL"); >- sema = malloc(sizeof(struct semid_ds) * seminfo.semmni, M_SEM, M_WAITOK); >- if (sema == NULL) >- panic("sema is NULL"); >- semu = malloc(seminfo.semmnu * seminfo.semusz, M_SEM, M_WAITOK); >- if (semu == NULL) >- panic("semu is NULL"); >- >- for (i = 0; i < seminfo.semmni; i++) { >- sema[i].sem_base = 0; >- sema[i].sem_perm.mode = 0; >+ sp->sema = malloc(sizeof(struct semid_ds) * sp->seminfo.semmni, M_SEM, M_WAITOK); >+ if (sp->sema == NULL) { >+ if (pr == NULL) >+ panic("sema is NULL"); >+ else { >+ error = ENOMEM; >+ goto fail_sema; >+ } >+ } >+ >+ sp->semu = malloc(sp->seminfo.semmnu * sp->seminfo.semusz, M_SEM, M_WAITOK); >+ if (sp->semu == NULL) { >+ if (pr == NULL) >+ panic("semu is NULL"); >+ else { >+ error = ENOMEM; >+ goto fail_semu; >+ } > } >- for (i = 0; i < seminfo.semmnu; i++) { >+ >+ for (i = 0; i < sp->seminfo.semmni; i++) { >+ sp->sema[i].sem_base = 0; >+ sp->sema[i].sem_perm.mode = 0; >+ } >+ for (i = 0; i < sp->seminfo.semmnu; i++) { > register struct sem_undo *suptr = SEMU(i); > suptr->un_proc = NULL; > } >- semu_list = NULL; >+ sp->semu_list = NULL; >+ >+ return (0); >+fail_sema: >+ free(sp->sem, M_SEM); >+fail_semu: >+ free(sp->sema, M_SEM); >+ >+ return (error); > } > SYSINIT(sysv_sem, SI_SUB_SYSV_SEM, SI_ORDER_FIRST, seminit, NULL) > >@@ -234,6 +215,12 @@ > register struct sem_undo *suptr; > register struct sem_undo **supptr; > int attempt; >+ struct sempriv *sp; >+ >+ if (p->p_prison == NULL) >+ sp = &mainsem; >+ else >+ sp = &p->p_prison->pr_sem; > > /* > * Try twice to allocate something. >@@ -247,11 +234,11 @@ > * Fill it in and return it if we find one. > */ > >- for (i = 0; i < seminfo.semmnu; i++) { >+ for (i = 0; i < sp->seminfo.semmnu; i++) { > suptr = SEMU(i); > if (suptr->un_proc == NULL) { >- suptr->un_next = semu_list; >- semu_list = suptr; >+ suptr->un_next = sp->semu_list; >+ sp->semu_list = suptr; > suptr->un_cnt = 0; > suptr->un_proc = p; > return(suptr); >@@ -267,7 +254,7 @@ > /* All the structures are in use - try to free some */ > int did_something = 0; > >- supptr = &semu_list; >+ supptr = &sp->semu_list; > while ((suptr = *supptr) != NULL) { > if (suptr->un_cnt == 0) { > suptr->un_proc = NULL; >@@ -306,13 +293,19 @@ > register struct sem_undo *suptr; > register struct undo *sunptr; > int i; >+ struct sempriv *sp; >+ >+ if (p->p_prison == NULL) >+ sp = &mainsem; >+ else >+ sp = &p->p_prison->pr_sem; > > /* Look for and remember the sem_undo if the caller doesn't provide > it */ > > suptr = *supptr; > if (suptr == NULL) { >- for (suptr = semu_list; suptr != NULL; >+ for (suptr = sp->semu_list; suptr != NULL; > suptr = suptr->un_next) { > if (suptr->un_proc == p) { > *supptr = suptr; >@@ -353,7 +346,7 @@ > /* Didn't find the right entry - create it */ > if (adjval == 0) > return(0); >- if (suptr->un_cnt != seminfo.semume) { >+ if (suptr->un_cnt != sp->seminfo.semume) { > sunptr = &suptr->un_ent[suptr->un_cnt]; > suptr->un_cnt++; > sunptr->un_adjval = adjval; >@@ -368,8 +361,14 @@ > int semid, semnum; > { > register struct sem_undo *suptr; >+ struct sempriv *sp; >+ >+ if (curproc->p_prison == NULL) >+ sp = &mainsem; >+ else >+ sp = &curproc->p_prison->pr_sem; > >- for (suptr = semu_list; suptr != NULL; suptr = suptr->un_next) { >+ for (suptr = sp->semu_list; suptr != NULL; suptr = suptr->un_next) { > register struct undo *sunptr = &suptr->un_ent[0]; > register int i = 0; > >@@ -417,6 +416,7 @@ > int i, rval, eval; > struct semid_ds sbuf; > register struct semid_ds *semaptr; >+ struct sempriv *sp; > > #ifdef SEM_DEBUG > printf("call to semctl(%d, %d, %d, 0x%x)\n", semid, semnum, cmd, arg); >@@ -425,11 +425,16 @@ > if (!jail_sysvipc_allowed && p->p_prison != NULL) > return (ENOSYS); > >+ if (p->p_prison == NULL) >+ sp = &mainsem; >+ else >+ sp = &p->p_prison->pr_sem; >+ > semid = IPCID_TO_IX(semid); >- if (semid < 0 || semid >= seminfo.semmni) >+ if (semid < 0 || semid >= sp->seminfo.semmni) > return(EINVAL); > >- semaptr = &sema[semid]; >+ semaptr = &sp->sema[semid]; > if ((semaptr->sem_perm.mode & SEM_ALLOC) == 0 || > semaptr->sem_perm.seq != IPCID_TO_SEQ(uap->semid)) > return(EINVAL); >@@ -443,13 +448,13 @@ > return(eval); > semaptr->sem_perm.cuid = cred->cr_uid; > semaptr->sem_perm.uid = cred->cr_uid; >- semtot -= semaptr->sem_nsems; >- for (i = semaptr->sem_base - sem; i < semtot; i++) >- sem[i] = sem[i + semaptr->sem_nsems]; >- for (i = 0; i < seminfo.semmni; i++) { >- if ((sema[i].sem_perm.mode & SEM_ALLOC) && >- sema[i].sem_base > semaptr->sem_base) >- sema[i].sem_base -= semaptr->sem_nsems; >+ sp->semtot -= semaptr->sem_nsems; >+ for (i = semaptr->sem_base - sp->sem; i < sp->semtot; i++) >+ sp->sem[i] = sp->sem[i + semaptr->sem_nsems]; >+ for (i = 0; i < sp->seminfo.semmni; i++) { >+ if ((sp->sema[i].sem_perm.mode & SEM_ALLOC) && >+ sp->sema[i].sem_base > semaptr->sem_base) >+ sp->sema[i].sem_base -= semaptr->sem_nsems; > } > semaptr->sem_perm.mode = 0; > semundo_clear(semid, -1); >@@ -580,6 +585,7 @@ > int nsems = uap->nsems; > int semflg = uap->semflg; > struct ucred *cred = p->p_ucred; >+ struct sempriv *sp; > > #ifdef SEM_DEBUG > printf("semget(0x%x, %d, 0%o)\n", key, nsems, semflg); >@@ -588,20 +594,25 @@ > if (!jail_sysvipc_allowed && p->p_prison != NULL) > return (ENOSYS); > >+ if (p->p_prison == NULL) >+ sp = &mainsem; >+ else >+ sp = &p->p_prison->pr_sem; >+ > if (key != IPC_PRIVATE) { >- for (semid = 0; semid < seminfo.semmni; semid++) { >- if ((sema[semid].sem_perm.mode & SEM_ALLOC) && >- sema[semid].sem_perm.key == key) >+ for (semid = 0; semid < sp->seminfo.semmni; semid++) { >+ if ((sp->sema[semid].sem_perm.mode & SEM_ALLOC) && >+ sp->sema[semid].sem_perm.key == key) > break; > } >- if (semid < seminfo.semmni) { >+ if (semid < sp->seminfo.semmni) { > #ifdef SEM_DEBUG > printf("found public key\n"); > #endif >- if ((eval = ipcperm(p, &sema[semid].sem_perm, >+ if ((eval = ipcperm(p, &sp->sema[semid].sem_perm, > semflg & 0700))) > return(eval); >- if (nsems > 0 && sema[semid].sem_nsems < nsems) { >+ if (nsems > 0 && sp->sema[semid].sem_nsems < nsems) { > #ifdef SEM_DEBUG > printf("too small\n"); > #endif >@@ -621,25 +632,25 @@ > printf("need to allocate the semid_ds\n"); > #endif > if (key == IPC_PRIVATE || (semflg & IPC_CREAT)) { >- if (nsems <= 0 || nsems > seminfo.semmsl) { >+ if (nsems <= 0 || nsems > sp->seminfo.semmsl) { > #ifdef SEM_DEBUG > printf("nsems out of range (0<%d<=%d)\n", nsems, >- seminfo.semmsl); >+ sp->seminfo.semmsl); > #endif > return(EINVAL); > } >- if (nsems > seminfo.semmns - semtot) { >+ if (nsems > sp->seminfo.semmns - sp->semtot) { > #ifdef SEM_DEBUG > printf("not enough semaphores left (need %d, got %d)\n", >- nsems, seminfo.semmns - semtot); >+ nsems, sp->seminfo.semmns - sp->semtot); > #endif > return(ENOSPC); > } >- for (semid = 0; semid < seminfo.semmni; semid++) { >- if ((sema[semid].sem_perm.mode & SEM_ALLOC) == 0) >+ for (semid = 0; semid < sp->seminfo.semmni; semid++) { >+ if ((sp->sema[semid].sem_perm.mode & SEM_ALLOC) == 0) > break; > } >- if (semid == seminfo.semmni) { >+ if (semid == sp->seminfo.semmni) { > #ifdef SEM_DEBUG > printf("no more semid_ds's available\n"); > #endif >@@ -648,24 +659,24 @@ > #ifdef SEM_DEBUG > printf("semid %d is available\n", semid); > #endif >- sema[semid].sem_perm.key = key; >- sema[semid].sem_perm.cuid = cred->cr_uid; >- sema[semid].sem_perm.uid = cred->cr_uid; >- sema[semid].sem_perm.cgid = cred->cr_gid; >- sema[semid].sem_perm.gid = cred->cr_gid; >- sema[semid].sem_perm.mode = (semflg & 0777) | SEM_ALLOC; >- sema[semid].sem_perm.seq = >- (sema[semid].sem_perm.seq + 1) & 0x7fff; >- sema[semid].sem_nsems = nsems; >- sema[semid].sem_otime = 0; >- sema[semid].sem_ctime = time_second; >- sema[semid].sem_base = &sem[semtot]; >- semtot += nsems; >- bzero(sema[semid].sem_base, >- sizeof(sema[semid].sem_base[0])*nsems); >+ sp->sema[semid].sem_perm.key = key; >+ sp->sema[semid].sem_perm.cuid = cred->cr_uid; >+ sp->sema[semid].sem_perm.uid = cred->cr_uid; >+ sp->sema[semid].sem_perm.cgid = cred->cr_gid; >+ sp->sema[semid].sem_perm.gid = cred->cr_gid; >+ sp->sema[semid].sem_perm.mode = (semflg & 0777) | SEM_ALLOC; >+ sp->sema[semid].sem_perm.seq = >+ (sp->sema[semid].sem_perm.seq + 1) & 0x7fff; >+ sp->sema[semid].sem_nsems = nsems; >+ sp->sema[semid].sem_otime = 0; >+ sp->sema[semid].sem_ctime = time_second; >+ sp->sema[semid].sem_base = &sp->sem[sp->semtot]; >+ sp->semtot += nsems; >+ bzero(sp->sema[semid].sem_base, >+ sizeof(sp->sema[semid].sem_base[0])*nsems); > #ifdef SEM_DEBUG >- printf("sembase = 0x%x, next = 0x%x\n", sema[semid].sem_base, >- &sem[semtot]); >+ printf("sembase = 0x%x, next = 0x%x\n", sp->sema[semid].sem_base, >+ &sp->sem[sp->semtot]); > #endif > } else { > #ifdef SEM_DEBUG >@@ -675,7 +686,7 @@ > } > > found: >- p->p_retval[0] = IXSEQ_TO_IPCID(semid, sema[semid].sem_perm); >+ p->p_retval[0] = IXSEQ_TO_IPCID(semid, sp->sema[semid].sem_perm); > return(0); > } > >@@ -701,6 +712,7 @@ > struct sem_undo *suptr = NULL; > int i, j, eval; > int do_wakeup, do_undos; >+ struct sempriv *sp; > > #ifdef SEM_DEBUG > printf("call to semop(%d, 0x%x, %u)\n", semid, sops, nsops); >@@ -709,12 +721,17 @@ > if (!jail_sysvipc_allowed && p->p_prison != NULL) > return (ENOSYS); > >+ if (p->p_prison == NULL) >+ sp = &mainsem; >+ else >+ sp = &p->p_prison->pr_sem; >+ > semid = IPCID_TO_IX(semid); /* Convert back to zero origin */ > >- if (semid < 0 || semid >= seminfo.semmni) >+ if (semid < 0 || semid >= sp->seminfo.semmni) > return(EINVAL); > >- semaptr = &sema[semid]; >+ semaptr = &sp->sema[semid]; > if ((semaptr->sem_perm.mode & SEM_ALLOC) == 0) > return(EINVAL); > if (semaptr->sem_perm.seq != IPCID_TO_SEQ(uap->semid)) >@@ -951,6 +968,12 @@ > register struct sem_undo *suptr; > register struct sem_undo **supptr; > int did_something; >+ struct sempriv *sp; >+ >+ if (p->p_prison == NULL) >+ sp = &mainsem; >+ else >+ sp = &p->p_prison->pr_sem; > > did_something = 0; > >@@ -959,7 +982,7 @@ > * associated with this process. > */ > >- for (supptr = &semu_list; (suptr = *supptr) != NULL; >+ for (supptr = &sp->semu_list; (suptr = *supptr) != NULL; > supptr = &suptr->un_next) { > if (suptr->un_proc == p) > break; >@@ -985,7 +1008,7 @@ > int adjval = suptr->un_ent[ix].un_adjval; > struct semid_ds *semaptr; > >- semaptr = &sema[semid]; >+ semaptr = &sp->sema[semid]; > if ((semaptr->sem_perm.mode & SEM_ALLOC) == 0) > panic("semexit - semid not allocated"); > if (semnum >= semaptr->sem_nsems) >@@ -1024,3 +1047,213 @@ > suptr->un_proc = NULL; > *supptr = suptr->un_next; > } >+ >+void >+semclear(struct prison *pr) >+{ >+ struct sempriv *sp; >+ >+ if (pr == NULL) >+ sp = &mainsem; >+ else >+ sp = &pr->pr_sem; >+ >+ free(sp->sem, M_SEM); >+ free(sp->sema, M_SEM); >+ free(sp->semu, M_SEM); >+} >+ >+TUNABLE_INT("kern.ipc.semmap", &mainsem.seminfo.semmap); >+TUNABLE_INT("kern.ipc.semmni", &mainsem.seminfo.semmni); >+TUNABLE_INT("kern.ipc.semmns", &mainsem.seminfo.semmns); >+TUNABLE_INT("kern.ipc.semmnu", &mainsem.seminfo.semmnu); >+TUNABLE_INT("kern.ipc.semmsl", &mainsem.seminfo.semmsl); >+TUNABLE_INT("kern.ipc.semopm", &mainsem.seminfo.semopm); >+TUNABLE_INT("kern.ipc.semume", &mainsem.seminfo.semume); >+TUNABLE_INT("kern.ipc.semusz", &mainsem.seminfo.semusz); >+TUNABLE_INT("kern.ipc.semvmx", &mainsem.seminfo.semvmx); >+TUNABLE_INT("kern.ipc.semaem", &mainsem.seminfo.semaem); >+ >+SYSCTL_DECL(_kern_ipc); >+ >+static int >+sysctl_sema(SYSCTL_HANDLER_ARGS) >+{ >+ struct sempriv *sp; >+ >+ if (req->p->p_prison == NULL) >+ sp = &mainsem; >+ else >+ sp = &req->p->p_prison->pr_sem; >+ >+ return (SYSCTL_OUT(req, sp->sema, >+ sizeof(struct semid_ds) * sp->seminfo.semmni)); >+} >+SYSCTL_PROC(_kern_ipc, OID_AUTO, sema, CTLFLAG_RD, >+ NULL, 0, sysctl_sema, "", "Semaphores IDs"); >+ >+static int >+sysctl_seminfo(SYSCTL_HANDLER_ARGS) >+{ >+ struct sempriv *sp; >+ >+ if (req->p->p_prison == NULL) >+ sp = &mainsem; >+ else >+ sp = &req->p->p_prison->pr_sem; >+ >+ return (sysctl_handle_opaque(oidp, &sp->seminfo, sizeof(struct seminfo), >+ req)); >+} >+SYSCTL_PROC(_kern_ipc, OID_AUTO, seminfo, CTLTYPE_STRUCT | CTLFLAG_RD, 0, 0, >+ sysctl_seminfo, "S,seminfo",""); >+ >+#define IPC_SEMMAP 0 >+#define IPC_SEMMNI 1 >+#define IPC_SEMMNS 2 >+#define IPC_SEMMNU 3 >+#define IPC_SEMMSL 4 >+#define IPC_SEMOPM 5 >+#define IPC_SEMUME 6 >+#define IPC_SEMUSZ 7 >+#define IPC_SEMVMX 8 >+#define IPC_SEMAEM 9 >+ >+static int >+sysctl_seminfo_val(struct sysctl_oid *oidp, struct sysctl_req *req, u_int type) >+{ >+ int *seminfo; >+ struct sempriv *sp; >+ >+ if (req->p->p_prison == NULL) >+ sp = &mainsem; >+ else >+ sp = &req->p->p_prison->pr_sem; >+ >+ switch (type) { >+ case IPC_SEMMAP: >+ seminfo = &sp->seminfo.semmap; >+ break; >+ case IPC_SEMMNI: >+ seminfo = &sp->seminfo.semmni; >+ break; >+ case IPC_SEMMNS: >+ seminfo = &sp->seminfo.semmns; >+ break; >+ case IPC_SEMMNU: >+ seminfo = &sp->seminfo.semmnu; >+ break; >+ case IPC_SEMMSL: >+ seminfo = &sp->seminfo.semmsl; >+ break; >+ case IPC_SEMOPM: >+ seminfo = &sp->seminfo.semopm; >+ break; >+ case IPC_SEMUME: >+ seminfo = &sp->seminfo.semume; >+ break; >+ case IPC_SEMUSZ: >+ seminfo = &sp->seminfo.semume; >+ break; >+ case IPC_SEMVMX: >+ seminfo = &sp->seminfo.semvmx; >+ break; >+ case IPC_SEMAEM: >+ seminfo = &sp->seminfo.semaem; >+ break; >+ default: >+ panic("unknown sem type"); >+ } >+ >+ return (sysctl_handle_int(oidp, seminfo, 0, req)); >+} >+ >+static int >+sysctl_seminfo_semmap(SYSCTL_HANDLER_ARGS) >+{ >+ >+ return (sysctl_seminfo_val(oidp, req, IPC_SEMMAP)); >+} >+SYSCTL_PROC(_kern_ipc, OID_AUTO, semmap, CTLTYPE_INT | CTLFLAG_RD, 0, 0, >+ sysctl_seminfo_semmap, "IU", ""); >+ >+static int >+sysctl_seminfo_semmni(SYSCTL_HANDLER_ARGS) >+{ >+ >+ return (sysctl_seminfo_val(oidp, req, IPC_SEMMNI)); >+} >+SYSCTL_PROC(_kern_ipc, OID_AUTO, semmni, CTLTYPE_INT | CTLFLAG_RD, 0, 0, >+ sysctl_seminfo_semmni, "IU", ""); >+ >+static int >+sysctl_seminfo_semmns(SYSCTL_HANDLER_ARGS) >+{ >+ >+ return (sysctl_seminfo_val(oidp, req, IPC_SEMMNS)); >+} >+SYSCTL_PROC(_kern_ipc, OID_AUTO, semmns, CTLTYPE_INT | CTLFLAG_RD, 0, 0, >+ sysctl_seminfo_semmns, "IU", ""); >+ >+static int >+sysctl_seminfo_semmnu(SYSCTL_HANDLER_ARGS) >+{ >+ >+ return (sysctl_seminfo_val(oidp, req, IPC_SEMMNU)); >+} >+SYSCTL_PROC(_kern_ipc, OID_AUTO, semmnu, CTLTYPE_INT | CTLFLAG_RD, 0, 0, >+ sysctl_seminfo_semmnu, "IU", ""); >+ >+static int >+sysctl_seminfo_semmsl(SYSCTL_HANDLER_ARGS) >+{ >+ >+ return (sysctl_seminfo_val(oidp, req, IPC_SEMMSL)); >+} >+SYSCTL_PROC(_kern_ipc, OID_AUTO, semmsl, CTLTYPE_INT | CTLFLAG_RD, 0, 0, >+ sysctl_seminfo_semmsl, "IU", ""); >+ >+static int >+sysctl_seminfo_semopm(SYSCTL_HANDLER_ARGS) >+{ >+ >+ return (sysctl_seminfo_val(oidp, req, IPC_SEMOPM)); >+} >+SYSCTL_PROC(_kern_ipc, OID_AUTO, semopm, CTLTYPE_INT | CTLFLAG_RD, 0, 0, >+ sysctl_seminfo_semopm, "IU", ""); >+ >+static int >+sysctl_seminfo_semume(SYSCTL_HANDLER_ARGS) >+{ >+ >+ return (sysctl_seminfo_val(oidp, req, IPC_SEMUME)); >+} >+SYSCTL_PROC(_kern_ipc, OID_AUTO, semume, CTLTYPE_INT | CTLFLAG_RD, 0, 0, >+ sysctl_seminfo_semume, "IU", ""); >+ >+static int >+sysctl_seminfo_semusz(SYSCTL_HANDLER_ARGS) >+{ >+ >+ return (sysctl_seminfo_val(oidp, req, IPC_SEMUSZ)); >+} >+SYSCTL_PROC(_kern_ipc, OID_AUTO, semusz, CTLTYPE_INT | CTLFLAG_RD, 0, 0, >+ sysctl_seminfo_semusz, "IU", ""); >+ >+static int >+sysctl_seminfo_semvmx(SYSCTL_HANDLER_ARGS) >+{ >+ >+ return (sysctl_seminfo_val(oidp, req, IPC_SEMVMX)); >+} >+SYSCTL_PROC(_kern_ipc, OID_AUTO, semvmx, CTLTYPE_INT | CTLFLAG_RD, 0, 0, >+ sysctl_seminfo_semvmx, "IU", ""); >+ >+static int >+sysctl_seminfo_semaem(SYSCTL_HANDLER_ARGS) >+{ >+ >+ return (sysctl_seminfo_val(oidp, req, IPC_SEMAEM)); >+} >+SYSCTL_PROC(_kern_ipc, OID_AUTO, semaem, CTLTYPE_INT | CTLFLAG_RD, 0, 0, >+ sysctl_seminfo_semaem, "IU", ""); >diff -ru /sys/kern/sysv_shm.c sys/kern/sysv_shm.c >--- /sys/kern/sysv_shm.c Wed Feb 19 19:29:13 2003 >+++ sys/kern/sysv_shm.c Wed Feb 19 18:27:12 2003 >@@ -1,8 +1,9 @@ >-/* $FreeBSD: src/sys/kern/sysv_shm.c,v 1.45.2.6 2002/10/22 20:45:03 fjoe Exp $ */ >+/* $FreeBSD$ */ > /* $NetBSD: sysv_shm.c,v 1.23 1994/07/04 23:25:12 glass Exp $ */ > > /* > * Copyright (c) 1994 Adam Glass and Charles Hannum. All rights reserved. >+ * Jailed by: Pawel Jakub Dawidek <nick@garage.freebsd.pl> > * > * Redistribution and use in source and binary forms, with or without > * modification, are permitted provided that the following conditions >@@ -76,9 +77,6 @@ > #define SHMSEG_ALLOCATED 0x0800 > #define SHMSEG_WANTED 0x1000 > >-static int shm_last_free, shm_nused, shm_committed, shmalloced; >-static struct shmid_ds *shmsegs; >- > struct shm_handle { > /* vm_offset_t kva; */ > vm_object_t shm_object; >@@ -94,7 +92,6 @@ > static struct shmid_ds *shm_find_segment_by_shmid __P((int)); > static int shm_delete_mapping __P((struct proc *, struct shmmap_state *)); > static void shmrealloc __P((void)); >-static void shminit __P((void *)); > > /* > * Tuneable values >@@ -118,39 +115,24 @@ > #define SHMALL (SHMMAXPGS) > #endif > >-struct shminfo shminfo = { >- SHMMAX, >- SHMMIN, >- SHMMNI, >- SHMSEG, >- SHMALL >-}; >- >-static int shm_use_phys; >- >-TUNABLE_INT("kern.ipc.shmmin", &shminfo.shmmin); >-TUNABLE_INT("kern.ipc.shmmni", &shminfo.shmmni); >-TUNABLE_INT("kern.ipc.shmseg", &shminfo.shmseg); >-TUNABLE_INT("kern.ipc.shmmaxpgs", &shminfo.shmall); >-TUNABLE_INT("kern.ipc.shm_use_phys", &shm_use_phys); >- >-SYSCTL_DECL(_kern_ipc); >-SYSCTL_INT(_kern_ipc, OID_AUTO, shmmax, CTLFLAG_RW, &shminfo.shmmax, 0, ""); >-SYSCTL_INT(_kern_ipc, OID_AUTO, shmmin, CTLFLAG_RW, &shminfo.shmmin, 0, ""); >-SYSCTL_INT(_kern_ipc, OID_AUTO, shmmni, CTLFLAG_RD, &shminfo.shmmni, 0, ""); >-SYSCTL_INT(_kern_ipc, OID_AUTO, shmseg, CTLFLAG_RW, &shminfo.shmseg, 0, ""); >-SYSCTL_INT(_kern_ipc, OID_AUTO, shmall, CTLFLAG_RW, &shminfo.shmall, 0, ""); >-SYSCTL_INT(_kern_ipc, OID_AUTO, shm_use_phys, CTLFLAG_RW, &shm_use_phys, 0, ""); >+/* Global struct for main system, all jails have its own. */ >+struct shmpriv mainshm; > > static int > shm_find_segment_by_key(key) > key_t key; > { > int i; >+ struct shmpriv *sp; > >- for (i = 0; i < shmalloced; i++) >- if ((shmsegs[i].shm_perm.mode & SHMSEG_ALLOCATED) && >- shmsegs[i].shm_perm.key == key) >+ if (curproc->p_prison == NULL) >+ sp = &mainshm; >+ else >+ sp = &curproc->p_prison->pr_shm; >+ >+ for (i = 0; i < sp->shmalloced; i++) >+ if ((sp->shmsegs[i].shm_perm.mode & SHMSEG_ALLOCATED) && >+ sp->shmsegs[i].shm_perm.key == key) > return i; > return -1; > } >@@ -161,11 +143,17 @@ > { > int segnum; > struct shmid_ds *shmseg; >+ struct shmpriv *sp; >+ >+ if (curproc->p_prison == NULL) >+ sp = &mainshm; >+ else >+ sp = &curproc->p_prison->pr_shm; > > segnum = IPCID_TO_IX(shmid); >- if (segnum < 0 || segnum >= shmalloced) >+ if (segnum < 0 || segnum >= sp->shmalloced) > return NULL; >- shmseg = &shmsegs[segnum]; >+ shmseg = &sp->shmsegs[segnum]; > if ((shmseg->shm_perm.mode & (SHMSEG_ALLOCATED | SHMSEG_REMOVED)) > != SHMSEG_ALLOCATED || > shmseg->shm_perm.seq != IPCID_TO_SEQ(shmid)) >@@ -179,14 +167,20 @@ > { > struct shm_handle *shm_handle; > size_t size; >+ struct shmpriv *sp; >+ >+ if (curproc->p_prison == NULL) >+ sp = &mainshm; >+ else >+ sp = &curproc->p_prison->pr_shm; > > shm_handle = shmseg->shm_internal; > vm_object_deallocate(shm_handle->shm_object); > free((caddr_t)shm_handle, M_SHM); > shmseg->shm_internal = NULL; > size = round_page(shmseg->shm_segsz); >- shm_committed -= btoc(size); >- shm_nused--; >+ sp->shm_committed -= btoc(size); >+ sp->shm_nused--; > shmseg->shm_perm.mode = SHMSEG_FREE; > } > >@@ -198,9 +192,15 @@ > struct shmid_ds *shmseg; > int segnum, result; > size_t size; >+ struct shmpriv *sp; >+ >+ if (p->p_prison == NULL) >+ sp = &mainshm; >+ else >+ sp = &p->p_prison->pr_shm; > > segnum = IPCID_TO_IX(shmmap_s->shmid); >- shmseg = &shmsegs[segnum]; >+ shmseg = &sp->shmsegs[segnum]; > size = round_page(shmseg->shm_segsz); > result = vm_map_remove(&p->p_vmspace->vm_map, shmmap_s->va, shmmap_s->va + size); > if (result != KERN_SUCCESS) >@@ -210,7 +210,7 @@ > if ((--shmseg->shm_nattch <= 0) && > (shmseg->shm_perm.mode & SHMSEG_REMOVED)) { > shm_deallocate_segment(shmseg); >- shm_last_free = segnum; >+ sp->shm_last_free = segnum; > } > return 0; > } >@@ -228,18 +228,24 @@ > { > struct shmmap_state *shmmap_s; > int i; >+ struct shmpriv *sp; > > if (!jail_sysvipc_allowed && p->p_prison != NULL) > return (ENOSYS); > >+ if (p->p_prison == NULL) >+ sp = &mainshm; >+ else >+ sp = &p->p_prison->pr_shm; >+ > shmmap_s = (struct shmmap_state *)p->p_vmspace->vm_shm; > if (shmmap_s == NULL) > return EINVAL; >- for (i = 0; i < shminfo.shmseg; i++, shmmap_s++) >+ for (i = 0; i < sp->shminfo.shmseg; i++, shmmap_s++) > if (shmmap_s->shmid != -1 && > shmmap_s->va == (vm_offset_t)uap->shmaddr) > break; >- if (i == shminfo.shmseg) >+ if (i == sp->shminfo.shmseg) > return EINVAL; > return shm_delete_mapping(p, shmmap_s); > } >@@ -265,15 +271,21 @@ > vm_prot_t prot; > vm_size_t size; > int rv; >+ struct shmpriv *sp; > > if (!jail_sysvipc_allowed && p->p_prison != NULL) > return (ENOSYS); > >+ if (p->p_prison == NULL) >+ sp = &mainshm; >+ else >+ sp = &p->p_prison->pr_shm; >+ > shmmap_s = (struct shmmap_state *)p->p_vmspace->vm_shm; > if (shmmap_s == NULL) { >- size = shminfo.shmseg * sizeof(struct shmmap_state); >+ size = sp->shminfo.shmseg * sizeof(struct shmmap_state); > shmmap_s = malloc(size, M_SHM, M_WAITOK); >- for (i = 0; i < shminfo.shmseg; i++) >+ for (i = 0; i < sp->shminfo.shmseg; i++) > shmmap_s[i].shmid = -1; > p->p_vmspace->vm_shm = (caddr_t)shmmap_s; > } >@@ -284,12 +296,12 @@ > (uap->shmflg & SHM_RDONLY) ? IPC_R : IPC_R|IPC_W); > if (error) > return error; >- for (i = 0; i < shminfo.shmseg; i++) { >+ for (i = 0; i < sp->shminfo.shmseg; i++) { > if (shmmap_s->shmid == -1) > break; > shmmap_s++; > } >- if (i >= shminfo.shmseg) >+ if (i >= sp->shminfo.shmseg) > return EMFILE; > size = round_page(shmseg->shm_segsz); > #ifdef VM_PROT_READ_IS_EXEC >@@ -410,10 +422,16 @@ > int error; > struct shmid_ds inbuf; > struct shmid_ds *shmseg; >+ struct shmpriv *sp; > > if (!jail_sysvipc_allowed && p->p_prison != NULL) > return (ENOSYS); > >+ if (p->p_prison == NULL) >+ sp = &mainshm; >+ else >+ sp = &p->p_prison->pr_shm; >+ > shmseg = shm_find_segment_by_shmid(uap->shmid); > if (shmseg == NULL) > return EINVAL; >@@ -448,7 +466,7 @@ > shmseg->shm_perm.mode |= SHMSEG_REMOVED; > if (shmseg->shm_nattch <= 0) { > shm_deallocate_segment(shmseg); >- shm_last_free = IPCID_TO_IX(uap->shmid); >+ sp->shm_last_free = IPCID_TO_IX(uap->shmid); > } > break; > #if 0 >@@ -478,8 +496,14 @@ > { > struct shmid_ds *shmseg; > int error; >+ struct shmpriv *sp; >+ >+ if (p->p_prison == NULL) >+ sp = &mainshm; >+ else >+ sp = &p->p_prison->pr_shm; > >- shmseg = &shmsegs[segnum]; >+ shmseg = &sp->shmsegs[segnum]; > if (shmseg->shm_perm.mode & SHMSEG_REMOVED) { > /* > * This segment is in the process of being allocated. Wait >@@ -513,27 +537,33 @@ > struct ucred *cred = p->p_ucred; > struct shmid_ds *shmseg; > struct shm_handle *shm_handle; >+ struct shmpriv *sp; >+ >+ if (p->p_prison == NULL) >+ sp = &mainshm; >+ else >+ sp = &p->p_prison->pr_shm; > >- if (uap->size < shminfo.shmmin || uap->size > shminfo.shmmax) >+ if (uap->size < sp->shminfo.shmmin || uap->size > sp->shminfo.shmmax) > return EINVAL; >- if (shm_nused >= shminfo.shmmni) /* any shmids left? */ >+ if (sp->shm_nused >= sp->shminfo.shmmni) /* any shmids left? */ > return ENOSPC; > size = round_page(uap->size); >- if (shm_committed + btoc(size) > shminfo.shmall) >+ if (sp->shm_committed + btoc(size) > sp->shminfo.shmall) > return ENOMEM; >- if (shm_last_free < 0) { >+ if (sp->shm_last_free < 0) { > shmrealloc(); /* maybe expand the shmsegs[] array */ >- for (i = 0; i < shmalloced; i++) >- if (shmsegs[i].shm_perm.mode & SHMSEG_FREE) >+ for (i = 0; i < sp->shmalloced; i++) >+ if (sp->shmsegs[i].shm_perm.mode & SHMSEG_FREE) > break; >- if (i == shmalloced) >+ if (i == sp->shmalloced) > return ENOSPC; > segnum = i; > } else { >- segnum = shm_last_free; >- shm_last_free = -1; >+ segnum = sp->shm_last_free; >+ sp->shm_last_free = -1; > } >- shmseg = &shmsegs[segnum]; >+ shmseg = &sp->shmsegs[segnum]; > /* > * In case we sleep in malloc(), mark the segment present but deleted > * so that noone else tries to create the same key. >@@ -549,7 +579,7 @@ > * We make sure that we have allocated a pager before we need > * to. > */ >- if (shm_use_phys) { >+ if (sp->shm_use_phys) { > shm_handle->shm_object = > vm_pager_allocate(OBJT_PHYS, 0, size, VM_PROT_DEFAULT, 0); > } else { >@@ -569,8 +599,8 @@ > shmseg->shm_lpid = shmseg->shm_nattch = 0; > shmseg->shm_atime = shmseg->shm_dtime = 0; > shmseg->shm_ctime = time_second; >- shm_committed += btoc(size); >- shm_nused++; >+ sp->shm_committed += btoc(size); >+ sp->shm_nused++; > if (shmseg->shm_perm.mode & SHMSEG_WANTED) { > /* > * Somebody else wanted this key while we were asleep. Wake >@@ -636,14 +666,20 @@ > struct shmmap_state *shmmap_s; > size_t size; > int i; >+ struct shmpriv *sp; > >- size = shminfo.shmseg * sizeof(struct shmmap_state); >+ if (p1->p_prison == NULL) >+ sp = &mainshm; >+ else >+ sp = &p1->p_prison->pr_shm; >+ >+ size = sp->shminfo.shmseg * sizeof(struct shmmap_state); > shmmap_s = malloc(size, M_SHM, M_WAITOK); > bcopy((caddr_t)p1->p_vmspace->vm_shm, (caddr_t)shmmap_s, size); > p2->p_vmspace->vm_shm = (caddr_t)shmmap_s; >- for (i = 0; i < shminfo.shmseg; i++, shmmap_s++) >+ for (i = 0; i < sp->shminfo.shmseg; i++, shmmap_s++) > if (shmmap_s->shmid != -1) >- shmsegs[IPCID_TO_IX(shmmap_s->shmid)].shm_nattch++; >+ sp->shmsegs[IPCID_TO_IX(shmmap_s->shmid)].shm_nattch++; > } > > void >@@ -652,9 +688,15 @@ > { > struct shmmap_state *shmmap_s; > int i; >+ struct shmpriv *sp; >+ >+ if (p->p_prison == NULL) >+ sp = &mainshm; >+ else >+ sp = &p->p_prison->pr_shm; > > shmmap_s = (struct shmmap_state *)p->p_vmspace->vm_shm; >- for (i = 0; i < shminfo.shmseg; i++, shmmap_s++) >+ for (i = 0; i < sp->shminfo.shmseg; i++, shmmap_s++) > if (shmmap_s->shmid != -1) > shm_delete_mapping(p, shmmap_s); > free((caddr_t)p->p_vmspace->vm_shm, M_SHM); >@@ -666,41 +708,217 @@ > { > int i; > struct shmid_ds *newsegs; >+ struct shmpriv *sp; >+ >+ if (curproc->p_prison == NULL) >+ sp = &mainshm; >+ else >+ sp = &curproc->p_prison->pr_shm; > >- if (shmalloced >= shminfo.shmmni) >+ if (sp->shmalloced >= sp->shminfo.shmmni) > return; > >- newsegs = malloc(shminfo.shmmni * sizeof(*newsegs), M_SHM, M_WAITOK); >+ newsegs = malloc(sp->shminfo.shmmni * sizeof(*newsegs), M_SHM, >+ M_WAITOK); > if (newsegs == NULL) > return; >- for (i = 0; i < shmalloced; i++) >- bcopy(&shmsegs[i], &newsegs[i], sizeof(newsegs[0])); >- for (; i < shminfo.shmmni; i++) { >- shmsegs[i].shm_perm.mode = SHMSEG_FREE; >- shmsegs[i].shm_perm.seq = 0; >- } >- free(shmsegs, M_SHM); >- shmsegs = newsegs; >- shmalloced = shminfo.shmmni; >+ for (i = 0; i < sp->shmalloced; i++) >+ bcopy(&sp->shmsegs[i], &newsegs[i], sizeof(newsegs[0])); >+ for (; i < sp->shminfo.shmmni; i++) { >+ sp->shmsegs[i].shm_perm.mode = SHMSEG_FREE; >+ sp->shmsegs[i].shm_perm.seq = 0; >+ } >+ free(sp->shmsegs, M_SHM); >+ sp->shmsegs = newsegs; >+ sp->shmalloced = sp->shminfo.shmmni; > } > >-static void >-shminit(dummy) >- void *dummy; >+int >+shminit(struct prison *pr) > { >+ struct shmpriv *sp; > int i; > >- shminfo.shmmax = shminfo.shmall * PAGE_SIZE; >- shmalloced = shminfo.shmmni; >- shmsegs = malloc(shmalloced * sizeof(shmsegs[0]), M_SHM, M_WAITOK); >- if (shmsegs == NULL) >- panic("cannot allocate initial memory for sysvshm"); >- for (i = 0; i < shmalloced; i++) { >- shmsegs[i].shm_perm.mode = SHMSEG_FREE; >- shmsegs[i].shm_perm.seq = 0; >- } >- shm_last_free = 0; >- shm_nused = 0; >- shm_committed = 0; >+ if (pr == NULL) >+ sp = &mainshm; >+ else >+ sp = &pr->pr_shm; >+ >+ sp->shminfo.shmmax = SHMMAX; >+ sp->shminfo.shmmin = SHMMIN; >+ sp->shminfo.shmmni = SHMMNI; >+ sp->shminfo.shmseg = SHMSEG; >+ sp->shminfo.shmall = SHMALL; >+ >+ sp->shminfo.shmmax = sp->shminfo.shmall * PAGE_SIZE; >+ sp->shmalloced = sp->shminfo.shmmni; >+ sp->shmsegs = malloc(sp->shmalloced * sizeof(sp->shmsegs[0]), M_SHM, >+ M_WAITOK); >+ if (sp->shmsegs == NULL) { >+ if (pr == NULL) >+ panic("cannot allocate initial memory for sysvshm"); >+ else >+ return (ENOMEM); >+ } >+ for (i = 0; i < sp->shmalloced; i++) { >+ sp->shmsegs[i].shm_perm.mode = SHMSEG_FREE; >+ sp->shmsegs[i].shm_perm.seq = 0; >+ } >+ sp->shm_last_free = 0; >+ sp->shm_nused = 0; >+ sp->shm_committed = 0; >+ >+ return (0); > } > SYSINIT(sysv_shm, SI_SUB_SYSV_SHM, SI_ORDER_FIRST, shminit, NULL); >+ >+void >+shmclear(struct prison *pr) >+{ >+ struct shmpriv *sp; >+ >+ if (pr == NULL) >+ sp = &mainshm; >+ else >+ sp = &pr->pr_shm; >+ >+ free(sp->shmsegs, M_SHM); >+} >+ >+TUNABLE_INT("kern.ipc.shmmin", &mainshm.shminfo.shmmin); >+TUNABLE_INT("kern.ipc.shmmni", &mainshm.shminfo.shmmni); >+TUNABLE_INT("kern.ipc.shmseg", &mainshm.shminfo.shmseg); >+TUNABLE_INT("kern.ipc.shmmaxpgs", &mainshm.shminfo.shmall); >+TUNABLE_INT("kern.ipc.shm_use_phys", &mainshm.shm_use_phys); >+ >+SYSCTL_DECL(_kern_ipc); >+ >+static int >+sysctl_shmsegs(SYSCTL_HANDLER_ARGS) >+{ >+ struct shmpriv *sp; >+ >+ if (req->p->p_prison == NULL) >+ sp = &mainshm; >+ else >+ sp = &req->p->p_prison->pr_shm; >+ >+ return (SYSCTL_OUT(req, sp->shmsegs, >+ sizeof(struct shmid_ds) * sp->shminfo.shmmni)); >+} >+SYSCTL_PROC(_kern_ipc, OID_AUTO, shmsegs, CTLFLAG_RD, >+ NULL, 0, sysctl_shmsegs, "", "Shared memory IDs"); >+ >+static int >+sysctl_shminfo(SYSCTL_HANDLER_ARGS) >+{ >+ struct shmpriv *sp; >+ >+ if (req->p->p_prison == NULL) >+ sp = &mainshm; >+ else >+ sp = &req->p->p_prison->pr_shm; >+ >+ return (sysctl_handle_opaque(oidp, &sp->shminfo, sizeof(struct shminfo), >+ req)); >+} >+SYSCTL_PROC(_kern_ipc, OID_AUTO, shminfo, CTLTYPE_STRUCT | CTLFLAG_RD, 0, 0, >+ sysctl_shminfo, "S,shminfo",""); >+ >+#define IPC_SHMMAX 0 >+#define IPC_SHMMIN 1 >+#define IPC_SHMMNI 2 >+#define IPC_SHMSEG 3 >+#define IPC_SHMALL 4 >+#define IPC_SHM_USE_PHYS 5 >+ >+static int >+sysctl_shminfo_val(struct sysctl_oid *oidp, struct sysctl_req *req, u_int type) >+{ >+ int *shminfo; >+ struct shmpriv *sp; >+ >+ if (req->p->p_prison == NULL) >+ sp = &mainshm; >+ else >+ sp = &req->p->p_prison->pr_shm; >+ >+ switch (type) { >+ case IPC_SHMMAX: >+ shminfo = &sp->shminfo.shmmax; >+ break; >+ case IPC_SHMMIN: >+ shminfo = &sp->shminfo.shmmin; >+ break; >+ case IPC_SHMMNI: >+ shminfo = &sp->shminfo.shmmni; >+ break; >+ case IPC_SHMSEG: >+ shminfo = &sp->shminfo.shmseg; >+ break; >+ case IPC_SHMALL: >+ shminfo = &sp->shminfo.shmall; >+ break; >+ case IPC_SHM_USE_PHYS: >+ shminfo = &sp->shm_use_phys; >+ break; >+ default: >+ panic("unknown shm type"); >+ } >+ >+ return (sysctl_handle_int(oidp, shminfo, 0, req)); >+} >+ >+static int >+sysctl_shminfo_shmmax(SYSCTL_HANDLER_ARGS) >+{ >+ >+ return (sysctl_shminfo_val(oidp, req, IPC_SHMMAX)); >+} >+SYSCTL_PROC(_kern_ipc, OID_AUTO, shmmax, CTLTYPE_INT | CTLFLAG_RW, 0, 0, >+ sysctl_shminfo_shmmax, "IU", ""); >+ >+static int >+sysctl_shminfo_shmmin(SYSCTL_HANDLER_ARGS) >+{ >+ >+ return (sysctl_shminfo_val(oidp, req, IPC_SHMMIN)); >+} >+SYSCTL_PROC(_kern_ipc, OID_AUTO, shmmin, CTLTYPE_INT | CTLFLAG_RW, 0, 0, >+ sysctl_shminfo_shmmin, "IU", ""); >+ >+static int >+sysctl_shminfo_shmmni(SYSCTL_HANDLER_ARGS) >+{ >+ >+ return (sysctl_shminfo_val(oidp, req, IPC_SHMMNI)); >+} >+SYSCTL_PROC(_kern_ipc, OID_AUTO, shmmni, CTLTYPE_INT | CTLFLAG_RD, 0, 0, >+ sysctl_shminfo_shmmni, "IU", ""); >+ >+static int >+sysctl_shminfo_shmseg(SYSCTL_HANDLER_ARGS) >+{ >+ >+ return (sysctl_shminfo_val(oidp, req, IPC_SHMSEG)); >+} >+SYSCTL_PROC(_kern_ipc, OID_AUTO, shmseg, CTLTYPE_INT | CTLFLAG_RW, 0, 0, >+ sysctl_shminfo_shmseg, "IU", ""); >+ >+static int >+sysctl_shminfo_shmall(SYSCTL_HANDLER_ARGS) >+{ >+ >+ return (sysctl_shminfo_val(oidp, req, IPC_SHMALL)); >+} >+SYSCTL_PROC(_kern_ipc, OID_AUTO, shmall, CTLTYPE_INT | CTLFLAG_RW, 0, 0, >+ sysctl_shminfo_shmall, "IU", ""); >+ >+static int >+sysctl_shminfo_shm_use_phys(SYSCTL_HANDLER_ARGS) >+{ >+ >+ return (sysctl_shminfo_val(oidp, req, IPC_SHM_USE_PHYS)); >+} >+SYSCTL_PROC(_kern_ipc, OID_AUTO, shm_use_phys, CTLTYPE_INT | CTLFLAG_RW, 0, 0, >+ sysctl_shminfo_shm_use_phys, "IU", ""); >diff -ru /sys/svr4/svr4_misc.c sys/svr4/svr4_misc.c >--- /sys/svr4/svr4_misc.c Wed Feb 19 19:29:13 2003 >+++ sys/svr4/svr4_misc.c Wed Feb 19 18:39:19 2003 >@@ -25,7 +25,7 @@ > * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF > * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. > * >- * $FreeBSD: src/sys/svr4/svr4_misc.c,v 1.13.2.7 2003/01/14 21:33:58 dillon Exp $ >+ * $FreeBSD$ > */ > > /* >@@ -35,6 +35,8 @@ > * handled here. > */ > >+#include "opt_sysvipc.h" >+ > #include <sys/param.h> > #include <sys/systm.h> > #include <sys/namei.h> >@@ -58,6 +60,7 @@ > #include <sys/fcntl.h> > #include <sys/sem.h> > #include <sys/msg.h> >+#include <sys/jail.h> > #include <sys/ptrace.h> > #include <vm/vm_zone.h> > >@@ -726,21 +729,34 @@ > case SVR4_CONFIG_DELAYTIMER_MAX: > *retval = 0; /* No delaytimer support */ > break; >+#ifdef SYSVMSG > case SVR4_CONFIG_MQ_OPEN_MAX: >- *retval = msginfo.msgmni; >+ if (p->p_prison == NULL) >+ *retval = mainmsg.msginfo.msgmni; >+ else >+ *retval = p->p_prison->pr_msg.msginfo.msgmni; > break; >+#endif > case SVR4_CONFIG_MQ_PRIO_MAX: > *retval = 0; /* XXX: Don't know */ > break; > case SVR4_CONFIG_RTSIG_MAX: > *retval = 0; > break; >+#ifdef SYSVSEM > case SVR4_CONFIG_SEM_NSEMS_MAX: >- *retval = seminfo.semmni; >+ if (p->p_prison == NULL) >+ *retval = mainsem.seminfo.semmni; >+ else >+ *retval = p->p_prison->pr_sem.seminfo.semmni; > break; > case SVR4_CONFIG_SEM_VALUE_MAX: >- *retval = seminfo.semvmx; >+ if (p->p_prison == NULL) >+ *retval = mainsem.seminfo.semvmx; >+ else >+ *retval = p->p_prison->pr_sem.seminfo.semvmx; > break; >+#endif > case SVR4_CONFIG_SIGQUEUE_MAX: > *retval = 0; /* XXX: Don't know */ > break; >diff -ru /sys/sys/jail.h sys/sys/jail.h >--- /sys/sys/jail.h Wed Feb 19 19:29:13 2003 >+++ sys/sys/jail.h Wed Feb 19 18:24:53 2003 >@@ -6,7 +6,7 @@ > * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp > * ---------------------------------------------------------------------------- > * >- * $FreeBSD: src/sys/sys/jail.h,v 1.8.2.2 2000/11/01 17:58:06 rwatson Exp $ >+ * $FreeBSD$ > * > */ > >@@ -26,6 +26,10 @@ > > #else /* _KERNEL */ > >+#include <sys/msg.h> >+#include <sys/sem.h> >+#include <sys/shm.h> >+ > #ifdef MALLOC_DECLARE > MALLOC_DECLARE(M_PRISON); > #endif >@@ -41,6 +45,15 @@ > char pr_host[MAXHOSTNAMELEN]; > u_int32_t pr_ip; > void *pr_linux; >+#ifdef SYSVMSG >+ struct msgpriv pr_msg; >+#endif >+#ifdef SYSVSEM >+ struct sempriv pr_sem; >+#endif >+#ifdef SYSVSHM >+ struct shmpriv pr_shm; >+#endif > }; > > /* >diff -ru /sys/sys/msg.h sys/sys/msg.h >--- /sys/sys/msg.h Wed Feb 19 19:29:13 2003 >+++ sys/sys/msg.h Wed Feb 19 14:15:43 2003 >@@ -32,7 +32,14 @@ > > #define MSG_NOERROR 010000 /* don't complain about too long msgs */ > >-struct msg; >+struct msg { >+ struct msg *msg_next; /* next msg in the chain */ >+ long msg_type; /* type of this message */ >+ /* >0 -> type of this message */ >+ /* 0 -> free header */ >+ u_short msg_ts; /* size of this message */ >+ short msg_spot; /* location of start of msg in buffer */ >+}; > > struct msqid_ds { > struct ipc_perm msg_perm; /* msg queue permission bits */ >@@ -87,7 +94,29 @@ > msgssz, /* size of a message segment (see notes above) */ > msgseg; /* number of message segments */ > }; >-extern struct msginfo msginfo; >+ >+struct msgmap { >+ short next; /* next segment in buffer */ >+ /* -1 -> available */ >+ /* 0..(MSGSEG-1) -> index of next segment */ >+}; >+ >+struct msgpriv { >+ struct msginfo msginfo; >+ int nfree_msgmaps; /* # of free map entries */ >+ short free_msgmaps; /* head of linked list of >+ free map entries */ >+ struct msg *free_msghdrs; /* list of free msg headers */ >+ char *msgpool; /* MSGMAX byte long msg buffer pool */ >+ struct msgmap *msgmaps; /* MSGSEG msgmap structures */ >+ struct msg *msghdrs; /* MSGTQL msg headers */ >+ struct msqid_ds *msqids; /* MSGMNI msqid_ds struct's */ >+}; >+extern struct msgpriv mainmsg; >+ >+struct prison; >+int msginit(struct prison *pr); >+void msgclear(struct prison *pr); > #endif > > #ifndef _KERNEL >diff -ru /sys/sys/sem.h sys/sys/sem.h >--- /sys/sys/sem.h Wed Feb 19 19:29:13 2003 >+++ sys/sys/sem.h Wed Feb 19 15:30:11 2003 >@@ -1,4 +1,4 @@ >-/* $FreeBSD: src/sys/sys/sem.h,v 1.20.2.2 2000/08/04 22:31:10 peter Exp $ */ >+/* $FreeBSD$ */ > /* $NetBSD: sem.h,v 1.5 1994/06/29 06:45:15 cgd Exp $ */ > > /* >@@ -67,6 +67,27 @@ > > #ifdef _KERNEL > >+struct sem { >+ u_short semval; /* semaphore value */ >+ pid_t sempid; /* pid of last operation */ >+ u_short semncnt; /* # awaiting semval > cval */ >+ u_short semzcnt; /* # awaiting semval = 0 */ >+}; >+ >+/* >+ * Undo structure (one per process) >+ */ >+struct sem_undo { >+ struct sem_undo *un_next; /* ptr to next active undo structure */ >+ struct proc *un_proc; /* owner of this structure */ >+ short un_cnt; /* # of active entries */ >+ struct undo { >+ short un_adjval; /* adjust on exit values */ >+ short un_num; /* semaphore # */ >+ int un_id; /* semid */ >+ } un_ent[1]; /* undo entries */ >+}; >+ > /* > * semaphore info struct > */ >@@ -82,12 +103,24 @@ > semvmx, /* semaphore maximum value */ > semaem; /* adjust on exit max value */ > }; >-extern struct seminfo seminfo; > > /* internal "mode" bits */ > #define SEM_ALLOC 01000 /* semaphore is allocated */ > #define SEM_DEST 02000 /* semaphore will be destroyed on last detach */ > >+struct sempriv { >+ struct seminfo seminfo; >+ int semtot; >+ struct semid_ds *sema; /* semaphore id pool */ >+ struct sem *sem; /* semaphore pool */ >+ struct sem_undo *semu_list; /* list of active undo structures */ >+ int *semu; /* undo structure pool */ >+}; >+extern struct sempriv mainsem; >+ >+struct prison; >+int seminit(struct prison *pr); >+void semclear(struct prison *pr); > /* > * Process sem_undo vectors at proc exit. > */ >diff -ru /sys/sys/shm.h sys/sys/shm.h >--- /sys/sys/shm.h Wed Feb 19 19:29:13 2003 >+++ sys/sys/shm.h Wed Feb 19 15:42:22 2003 >@@ -1,4 +1,4 @@ >-/* $FreeBSD: src/sys/sys/shm.h,v 1.14 1999/12/29 04:24:46 peter Exp $ */ >+/* $FreeBSD$ */ > /* $NetBSD: shm.h,v 1.15 1994/06/29 06:45:17 cgd Exp $ */ > > /* >@@ -76,13 +76,24 @@ > shmseg, /* max shared memory segments per process */ > shmall; /* max amount of shared memory (pages) */ > }; >-extern struct shminfo shminfo; >-extern struct shmid_ds *shmsegs; > >-struct proc; >+struct shmpriv { >+ struct shminfo shminfo; >+ struct shmid_ds *shmsegs; >+ int shm_last_free; >+ int shm_nused; >+ int shm_committed; >+ int shmalloced; >+ int shm_use_phys; >+}; >+extern struct shmpriv mainshm; > >+struct proc; > void shmexit __P((struct proc *)); > void shmfork __P((struct proc *, struct proc *)); >+struct prison; >+int shminit(struct prison *pr); >+void shmclear(struct prison *pr); > #else /* !_KERNEL */ > > #include <sys/cdefs.h>
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 48471
: 28925 |
28926
|
157658
|
157661
|
169450
|
169452
|
169480