summaryrefslogtreecommitdiff
path: root/sys/kern
diff options
context:
space:
mode:
Diffstat (limited to 'sys/kern')
-rw-r--r--sys/kern/sysv_msg.c78
-rw-r--r--sys/kern/sysv_sem.c91
-rw-r--r--sys/kern/sysv_shm.c29
3 files changed, 104 insertions, 94 deletions
diff --git a/sys/kern/sysv_msg.c b/sys/kern/sysv_msg.c
index bf7cf0fbd27..071d839fab7 100644
--- a/sys/kern/sysv_msg.c
+++ b/sys/kern/sysv_msg.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: sysv_msg.c,v 1.16 2004/06/21 23:50:36 tholo Exp $ */
+/* $OpenBSD: sysv_msg.c,v 1.17 2004/07/14 23:40:27 millert Exp $ */
/* $NetBSD: sysv_msg.c,v 1.19 1996/02/09 19:00:18 christos Exp $ */
/*
@@ -167,45 +167,50 @@ sys_msgctl(p, v, retval)
syscallarg(int) cmd;
syscallarg(struct msqid_ds *) buf;
} */ *uap = v;
- int msqid = SCARG(uap, msqid);
- int cmd = SCARG(uap, cmd);
- struct msqid_ds *user_msqptr = SCARG(uap, buf);
+
+ return (msgctl1(p, SCARG(uap, msqid), SCARG(uap, cmd),
+ (caddr_t)SCARG(uap, buf), copyin, copyout));
+}
+
+int
+msgctl1(p, msqid, cmd, buf, ds_copyin, ds_copyout)
+ struct proc *p;
+ int msqid;
+ int cmd;
+ caddr_t buf;
+ int (*ds_copyin)(const void *, void *, size_t);
+ int (*ds_copyout)(const void *, void *, size_t);
+{
struct ucred *cred = p->p_ucred;
- int rval, eval;
- struct msqid_ds msqbuf;
- register struct msqid_ds *msqptr;
+ struct msqid_ds msqbuf, *msqptr;
+ struct msg *msghdr;
+ int ix, error = 0;
- DPRINTF(("call to msgctl(%d, %d, %p)\n", msqid, cmd, user_msqptr));
+ DPRINTF(("call to msgctl(%d, %d, %p)\n", msqid, cmd, buf));
- msqid = IPCID_TO_IX(msqid);
+ ix = IPCID_TO_IX(msqid);
- if (msqid < 0 || msqid >= msginfo.msgmni) {
- DPRINTF(("msqid (%d) out of range (0<=msqid<%d)\n", msqid,
+ if (ix < 0 || ix >= msginfo.msgmni) {
+ DPRINTF(("msqid (%d) out of range (0<=msqid<%d)\n", ix,
msginfo.msgmni));
return (EINVAL);
}
- msqptr = &msqids[msqid];
+ msqptr = &msqids[ix];
if (msqptr->msg_qbytes == 0) {
DPRINTF(("no such msqid\n"));
return (EINVAL);
}
- if (msqptr->msg_perm.seq != IPCID_TO_SEQ(SCARG(uap, msqid))) {
+ if (msqptr->msg_perm.seq != IPCID_TO_SEQ(msqid)) {
DPRINTF(("wrong sequence number\n"));
return (EINVAL);
}
- eval = 0;
- rval = 0;
-
switch (cmd) {
-
case IPC_RMID:
- {
- struct msg *msghdr;
- if ((eval = ipcperm(cred, &msqptr->msg_perm, IPC_M)) != 0)
- return (eval);
+ if ((error = ipcperm(cred, &msqptr->msg_perm, IPC_M)) != 0)
+ return (error);
/* Free the message headers */
msghdr = msqptr->msg_first;
while (msghdr != NULL) {
@@ -225,20 +230,17 @@ sys_msgctl(p, v, retval)
if (msqptr->msg_qnum != 0)
panic("sys_msgctl: msg_qnum is screwed up");
#endif
-
msqptr->msg_qbytes = 0; /* Mark it as free */
-
wakeup(msqptr);
- }
-
break;
case IPC_SET:
- if ((eval = ipcperm(cred, &msqptr->msg_perm, IPC_M)))
- return (eval);
- if ((eval = copyin(user_msqptr, &msqbuf, sizeof(msqbuf))) != 0)
- return (eval);
- if (msqbuf.msg_qbytes > msqptr->msg_qbytes && cred->cr_uid != 0)
+ if ((error = ipcperm(cred, &msqptr->msg_perm, IPC_M)))
+ return (error);
+ if ((error = ds_copyin(buf, &msqbuf, sizeof(msqbuf))) != 0)
+ return (error);
+ if (msqbuf.msg_qbytes > msqptr->msg_qbytes &&
+ cred->cr_uid != 0)
return (EPERM);
if (msqbuf.msg_qbytes > msginfo.msgmnb) {
DPRINTF(("can't increase msg_qbytes beyond %d "
@@ -250,8 +252,8 @@ sys_msgctl(p, v, retval)
DPRINTF(("can't reduce msg_qbytes to 0\n"));
return (EINVAL); /* non-standard errno! */
}
- msqptr->msg_perm.uid = msqbuf.msg_perm.uid; /* change owner */
- msqptr->msg_perm.gid = msqbuf.msg_perm.gid; /* change owner */
+ msqptr->msg_perm.uid = msqbuf.msg_perm.uid;
+ msqptr->msg_perm.gid = msqbuf.msg_perm.gid;
msqptr->msg_perm.mode = (msqptr->msg_perm.mode & ~0777) |
(msqbuf.msg_perm.mode & 0777);
msqptr->msg_qbytes = msqbuf.msg_qbytes;
@@ -259,22 +261,18 @@ sys_msgctl(p, v, retval)
break;
case IPC_STAT:
- if ((eval = ipcperm(cred, &msqptr->msg_perm, IPC_R))) {
+ if ((error = ipcperm(cred, &msqptr->msg_perm, IPC_R))) {
DPRINTF(("requester doesn't have read access\n"));
- return (eval);
+ return (error);
}
- eval = copyout(msqptr, user_msqptr,
- sizeof(struct msqid_ds));
+ error = ds_copyout(msqptr, buf, sizeof(struct msqid_ds));
break;
default:
DPRINTF(("invalid command %d\n", cmd));
return (EINVAL);
}
-
- if (eval == 0)
- *retval = rval;
- return (eval);
+ return (error);
}
int
diff --git a/sys/kern/sysv_sem.c b/sys/kern/sysv_sem.c
index d868dbd7ced..5e86bf14461 100644
--- a/sys/kern/sysv_sem.c
+++ b/sys/kern/sysv_sem.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: sysv_sem.c,v 1.30 2004/06/21 23:50:36 tholo Exp $ */
+/* $OpenBSD: sysv_sem.c,v 1.31 2004/07/14 23:40:27 millert Exp $ */
/* $NetBSD: sysv_sem.c,v 1.26 1996/02/09 19:00:25 christos Exp $ */
/*
@@ -249,28 +249,45 @@ sys___semctl(struct proc *p, void *v, register_t *retval)
syscallarg(int) cmd;
syscallarg(union semun *) arg;
} */ *uap = v;
- int semid = SCARG(uap, semid);
- int semnum = SCARG(uap, semnum);
- int cmd = SCARG(uap, cmd);
- union semun *arg = SCARG(uap, arg);
- union semun real_arg;
+ union semun arg;
+ int error = 0, cmd = SCARG(uap, cmd);
+
+ switch (cmd) {
+ case IPC_SET:
+ case IPC_STAT:
+ case GETALL:
+ case SETVAL:
+ case SETALL:
+ error = copyin(SCARG(uap, arg), &arg, sizeof(arg));
+ break;
+ }
+ if (error == 0) {
+ error = semctl1(p, SCARG(uap, semid), SCARG(uap, semnum),
+ cmd, &arg, retval, copyin, copyout);
+ }
+ return (error);
+}
+
+int
+semctl1(struct proc *p, int semid, int semnum, int cmd, union semun *arg,
+ register_t *retval, int (*ds_copyin)(const void *, void *, size_t),
+ int (*ds_copyout)(const void *, void *, size_t))
+{
struct ucred *cred = p->p_ucred;
- int i, rval, error;
+ int i, ix, error = 0;
struct semid_ds sbuf;
struct semid_ds *semaptr;
DPRINTF(("call to semctl(%d, %d, %d, %p)\n", semid, semnum, cmd, arg));
- semid = IPCID_TO_IX(semid);
- if (semid < 0 || semid >= seminfo.semmni)
+ ix = IPCID_TO_IX(semid);
+ if (ix < 0 || ix >= seminfo.semmni)
return (EINVAL);
- if ((semaptr = sema[semid]) == NULL ||
- semaptr->sem_perm.seq != IPCID_TO_SEQ(SCARG(uap, semid)))
+ if ((semaptr = sema[ix]) == NULL ||
+ semaptr->sem_perm.seq != IPCID_TO_SEQ(semid))
return (EINVAL);
- error = rval = 0;
-
switch (cmd) {
case IPC_RMID:
if ((error = ipcperm(cred, &semaptr->sem_perm, IPC_M)) != 0)
@@ -280,17 +297,15 @@ sys___semctl(struct proc *p, void *v, register_t *retval)
semtot -= semaptr->sem_nsems;
free(semaptr->sem_base, M_SEM);
pool_put(&sema_pool, semaptr);
- sema[semid] = NULL;
- semundo_clear(semid, -1);
- wakeup(&sema[semid]);
+ sema[ix] = NULL;
+ semundo_clear(ix, -1);
+ wakeup(&sema[ix]);
break;
case IPC_SET:
if ((error = ipcperm(cred, &semaptr->sem_perm, IPC_M)))
return (error);
- if ((error = copyin(arg, &real_arg, sizeof(real_arg))) != 0)
- return (error);
- if ((error = copyin(real_arg.buf, &sbuf, sizeof(sbuf))) != 0)
+ if ((error = ds_copyin(arg->buf, &sbuf, sizeof(sbuf))) != 0)
return (error);
semaptr->sem_perm.uid = sbuf.sem_perm.uid;
semaptr->sem_perm.gid = sbuf.sem_perm.gid;
@@ -302,9 +317,7 @@ sys___semctl(struct proc *p, void *v, register_t *retval)
case IPC_STAT:
if ((error = ipcperm(cred, &semaptr->sem_perm, IPC_R)))
return (error);
- if ((error = copyin(arg, &real_arg, sizeof(real_arg))) != 0)
- return (error);
- error = copyout(semaptr, real_arg.buf, sizeof(struct semid_ds));
+ error = ds_copyout(semaptr, arg->buf, sizeof(struct semid_ds));
break;
case GETNCNT:
@@ -312,7 +325,7 @@ sys___semctl(struct proc *p, void *v, register_t *retval)
return (error);
if (semnum < 0 || semnum >= semaptr->sem_nsems)
return (EINVAL);
- rval = semaptr->sem_base[semnum].semncnt;
+ *retval = semaptr->sem_base[semnum].semncnt;
break;
case GETPID:
@@ -320,7 +333,7 @@ sys___semctl(struct proc *p, void *v, register_t *retval)
return (error);
if (semnum < 0 || semnum >= semaptr->sem_nsems)
return (EINVAL);
- rval = semaptr->sem_base[semnum].sempid;
+ *retval = semaptr->sem_base[semnum].sempid;
break;
case GETVAL:
@@ -328,17 +341,15 @@ sys___semctl(struct proc *p, void *v, register_t *retval)
return (error);
if (semnum < 0 || semnum >= semaptr->sem_nsems)
return (EINVAL);
- rval = semaptr->sem_base[semnum].semval;
+ *retval = semaptr->sem_base[semnum].semval;
break;
case GETALL:
if ((error = ipcperm(cred, &semaptr->sem_perm, IPC_R)))
return (error);
- if ((error = copyin(arg, &real_arg, sizeof(real_arg))) != 0)
- return (error);
for (i = 0; i < semaptr->sem_nsems; i++) {
- error = copyout(&semaptr->sem_base[i].semval,
- &real_arg.array[i], sizeof(real_arg.array[0]));
+ error = ds_copyout(&semaptr->sem_base[i].semval,
+ &arg->array[i], sizeof(arg->array[0]));
if (error != 0)
break;
}
@@ -349,7 +360,7 @@ sys___semctl(struct proc *p, void *v, register_t *retval)
return (error);
if (semnum < 0 || semnum >= semaptr->sem_nsems)
return (EINVAL);
- rval = semaptr->sem_base[semnum].semzcnt;
+ *retval = semaptr->sem_base[semnum].semzcnt;
break;
case SETVAL:
@@ -357,35 +368,29 @@ sys___semctl(struct proc *p, void *v, register_t *retval)
return (error);
if (semnum < 0 || semnum >= semaptr->sem_nsems)
return (EINVAL);
- if ((error = copyin(arg, &real_arg, sizeof(real_arg))) != 0)
- return (error);
- semaptr->sem_base[semnum].semval = real_arg.val;
- semundo_clear(semid, semnum);
- wakeup(&sema[semid]);
+ semaptr->sem_base[semnum].semval = arg->val;
+ semundo_clear(ix, semnum);
+ wakeup(&sema[ix]);
break;
case SETALL:
if ((error = ipcperm(cred, &semaptr->sem_perm, IPC_W)))
return (error);
- if ((error = copyin(arg, &real_arg, sizeof(real_arg))) != 0)
- return (error);
for (i = 0; i < semaptr->sem_nsems; i++) {
- error = copyin(&real_arg.array[i],
+ error = ds_copyin(&arg->array[i],
&semaptr->sem_base[i].semval,
- sizeof(real_arg.array[0]));
+ sizeof(arg->array[0]));
if (error != 0)
break;
}
- semundo_clear(semid, -1);
- wakeup(&sema[semid]);
+ semundo_clear(ix, -1);
+ wakeup(&sema[ix]);
break;
default:
return (EINVAL);
}
- if (error == 0)
- *retval = rval;
return (error);
}
diff --git a/sys/kern/sysv_shm.c b/sys/kern/sysv_shm.c
index 3be8c1a1523..df588682aea 100644
--- a/sys/kern/sysv_shm.c
+++ b/sys/kern/sysv_shm.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: sysv_shm.c,v 1.44 2004/06/21 23:50:36 tholo Exp $ */
+/* $OpenBSD: sysv_shm.c,v 1.45 2004/07/14 23:40:27 millert Exp $ */
/* $NetBSD: sysv_shm.c,v 1.50 1998/10/21 22:24:29 tron Exp $ */
/*
@@ -300,28 +300,35 @@ sys_shmctl(struct proc *p, void *v, register_t *retval)
syscallarg(int) cmd;
syscallarg(struct shmid_ds *) buf;
} */ *uap = v;
- int error;
+
+ return (shmctl1(p, SCARG(uap, shmid), SCARG(uap, cmd),
+ (caddr_t)SCARG(uap, buf), copyin, copyout));
+}
+
+int
+shmctl1(struct proc *p, int shmid, int cmd, caddr_t buf,
+ int (*ds_copyin)(const void *, void *, size_t),
+ int (*ds_copyout)(const void *, void *, size_t))
+{
struct ucred *cred = p->p_ucred;
- struct shmid_ds inbuf;
- struct shmid_ds *shmseg;
+ struct shmid_ds inbuf, *shmseg;
+ int error;
- shmseg = shm_find_segment_by_shmid(SCARG(uap, shmid), 1);
+ shmseg = shm_find_segment_by_shmid(shmid, 1);
if (shmseg == NULL)
return (EINVAL);
- switch (SCARG(uap, cmd)) {
+ switch (cmd) {
case IPC_STAT:
if ((error = ipcperm(cred, &shmseg->shm_perm, IPC_R)) != 0)
return (error);
- error = copyout((caddr_t)shmseg, SCARG(uap, buf),
- sizeof(inbuf));
+ error = ds_copyout(shmseg, buf, sizeof(inbuf));
if (error)
return (error);
break;
case IPC_SET:
if ((error = ipcperm(cred, &shmseg->shm_perm, IPC_M)) != 0)
return (error);
- error = copyin(SCARG(uap, buf), (caddr_t)&inbuf,
- sizeof(inbuf));
+ error = ds_copyin(buf, &inbuf, sizeof(inbuf));
if (error)
return (error);
shmseg->shm_perm.uid = inbuf.shm_perm.uid;
@@ -338,7 +345,7 @@ sys_shmctl(struct proc *p, void *v, register_t *retval)
shmseg->shm_perm.mode |= SHMSEG_REMOVED;
if (shmseg->shm_nattch <= 0) {
shm_deallocate_segment(shmseg);
- shm_last_free = IPCID_TO_IX(SCARG(uap, shmid));
+ shm_last_free = IPCID_TO_IX(shmid);
shmsegs[shm_last_free] = NULL;
}
break;