Giant Pushdown: sysv shm, sem, and msg calls.
This commit is contained in:
parent
f99a696093
commit
b6a4b4f9ae
@ -3,7 +3,7 @@
|
|||||||
*
|
*
|
||||||
* DO NOT EDIT-- this file is automatically generated.
|
* DO NOT EDIT-- this file is automatically generated.
|
||||||
* $FreeBSD$
|
* $FreeBSD$
|
||||||
* created from FreeBSD: src/sys/kern/syscalls.master,v 1.91 2001/05/29 09:22:22 phk Exp
|
* created from FreeBSD: src/sys/kern/syscalls.master,v 1.92 2001/08/30 18:50:56 dillon Exp
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "opt_compat.h"
|
#include "opt_compat.h"
|
||||||
@ -191,9 +191,9 @@ struct sysent sysent[] = {
|
|||||||
{ AS(rtprio_args), (sy_call_t *)rtprio }, /* 166 = rtprio */
|
{ AS(rtprio_args), (sy_call_t *)rtprio }, /* 166 = rtprio */
|
||||||
{ 0, (sy_call_t *)nosys }, /* 167 = nosys */
|
{ 0, (sy_call_t *)nosys }, /* 167 = nosys */
|
||||||
{ 0, (sy_call_t *)nosys }, /* 168 = nosys */
|
{ 0, (sy_call_t *)nosys }, /* 168 = nosys */
|
||||||
{ AS(semsys_args), (sy_call_t *)lkmressys }, /* 169 = semsys */
|
{ SYF_MPSAFE | AS(semsys_args), (sy_call_t *)lkmressys }, /* 169 = semsys */
|
||||||
{ AS(msgsys_args), (sy_call_t *)lkmressys }, /* 170 = msgsys */
|
{ SYF_MPSAFE | AS(msgsys_args), (sy_call_t *)lkmressys }, /* 170 = msgsys */
|
||||||
{ AS(shmsys_args), (sy_call_t *)lkmressys }, /* 171 = shmsys */
|
{ SYF_MPSAFE | AS(shmsys_args), (sy_call_t *)lkmressys }, /* 171 = shmsys */
|
||||||
{ 0, (sy_call_t *)nosys }, /* 172 = nosys */
|
{ 0, (sy_call_t *)nosys }, /* 172 = nosys */
|
||||||
{ AS(pread_args), (sy_call_t *)pread }, /* 173 = pread */
|
{ AS(pread_args), (sy_call_t *)pread }, /* 173 = pread */
|
||||||
{ AS(pwrite_args), (sy_call_t *)pwrite }, /* 174 = pwrite */
|
{ AS(pwrite_args), (sy_call_t *)pwrite }, /* 174 = pwrite */
|
||||||
@ -242,18 +242,18 @@ struct sysent sysent[] = {
|
|||||||
{ 0, (sy_call_t *)lkmnosys }, /* 217 = lkmnosys */
|
{ 0, (sy_call_t *)lkmnosys }, /* 217 = lkmnosys */
|
||||||
{ 0, (sy_call_t *)lkmnosys }, /* 218 = lkmnosys */
|
{ 0, (sy_call_t *)lkmnosys }, /* 218 = lkmnosys */
|
||||||
{ 0, (sy_call_t *)lkmnosys }, /* 219 = lkmnosys */
|
{ 0, (sy_call_t *)lkmnosys }, /* 219 = lkmnosys */
|
||||||
{ AS(__semctl_args), (sy_call_t *)lkmressys }, /* 220 = __semctl */
|
{ SYF_MPSAFE | AS(__semctl_args), (sy_call_t *)lkmressys }, /* 220 = __semctl */
|
||||||
{ AS(semget_args), (sy_call_t *)lkmressys }, /* 221 = semget */
|
{ SYF_MPSAFE | AS(semget_args), (sy_call_t *)lkmressys }, /* 221 = semget */
|
||||||
{ AS(semop_args), (sy_call_t *)lkmressys }, /* 222 = semop */
|
{ SYF_MPSAFE | AS(semop_args), (sy_call_t *)lkmressys }, /* 222 = semop */
|
||||||
{ 0, (sy_call_t *)nosys }, /* 223 = semconfig */
|
{ 0, (sy_call_t *)nosys }, /* 223 = semconfig */
|
||||||
{ AS(msgctl_args), (sy_call_t *)lkmressys }, /* 224 = msgctl */
|
{ SYF_MPSAFE | AS(msgctl_args), (sy_call_t *)lkmressys }, /* 224 = msgctl */
|
||||||
{ AS(msgget_args), (sy_call_t *)lkmressys }, /* 225 = msgget */
|
{ SYF_MPSAFE | AS(msgget_args), (sy_call_t *)lkmressys }, /* 225 = msgget */
|
||||||
{ AS(msgsnd_args), (sy_call_t *)lkmressys }, /* 226 = msgsnd */
|
{ SYF_MPSAFE | AS(msgsnd_args), (sy_call_t *)lkmressys }, /* 226 = msgsnd */
|
||||||
{ AS(msgrcv_args), (sy_call_t *)lkmressys }, /* 227 = msgrcv */
|
{ SYF_MPSAFE | AS(msgrcv_args), (sy_call_t *)lkmressys }, /* 227 = msgrcv */
|
||||||
{ AS(shmat_args), (sy_call_t *)lkmressys }, /* 228 = shmat */
|
{ SYF_MPSAFE | AS(shmat_args), (sy_call_t *)lkmressys }, /* 228 = shmat */
|
||||||
{ AS(shmctl_args), (sy_call_t *)lkmressys }, /* 229 = shmctl */
|
{ SYF_MPSAFE | AS(shmctl_args), (sy_call_t *)lkmressys }, /* 229 = shmctl */
|
||||||
{ AS(shmdt_args), (sy_call_t *)lkmressys }, /* 230 = shmdt */
|
{ SYF_MPSAFE | AS(shmdt_args), (sy_call_t *)lkmressys }, /* 230 = shmdt */
|
||||||
{ AS(shmget_args), (sy_call_t *)lkmressys }, /* 231 = shmget */
|
{ SYF_MPSAFE | AS(shmget_args), (sy_call_t *)lkmressys }, /* 231 = shmget */
|
||||||
{ AS(clock_gettime_args), (sy_call_t *)clock_gettime }, /* 232 = clock_gettime */
|
{ AS(clock_gettime_args), (sy_call_t *)clock_gettime }, /* 232 = clock_gettime */
|
||||||
{ AS(clock_settime_args), (sy_call_t *)clock_settime }, /* 233 = clock_settime */
|
{ AS(clock_settime_args), (sy_call_t *)clock_settime }, /* 233 = clock_settime */
|
||||||
{ AS(clock_getres_args), (sy_call_t *)clock_getres }, /* 234 = clock_getres */
|
{ AS(clock_getres_args), (sy_call_t *)clock_getres }, /* 234 = clock_getres */
|
||||||
|
@ -263,15 +263,15 @@
|
|||||||
167 UNIMPL NOHIDE nosys
|
167 UNIMPL NOHIDE nosys
|
||||||
168 UNIMPL NOHIDE nosys
|
168 UNIMPL NOHIDE nosys
|
||||||
; 169 is initialized by the SYSVSEM code if present or loaded
|
; 169 is initialized by the SYSVSEM code if present or loaded
|
||||||
169 NOSTD BSD { int semsys(int which, int a2, int a3, int a4, \
|
169 MNOSTD BSD { int semsys(int which, int a2, int a3, int a4, \
|
||||||
int a5); }
|
int a5); }
|
||||||
; 169 is initialized by the SYSVMSG code if present or loaded
|
; 169 is initialized by the SYSVMSG code if present or loaded
|
||||||
; XXX should be { int semsys(int which, ...); }
|
; XXX should be { int semsys(int which, ...); }
|
||||||
170 NOSTD BSD { int msgsys(int which, int a2, int a3, int a4, \
|
170 MNOSTD BSD { int msgsys(int which, int a2, int a3, int a4, \
|
||||||
int a5, int a6); }
|
int a5, int a6); }
|
||||||
; 169 is initialized by the SYSVSHM code if present or loaded
|
; 169 is initialized by the SYSVSHM code if present or loaded
|
||||||
; XXX should be { int msgsys(int which, ...); }
|
; XXX should be { int msgsys(int which, ...); }
|
||||||
171 NOSTD BSD { int shmsys(int which, int a2, int a3, int a4); }
|
171 MNOSTD BSD { int shmsys(int which, int a2, int a3, int a4); }
|
||||||
; XXX should be { int shmsys(int which, ...); }
|
; XXX should be { int shmsys(int which, ...); }
|
||||||
172 UNIMPL NOHIDE nosys
|
172 UNIMPL NOHIDE nosys
|
||||||
173 STD POSIX { ssize_t pread(int fd, void *buf, size_t nbyte, \
|
173 STD POSIX { ssize_t pread(int fd, void *buf, size_t nbyte, \
|
||||||
@ -345,24 +345,24 @@
|
|||||||
;
|
;
|
||||||
; The following were introduced with NetBSD/4.4Lite-2
|
; The following were introduced with NetBSD/4.4Lite-2
|
||||||
; They are initialized by thier respective modules/sysinits
|
; They are initialized by thier respective modules/sysinits
|
||||||
220 NOSTD BSD { int __semctl(int semid, int semnum, int cmd, \
|
220 MNOSTD BSD { int __semctl(int semid, int semnum, int cmd, \
|
||||||
union semun *arg); }
|
union semun *arg); }
|
||||||
221 NOSTD BSD { int semget(key_t key, int nsems, int semflg); }
|
221 MNOSTD BSD { int semget(key_t key, int nsems, int semflg); }
|
||||||
222 NOSTD BSD { int semop(int semid, struct sembuf *sops, \
|
222 MNOSTD BSD { int semop(int semid, struct sembuf *sops, \
|
||||||
u_int nsops); }
|
u_int nsops); }
|
||||||
223 UNIMPL NOHIDE semconfig
|
223 UNIMPL NOHIDE semconfig
|
||||||
224 NOSTD BSD { int msgctl(int msqid, int cmd, \
|
224 MNOSTD BSD { int msgctl(int msqid, int cmd, \
|
||||||
struct msqid_ds *buf); }
|
struct msqid_ds *buf); }
|
||||||
225 NOSTD BSD { int msgget(key_t key, int msgflg); }
|
225 MNOSTD BSD { int msgget(key_t key, int msgflg); }
|
||||||
226 NOSTD BSD { int msgsnd(int msqid, void *msgp, size_t msgsz, \
|
226 MNOSTD BSD { int msgsnd(int msqid, void *msgp, size_t msgsz, \
|
||||||
int msgflg); }
|
int msgflg); }
|
||||||
227 NOSTD BSD { int msgrcv(int msqid, void *msgp, size_t msgsz, \
|
227 MNOSTD BSD { int msgrcv(int msqid, void *msgp, size_t msgsz, \
|
||||||
long msgtyp, int msgflg); }
|
long msgtyp, int msgflg); }
|
||||||
228 NOSTD BSD { int shmat(int shmid, void *shmaddr, int shmflg); }
|
228 MNOSTD BSD { int shmat(int shmid, void *shmaddr, int shmflg); }
|
||||||
229 NOSTD BSD { int shmctl(int shmid, int cmd, \
|
229 MNOSTD BSD { int shmctl(int shmid, int cmd, \
|
||||||
struct shmid_ds *buf); }
|
struct shmid_ds *buf); }
|
||||||
230 NOSTD BSD { int shmdt(void *shmaddr); }
|
230 MNOSTD BSD { int shmdt(void *shmaddr); }
|
||||||
231 NOSTD BSD { int shmget(key_t key, int size, int shmflg); }
|
231 MNOSTD BSD { int shmget(key_t key, int size, int shmflg); }
|
||||||
;
|
;
|
||||||
232 STD POSIX { int clock_gettime(clockid_t clock_id, \
|
232 STD POSIX { int clock_gettime(clockid_t clock_id, \
|
||||||
struct timespec *tp); }
|
struct timespec *tp); }
|
||||||
|
@ -26,6 +26,8 @@
|
|||||||
#include <sys/sysproto.h>
|
#include <sys/sysproto.h>
|
||||||
#include <sys/kernel.h>
|
#include <sys/kernel.h>
|
||||||
#include <sys/proc.h>
|
#include <sys/proc.h>
|
||||||
|
#include <sys/lock.h>
|
||||||
|
#include <sys/mutex.h>
|
||||||
#include <sys/msg.h>
|
#include <sys/msg.h>
|
||||||
#include <sys/syscall.h>
|
#include <sys/syscall.h>
|
||||||
#include <sys/sysent.h>
|
#include <sys/sysent.h>
|
||||||
@ -263,6 +265,8 @@ MODULE_VERSION(sysvmsg, 1);
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* Entry point for all MSG calls
|
* Entry point for all MSG calls
|
||||||
|
*
|
||||||
|
* MPSAFE
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
msgsys(p, uap)
|
msgsys(p, uap)
|
||||||
@ -277,13 +281,22 @@ msgsys(p, uap)
|
|||||||
int a6;
|
int a6;
|
||||||
} */ *uap;
|
} */ *uap;
|
||||||
{
|
{
|
||||||
|
int error;
|
||||||
|
|
||||||
if (!jail_sysvipc_allowed && jailed(p->p_ucred))
|
mtx_lock(&Giant);
|
||||||
return (ENOSYS);
|
|
||||||
|
|
||||||
if (uap->which >= sizeof(msgcalls)/sizeof(msgcalls[0]))
|
if (!jail_sysvipc_allowed && jailed(p->p_ucred)) {
|
||||||
return (EINVAL);
|
error = ENOSYS;
|
||||||
return ((*msgcalls[uap->which])(p, &uap->a2));
|
goto done2;
|
||||||
|
}
|
||||||
|
if (uap->which >= sizeof(msgcalls)/sizeof(msgcalls[0])) {
|
||||||
|
error = EINVAL;
|
||||||
|
goto done2;
|
||||||
|
}
|
||||||
|
error = (*msgcalls[uap->which])(p, &uap->a2);
|
||||||
|
done2:
|
||||||
|
mtx_unlock(&Giant);
|
||||||
|
return (error);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -318,6 +331,9 @@ struct msgctl_args {
|
|||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* MPSAFE
|
||||||
|
*/
|
||||||
int
|
int
|
||||||
msgctl(p, uap)
|
msgctl(p, uap)
|
||||||
struct proc *p;
|
struct proc *p;
|
||||||
@ -326,16 +342,19 @@ msgctl(p, uap)
|
|||||||
int msqid = uap->msqid;
|
int msqid = uap->msqid;
|
||||||
int cmd = uap->cmd;
|
int cmd = uap->cmd;
|
||||||
struct msqid_ds *user_msqptr = uap->buf;
|
struct msqid_ds *user_msqptr = uap->buf;
|
||||||
int rval, eval;
|
int rval, error;
|
||||||
struct msqid_ds msqbuf;
|
struct msqid_ds msqbuf;
|
||||||
register struct msqid_ds *msqptr;
|
register struct msqid_ds *msqptr;
|
||||||
|
|
||||||
#ifdef MSG_DEBUG_OK
|
#ifdef MSG_DEBUG_OK
|
||||||
printf("call to msgctl(%d, %d, 0x%x)\n", msqid, cmd, user_msqptr);
|
printf("call to msgctl(%d, %d, 0x%x)\n", msqid, cmd, user_msqptr);
|
||||||
#endif
|
#endif
|
||||||
|
mtx_lock(&Giant);
|
||||||
|
|
||||||
if (!jail_sysvipc_allowed && jailed(p->p_ucred))
|
if (!jail_sysvipc_allowed && jailed(p->p_ucred)) {
|
||||||
return (ENOSYS);
|
error = ENOSYS;
|
||||||
|
goto done2;
|
||||||
|
}
|
||||||
|
|
||||||
msqid = IPCID_TO_IX(msqid);
|
msqid = IPCID_TO_IX(msqid);
|
||||||
|
|
||||||
@ -344,7 +363,8 @@ msgctl(p, uap)
|
|||||||
printf("msqid (%d) out of range (0<=msqid<%d)\n", msqid,
|
printf("msqid (%d) out of range (0<=msqid<%d)\n", msqid,
|
||||||
msginfo.msgmni);
|
msginfo.msgmni);
|
||||||
#endif
|
#endif
|
||||||
return(EINVAL);
|
error = EINVAL;
|
||||||
|
goto done2;
|
||||||
}
|
}
|
||||||
|
|
||||||
msqptr = &msqids[msqid];
|
msqptr = &msqids[msqid];
|
||||||
@ -353,16 +373,18 @@ msgctl(p, uap)
|
|||||||
#ifdef MSG_DEBUG_OK
|
#ifdef MSG_DEBUG_OK
|
||||||
printf("no such msqid\n");
|
printf("no such msqid\n");
|
||||||
#endif
|
#endif
|
||||||
return(EINVAL);
|
error = EINVAL;
|
||||||
|
goto done2;
|
||||||
}
|
}
|
||||||
if (msqptr->msg_perm.seq != IPCID_TO_SEQ(uap->msqid)) {
|
if (msqptr->msg_perm.seq != IPCID_TO_SEQ(uap->msqid)) {
|
||||||
#ifdef MSG_DEBUG_OK
|
#ifdef MSG_DEBUG_OK
|
||||||
printf("wrong sequence number\n");
|
printf("wrong sequence number\n");
|
||||||
#endif
|
#endif
|
||||||
return(EINVAL);
|
error = EINVAL;
|
||||||
|
goto done2;
|
||||||
}
|
}
|
||||||
|
|
||||||
eval = 0;
|
error = 0;
|
||||||
rval = 0;
|
rval = 0;
|
||||||
|
|
||||||
switch (cmd) {
|
switch (cmd) {
|
||||||
@ -370,8 +392,8 @@ msgctl(p, uap)
|
|||||||
case IPC_RMID:
|
case IPC_RMID:
|
||||||
{
|
{
|
||||||
struct msg *msghdr;
|
struct msg *msghdr;
|
||||||
if ((eval = ipcperm(p, &msqptr->msg_perm, IPC_M)))
|
if ((error = ipcperm(p, &msqptr->msg_perm, IPC_M)))
|
||||||
return(eval);
|
goto done2;
|
||||||
/* Free the message headers */
|
/* Free the message headers */
|
||||||
msghdr = msqptr->msg_first;
|
msghdr = msqptr->msg_first;
|
||||||
while (msghdr != NULL) {
|
while (msghdr != NULL) {
|
||||||
@ -398,14 +420,14 @@ msgctl(p, uap)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case IPC_SET:
|
case IPC_SET:
|
||||||
if ((eval = ipcperm(p, &msqptr->msg_perm, IPC_M)))
|
if ((error = ipcperm(p, &msqptr->msg_perm, IPC_M)))
|
||||||
return(eval);
|
goto done2;
|
||||||
if ((eval = copyin(user_msqptr, &msqbuf, sizeof(msqbuf))) != 0)
|
if ((error = copyin(user_msqptr, &msqbuf, sizeof(msqbuf))) != 0)
|
||||||
return(eval);
|
goto done2;
|
||||||
if (msqbuf.msg_qbytes > msqptr->msg_qbytes) {
|
if (msqbuf.msg_qbytes > msqptr->msg_qbytes) {
|
||||||
eval = suser(p);
|
error = suser(p);
|
||||||
if (eval)
|
if (error)
|
||||||
return(eval);
|
goto done2;
|
||||||
}
|
}
|
||||||
if (msqbuf.msg_qbytes > msginfo.msgmnb) {
|
if (msqbuf.msg_qbytes > msginfo.msgmnb) {
|
||||||
#ifdef MSG_DEBUG_OK
|
#ifdef MSG_DEBUG_OK
|
||||||
@ -418,7 +440,8 @@ msgctl(p, uap)
|
|||||||
#ifdef MSG_DEBUG_OK
|
#ifdef MSG_DEBUG_OK
|
||||||
printf("can't reduce msg_qbytes to 0\n");
|
printf("can't reduce msg_qbytes to 0\n");
|
||||||
#endif
|
#endif
|
||||||
return(EINVAL); /* non-standard errno! */
|
error = EINVAL; /* non-standard errno! */
|
||||||
|
goto done2;
|
||||||
}
|
}
|
||||||
msqptr->msg_perm.uid = msqbuf.msg_perm.uid; /* change the owner */
|
msqptr->msg_perm.uid = msqbuf.msg_perm.uid; /* change the owner */
|
||||||
msqptr->msg_perm.gid = msqbuf.msg_perm.gid; /* change the owner */
|
msqptr->msg_perm.gid = msqbuf.msg_perm.gid; /* change the owner */
|
||||||
@ -429,13 +452,13 @@ msgctl(p, uap)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case IPC_STAT:
|
case IPC_STAT:
|
||||||
if ((eval = ipcperm(p, &msqptr->msg_perm, IPC_R))) {
|
if ((error = ipcperm(p, &msqptr->msg_perm, IPC_R))) {
|
||||||
#ifdef MSG_DEBUG_OK
|
#ifdef MSG_DEBUG_OK
|
||||||
printf("requester doesn't have read access\n");
|
printf("requester doesn't have read access\n");
|
||||||
#endif
|
#endif
|
||||||
return(eval);
|
goto done2;
|
||||||
}
|
}
|
||||||
eval = copyout((caddr_t)msqptr, user_msqptr,
|
error = copyout((caddr_t)msqptr, user_msqptr,
|
||||||
sizeof(struct msqid_ds));
|
sizeof(struct msqid_ds));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -443,12 +466,15 @@ msgctl(p, uap)
|
|||||||
#ifdef MSG_DEBUG_OK
|
#ifdef MSG_DEBUG_OK
|
||||||
printf("invalid command %d\n", cmd);
|
printf("invalid command %d\n", cmd);
|
||||||
#endif
|
#endif
|
||||||
return(EINVAL);
|
error = EINVAL;
|
||||||
|
goto done2;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (eval == 0)
|
if (error == 0)
|
||||||
p->p_retval[0] = rval;
|
p->p_retval[0] = rval;
|
||||||
return(eval);
|
done2:
|
||||||
|
mtx_unlock(&Giant);
|
||||||
|
return(error);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef _SYS_SYSPROTO_H_
|
#ifndef _SYS_SYSPROTO_H_
|
||||||
@ -458,12 +484,15 @@ struct msgget_args {
|
|||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* MPSAFE
|
||||||
|
*/
|
||||||
int
|
int
|
||||||
msgget(p, uap)
|
msgget(p, uap)
|
||||||
struct proc *p;
|
struct proc *p;
|
||||||
register struct msgget_args *uap;
|
register struct msgget_args *uap;
|
||||||
{
|
{
|
||||||
int msqid, eval;
|
int msqid, error = 0;
|
||||||
int key = uap->key;
|
int key = uap->key;
|
||||||
int msgflg = uap->msgflg;
|
int msgflg = uap->msgflg;
|
||||||
struct ucred *cred = p->p_ucred;
|
struct ucred *cred = p->p_ucred;
|
||||||
@ -473,8 +502,12 @@ msgget(p, uap)
|
|||||||
printf("msgget(0x%x, 0%o)\n", key, msgflg);
|
printf("msgget(0x%x, 0%o)\n", key, msgflg);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (!jail_sysvipc_allowed && jailed(p->p_ucred))
|
mtx_lock(&Giant);
|
||||||
return (ENOSYS);
|
|
||||||
|
if (!jail_sysvipc_allowed && jailed(p->p_ucred)) {
|
||||||
|
error = ENOSYS;
|
||||||
|
goto done2;
|
||||||
|
}
|
||||||
|
|
||||||
if (key != IPC_PRIVATE) {
|
if (key != IPC_PRIVATE) {
|
||||||
for (msqid = 0; msqid < msginfo.msgmni; msqid++) {
|
for (msqid = 0; msqid < msginfo.msgmni; msqid++) {
|
||||||
@ -491,14 +524,15 @@ msgget(p, uap)
|
|||||||
#ifdef MSG_DEBUG_OK
|
#ifdef MSG_DEBUG_OK
|
||||||
printf("not exclusive\n");
|
printf("not exclusive\n");
|
||||||
#endif
|
#endif
|
||||||
return(EEXIST);
|
error = EEXIST;
|
||||||
|
goto done2;
|
||||||
}
|
}
|
||||||
if ((eval = ipcperm(p, &msqptr->msg_perm, msgflg & 0700 ))) {
|
if ((error = ipcperm(p, &msqptr->msg_perm, msgflg & 0700 ))) {
|
||||||
#ifdef MSG_DEBUG_OK
|
#ifdef MSG_DEBUG_OK
|
||||||
printf("requester doesn't have 0%o access\n",
|
printf("requester doesn't have 0%o access\n",
|
||||||
msgflg & 0700);
|
msgflg & 0700);
|
||||||
#endif
|
#endif
|
||||||
return(eval);
|
goto done2;
|
||||||
}
|
}
|
||||||
goto found;
|
goto found;
|
||||||
}
|
}
|
||||||
@ -524,7 +558,8 @@ msgget(p, uap)
|
|||||||
#ifdef MSG_DEBUG_OK
|
#ifdef MSG_DEBUG_OK
|
||||||
printf("no more msqid_ds's available\n");
|
printf("no more msqid_ds's available\n");
|
||||||
#endif
|
#endif
|
||||||
return(ENOSPC);
|
error = ENOSPC;
|
||||||
|
goto done2;
|
||||||
}
|
}
|
||||||
#ifdef MSG_DEBUG_OK
|
#ifdef MSG_DEBUG_OK
|
||||||
printf("msqid %d is available\n", msqid);
|
printf("msqid %d is available\n", msqid);
|
||||||
@ -551,13 +586,16 @@ msgget(p, uap)
|
|||||||
#ifdef MSG_DEBUG_OK
|
#ifdef MSG_DEBUG_OK
|
||||||
printf("didn't find it and wasn't asked to create it\n");
|
printf("didn't find it and wasn't asked to create it\n");
|
||||||
#endif
|
#endif
|
||||||
return(ENOENT);
|
error = ENOENT;
|
||||||
|
goto done2;
|
||||||
}
|
}
|
||||||
|
|
||||||
found:
|
found:
|
||||||
/* Construct the unique msqid */
|
/* Construct the unique msqid */
|
||||||
p->p_retval[0] = IXSEQ_TO_IPCID(msqid, msqptr->msg_perm);
|
p->p_retval[0] = IXSEQ_TO_IPCID(msqid, msqptr->msg_perm);
|
||||||
return(0);
|
done2:
|
||||||
|
mtx_unlock(&Giant);
|
||||||
|
return (error);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef _SYS_SYSPROTO_H_
|
#ifndef _SYS_SYSPROTO_H_
|
||||||
@ -569,6 +607,9 @@ struct msgsnd_args {
|
|||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* MPSAFE
|
||||||
|
*/
|
||||||
int
|
int
|
||||||
msgsnd(p, uap)
|
msgsnd(p, uap)
|
||||||
struct proc *p;
|
struct proc *p;
|
||||||
@ -578,7 +619,7 @@ msgsnd(p, uap)
|
|||||||
void *user_msgp = uap->msgp;
|
void *user_msgp = uap->msgp;
|
||||||
size_t msgsz = uap->msgsz;
|
size_t msgsz = uap->msgsz;
|
||||||
int msgflg = uap->msgflg;
|
int msgflg = uap->msgflg;
|
||||||
int segs_needed, eval;
|
int segs_needed, error = 0;
|
||||||
register struct msqid_ds *msqptr;
|
register struct msqid_ds *msqptr;
|
||||||
register struct msg *msghdr;
|
register struct msg *msghdr;
|
||||||
short next;
|
short next;
|
||||||
@ -587,9 +628,12 @@ msgsnd(p, uap)
|
|||||||
printf("call to msgsnd(%d, 0x%x, %d, %d)\n", msqid, user_msgp, msgsz,
|
printf("call to msgsnd(%d, 0x%x, %d, %d)\n", msqid, user_msgp, msgsz,
|
||||||
msgflg);
|
msgflg);
|
||||||
#endif
|
#endif
|
||||||
|
mtx_lock(&Giant);
|
||||||
|
|
||||||
if (!jail_sysvipc_allowed && jailed(p->p_ucred))
|
if (!jail_sysvipc_allowed && jailed(p->p_ucred)) {
|
||||||
return (ENOSYS);
|
error = ENOSYS;
|
||||||
|
goto done2;
|
||||||
|
}
|
||||||
|
|
||||||
msqid = IPCID_TO_IX(msqid);
|
msqid = IPCID_TO_IX(msqid);
|
||||||
|
|
||||||
@ -598,7 +642,8 @@ msgsnd(p, uap)
|
|||||||
printf("msqid (%d) out of range (0<=msqid<%d)\n", msqid,
|
printf("msqid (%d) out of range (0<=msqid<%d)\n", msqid,
|
||||||
msginfo.msgmni);
|
msginfo.msgmni);
|
||||||
#endif
|
#endif
|
||||||
return(EINVAL);
|
error = EINVAL;
|
||||||
|
goto done2;
|
||||||
}
|
}
|
||||||
|
|
||||||
msqptr = &msqids[msqid];
|
msqptr = &msqids[msqid];
|
||||||
@ -606,20 +651,22 @@ msgsnd(p, uap)
|
|||||||
#ifdef MSG_DEBUG_OK
|
#ifdef MSG_DEBUG_OK
|
||||||
printf("no such message queue id\n");
|
printf("no such message queue id\n");
|
||||||
#endif
|
#endif
|
||||||
return(EINVAL);
|
error = EINVAL;
|
||||||
|
goto done2;
|
||||||
}
|
}
|
||||||
if (msqptr->msg_perm.seq != IPCID_TO_SEQ(uap->msqid)) {
|
if (msqptr->msg_perm.seq != IPCID_TO_SEQ(uap->msqid)) {
|
||||||
#ifdef MSG_DEBUG_OK
|
#ifdef MSG_DEBUG_OK
|
||||||
printf("wrong sequence number\n");
|
printf("wrong sequence number\n");
|
||||||
#endif
|
#endif
|
||||||
return(EINVAL);
|
error = EINVAL;
|
||||||
|
goto done2;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((eval = ipcperm(p, &msqptr->msg_perm, IPC_W))) {
|
if ((error = ipcperm(p, &msqptr->msg_perm, IPC_W))) {
|
||||||
#ifdef MSG_DEBUG_OK
|
#ifdef MSG_DEBUG_OK
|
||||||
printf("requester doesn't have write access\n");
|
printf("requester doesn't have write access\n");
|
||||||
#endif
|
#endif
|
||||||
return(eval);
|
goto done2;
|
||||||
}
|
}
|
||||||
|
|
||||||
segs_needed = (msgsz + msginfo.msgssz - 1) / msginfo.msgssz;
|
segs_needed = (msgsz + msginfo.msgssz - 1) / msginfo.msgssz;
|
||||||
@ -639,7 +686,8 @@ msgsnd(p, uap)
|
|||||||
#ifdef MSG_DEBUG_OK
|
#ifdef MSG_DEBUG_OK
|
||||||
printf("msgsz > msqptr->msg_qbytes\n");
|
printf("msgsz > msqptr->msg_qbytes\n");
|
||||||
#endif
|
#endif
|
||||||
return(EINVAL);
|
error = EINVAL;
|
||||||
|
goto done2;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (msqptr->msg_perm.mode & MSG_LOCKED) {
|
if (msqptr->msg_perm.mode & MSG_LOCKED) {
|
||||||
@ -674,7 +722,8 @@ msgsnd(p, uap)
|
|||||||
#ifdef MSG_DEBUG_OK
|
#ifdef MSG_DEBUG_OK
|
||||||
printf("need more resources but caller doesn't want to wait\n");
|
printf("need more resources but caller doesn't want to wait\n");
|
||||||
#endif
|
#endif
|
||||||
return(EAGAIN);
|
error = EAGAIN;
|
||||||
|
goto done2;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((msqptr->msg_perm.mode & MSG_LOCKED) != 0) {
|
if ((msqptr->msg_perm.mode & MSG_LOCKED) != 0) {
|
||||||
@ -694,18 +743,19 @@ msgsnd(p, uap)
|
|||||||
#ifdef MSG_DEBUG_OK
|
#ifdef MSG_DEBUG_OK
|
||||||
printf("goodnight\n");
|
printf("goodnight\n");
|
||||||
#endif
|
#endif
|
||||||
eval = tsleep((caddr_t)msqptr, (PZERO - 4) | PCATCH,
|
error = tsleep((caddr_t)msqptr, (PZERO - 4) | PCATCH,
|
||||||
"msgwait", 0);
|
"msgwait", 0);
|
||||||
#ifdef MSG_DEBUG_OK
|
#ifdef MSG_DEBUG_OK
|
||||||
printf("good morning, eval=%d\n", eval);
|
printf("good morning, error=%d\n", error);
|
||||||
#endif
|
#endif
|
||||||
if (we_own_it)
|
if (we_own_it)
|
||||||
msqptr->msg_perm.mode &= ~MSG_LOCKED;
|
msqptr->msg_perm.mode &= ~MSG_LOCKED;
|
||||||
if (eval != 0) {
|
if (error != 0) {
|
||||||
#ifdef MSG_DEBUG_OK
|
#ifdef MSG_DEBUG_OK
|
||||||
printf("msgsnd: interrupted system call\n");
|
printf("msgsnd: interrupted system call\n");
|
||||||
#endif
|
#endif
|
||||||
return(EINTR);
|
error = EINTR;
|
||||||
|
goto done2;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -716,7 +766,8 @@ msgsnd(p, uap)
|
|||||||
#ifdef MSG_DEBUG_OK
|
#ifdef MSG_DEBUG_OK
|
||||||
printf("msqid deleted\n");
|
printf("msqid deleted\n");
|
||||||
#endif
|
#endif
|
||||||
return(EIDRM);
|
error = EIDRM;
|
||||||
|
goto done2;
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
@ -787,15 +838,15 @@ msgsnd(p, uap)
|
|||||||
* Copy in the message type
|
* Copy in the message type
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if ((eval = copyin(user_msgp, &msghdr->msg_type,
|
if ((error = copyin(user_msgp, &msghdr->msg_type,
|
||||||
sizeof(msghdr->msg_type))) != 0) {
|
sizeof(msghdr->msg_type))) != 0) {
|
||||||
#ifdef MSG_DEBUG_OK
|
#ifdef MSG_DEBUG_OK
|
||||||
printf("error %d copying the message type\n", eval);
|
printf("error %d copying the message type\n", error);
|
||||||
#endif
|
#endif
|
||||||
msg_freehdr(msghdr);
|
msg_freehdr(msghdr);
|
||||||
msqptr->msg_perm.mode &= ~MSG_LOCKED;
|
msqptr->msg_perm.mode &= ~MSG_LOCKED;
|
||||||
wakeup((caddr_t)msqptr);
|
wakeup((caddr_t)msqptr);
|
||||||
return(eval);
|
goto done2;
|
||||||
}
|
}
|
||||||
user_msgp = (char *)user_msgp + sizeof(msghdr->msg_type);
|
user_msgp = (char *)user_msgp + sizeof(msghdr->msg_type);
|
||||||
|
|
||||||
@ -810,7 +861,8 @@ msgsnd(p, uap)
|
|||||||
#ifdef MSG_DEBUG_OK
|
#ifdef MSG_DEBUG_OK
|
||||||
printf("mtype (%d) < 1\n", msghdr->msg_type);
|
printf("mtype (%d) < 1\n", msghdr->msg_type);
|
||||||
#endif
|
#endif
|
||||||
return(EINVAL);
|
error = EINVAL;
|
||||||
|
goto done2;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -828,15 +880,15 @@ msgsnd(p, uap)
|
|||||||
panic("next too low #2");
|
panic("next too low #2");
|
||||||
if (next >= msginfo.msgseg)
|
if (next >= msginfo.msgseg)
|
||||||
panic("next out of range #2");
|
panic("next out of range #2");
|
||||||
if ((eval = copyin(user_msgp, &msgpool[next * msginfo.msgssz],
|
if ((error = copyin(user_msgp, &msgpool[next * msginfo.msgssz],
|
||||||
tlen)) != 0) {
|
tlen)) != 0) {
|
||||||
#ifdef MSG_DEBUG_OK
|
#ifdef MSG_DEBUG_OK
|
||||||
printf("error %d copying in message segment\n", eval);
|
printf("error %d copying in message segment\n", error);
|
||||||
#endif
|
#endif
|
||||||
msg_freehdr(msghdr);
|
msg_freehdr(msghdr);
|
||||||
msqptr->msg_perm.mode &= ~MSG_LOCKED;
|
msqptr->msg_perm.mode &= ~MSG_LOCKED;
|
||||||
wakeup((caddr_t)msqptr);
|
wakeup((caddr_t)msqptr);
|
||||||
return(eval);
|
goto done2;
|
||||||
}
|
}
|
||||||
msgsz -= tlen;
|
msgsz -= tlen;
|
||||||
user_msgp = (char *)user_msgp + tlen;
|
user_msgp = (char *)user_msgp + tlen;
|
||||||
@ -858,7 +910,8 @@ msgsnd(p, uap)
|
|||||||
if (msqptr->msg_qbytes == 0) {
|
if (msqptr->msg_qbytes == 0) {
|
||||||
msg_freehdr(msghdr);
|
msg_freehdr(msghdr);
|
||||||
wakeup((caddr_t)msqptr);
|
wakeup((caddr_t)msqptr);
|
||||||
return(EIDRM);
|
error = EIDRM;
|
||||||
|
goto done2;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -881,7 +934,9 @@ msgsnd(p, uap)
|
|||||||
|
|
||||||
wakeup((caddr_t)msqptr);
|
wakeup((caddr_t)msqptr);
|
||||||
p->p_retval[0] = 0;
|
p->p_retval[0] = 0;
|
||||||
return(0);
|
done2:
|
||||||
|
mtx_unlock(&Giant);
|
||||||
|
return (error);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef _SYS_SYSPROTO_H_
|
#ifndef _SYS_SYSPROTO_H_
|
||||||
@ -894,6 +949,9 @@ struct msgrcv_args {
|
|||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* MPSAFE
|
||||||
|
*/
|
||||||
int
|
int
|
||||||
msgrcv(p, uap)
|
msgrcv(p, uap)
|
||||||
struct proc *p;
|
struct proc *p;
|
||||||
@ -907,7 +965,7 @@ msgrcv(p, uap)
|
|||||||
size_t len;
|
size_t len;
|
||||||
register struct msqid_ds *msqptr;
|
register struct msqid_ds *msqptr;
|
||||||
register struct msg *msghdr;
|
register struct msg *msghdr;
|
||||||
int eval;
|
int error = 0;
|
||||||
short next;
|
short next;
|
||||||
|
|
||||||
#ifdef MSG_DEBUG_OK
|
#ifdef MSG_DEBUG_OK
|
||||||
@ -915,8 +973,12 @@ msgrcv(p, uap)
|
|||||||
msgsz, msgtyp, msgflg);
|
msgsz, msgtyp, msgflg);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (!jail_sysvipc_allowed && jailed(p->p_ucred))
|
mtx_lock(&Giant);
|
||||||
return (ENOSYS);
|
|
||||||
|
if (!jail_sysvipc_allowed && jailed(p->p_ucred)) {
|
||||||
|
error = ENOSYS;
|
||||||
|
goto done2;
|
||||||
|
}
|
||||||
|
|
||||||
msqid = IPCID_TO_IX(msqid);
|
msqid = IPCID_TO_IX(msqid);
|
||||||
|
|
||||||
@ -925,7 +987,8 @@ msgrcv(p, uap)
|
|||||||
printf("msqid (%d) out of range (0<=msqid<%d)\n", msqid,
|
printf("msqid (%d) out of range (0<=msqid<%d)\n", msqid,
|
||||||
msginfo.msgmni);
|
msginfo.msgmni);
|
||||||
#endif
|
#endif
|
||||||
return(EINVAL);
|
error = EINVAL;
|
||||||
|
goto done2;
|
||||||
}
|
}
|
||||||
|
|
||||||
msqptr = &msqids[msqid];
|
msqptr = &msqids[msqid];
|
||||||
@ -933,20 +996,22 @@ msgrcv(p, uap)
|
|||||||
#ifdef MSG_DEBUG_OK
|
#ifdef MSG_DEBUG_OK
|
||||||
printf("no such message queue id\n");
|
printf("no such message queue id\n");
|
||||||
#endif
|
#endif
|
||||||
return(EINVAL);
|
error = EINVAL;
|
||||||
|
goto done2;
|
||||||
}
|
}
|
||||||
if (msqptr->msg_perm.seq != IPCID_TO_SEQ(uap->msqid)) {
|
if (msqptr->msg_perm.seq != IPCID_TO_SEQ(uap->msqid)) {
|
||||||
#ifdef MSG_DEBUG_OK
|
#ifdef MSG_DEBUG_OK
|
||||||
printf("wrong sequence number\n");
|
printf("wrong sequence number\n");
|
||||||
#endif
|
#endif
|
||||||
return(EINVAL);
|
error = EINVAL;
|
||||||
|
goto done2;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((eval = ipcperm(p, &msqptr->msg_perm, IPC_R))) {
|
if ((error = ipcperm(p, &msqptr->msg_perm, IPC_R))) {
|
||||||
#ifdef MSG_DEBUG_OK
|
#ifdef MSG_DEBUG_OK
|
||||||
printf("requester doesn't have read access\n");
|
printf("requester doesn't have read access\n");
|
||||||
#endif
|
#endif
|
||||||
return(eval);
|
goto done2;
|
||||||
}
|
}
|
||||||
|
|
||||||
msghdr = NULL;
|
msghdr = NULL;
|
||||||
@ -960,7 +1025,8 @@ msgrcv(p, uap)
|
|||||||
printf("first message on the queue is too big (want %d, got %d)\n",
|
printf("first message on the queue is too big (want %d, got %d)\n",
|
||||||
msgsz, msghdr->msg_ts);
|
msgsz, msghdr->msg_ts);
|
||||||
#endif
|
#endif
|
||||||
return(E2BIG);
|
error = E2BIG;
|
||||||
|
goto done2;
|
||||||
}
|
}
|
||||||
if (msqptr->msg_first == msqptr->msg_last) {
|
if (msqptr->msg_first == msqptr->msg_last) {
|
||||||
msqptr->msg_first = NULL;
|
msqptr->msg_first = NULL;
|
||||||
@ -999,7 +1065,8 @@ msgrcv(p, uap)
|
|||||||
printf("requested message on the queue is too big (want %d, got %d)\n",
|
printf("requested message on the queue is too big (want %d, got %d)\n",
|
||||||
msgsz, msghdr->msg_ts);
|
msgsz, msghdr->msg_ts);
|
||||||
#endif
|
#endif
|
||||||
return(E2BIG);
|
error = E2BIG;
|
||||||
|
goto done2;
|
||||||
}
|
}
|
||||||
*prev = msghdr->msg_next;
|
*prev = msghdr->msg_next;
|
||||||
if (msghdr == msqptr->msg_last) {
|
if (msghdr == msqptr->msg_last) {
|
||||||
@ -1045,7 +1112,8 @@ msgrcv(p, uap)
|
|||||||
msgtyp);
|
msgtyp);
|
||||||
#endif
|
#endif
|
||||||
/* The SVID says to return ENOMSG. */
|
/* The SVID says to return ENOMSG. */
|
||||||
return(ENOMSG);
|
error = ENOMSG;
|
||||||
|
goto done2;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1055,17 +1123,18 @@ msgrcv(p, uap)
|
|||||||
#ifdef MSG_DEBUG_OK
|
#ifdef MSG_DEBUG_OK
|
||||||
printf("msgrcv: goodnight\n");
|
printf("msgrcv: goodnight\n");
|
||||||
#endif
|
#endif
|
||||||
eval = tsleep((caddr_t)msqptr, (PZERO - 4) | PCATCH, "msgwait",
|
error = tsleep((caddr_t)msqptr, (PZERO - 4) | PCATCH, "msgwait",
|
||||||
0);
|
0);
|
||||||
#ifdef MSG_DEBUG_OK
|
#ifdef MSG_DEBUG_OK
|
||||||
printf("msgrcv: good morning (eval=%d)\n", eval);
|
printf("msgrcv: good morning (error=%d)\n", error);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (eval != 0) {
|
if (error != 0) {
|
||||||
#ifdef MSG_DEBUG_OK
|
#ifdef MSG_DEBUG_OK
|
||||||
printf("msgsnd: interrupted system call\n");
|
printf("msgsnd: interrupted system call\n");
|
||||||
#endif
|
#endif
|
||||||
return(EINTR);
|
error = EINTR;
|
||||||
|
goto done2;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1077,7 +1146,8 @@ msgrcv(p, uap)
|
|||||||
#ifdef MSG_DEBUG_OK
|
#ifdef MSG_DEBUG_OK
|
||||||
printf("msqid deleted\n");
|
printf("msqid deleted\n");
|
||||||
#endif
|
#endif
|
||||||
return(EIDRM);
|
error = EIDRM;
|
||||||
|
goto done2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1109,15 +1179,15 @@ msgrcv(p, uap)
|
|||||||
* Return the type to the user.
|
* Return the type to the user.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
eval = copyout((caddr_t)&(msghdr->msg_type), user_msgp,
|
error = copyout((caddr_t)&(msghdr->msg_type), user_msgp,
|
||||||
sizeof(msghdr->msg_type));
|
sizeof(msghdr->msg_type));
|
||||||
if (eval != 0) {
|
if (error != 0) {
|
||||||
#ifdef MSG_DEBUG_OK
|
#ifdef MSG_DEBUG_OK
|
||||||
printf("error (%d) copying out message type\n", eval);
|
printf("error (%d) copying out message type\n", error);
|
||||||
#endif
|
#endif
|
||||||
msg_freehdr(msghdr);
|
msg_freehdr(msghdr);
|
||||||
wakeup((caddr_t)msqptr);
|
wakeup((caddr_t)msqptr);
|
||||||
return(eval);
|
goto done2;
|
||||||
}
|
}
|
||||||
user_msgp = (char *)user_msgp + sizeof(msghdr->msg_type);
|
user_msgp = (char *)user_msgp + sizeof(msghdr->msg_type);
|
||||||
|
|
||||||
@ -1137,16 +1207,16 @@ msgrcv(p, uap)
|
|||||||
panic("next too low #3");
|
panic("next too low #3");
|
||||||
if (next >= msginfo.msgseg)
|
if (next >= msginfo.msgseg)
|
||||||
panic("next out of range #3");
|
panic("next out of range #3");
|
||||||
eval = copyout((caddr_t)&msgpool[next * msginfo.msgssz],
|
error = copyout((caddr_t)&msgpool[next * msginfo.msgssz],
|
||||||
user_msgp, tlen);
|
user_msgp, tlen);
|
||||||
if (eval != 0) {
|
if (error != 0) {
|
||||||
#ifdef MSG_DEBUG_OK
|
#ifdef MSG_DEBUG_OK
|
||||||
printf("error (%d) copying out message segment\n",
|
printf("error (%d) copying out message segment\n",
|
||||||
eval);
|
error);
|
||||||
#endif
|
#endif
|
||||||
msg_freehdr(msghdr);
|
msg_freehdr(msghdr);
|
||||||
wakeup((caddr_t)msqptr);
|
wakeup((caddr_t)msqptr);
|
||||||
return(eval);
|
goto done2;
|
||||||
}
|
}
|
||||||
user_msgp = (char *)user_msgp + tlen;
|
user_msgp = (char *)user_msgp + tlen;
|
||||||
next = msgmaps[next].next;
|
next = msgmaps[next].next;
|
||||||
@ -1159,7 +1229,9 @@ msgrcv(p, uap)
|
|||||||
msg_freehdr(msghdr);
|
msg_freehdr(msghdr);
|
||||||
wakeup((caddr_t)msqptr);
|
wakeup((caddr_t)msqptr);
|
||||||
p->p_retval[0] = msgsz;
|
p->p_retval[0] = msgsz;
|
||||||
return(0);
|
done2:
|
||||||
|
mtx_unlock(&Giant);
|
||||||
|
return (error);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
|
@ -15,6 +15,8 @@
|
|||||||
#include <sys/sysproto.h>
|
#include <sys/sysproto.h>
|
||||||
#include <sys/kernel.h>
|
#include <sys/kernel.h>
|
||||||
#include <sys/proc.h>
|
#include <sys/proc.h>
|
||||||
|
#include <sys/lock.h>
|
||||||
|
#include <sys/mutex.h>
|
||||||
#include <sys/sem.h>
|
#include <sys/sem.h>
|
||||||
#include <sys/syscall.h>
|
#include <sys/syscall.h>
|
||||||
#include <sys/sysent.h>
|
#include <sys/sysent.h>
|
||||||
@ -244,6 +246,8 @@ MODULE_VERSION(sysvsem, 1);
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* Entry point for all SEM calls
|
* Entry point for all SEM calls
|
||||||
|
*
|
||||||
|
* MPSAFE
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
semsys(p, uap)
|
semsys(p, uap)
|
||||||
@ -257,13 +261,23 @@ semsys(p, uap)
|
|||||||
int a5;
|
int a5;
|
||||||
} */ *uap;
|
} */ *uap;
|
||||||
{
|
{
|
||||||
|
int error;
|
||||||
|
|
||||||
if (!jail_sysvipc_allowed && jailed(p->p_ucred))
|
mtx_lock(&Giant);
|
||||||
return (ENOSYS);
|
|
||||||
|
|
||||||
if (uap->which >= sizeof(semcalls)/sizeof(semcalls[0]))
|
if (!jail_sysvipc_allowed && jailed(p->p_ucred)) {
|
||||||
return (EINVAL);
|
error = ENOSYS;
|
||||||
return ((*semcalls[uap->which])(p, &uap->a2));
|
goto done2;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (uap->which >= sizeof(semcalls)/sizeof(semcalls[0])) {
|
||||||
|
error = EINVAL;
|
||||||
|
goto done2;
|
||||||
|
}
|
||||||
|
error = (*semcalls[uap->which])(p, &uap->a2);
|
||||||
|
done2:
|
||||||
|
mtx_unlock(&Giant);
|
||||||
|
return (error);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -448,6 +462,9 @@ struct __semctl_args {
|
|||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* MPSAFE
|
||||||
|
*/
|
||||||
int
|
int
|
||||||
__semctl(p, uap)
|
__semctl(p, uap)
|
||||||
struct proc *p;
|
struct proc *p;
|
||||||
@ -459,33 +476,40 @@ __semctl(p, uap)
|
|||||||
union semun *arg = uap->arg;
|
union semun *arg = uap->arg;
|
||||||
union semun real_arg;
|
union semun real_arg;
|
||||||
struct ucred *cred = p->p_ucred;
|
struct ucred *cred = p->p_ucred;
|
||||||
int i, rval, eval;
|
int i, rval, error;
|
||||||
struct semid_ds sbuf;
|
struct semid_ds sbuf;
|
||||||
register struct semid_ds *semaptr;
|
register struct semid_ds *semaptr;
|
||||||
|
|
||||||
#ifdef SEM_DEBUG
|
#ifdef SEM_DEBUG
|
||||||
printf("call to semctl(%d, %d, %d, 0x%x)\n", semid, semnum, cmd, arg);
|
printf("call to semctl(%d, %d, %d, 0x%x)\n", semid, semnum, cmd, arg);
|
||||||
#endif
|
#endif
|
||||||
|
mtx_lock(&Giant);
|
||||||
|
|
||||||
if (!jail_sysvipc_allowed && jailed(p->p_ucred))
|
if (!jail_sysvipc_allowed && jailed(p->p_ucred)) {
|
||||||
return (ENOSYS);
|
error = ENOSYS;
|
||||||
|
goto done2;
|
||||||
|
}
|
||||||
|
|
||||||
semid = IPCID_TO_IX(semid);
|
semid = IPCID_TO_IX(semid);
|
||||||
if (semid < 0 || semid >= seminfo.semmsl)
|
if (semid < 0 || semid >= seminfo.semmsl) {
|
||||||
return(EINVAL);
|
error = EINVAL;
|
||||||
|
goto done2;
|
||||||
|
}
|
||||||
|
|
||||||
semaptr = &sema[semid];
|
semaptr = &sema[semid];
|
||||||
if ((semaptr->sem_perm.mode & SEM_ALLOC) == 0 ||
|
if ((semaptr->sem_perm.mode & SEM_ALLOC) == 0 ||
|
||||||
semaptr->sem_perm.seq != IPCID_TO_SEQ(uap->semid))
|
semaptr->sem_perm.seq != IPCID_TO_SEQ(uap->semid)) {
|
||||||
return(EINVAL);
|
error = EINVAL;
|
||||||
|
goto done2;
|
||||||
|
}
|
||||||
|
|
||||||
eval = 0;
|
error = 0;
|
||||||
rval = 0;
|
rval = 0;
|
||||||
|
|
||||||
switch (cmd) {
|
switch (cmd) {
|
||||||
case IPC_RMID:
|
case IPC_RMID:
|
||||||
if ((eval = ipcperm(p, &semaptr->sem_perm, IPC_M)))
|
if ((error = ipcperm(p, &semaptr->sem_perm, IPC_M)))
|
||||||
return(eval);
|
goto done2;
|
||||||
semaptr->sem_perm.cuid = cred->cr_uid;
|
semaptr->sem_perm.cuid = cred->cr_uid;
|
||||||
semaptr->sem_perm.uid = cred->cr_uid;
|
semaptr->sem_perm.uid = cred->cr_uid;
|
||||||
semtot -= semaptr->sem_nsems;
|
semtot -= semaptr->sem_nsems;
|
||||||
@ -502,13 +526,14 @@ __semctl(p, uap)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case IPC_SET:
|
case IPC_SET:
|
||||||
if ((eval = ipcperm(p, &semaptr->sem_perm, IPC_M)))
|
if ((error = ipcperm(p, &semaptr->sem_perm, IPC_M)))
|
||||||
return(eval);
|
goto done2;
|
||||||
if ((eval = copyin(arg, &real_arg, sizeof(real_arg))) != 0)
|
if ((error = copyin(arg, &real_arg, sizeof(real_arg))) != 0)
|
||||||
return(eval);
|
goto done2;
|
||||||
if ((eval = copyin(real_arg.buf, (caddr_t)&sbuf,
|
if ((error = copyin(real_arg.buf, (caddr_t)&sbuf,
|
||||||
sizeof(sbuf))) != 0)
|
sizeof(sbuf))) != 0) {
|
||||||
return(eval);
|
goto done2;
|
||||||
|
}
|
||||||
semaptr->sem_perm.uid = sbuf.sem_perm.uid;
|
semaptr->sem_perm.uid = sbuf.sem_perm.uid;
|
||||||
semaptr->sem_perm.gid = sbuf.sem_perm.gid;
|
semaptr->sem_perm.gid = sbuf.sem_perm.gid;
|
||||||
semaptr->sem_perm.mode = (semaptr->sem_perm.mode & ~0777) |
|
semaptr->sem_perm.mode = (semaptr->sem_perm.mode & ~0777) |
|
||||||
@ -517,81 +542,91 @@ __semctl(p, uap)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case IPC_STAT:
|
case IPC_STAT:
|
||||||
if ((eval = ipcperm(p, &semaptr->sem_perm, IPC_R)))
|
if ((error = ipcperm(p, &semaptr->sem_perm, IPC_R)))
|
||||||
return(eval);
|
goto done2;
|
||||||
if ((eval = copyin(arg, &real_arg, sizeof(real_arg))) != 0)
|
if ((error = copyin(arg, &real_arg, sizeof(real_arg))) != 0)
|
||||||
return(eval);
|
goto done2;
|
||||||
eval = copyout((caddr_t)semaptr, real_arg.buf,
|
error = copyout((caddr_t)semaptr, real_arg.buf,
|
||||||
sizeof(struct semid_ds));
|
sizeof(struct semid_ds));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GETNCNT:
|
case GETNCNT:
|
||||||
if ((eval = ipcperm(p, &semaptr->sem_perm, IPC_R)))
|
if ((error = ipcperm(p, &semaptr->sem_perm, IPC_R)))
|
||||||
return(eval);
|
goto done2;
|
||||||
if (semnum < 0 || semnum >= semaptr->sem_nsems)
|
if (semnum < 0 || semnum >= semaptr->sem_nsems) {
|
||||||
return(EINVAL);
|
error = EINVAL;
|
||||||
|
goto done2;
|
||||||
|
}
|
||||||
rval = semaptr->sem_base[semnum].semncnt;
|
rval = semaptr->sem_base[semnum].semncnt;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GETPID:
|
case GETPID:
|
||||||
if ((eval = ipcperm(p, &semaptr->sem_perm, IPC_R)))
|
if ((error = ipcperm(p, &semaptr->sem_perm, IPC_R)))
|
||||||
return(eval);
|
goto done2;
|
||||||
if (semnum < 0 || semnum >= semaptr->sem_nsems)
|
if (semnum < 0 || semnum >= semaptr->sem_nsems) {
|
||||||
return(EINVAL);
|
error = EINVAL;
|
||||||
|
goto done2;
|
||||||
|
}
|
||||||
rval = semaptr->sem_base[semnum].sempid;
|
rval = semaptr->sem_base[semnum].sempid;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GETVAL:
|
case GETVAL:
|
||||||
if ((eval = ipcperm(p, &semaptr->sem_perm, IPC_R)))
|
if ((error = ipcperm(p, &semaptr->sem_perm, IPC_R)))
|
||||||
return(eval);
|
goto done2;
|
||||||
if (semnum < 0 || semnum >= semaptr->sem_nsems)
|
if (semnum < 0 || semnum >= semaptr->sem_nsems) {
|
||||||
return(EINVAL);
|
error = EINVAL;
|
||||||
|
goto done2;
|
||||||
|
}
|
||||||
rval = semaptr->sem_base[semnum].semval;
|
rval = semaptr->sem_base[semnum].semval;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GETALL:
|
case GETALL:
|
||||||
if ((eval = ipcperm(p, &semaptr->sem_perm, IPC_R)))
|
if ((error = ipcperm(p, &semaptr->sem_perm, IPC_R)))
|
||||||
return(eval);
|
goto done2;
|
||||||
if ((eval = copyin(arg, &real_arg, sizeof(real_arg))) != 0)
|
if ((error = copyin(arg, &real_arg, sizeof(real_arg))) != 0)
|
||||||
return(eval);
|
goto done2;
|
||||||
for (i = 0; i < semaptr->sem_nsems; i++) {
|
for (i = 0; i < semaptr->sem_nsems; i++) {
|
||||||
eval = copyout((caddr_t)&semaptr->sem_base[i].semval,
|
error = copyout((caddr_t)&semaptr->sem_base[i].semval,
|
||||||
&real_arg.array[i], sizeof(real_arg.array[0]));
|
&real_arg.array[i], sizeof(real_arg.array[0]));
|
||||||
if (eval != 0)
|
if (error != 0)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GETZCNT:
|
case GETZCNT:
|
||||||
if ((eval = ipcperm(p, &semaptr->sem_perm, IPC_R)))
|
if ((error = ipcperm(p, &semaptr->sem_perm, IPC_R)))
|
||||||
return(eval);
|
goto done2;
|
||||||
if (semnum < 0 || semnum >= semaptr->sem_nsems)
|
if (semnum < 0 || semnum >= semaptr->sem_nsems) {
|
||||||
return(EINVAL);
|
error = EINVAL;
|
||||||
|
goto done2;
|
||||||
|
}
|
||||||
rval = semaptr->sem_base[semnum].semzcnt;
|
rval = semaptr->sem_base[semnum].semzcnt;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SETVAL:
|
case SETVAL:
|
||||||
if ((eval = ipcperm(p, &semaptr->sem_perm, IPC_W)))
|
if ((error = ipcperm(p, &semaptr->sem_perm, IPC_W)))
|
||||||
return(eval);
|
goto done2;
|
||||||
if (semnum < 0 || semnum >= semaptr->sem_nsems)
|
if (semnum < 0 || semnum >= semaptr->sem_nsems) {
|
||||||
return(EINVAL);
|
error = EINVAL;
|
||||||
if ((eval = copyin(arg, &real_arg, sizeof(real_arg))) != 0)
|
goto done2;
|
||||||
return(eval);
|
}
|
||||||
|
if ((error = copyin(arg, &real_arg, sizeof(real_arg))) != 0)
|
||||||
|
goto done2;
|
||||||
semaptr->sem_base[semnum].semval = real_arg.val;
|
semaptr->sem_base[semnum].semval = real_arg.val;
|
||||||
semundo_clear(semid, semnum);
|
semundo_clear(semid, semnum);
|
||||||
wakeup((caddr_t)semaptr);
|
wakeup((caddr_t)semaptr);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SETALL:
|
case SETALL:
|
||||||
if ((eval = ipcperm(p, &semaptr->sem_perm, IPC_W)))
|
if ((error = ipcperm(p, &semaptr->sem_perm, IPC_W)))
|
||||||
return(eval);
|
goto done2;
|
||||||
if ((eval = copyin(arg, &real_arg, sizeof(real_arg))) != 0)
|
if ((error = copyin(arg, &real_arg, sizeof(real_arg))) != 0)
|
||||||
return(eval);
|
goto done2;
|
||||||
for (i = 0; i < semaptr->sem_nsems; i++) {
|
for (i = 0; i < semaptr->sem_nsems; i++) {
|
||||||
eval = copyin(&real_arg.array[i],
|
error = copyin(&real_arg.array[i],
|
||||||
(caddr_t)&semaptr->sem_base[i].semval,
|
(caddr_t)&semaptr->sem_base[i].semval,
|
||||||
sizeof(real_arg.array[0]));
|
sizeof(real_arg.array[0]));
|
||||||
if (eval != 0)
|
if (error != 0)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
semundo_clear(semid, -1);
|
semundo_clear(semid, -1);
|
||||||
@ -599,12 +634,15 @@ __semctl(p, uap)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return(EINVAL);
|
error = EINVAL;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (eval == 0)
|
if (error == 0)
|
||||||
p->p_retval[0] = rval;
|
p->p_retval[0] = rval;
|
||||||
return(eval);
|
done2:
|
||||||
|
mtx_unlock(&Giant);
|
||||||
|
return(error);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef _SYS_SYSPROTO_H_
|
#ifndef _SYS_SYSPROTO_H_
|
||||||
@ -615,12 +653,15 @@ struct semget_args {
|
|||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* MPSAFE
|
||||||
|
*/
|
||||||
int
|
int
|
||||||
semget(p, uap)
|
semget(p, uap)
|
||||||
struct proc *p;
|
struct proc *p;
|
||||||
register struct semget_args *uap;
|
register struct semget_args *uap;
|
||||||
{
|
{
|
||||||
int semid, eval;
|
int semid, error = 0;
|
||||||
int key = uap->key;
|
int key = uap->key;
|
||||||
int nsems = uap->nsems;
|
int nsems = uap->nsems;
|
||||||
int semflg = uap->semflg;
|
int semflg = uap->semflg;
|
||||||
@ -629,9 +670,12 @@ semget(p, uap)
|
|||||||
#ifdef SEM_DEBUG
|
#ifdef SEM_DEBUG
|
||||||
printf("semget(0x%x, %d, 0%o)\n", key, nsems, semflg);
|
printf("semget(0x%x, %d, 0%o)\n", key, nsems, semflg);
|
||||||
#endif
|
#endif
|
||||||
|
mtx_lock(&Giant);
|
||||||
|
|
||||||
if (!jail_sysvipc_allowed && jailed(p->p_ucred))
|
if (!jail_sysvipc_allowed && jailed(p->p_ucred)) {
|
||||||
return (ENOSYS);
|
error = ENOSYS;
|
||||||
|
goto done2;
|
||||||
|
}
|
||||||
|
|
||||||
if (key != IPC_PRIVATE) {
|
if (key != IPC_PRIVATE) {
|
||||||
for (semid = 0; semid < seminfo.semmni; semid++) {
|
for (semid = 0; semid < seminfo.semmni; semid++) {
|
||||||
@ -643,20 +687,23 @@ semget(p, uap)
|
|||||||
#ifdef SEM_DEBUG
|
#ifdef SEM_DEBUG
|
||||||
printf("found public key\n");
|
printf("found public key\n");
|
||||||
#endif
|
#endif
|
||||||
if ((eval = ipcperm(p, &sema[semid].sem_perm,
|
if ((error = ipcperm(p, &sema[semid].sem_perm,
|
||||||
semflg & 0700)))
|
semflg & 0700))) {
|
||||||
return(eval);
|
goto done2;
|
||||||
|
}
|
||||||
if (nsems > 0 && sema[semid].sem_nsems < nsems) {
|
if (nsems > 0 && sema[semid].sem_nsems < nsems) {
|
||||||
#ifdef SEM_DEBUG
|
#ifdef SEM_DEBUG
|
||||||
printf("too small\n");
|
printf("too small\n");
|
||||||
#endif
|
#endif
|
||||||
return(EINVAL);
|
error = EINVAL;
|
||||||
|
goto done2;
|
||||||
}
|
}
|
||||||
if ((semflg & IPC_CREAT) && (semflg & IPC_EXCL)) {
|
if ((semflg & IPC_CREAT) && (semflg & IPC_EXCL)) {
|
||||||
#ifdef SEM_DEBUG
|
#ifdef SEM_DEBUG
|
||||||
printf("not exclusive\n");
|
printf("not exclusive\n");
|
||||||
#endif
|
#endif
|
||||||
return(EEXIST);
|
error = EEXIST;
|
||||||
|
goto done2;
|
||||||
}
|
}
|
||||||
goto found;
|
goto found;
|
||||||
}
|
}
|
||||||
@ -671,14 +718,16 @@ semget(p, uap)
|
|||||||
printf("nsems out of range (0<%d<=%d)\n", nsems,
|
printf("nsems out of range (0<%d<=%d)\n", nsems,
|
||||||
seminfo.semmsl);
|
seminfo.semmsl);
|
||||||
#endif
|
#endif
|
||||||
return(EINVAL);
|
error = EINVAL;
|
||||||
|
goto done2;
|
||||||
}
|
}
|
||||||
if (nsems > seminfo.semmns - semtot) {
|
if (nsems > seminfo.semmns - semtot) {
|
||||||
#ifdef SEM_DEBUG
|
#ifdef SEM_DEBUG
|
||||||
printf("not enough semaphores left (need %d, got %d)\n",
|
printf("not enough semaphores left (need %d, got %d)\n",
|
||||||
nsems, seminfo.semmns - semtot);
|
nsems, seminfo.semmns - semtot);
|
||||||
#endif
|
#endif
|
||||||
return(ENOSPC);
|
error = ENOSPC;
|
||||||
|
goto done2;
|
||||||
}
|
}
|
||||||
for (semid = 0; semid < seminfo.semmni; semid++) {
|
for (semid = 0; semid < seminfo.semmni; semid++) {
|
||||||
if ((sema[semid].sem_perm.mode & SEM_ALLOC) == 0)
|
if ((sema[semid].sem_perm.mode & SEM_ALLOC) == 0)
|
||||||
@ -688,7 +737,8 @@ semget(p, uap)
|
|||||||
#ifdef SEM_DEBUG
|
#ifdef SEM_DEBUG
|
||||||
printf("no more semid_ds's available\n");
|
printf("no more semid_ds's available\n");
|
||||||
#endif
|
#endif
|
||||||
return(ENOSPC);
|
error = ENOSPC;
|
||||||
|
goto done2;
|
||||||
}
|
}
|
||||||
#ifdef SEM_DEBUG
|
#ifdef SEM_DEBUG
|
||||||
printf("semid %d is available\n", semid);
|
printf("semid %d is available\n", semid);
|
||||||
@ -716,12 +766,15 @@ semget(p, uap)
|
|||||||
#ifdef SEM_DEBUG
|
#ifdef SEM_DEBUG
|
||||||
printf("didn't find it and wasn't asked to create it\n");
|
printf("didn't find it and wasn't asked to create it\n");
|
||||||
#endif
|
#endif
|
||||||
return(ENOENT);
|
error = ENOENT;
|
||||||
|
goto done2;
|
||||||
}
|
}
|
||||||
|
|
||||||
found:
|
found:
|
||||||
p->p_retval[0] = IXSEQ_TO_IPCID(semid, sema[semid].sem_perm);
|
p->p_retval[0] = IXSEQ_TO_IPCID(semid, sema[semid].sem_perm);
|
||||||
return(0);
|
done2:
|
||||||
|
mtx_unlock(&Giant);
|
||||||
|
return (error);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef _SYS_SYSPROTO_H_
|
#ifndef _SYS_SYSPROTO_H_
|
||||||
@ -732,6 +785,9 @@ struct semop_args {
|
|||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* MPSAFE
|
||||||
|
*/
|
||||||
int
|
int
|
||||||
semop(p, uap)
|
semop(p, uap)
|
||||||
struct proc *p;
|
struct proc *p;
|
||||||
@ -744,47 +800,58 @@ semop(p, uap)
|
|||||||
register struct sembuf *sopptr;
|
register struct sembuf *sopptr;
|
||||||
register struct sem *semptr;
|
register struct sem *semptr;
|
||||||
struct sem_undo *suptr = NULL;
|
struct sem_undo *suptr = NULL;
|
||||||
int i, j, eval;
|
int i, j, error = 0;
|
||||||
int do_wakeup, do_undos;
|
int do_wakeup, do_undos;
|
||||||
|
|
||||||
#ifdef SEM_DEBUG
|
#ifdef SEM_DEBUG
|
||||||
printf("call to semop(%d, 0x%x, %d)\n", semid, sops, nsops);
|
printf("call to semop(%d, 0x%x, %d)\n", semid, sops, nsops);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (!jail_sysvipc_allowed && jailed(p->p_ucred))
|
mtx_lock(&Giant);
|
||||||
return (ENOSYS);
|
|
||||||
|
if (!jail_sysvipc_allowed && jailed(p->p_ucred)) {
|
||||||
|
error = ENOSYS;
|
||||||
|
goto done2;
|
||||||
|
}
|
||||||
|
|
||||||
semid = IPCID_TO_IX(semid); /* Convert back to zero origin */
|
semid = IPCID_TO_IX(semid); /* Convert back to zero origin */
|
||||||
|
|
||||||
if (semid < 0 || semid >= seminfo.semmsl)
|
if (semid < 0 || semid >= seminfo.semmsl) {
|
||||||
return(EINVAL);
|
error = EINVAL;
|
||||||
|
goto done2;
|
||||||
|
}
|
||||||
|
|
||||||
semaptr = &sema[semid];
|
semaptr = &sema[semid];
|
||||||
if ((semaptr->sem_perm.mode & SEM_ALLOC) == 0)
|
if ((semaptr->sem_perm.mode & SEM_ALLOC) == 0) {
|
||||||
return(EINVAL);
|
error = EINVAL;
|
||||||
if (semaptr->sem_perm.seq != IPCID_TO_SEQ(uap->semid))
|
goto done2;
|
||||||
return(EINVAL);
|
}
|
||||||
|
if (semaptr->sem_perm.seq != IPCID_TO_SEQ(uap->semid)) {
|
||||||
|
error = EINVAL;
|
||||||
|
goto done2;
|
||||||
|
}
|
||||||
|
|
||||||
if ((eval = ipcperm(p, &semaptr->sem_perm, IPC_W))) {
|
if ((error = ipcperm(p, &semaptr->sem_perm, IPC_W))) {
|
||||||
#ifdef SEM_DEBUG
|
#ifdef SEM_DEBUG
|
||||||
printf("eval = %d from ipaccess\n", eval);
|
printf("error = %d from ipaccess\n", error);
|
||||||
#endif
|
#endif
|
||||||
return(eval);
|
goto done2;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nsops > MAX_SOPS) {
|
if (nsops > MAX_SOPS) {
|
||||||
#ifdef SEM_DEBUG
|
#ifdef SEM_DEBUG
|
||||||
printf("too many sops (max=%d, nsops=%d)\n", MAX_SOPS, nsops);
|
printf("too many sops (max=%d, nsops=%d)\n", MAX_SOPS, nsops);
|
||||||
#endif
|
#endif
|
||||||
return(E2BIG);
|
error = E2BIG;
|
||||||
|
goto done2;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((eval = copyin(uap->sops, &sops, nsops * sizeof(sops[0]))) != 0) {
|
if ((error = copyin(uap->sops, &sops, nsops * sizeof(sops[0]))) != 0) {
|
||||||
#ifdef SEM_DEBUG
|
#ifdef SEM_DEBUG
|
||||||
printf("eval = %d from copyin(%08x, %08x, %d)\n", eval,
|
printf("error = %d from copyin(%08x, %08x, %d)\n", error,
|
||||||
uap->sops, &sops, nsops * sizeof(sops[0]));
|
uap->sops, &sops, nsops * sizeof(sops[0]));
|
||||||
#endif
|
#endif
|
||||||
return(eval);
|
goto done2;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -804,8 +871,10 @@ semop(p, uap)
|
|||||||
for (i = 0; i < nsops; i++) {
|
for (i = 0; i < nsops; i++) {
|
||||||
sopptr = &sops[i];
|
sopptr = &sops[i];
|
||||||
|
|
||||||
if (sopptr->sem_num >= semaptr->sem_nsems)
|
if (sopptr->sem_num >= semaptr->sem_nsems) {
|
||||||
return(EFBIG);
|
error = EFBIG;
|
||||||
|
goto done2;
|
||||||
|
}
|
||||||
|
|
||||||
semptr = &semaptr->sem_base[sopptr->sem_num];
|
semptr = &semaptr->sem_base[sopptr->sem_num];
|
||||||
|
|
||||||
@ -866,8 +935,10 @@ semop(p, uap)
|
|||||||
* If the request that we couldn't satisfy has the
|
* If the request that we couldn't satisfy has the
|
||||||
* NOWAIT flag set then return with EAGAIN.
|
* NOWAIT flag set then return with EAGAIN.
|
||||||
*/
|
*/
|
||||||
if (sopptr->sem_flg & IPC_NOWAIT)
|
if (sopptr->sem_flg & IPC_NOWAIT) {
|
||||||
return(EAGAIN);
|
error = EAGAIN;
|
||||||
|
goto done2;
|
||||||
|
}
|
||||||
|
|
||||||
if (sopptr->sem_op == 0)
|
if (sopptr->sem_op == 0)
|
||||||
semptr->semzcnt++;
|
semptr->semzcnt++;
|
||||||
@ -877,16 +948,18 @@ semop(p, uap)
|
|||||||
#ifdef SEM_DEBUG
|
#ifdef SEM_DEBUG
|
||||||
printf("semop: good night!\n");
|
printf("semop: good night!\n");
|
||||||
#endif
|
#endif
|
||||||
eval = tsleep((caddr_t)semaptr, (PZERO - 4) | PCATCH,
|
error = tsleep((caddr_t)semaptr, (PZERO - 4) | PCATCH,
|
||||||
"semwait", 0);
|
"semwait", 0);
|
||||||
#ifdef SEM_DEBUG
|
#ifdef SEM_DEBUG
|
||||||
printf("semop: good morning (eval=%d)!\n", eval);
|
printf("semop: good morning (error=%d)!\n", error);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
suptr = NULL; /* sem_undo may have been reallocated */
|
suptr = NULL; /* sem_undo may have been reallocated */
|
||||||
|
|
||||||
if (eval != 0)
|
if (error != 0) {
|
||||||
return(EINTR);
|
error = EINTR;
|
||||||
|
goto done2;
|
||||||
|
}
|
||||||
#ifdef SEM_DEBUG
|
#ifdef SEM_DEBUG
|
||||||
printf("semop: good morning!\n");
|
printf("semop: good morning!\n");
|
||||||
#endif
|
#endif
|
||||||
@ -895,8 +968,10 @@ semop(p, uap)
|
|||||||
* Make sure that the semaphore still exists
|
* Make sure that the semaphore still exists
|
||||||
*/
|
*/
|
||||||
if ((semaptr->sem_perm.mode & SEM_ALLOC) == 0 ||
|
if ((semaptr->sem_perm.mode & SEM_ALLOC) == 0 ||
|
||||||
semaptr->sem_perm.seq != IPCID_TO_SEQ(uap->semid))
|
semaptr->sem_perm.seq != IPCID_TO_SEQ(uap->semid)) {
|
||||||
return(EIDRM);
|
error = EIDRM;
|
||||||
|
goto done2;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The semaphore is still alive. Readjust the count of
|
* The semaphore is still alive. Readjust the count of
|
||||||
@ -925,9 +1000,9 @@ done:
|
|||||||
adjval = sops[i].sem_op;
|
adjval = sops[i].sem_op;
|
||||||
if (adjval == 0)
|
if (adjval == 0)
|
||||||
continue;
|
continue;
|
||||||
eval = semundo_adjust(p, &suptr, semid,
|
error = semundo_adjust(p, &suptr, semid,
|
||||||
sops[i].sem_num, -adjval);
|
sops[i].sem_num, -adjval);
|
||||||
if (eval == 0)
|
if (error == 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -955,9 +1030,9 @@ done:
|
|||||||
sops[j].sem_op;
|
sops[j].sem_op;
|
||||||
|
|
||||||
#ifdef SEM_DEBUG
|
#ifdef SEM_DEBUG
|
||||||
printf("eval = %d from semundo_adjust\n", eval);
|
printf("error = %d from semundo_adjust\n", error);
|
||||||
#endif
|
#endif
|
||||||
return(eval);
|
goto done2;
|
||||||
} /* loop through the sops */
|
} /* loop through the sops */
|
||||||
} /* if (do_undos) */
|
} /* if (do_undos) */
|
||||||
|
|
||||||
@ -982,7 +1057,9 @@ done:
|
|||||||
printf("semop: done\n");
|
printf("semop: done\n");
|
||||||
#endif
|
#endif
|
||||||
p->p_retval[0] = 0;
|
p->p_retval[0] = 0;
|
||||||
return(0);
|
done2:
|
||||||
|
mtx_unlock(&Giant);
|
||||||
|
return (error);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -233,6 +233,9 @@ struct shmdt_args {
|
|||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* MPSAFE
|
||||||
|
*/
|
||||||
int
|
int
|
||||||
shmdt(p, uap)
|
shmdt(p, uap)
|
||||||
struct proc *p;
|
struct proc *p;
|
||||||
@ -240,22 +243,34 @@ shmdt(p, uap)
|
|||||||
{
|
{
|
||||||
struct shmmap_state *shmmap_s;
|
struct shmmap_state *shmmap_s;
|
||||||
int i;
|
int i;
|
||||||
int error;
|
int error = 0;
|
||||||
|
|
||||||
if (!jail_sysvipc_allowed && jailed(p->p_ucred))
|
mtx_lock(&Giant);
|
||||||
return (ENOSYS);
|
|
||||||
|
if (!jail_sysvipc_allowed && jailed(p->p_ucred)) {
|
||||||
|
error = ENOSYS;
|
||||||
|
goto done2;
|
||||||
|
}
|
||||||
|
|
||||||
shmmap_s = (struct shmmap_state *)p->p_vmspace->vm_shm;
|
shmmap_s = (struct shmmap_state *)p->p_vmspace->vm_shm;
|
||||||
if (shmmap_s == NULL)
|
if (shmmap_s == NULL) {
|
||||||
return EINVAL;
|
error = EINVAL;
|
||||||
for (i = 0; i < shminfo.shmseg; i++, shmmap_s++)
|
goto done2;
|
||||||
|
}
|
||||||
|
for (i = 0; i < shminfo.shmseg; i++, shmmap_s++) {
|
||||||
if (shmmap_s->shmid != -1 &&
|
if (shmmap_s->shmid != -1 &&
|
||||||
shmmap_s->va == (vm_offset_t)uap->shmaddr)
|
shmmap_s->va == (vm_offset_t)uap->shmaddr) {
|
||||||
break;
|
break;
|
||||||
if (i == shminfo.shmseg)
|
}
|
||||||
return EINVAL;
|
}
|
||||||
|
if (i == shminfo.shmseg) {
|
||||||
|
error = EINVAL;
|
||||||
|
goto done2;
|
||||||
|
}
|
||||||
error = shm_delete_mapping(p, shmmap_s);
|
error = shm_delete_mapping(p, shmmap_s);
|
||||||
return error;
|
done2:
|
||||||
|
mtx_unlock(&Giant);
|
||||||
|
return (error);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef _SYS_SYSPROTO_H_
|
#ifndef _SYS_SYSPROTO_H_
|
||||||
@ -266,12 +281,15 @@ struct shmat_args {
|
|||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* MPSAFE
|
||||||
|
*/
|
||||||
int
|
int
|
||||||
shmat(p, uap)
|
shmat(p, uap)
|
||||||
struct proc *p;
|
struct proc *p;
|
||||||
struct shmat_args *uap;
|
struct shmat_args *uap;
|
||||||
{
|
{
|
||||||
int error, i, flags;
|
int i, flags;
|
||||||
struct shmid_ds *shmseg;
|
struct shmid_ds *shmseg;
|
||||||
struct shmmap_state *shmmap_s = NULL;
|
struct shmmap_state *shmmap_s = NULL;
|
||||||
struct shm_handle *shm_handle;
|
struct shm_handle *shm_handle;
|
||||||
@ -279,11 +297,14 @@ shmat(p, uap)
|
|||||||
vm_prot_t prot;
|
vm_prot_t prot;
|
||||||
vm_size_t size;
|
vm_size_t size;
|
||||||
int rv;
|
int rv;
|
||||||
|
int error = 0;
|
||||||
|
|
||||||
GIANT_REQUIRED;
|
mtx_lock(&Giant);
|
||||||
|
|
||||||
if (!jail_sysvipc_allowed && jailed(p->p_ucred))
|
if (!jail_sysvipc_allowed && jailed(p->p_ucred)) {
|
||||||
return (ENOSYS);
|
error = ENOSYS;
|
||||||
|
goto done2;
|
||||||
|
}
|
||||||
|
|
||||||
shmmap_s = (struct shmmap_state *)p->p_vmspace->vm_shm;
|
shmmap_s = (struct shmmap_state *)p->p_vmspace->vm_shm;
|
||||||
if (shmmap_s == NULL) {
|
if (shmmap_s == NULL) {
|
||||||
@ -294,19 +315,23 @@ shmat(p, uap)
|
|||||||
p->p_vmspace->vm_shm = (caddr_t)shmmap_s;
|
p->p_vmspace->vm_shm = (caddr_t)shmmap_s;
|
||||||
}
|
}
|
||||||
shmseg = shm_find_segment_by_shmid(uap->shmid);
|
shmseg = shm_find_segment_by_shmid(uap->shmid);
|
||||||
if (shmseg == NULL)
|
if (shmseg == NULL) {
|
||||||
return EINVAL;
|
error = EINVAL;
|
||||||
|
goto done2;
|
||||||
|
}
|
||||||
error = ipcperm(p, &shmseg->shm_perm,
|
error = ipcperm(p, &shmseg->shm_perm,
|
||||||
(uap->shmflg & SHM_RDONLY) ? IPC_R : IPC_R|IPC_W);
|
(uap->shmflg & SHM_RDONLY) ? IPC_R : IPC_R|IPC_W);
|
||||||
if (error)
|
if (error)
|
||||||
return error;
|
goto done2;
|
||||||
for (i = 0; i < shminfo.shmseg; i++) {
|
for (i = 0; i < shminfo.shmseg; i++) {
|
||||||
if (shmmap_s->shmid == -1)
|
if (shmmap_s->shmid == -1)
|
||||||
break;
|
break;
|
||||||
shmmap_s++;
|
shmmap_s++;
|
||||||
}
|
}
|
||||||
if (i >= shminfo.shmseg)
|
if (i >= shminfo.shmseg) {
|
||||||
return EMFILE;
|
error = EMFILE;
|
||||||
|
goto done2;
|
||||||
|
}
|
||||||
size = round_page(shmseg->shm_segsz);
|
size = round_page(shmseg->shm_segsz);
|
||||||
#ifdef VM_PROT_READ_IS_EXEC
|
#ifdef VM_PROT_READ_IS_EXEC
|
||||||
prot = VM_PROT_READ | VM_PROT_EXECUTE;
|
prot = VM_PROT_READ | VM_PROT_EXECUTE;
|
||||||
@ -318,12 +343,14 @@ shmat(p, uap)
|
|||||||
flags = MAP_ANON | MAP_SHARED;
|
flags = MAP_ANON | MAP_SHARED;
|
||||||
if (uap->shmaddr) {
|
if (uap->shmaddr) {
|
||||||
flags |= MAP_FIXED;
|
flags |= MAP_FIXED;
|
||||||
if (uap->shmflg & SHM_RND)
|
if (uap->shmflg & SHM_RND) {
|
||||||
attach_va = (vm_offset_t)uap->shmaddr & ~(SHMLBA-1);
|
attach_va = (vm_offset_t)uap->shmaddr & ~(SHMLBA-1);
|
||||||
else if (((vm_offset_t)uap->shmaddr & (SHMLBA-1)) == 0)
|
} else if (((vm_offset_t)uap->shmaddr & (SHMLBA-1)) == 0) {
|
||||||
attach_va = (vm_offset_t)uap->shmaddr;
|
attach_va = (vm_offset_t)uap->shmaddr;
|
||||||
else
|
} else {
|
||||||
return EINVAL;
|
error = EINVAL;
|
||||||
|
goto done2;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
/*
|
/*
|
||||||
* This is just a hint to vm_map_find() about where to
|
* This is just a hint to vm_map_find() about where to
|
||||||
@ -338,7 +365,8 @@ shmat(p, uap)
|
|||||||
rv = vm_map_find(&p->p_vmspace->vm_map, shm_handle->shm_object,
|
rv = vm_map_find(&p->p_vmspace->vm_map, shm_handle->shm_object,
|
||||||
0, &attach_va, size, (flags & MAP_FIXED)?0:1, prot, prot, 0);
|
0, &attach_va, size, (flags & MAP_FIXED)?0:1, prot, prot, 0);
|
||||||
if (rv != KERN_SUCCESS) {
|
if (rv != KERN_SUCCESS) {
|
||||||
return ENOMEM;
|
error = ENOMEM;
|
||||||
|
goto done2;
|
||||||
}
|
}
|
||||||
vm_map_inherit(&p->p_vmspace->vm_map,
|
vm_map_inherit(&p->p_vmspace->vm_map,
|
||||||
attach_va, attach_va + size, VM_INHERIT_SHARE);
|
attach_va, attach_va + size, VM_INHERIT_SHARE);
|
||||||
@ -349,7 +377,9 @@ shmat(p, uap)
|
|||||||
shmseg->shm_atime = time_second;
|
shmseg->shm_atime = time_second;
|
||||||
shmseg->shm_nattch++;
|
shmseg->shm_nattch++;
|
||||||
p->p_retval[0] = attach_va;
|
p->p_retval[0] = attach_va;
|
||||||
return 0;
|
done2:
|
||||||
|
mtx_unlock(&Giant);
|
||||||
|
return (error);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct oshmid_ds {
|
struct oshmid_ds {
|
||||||
@ -370,27 +400,36 @@ struct oshmctl_args {
|
|||||||
struct oshmid_ds *ubuf;
|
struct oshmid_ds *ubuf;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* MPSAFE
|
||||||
|
*/
|
||||||
static int
|
static int
|
||||||
oshmctl(p, uap)
|
oshmctl(p, uap)
|
||||||
struct proc *p;
|
struct proc *p;
|
||||||
struct oshmctl_args *uap;
|
struct oshmctl_args *uap;
|
||||||
{
|
{
|
||||||
#ifdef COMPAT_43
|
#ifdef COMPAT_43
|
||||||
int error;
|
int error = 0;
|
||||||
struct shmid_ds *shmseg;
|
struct shmid_ds *shmseg;
|
||||||
struct oshmid_ds outbuf;
|
struct oshmid_ds outbuf;
|
||||||
|
|
||||||
if (!jail_sysvipc_allowed && jailed(p->p_ucred))
|
mtx_lock(&Giant);
|
||||||
return (ENOSYS);
|
|
||||||
|
if (!jail_sysvipc_allowed && jailed(p->p_ucred)) {
|
||||||
|
error = ENOSYS;
|
||||||
|
goto done2;
|
||||||
|
}
|
||||||
|
|
||||||
shmseg = shm_find_segment_by_shmid(uap->shmid);
|
shmseg = shm_find_segment_by_shmid(uap->shmid);
|
||||||
if (shmseg == NULL)
|
if (shmseg == NULL) {
|
||||||
return EINVAL;
|
error = EINVAL;
|
||||||
|
goto done2;
|
||||||
|
}
|
||||||
switch (uap->cmd) {
|
switch (uap->cmd) {
|
||||||
case IPC_STAT:
|
case IPC_STAT:
|
||||||
error = ipcperm(p, &shmseg->shm_perm, IPC_R);
|
error = ipcperm(p, &shmseg->shm_perm, IPC_R);
|
||||||
if (error)
|
if (error)
|
||||||
return error;
|
goto done2;
|
||||||
outbuf.shm_perm = shmseg->shm_perm;
|
outbuf.shm_perm = shmseg->shm_perm;
|
||||||
outbuf.shm_segsz = shmseg->shm_segsz;
|
outbuf.shm_segsz = shmseg->shm_segsz;
|
||||||
outbuf.shm_cpid = shmseg->shm_cpid;
|
outbuf.shm_cpid = shmseg->shm_cpid;
|
||||||
@ -402,13 +441,16 @@ oshmctl(p, uap)
|
|||||||
outbuf.shm_handle = shmseg->shm_internal;
|
outbuf.shm_handle = shmseg->shm_internal;
|
||||||
error = copyout((caddr_t)&outbuf, uap->ubuf, sizeof(outbuf));
|
error = copyout((caddr_t)&outbuf, uap->ubuf, sizeof(outbuf));
|
||||||
if (error)
|
if (error)
|
||||||
return error;
|
goto done2;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
/* XXX casting to (sy_call_t *) is bogus, as usual. */
|
/* XXX casting to (sy_call_t *) is bogus, as usual. */
|
||||||
return ((sy_call_t *)shmctl)(p, uap);
|
error = ((sy_call_t *)shmctl)(p, uap);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
return 0;
|
done2:
|
||||||
|
mtx_unlock(&Giant);
|
||||||
|
return (error);
|
||||||
#else
|
#else
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
#endif
|
#endif
|
||||||
@ -422,39 +464,46 @@ struct shmctl_args {
|
|||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* MPSAFE
|
||||||
|
*/
|
||||||
int
|
int
|
||||||
shmctl(p, uap)
|
shmctl(p, uap)
|
||||||
struct proc *p;
|
struct proc *p;
|
||||||
struct shmctl_args *uap;
|
struct shmctl_args *uap;
|
||||||
{
|
{
|
||||||
int error;
|
int error = 0;
|
||||||
struct shmid_ds inbuf;
|
struct shmid_ds inbuf;
|
||||||
struct shmid_ds *shmseg;
|
struct shmid_ds *shmseg;
|
||||||
|
|
||||||
GIANT_REQUIRED;
|
mtx_lock(&Giant);
|
||||||
|
|
||||||
if (!jail_sysvipc_allowed && jailed(p->p_ucred))
|
if (!jail_sysvipc_allowed && jailed(p->p_ucred)) {
|
||||||
return (ENOSYS);
|
error = ENOSYS;
|
||||||
|
goto done2;
|
||||||
|
}
|
||||||
|
|
||||||
shmseg = shm_find_segment_by_shmid(uap->shmid);
|
shmseg = shm_find_segment_by_shmid(uap->shmid);
|
||||||
if (shmseg == NULL)
|
if (shmseg == NULL) {
|
||||||
return EINVAL;
|
error = EINVAL;
|
||||||
|
goto done2;
|
||||||
|
}
|
||||||
switch (uap->cmd) {
|
switch (uap->cmd) {
|
||||||
case IPC_STAT:
|
case IPC_STAT:
|
||||||
error = ipcperm(p, &shmseg->shm_perm, IPC_R);
|
error = ipcperm(p, &shmseg->shm_perm, IPC_R);
|
||||||
if (error)
|
if (error)
|
||||||
return error;
|
goto done2;
|
||||||
error = copyout((caddr_t)shmseg, uap->buf, sizeof(inbuf));
|
error = copyout((caddr_t)shmseg, uap->buf, sizeof(inbuf));
|
||||||
if (error)
|
if (error)
|
||||||
return error;
|
goto done2;
|
||||||
break;
|
break;
|
||||||
case IPC_SET:
|
case IPC_SET:
|
||||||
error = ipcperm(p, &shmseg->shm_perm, IPC_M);
|
error = ipcperm(p, &shmseg->shm_perm, IPC_M);
|
||||||
if (error)
|
if (error)
|
||||||
return error;
|
goto done2;
|
||||||
error = copyin(uap->buf, (caddr_t)&inbuf, sizeof(inbuf));
|
error = copyin(uap->buf, (caddr_t)&inbuf, sizeof(inbuf));
|
||||||
if (error)
|
if (error)
|
||||||
return error;
|
goto done2;
|
||||||
shmseg->shm_perm.uid = inbuf.shm_perm.uid;
|
shmseg->shm_perm.uid = inbuf.shm_perm.uid;
|
||||||
shmseg->shm_perm.gid = inbuf.shm_perm.gid;
|
shmseg->shm_perm.gid = inbuf.shm_perm.gid;
|
||||||
shmseg->shm_perm.mode =
|
shmseg->shm_perm.mode =
|
||||||
@ -465,7 +514,7 @@ shmctl(p, uap)
|
|||||||
case IPC_RMID:
|
case IPC_RMID:
|
||||||
error = ipcperm(p, &shmseg->shm_perm, IPC_M);
|
error = ipcperm(p, &shmseg->shm_perm, IPC_M);
|
||||||
if (error)
|
if (error)
|
||||||
return error;
|
goto done2;
|
||||||
shmseg->shm_perm.key = IPC_PRIVATE;
|
shmseg->shm_perm.key = IPC_PRIVATE;
|
||||||
shmseg->shm_perm.mode |= SHMSEG_REMOVED;
|
shmseg->shm_perm.mode |= SHMSEG_REMOVED;
|
||||||
if (shmseg->shm_nattch <= 0) {
|
if (shmseg->shm_nattch <= 0) {
|
||||||
@ -478,9 +527,12 @@ shmctl(p, uap)
|
|||||||
case SHM_UNLOCK:
|
case SHM_UNLOCK:
|
||||||
#endif
|
#endif
|
||||||
default:
|
default:
|
||||||
return EINVAL;
|
error = EINVAL;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
return 0;
|
done2:
|
||||||
|
mtx_unlock(&Giant);
|
||||||
|
return (error);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef _SYS_SYSPROTO_H_
|
#ifndef _SYS_SYSPROTO_H_
|
||||||
@ -607,15 +659,23 @@ shmget_allocate_segment(p, uap, mode)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* MPSAFE
|
||||||
|
*/
|
||||||
int
|
int
|
||||||
shmget(p, uap)
|
shmget(p, uap)
|
||||||
struct proc *p;
|
struct proc *p;
|
||||||
struct shmget_args *uap;
|
struct shmget_args *uap;
|
||||||
{
|
{
|
||||||
int segnum, mode, error;
|
int segnum, mode;
|
||||||
|
int error;
|
||||||
|
|
||||||
if (!jail_sysvipc_allowed && jailed(p->p_ucred))
|
mtx_lock(&Giant);
|
||||||
return (ENOSYS);
|
|
||||||
|
if (!jail_sysvipc_allowed && jailed(p->p_ucred)) {
|
||||||
|
error = ENOSYS;
|
||||||
|
goto done2;
|
||||||
|
}
|
||||||
|
|
||||||
mode = uap->shmflg & ACCESSPERMS;
|
mode = uap->shmflg & ACCESSPERMS;
|
||||||
if (uap->key != IPC_PRIVATE) {
|
if (uap->key != IPC_PRIVATE) {
|
||||||
@ -625,14 +685,22 @@ shmget(p, uap)
|
|||||||
error = shmget_existing(p, uap, mode, segnum);
|
error = shmget_existing(p, uap, mode, segnum);
|
||||||
if (error == EAGAIN)
|
if (error == EAGAIN)
|
||||||
goto again;
|
goto again;
|
||||||
return error;
|
goto done2;
|
||||||
|
}
|
||||||
|
if ((uap->shmflg & IPC_CREAT) == 0) {
|
||||||
|
error = ENOENT;
|
||||||
|
goto done2;
|
||||||
}
|
}
|
||||||
if ((uap->shmflg & IPC_CREAT) == 0)
|
|
||||||
return ENOENT;
|
|
||||||
}
|
}
|
||||||
return shmget_allocate_segment(p, uap, mode);
|
error = shmget_allocate_segment(p, uap, mode);
|
||||||
|
done2:
|
||||||
|
mtx_unlock(&Giant);
|
||||||
|
return (error);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* MPSAFE
|
||||||
|
*/
|
||||||
int
|
int
|
||||||
shmsys(p, uap)
|
shmsys(p, uap)
|
||||||
struct proc *p;
|
struct proc *p;
|
||||||
@ -644,13 +712,23 @@ shmsys(p, uap)
|
|||||||
int a4;
|
int a4;
|
||||||
} */ *uap;
|
} */ *uap;
|
||||||
{
|
{
|
||||||
|
int error;
|
||||||
|
|
||||||
if (!jail_sysvipc_allowed && jailed(p->p_ucred))
|
mtx_lock(&Giant);
|
||||||
return (ENOSYS);
|
|
||||||
|
|
||||||
if (uap->which >= sizeof(shmcalls)/sizeof(shmcalls[0]))
|
if (!jail_sysvipc_allowed && jailed(p->p_ucred)) {
|
||||||
return EINVAL;
|
error = ENOSYS;
|
||||||
return ((*shmcalls[uap->which])(p, &uap->a2));
|
goto done2;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (uap->which >= sizeof(shmcalls)/sizeof(shmcalls[0])) {
|
||||||
|
error = EINVAL;
|
||||||
|
goto done2;
|
||||||
|
}
|
||||||
|
error = (*shmcalls[uap->which])(p, &uap->a2);
|
||||||
|
done2:
|
||||||
|
mtx_unlock(&Giant);
|
||||||
|
return (error);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
Loading…
x
Reference in New Issue
Block a user