summaryrefslogtreecommitdiff
path: root/sys/kern
diff options
context:
space:
mode:
authorTheo de Raadt <deraadt@cvs.openbsd.org>1998-06-11 18:32:25 +0000
committerTheo de Raadt <deraadt@cvs.openbsd.org>1998-06-11 18:32:25 +0000
commit972db8ac87c9fdf7160f080d738040aa720f719c (patch)
tree7b0fcf15c0cfb9b0af9865d566b5eafd920bdf1f /sys/kern
parent13a4ff03320e09fd87539e8e2116c1580d09806d (diff)
change ipc.h to use uid_t and friends, and then build compat system calls for the old ushort based ipc.h
Diffstat (limited to 'sys/kern')
-rw-r--r--sys/kern/sysv_ipc.c31
-rw-r--r--sys/kern/sysv_msg.c158
-rw-r--r--sys/kern/sysv_sem.c182
-rw-r--r--sys/kern/sysv_shm.c79
4 files changed, 446 insertions, 4 deletions
diff --git a/sys/kern/sysv_ipc.c b/sys/kern/sysv_ipc.c
index 7a093ec6e01..de684b9834c 100644
--- a/sys/kern/sysv_ipc.c
+++ b/sys/kern/sysv_ipc.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: sysv_ipc.c,v 1.2 1997/02/24 14:20:00 niklas Exp $ */
+/* $OpenBSD: sysv_ipc.c,v 1.3 1998/06/11 18:32:13 deraadt Exp $ */
/* $NetBSD: sysv_ipc.c,v 1.10 1995/06/03 05:53:28 mycroft Exp $ */
/*
@@ -62,3 +62,32 @@ ipcperm(cred, perm, mode)
return (0);
return (EACCES);
}
+
+void
+ipc_n2o(n, o)
+ struct ipc_perm *n;
+ struct oipc_perm *o;
+{
+ o->cuid = n->cuid; /* XXX */
+ o->cgid = n->cgid; /* XXX */
+ o->uid = n->uid; /* XXX */
+ o->gid = n->gid; /* XXX */
+ o->mode = n->mode; /* XXX */
+ o->seq = n->seq;
+ o->key = n->key;
+}
+
+void
+ipc_o2n(o, n)
+ struct oipc_perm *o;
+ struct ipc_perm *n;
+{
+ n->cuid = o->cuid; /* XXX */
+ n->cgid = o->cgid; /* XXX */
+ n->uid = o->uid; /* XXX */
+ n->gid = o->gid; /* XXX */
+ n->mode = o->mode; /* XXX */
+ n->seq = o->seq;
+ n->key = o->key;
+}
+
diff --git a/sys/kern/sysv_msg.c b/sys/kern/sysv_msg.c
index f2cb055667e..3db6be02e07 100644
--- a/sys/kern/sysv_msg.c
+++ b/sys/kern/sysv_msg.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: sysv_msg.c,v 1.4 1998/05/11 16:40:45 deraadt Exp $ */
+/* $OpenBSD: sysv_msg.c,v 1.5 1998/06/11 18:32:14 deraadt Exp $ */
/* $NetBSD: sysv_msg.c,v 1.19 1996/02/09 19:00:18 christos Exp $ */
/*
@@ -119,6 +119,162 @@ msg_freehdr(msghdr)
free_msghdrs = msghdr;
}
+void
+msqid_n2o(n, o)
+ struct msqid_ds *n;
+ struct omsqid_ds *o;
+{
+ o->msg_first = n->msg_first;
+ o->msg_last = n->msg_last;
+ o->msg_cbytes = n->msg_cbytes;
+ o->msg_qnum = n->msg_qnum;
+ o->msg_qbytes = n->msg_qbytes;
+ o->msg_lspid = n->msg_lspid;
+ o->msg_lrpid = n->msg_lrpid;
+ o->msg_stime = n->msg_stime;
+ o->msg_pad1 = n->msg_pad1;
+ o->msg_rtime = n->msg_rtime;
+ o->msg_pad2 = n->msg_pad2;
+ o->msg_ctime = n->msg_ctime;
+ o->msg_pad3 = n->msg_pad3;
+ bcopy(n->msg_pad4, o->msg_pad4, sizeof o->msg_pad4);
+ ipc_n2o(&n->msg_perm, &o->msg_perm);
+}
+
+int
+sys_omsgctl(p, v, retval)
+ struct proc *p;
+ void *v;
+ register_t *retval;
+{
+ register struct sys_msgctl_args /* {
+ syscallarg(int) msqid;
+ 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);
+ struct ucred *cred = p->p_ucred;
+ int rval, eval;
+ struct omsqid_ds omsqbuf;
+ register struct msqid_ds *msqptr;
+
+#ifdef MSG_DEBUG_OK
+ printf("call to msgctl(%d, %d, %p)\n", msqid, cmd, user_msqptr);
+#endif
+
+ msqid = IPCID_TO_IX(msqid);
+
+ if (msqid < 0 || msqid >= msginfo.msgmni) {
+#ifdef MSG_DEBUG_OK
+ printf("msqid (%d) out of range (0<=msqid<%d)\n", msqid,
+ msginfo.msgmni);
+#endif
+ return(EINVAL);
+ }
+
+ msqptr = &msqids[msqid];
+
+ if (msqptr->msg_qbytes == 0) {
+#ifdef MSG_DEBUG_OK
+ printf("no such msqid\n");
+#endif
+ return(EINVAL);
+ }
+ if (msqptr->msg_perm.seq != IPCID_TO_SEQ(SCARG(uap, msqid))) {
+#ifdef MSG_DEBUG_OK
+ printf("wrong sequence number\n");
+#endif
+ 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);
+ /* Free the message headers */
+ msghdr = msqptr->msg_first;
+ while (msghdr != NULL) {
+ struct msg *msghdr_tmp;
+
+ /* Free the segments of each message */
+ msqptr->msg_cbytes -= msghdr->msg_ts;
+ msqptr->msg_qnum--;
+ msghdr_tmp = msghdr;
+ msghdr = msghdr->msg_next;
+ msg_freehdr(msghdr_tmp);
+ }
+
+ if (msqptr->msg_cbytes != 0)
+ panic("msg_cbytes is screwed up");
+ if (msqptr->msg_qnum != 0)
+ panic("msg_qnum is screwed up");
+
+ msqptr->msg_qbytes = 0; /* Mark it as free */
+
+ wakeup((caddr_t)msqptr);
+ }
+
+ break;
+
+ case IPC_SET:
+ if ((eval = ipcperm(cred, &msqptr->msg_perm, IPC_M)))
+ return(eval);
+ if ((eval = copyin(user_msqptr, &omsqbuf, sizeof(omsqbuf))) != 0)
+ return(eval);
+ if (omsqbuf.msg_qbytes > msqptr->msg_qbytes && cred->cr_uid != 0)
+ return(EPERM);
+ if (omsqbuf.msg_qbytes > msginfo.msgmnb) {
+#ifdef MSG_DEBUG_OK
+ printf("can't increase msg_qbytes beyond %d (truncating)\n",
+ msginfo.msgmnb);
+#endif
+ omsqbuf.msg_qbytes = msginfo.msgmnb; /* silently restrict qbytes to system limit */
+ }
+ if (omsqbuf.msg_qbytes == 0) {
+#ifdef MSG_DEBUG_OK
+ printf("can't reduce msg_qbytes to 0\n");
+#endif
+ return(EINVAL); /* non-standard errno! */
+ }
+ msqptr->msg_perm.uid = omsqbuf.msg_perm.uid; /* change the owner */
+ msqptr->msg_perm.gid = omsqbuf.msg_perm.gid; /* change the owner */
+ msqptr->msg_perm.mode = (msqptr->msg_perm.mode & ~0777) |
+ (omsqbuf.msg_perm.mode & 0777);
+ msqptr->msg_qbytes = omsqbuf.msg_qbytes;
+ msqptr->msg_ctime = time.tv_sec;
+ break;
+
+ case IPC_STAT:
+ if ((eval = ipcperm(cred, &msqptr->msg_perm, IPC_R))) {
+#ifdef MSG_DEBUG_OK
+ printf("requester doesn't have read access\n");
+#endif
+ return(eval);
+ }
+ msqid_n2o(msqptr, &omsqbuf);
+ eval = copyout((caddr_t)&omsqbuf, user_msqptr, sizeof omsqbuf);
+ break;
+
+ default:
+#ifdef MSG_DEBUG_OK
+ printf("invalid command %d\n", cmd);
+#endif
+ return(EINVAL);
+ }
+
+ if (eval == 0)
+ *retval = rval;
+ return(eval);
+}
+
int
sys_msgctl(p, v, retval)
struct proc *p;
diff --git a/sys/kern/sysv_sem.c b/sys/kern/sysv_sem.c
index c4d7c1c5b25..f6c312bff35 100644
--- a/sys/kern/sysv_sem.c
+++ b/sys/kern/sysv_sem.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: sysv_sem.c,v 1.2 1996/03/03 17:20:06 niklas Exp $ */
+/* $OpenBSD: sysv_sem.c,v 1.3 1998/06/11 18:32:16 deraadt Exp $ */
/* $NetBSD: sysv_sem.c,v 1.26 1996/02/09 19:00:25 christos Exp $ */
/*
@@ -277,6 +277,186 @@ semundo_clear(semid, semnum)
}
}
+void
+semid_n2o(n, o)
+ struct semid_ds *n;
+ struct osemid_ds *o;
+{
+ o->sem_base = n->sem_base;
+ o->sem_nsems = n->sem_nsems;
+ o->sem_otime = n->sem_otime;
+ o->sem_pad1 = n->sem_pad1;
+ o->sem_ctime = n->sem_ctime;
+ o->sem_pad2 = n->sem_pad2;
+ bcopy(n->sem_pad3, o->sem_pad3, sizeof o->sem_pad3);
+ ipc_n2o(&n->sem_perm, &o->sem_perm);
+}
+
+int
+sys___osemctl(p, v, retval)
+ struct proc *p;
+ register void *v;
+ register_t *retval;
+{
+ register struct sys___semctl_args /* {
+ syscallarg(int) semid;
+ syscallarg(int) semnum;
+ 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;
+ struct ucred *cred = p->p_ucred;
+ int i, rval, eval;
+ struct semid_ds *semaptr;
+ struct osemid_ds osbuf;
+
+#ifdef SEM_DEBUG
+ printf("call to semctl(%d, %d, %d, %p)\n", semid, semnum, cmd, arg);
+#endif
+
+ semlock(p);
+
+ semid = IPCID_TO_IX(semid);
+ if (semid < 0 || semid >= seminfo.semmsl)
+ return(EINVAL);
+
+ semaptr = &sema[semid];
+ if ((semaptr->sem_perm.mode & SEM_ALLOC) == 0 ||
+ semaptr->sem_perm.seq != IPCID_TO_SEQ(SCARG(uap, semid)))
+ return(EINVAL);
+
+ eval = 0;
+ rval = 0;
+
+ switch (cmd) {
+ case IPC_RMID:
+ if ((eval = ipcperm(cred, &semaptr->sem_perm, IPC_M)) != 0)
+ 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;
+ }
+ semaptr->sem_perm.mode = 0;
+ semundo_clear(semid, -1);
+ wakeup((caddr_t)semaptr);
+ break;
+
+ case IPC_SET:
+ if ((eval = ipcperm(cred, &semaptr->sem_perm, IPC_M)))
+ return(eval);
+ if ((eval = copyin(arg, &real_arg, sizeof(real_arg))) != 0)
+ return(eval);
+ if ((eval = copyin(real_arg.buf, (caddr_t)&osbuf,
+ sizeof(osbuf))) != 0)
+ return(eval);
+ semaptr->sem_perm.uid = osbuf.sem_perm.uid;
+ semaptr->sem_perm.gid = osbuf.sem_perm.gid;
+ semaptr->sem_perm.mode = (semaptr->sem_perm.mode & ~0777) |
+ (osbuf.sem_perm.mode & 0777);
+ semaptr->sem_ctime = time.tv_sec;
+ break;
+
+ case IPC_STAT:
+ if ((eval = ipcperm(cred, &semaptr->sem_perm, IPC_R)))
+ return(eval);
+ if ((eval = copyin(arg, &real_arg, sizeof(real_arg))) != 0)
+ return(eval);
+ semid_n2o(semaptr, &osbuf);
+ eval = copyout((caddr_t)&osbuf, real_arg.buf, sizeof osbuf);
+ break;
+
+ case GETNCNT:
+ if ((eval = ipcperm(cred, &semaptr->sem_perm, IPC_R)))
+ return(eval);
+ if (semnum < 0 || semnum >= semaptr->sem_nsems)
+ return(EINVAL);
+ rval = semaptr->sem_base[semnum].semncnt;
+ break;
+
+ case GETPID:
+ if ((eval = ipcperm(cred, &semaptr->sem_perm, IPC_R)))
+ return(eval);
+ if (semnum < 0 || semnum >= semaptr->sem_nsems)
+ return(EINVAL);
+ rval = semaptr->sem_base[semnum].sempid;
+ break;
+
+ case GETVAL:
+ if ((eval = ipcperm(cred, &semaptr->sem_perm, IPC_R)))
+ return(eval);
+ if (semnum < 0 || semnum >= semaptr->sem_nsems)
+ return(EINVAL);
+ rval = semaptr->sem_base[semnum].semval;
+ break;
+
+ case GETALL:
+ if ((eval = ipcperm(cred, &semaptr->sem_perm, IPC_R)))
+ return(eval);
+ if ((eval = copyin(arg, &real_arg, sizeof(real_arg))) != 0)
+ return(eval);
+ for (i = 0; i < semaptr->sem_nsems; i++) {
+ eval = copyout((caddr_t)&semaptr->sem_base[i].semval,
+ &real_arg.array[i], sizeof(real_arg.array[0]));
+ if (eval != 0)
+ break;
+ }
+ break;
+
+ case GETZCNT:
+ if ((eval = ipcperm(cred, &semaptr->sem_perm, IPC_R)))
+ return(eval);
+ if (semnum < 0 || semnum >= semaptr->sem_nsems)
+ return(EINVAL);
+ rval = semaptr->sem_base[semnum].semzcnt;
+ break;
+
+ case SETVAL:
+ if ((eval = ipcperm(cred, &semaptr->sem_perm, IPC_W)))
+ return(eval);
+ if (semnum < 0 || semnum >= semaptr->sem_nsems)
+ return(EINVAL);
+ if ((eval = copyin(arg, &real_arg, sizeof(real_arg))) != 0)
+ return(eval);
+ semaptr->sem_base[semnum].semval = real_arg.val;
+ semundo_clear(semid, semnum);
+ wakeup((caddr_t)semaptr);
+ break;
+
+ case SETALL:
+ if ((eval = ipcperm(cred, &semaptr->sem_perm, IPC_W)))
+ return(eval);
+ if ((eval = copyin(arg, &real_arg, sizeof(real_arg))) != 0)
+ return(eval);
+ for (i = 0; i < semaptr->sem_nsems; i++) {
+ eval = copyin(&real_arg.array[i],
+ (caddr_t)&semaptr->sem_base[i].semval,
+ sizeof(real_arg.array[0]));
+ if (eval != 0)
+ break;
+ }
+ semundo_clear(semid, -1);
+ wakeup((caddr_t)semaptr);
+ break;
+
+ default:
+ return(EINVAL);
+ }
+
+ if (eval == 0)
+ *retval = rval;
+ return(eval);
+}
+
int
sys___semctl(p, v, retval)
struct proc *p;
diff --git a/sys/kern/sysv_shm.c b/sys/kern/sysv_shm.c
index 9ac0728b015..f8641b04648 100644
--- a/sys/kern/sysv_shm.c
+++ b/sys/kern/sysv_shm.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: sysv_shm.c,v 1.7 1998/05/11 06:13:48 deraadt Exp $ */
+/* $OpenBSD: sysv_shm.c,v 1.8 1998/06/11 18:32:17 deraadt Exp $ */
/* $NetBSD: sysv_shm.c,v 1.37 1996/03/16 23:17:13 christos Exp $ */
/*
@@ -262,6 +262,83 @@ sys_shmat(p, v, retval)
return 0;
}
+void
+shmid_n2o(n, o)
+ struct shmid_ds *n;
+ struct oshmid_ds *o;
+{
+ o->shm_segsz = n->shm_segsz;
+ o->shm_lpid = n->shm_lpid;
+ o->shm_cpid = n->shm_cpid;
+ o->shm_nattch = n->shm_nattch;
+ o->shm_atime = n->shm_atime;
+ o->shm_dtime = n->shm_dtime;
+ o->shm_ctime = n->shm_ctime;
+ o->shm_internal = n->shm_internal;
+ ipc_n2o(&n->shm_perm, &o->shm_perm);
+}
+
+int
+sys_oshmctl(p, v, retval)
+ struct proc *p;
+ void *v;
+ register_t *retval;
+{
+ struct sys_shmctl_args /* {
+ syscallarg(int) shmid;
+ syscallarg(int) cmd;
+ syscallarg(struct shmid_ds *) buf;
+ } */ *uap = v;
+ int error;
+ struct ucred *cred = p->p_ucred;
+ struct oshmid_ds oinbuf;
+ struct shmid_ds *shmseg;
+
+ shmseg = shm_find_segment_by_shmid(SCARG(uap, shmid));
+ if (shmseg == NULL)
+ return EINVAL;
+ switch (SCARG(uap, cmd)) {
+ case IPC_STAT:
+ if ((error = ipcperm(cred, &shmseg->shm_perm, IPC_R)) != 0)
+ return error;
+ shmid_n2o(shmseg, &oinbuf);
+ error = copyout((caddr_t)shmseg, SCARG(uap, buf),
+ sizeof(oinbuf));
+ 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)&oinbuf,
+ sizeof(oinbuf));
+ if (error)
+ return error;
+ shmseg->shm_perm.uid = oinbuf.shm_perm.uid;
+ shmseg->shm_perm.gid = oinbuf.shm_perm.gid;
+ shmseg->shm_perm.mode =
+ (shmseg->shm_perm.mode & ~ACCESSPERMS) |
+ (oinbuf.shm_perm.mode & ACCESSPERMS);
+ shmseg->shm_ctime = time.tv_sec;
+ break;
+ case IPC_RMID:
+ if ((error = ipcperm(cred, &shmseg->shm_perm, IPC_M)) != 0)
+ return error;
+ shmseg->shm_perm.key = IPC_PRIVATE;
+ shmseg->shm_perm.mode |= SHMSEG_REMOVED;
+ if (shmseg->shm_nattch <= 0) {
+ shm_deallocate_segment(shmseg);
+ shm_last_free = IPCID_TO_IX(SCARG(uap, shmid));
+ }
+ break;
+ case SHM_LOCK:
+ case SHM_UNLOCK:
+ default:
+ return EINVAL;
+ }
+ return 0;
+}
+
int
sys_shmctl(p, v, retval)
struct proc *p;