diff options
author | Theo de Raadt <deraadt@cvs.openbsd.org> | 1998-06-11 18:32:25 +0000 |
---|---|---|
committer | Theo de Raadt <deraadt@cvs.openbsd.org> | 1998-06-11 18:32:25 +0000 |
commit | 972db8ac87c9fdf7160f080d738040aa720f719c (patch) | |
tree | 7b0fcf15c0cfb9b0af9865d566b5eafd920bdf1f /sys/kern | |
parent | 13a4ff03320e09fd87539e8e2116c1580d09806d (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.c | 31 | ||||
-rw-r--r-- | sys/kern/sysv_msg.c | 158 | ||||
-rw-r--r-- | sys/kern/sysv_sem.c | 182 | ||||
-rw-r--r-- | sys/kern/sysv_shm.c | 79 |
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; |