summaryrefslogtreecommitdiff
path: root/sys/compat
diff options
context:
space:
mode:
authorTodd C. Miller <millert@cvs.openbsd.org>2002-12-17 23:11:33 +0000
committerTodd C. Miller <millert@cvs.openbsd.org>2002-12-17 23:11:33 +0000
commit25ea8c8a69576ca14e0d418bcc7d03b82db24db2 (patch)
treed9af0722d8761b2c04ddf3def6874033dfd44219 /sys/compat
parenta6dcb6be4019c0f02edd62f13fbb5737a42598aa (diff)
Make SysV-style shared memory and semaphore limits sysctl'able.
Instead of allocating a static amount of memory for the data structures via valloc() in allocsys(), allocate things dynamically using pool(9) when possible and malloc(9) when not. The various members of struct seminfo and struct shminfo are in kern.seminfo and kern.shminfo respectively (not all members of kern.seminfo are changable). The data structures used still leave something to be desired but things are not made worse in that respect by this commit.
Diffstat (limited to 'sys/compat')
-rw-r--r--sys/compat/common/kern_ipc_23.c134
1 files changed, 64 insertions, 70 deletions
diff --git a/sys/compat/common/kern_ipc_23.c b/sys/compat/common/kern_ipc_23.c
index 3b004a817d6..9b092daff93 100644
--- a/sys/compat/common/kern_ipc_23.c
+++ b/sys/compat/common/kern_ipc_23.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: kern_ipc_23.c,v 1.2 2002/03/14 01:26:49 millert Exp $ */
+/* $OpenBSD: kern_ipc_23.c,v 1.3 2002/12/17 23:11:31 millert Exp $ */
/*
* Implementation of SVID semaphores
@@ -64,6 +64,7 @@
#include <sys/sem.h>
#include <sys/shm.h>
#include <sys/malloc.h>
+#include <sys/pool.h>
#include <sys/mount.h>
#include <sys/syscallargs.h>
@@ -87,7 +88,7 @@ compat_23_sys_msgctl(p, v, retval)
int cmd = SCARG(uap, cmd);
struct omsqid_ds *user_msqptr = SCARG(uap, buf);
struct ucred *cred = p->p_ucred;
- int rval, eval;
+ int rval, error;
struct omsqid_ds omsqbuf;
register struct msqid_ds *msqptr;
@@ -120,16 +121,15 @@ compat_23_sys_msgctl(p, v, retval)
return(EINVAL);
}
- eval = 0;
- rval = 0;
+ error = 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) {
@@ -158,10 +158,10 @@ compat_23_sys_msgctl(p, v, retval)
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 ((error = ipcperm(cred, &msqptr->msg_perm, IPC_M)))
+ return(error);
+ if ((error = copyin(user_msqptr, &omsqbuf, sizeof(omsqbuf))) != 0)
+ return(error);
if (omsqbuf.msg_qbytes > msqptr->msg_qbytes && cred->cr_uid != 0)
return(EPERM);
if (omsqbuf.msg_qbytes > msginfo.msgmnb) {
@@ -186,14 +186,14 @@ compat_23_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))) {
#ifdef MSG_DEBUG_OK
printf("requester doesn't have read access\n");
#endif
- return(eval);
+ return(error);
}
msqid_n2o(msqptr, &omsqbuf);
- eval = copyout((caddr_t)&omsqbuf, user_msqptr, sizeof omsqbuf);
+ error = copyout((caddr_t)&omsqbuf, user_msqptr, sizeof omsqbuf);
break;
default:
@@ -203,9 +203,9 @@ compat_23_sys_msgctl(p, v, retval)
return(EINVAL);
}
- if (eval == 0)
+ if (error == 0)
*retval = rval;
- return(eval);
+ return(error);
}
#endif /* SYSVMSG */
@@ -281,6 +281,7 @@ compat_23_sys_shmctl(p, v, retval)
#ifdef SYSVSEM
+extern struct pool sema_pool;
void semundo_clear(int, int);
int
@@ -301,7 +302,7 @@ compat_23_sys___semctl(p, v, retval)
union semun *arg = SCARG(uap, arg);
union semun real_arg;
struct ucred *cred = p->p_ucred;
- int i, rval, eval;
+ int i, rval, error;
struct semid_ds *semaptr;
struct osemid_ds osbuf;
extern int semtot;
@@ -314,41 +315,34 @@ compat_23_sys___semctl(p, v, retval)
if (semid < 0 || semid >= seminfo.semmsl)
return(EINVAL);
- semaptr = &sema[semid];
- if ((semaptr->sem_perm.mode & SEM_ALLOC) == 0 ||
+ if ((semaptr = sema[semid]) == NULL ||
semaptr->sem_perm.seq != IPCID_TO_SEQ(SCARG(uap, semid)))
return(EINVAL);
- eval = 0;
- rval = 0;
+ error = rval = 0;
switch (cmd) {
case IPC_RMID:
- if ((eval = ipcperm(cred, &semaptr->sem_perm, IPC_M)) != 0)
- return(eval);
+ if ((error = ipcperm(cred, &semaptr->sem_perm, IPC_M)) != 0)
+ return(error);
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;
+ free(semaptr->sem_base, M_SHM);
+ pool_put(&sema_pool, semaptr);
+ sema[semid] = NULL;
semundo_clear(semid, -1);
- wakeup((caddr_t)semaptr);
+ wakeup((caddr_t)&sema[semid]);
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,
+ 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, (caddr_t)&osbuf,
sizeof(osbuf))) != 0)
- return(eval);
+ return(error);
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) |
@@ -357,93 +351,93 @@ compat_23_sys___semctl(p, v, retval)
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);
+ if ((error = ipcperm(cred, &semaptr->sem_perm, IPC_R)))
+ return(error);
+ if ((error = copyin(arg, &real_arg, sizeof(real_arg))) != 0)
+ return(error);
semid_n2o(semaptr, &osbuf);
- eval = copyout((caddr_t)&osbuf, real_arg.buf, sizeof osbuf);
+ error = copyout((caddr_t)&osbuf, real_arg.buf, sizeof(osbuf));
break;
case GETNCNT:
- if ((eval = ipcperm(cred, &semaptr->sem_perm, IPC_R)))
- return(eval);
+ if ((error = ipcperm(cred, &semaptr->sem_perm, IPC_R)))
+ return(error);
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 ((error = ipcperm(cred, &semaptr->sem_perm, IPC_R)))
+ return(error);
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 ((error = ipcperm(cred, &semaptr->sem_perm, IPC_R)))
+ return(error);
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);
+ 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++) {
- 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]));
- if (eval != 0)
+ if (error != 0)
break;
}
break;
case GETZCNT:
- if ((eval = ipcperm(cred, &semaptr->sem_perm, IPC_R)))
- return(eval);
+ if ((error = ipcperm(cred, &semaptr->sem_perm, IPC_R)))
+ return(error);
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 ((error = ipcperm(cred, &semaptr->sem_perm, IPC_W)))
+ return(error);
if (semnum < 0 || semnum >= semaptr->sem_nsems)
return(EINVAL);
- if ((eval = copyin(arg, &real_arg, sizeof(real_arg))) != 0)
- return(eval);
+ 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((caddr_t)semaptr);
+ wakeup((caddr_t)&sema[semid]);
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);
+ 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++) {
- eval = copyin(&real_arg.array[i],
+ error = copyin(&real_arg.array[i],
(caddr_t)&semaptr->sem_base[i].semval,
sizeof(real_arg.array[0]));
- if (eval != 0)
+ if (error != 0)
break;
}
semundo_clear(semid, -1);
- wakeup((caddr_t)semaptr);
+ wakeup((caddr_t)&sema[semid]);
break;
default:
return(EINVAL);
}
- if (eval == 0)
+ if (error == 0)
*retval = rval;
- return(eval);
+ return(error);
}
#endif /* SYSVSEM */