From 160f13825c77e0a8eb8370ae72eab3622174cb60 Mon Sep 17 00:00:00 2001 From: fjoe Date: Wed, 5 Nov 2003 01:53:10 +0000 Subject: [PATCH] Back out the following revisions: 1.36 +73 -60 src/sys/compat/linux/linux_ipc.c 1.83 +102 -48 src/sys/kern/sysv_shm.c 1.8 +4 -0 src/sys/sys/syscallsubr.h That change was intended to support vmware3, but wantrem parameter is useless because vmware3 uses SYSV shared memory to talk with X server and X server is native application. The patch worked because check for wantrem was not valid (wantrem and SHMSEG_REMOVED was never checked for SHMSEG_ALLOCATED segments). Add kern.ipc.shm_allow_removed (integer, rw) sysctl (default 0) which when set to 1 allows to return removed segments in shm_find_segment_by_shmid() and shm_find_segment_by_shmidx(). MFC after: 1 week --- sys/compat/linux/linux_ipc.c | 12 +++++------ sys/kern/sysv_shm.c | 39 +++++++++++++++++++----------------- sys/sys/syscallsubr.h | 4 ++-- 3 files changed, 29 insertions(+), 26 deletions(-) diff --git a/sys/compat/linux/linux_ipc.c b/sys/compat/linux/linux_ipc.c index 27992294d492..71b6d60702d1 100644 --- a/sys/compat/linux/linux_ipc.c +++ b/sys/compat/linux/linux_ipc.c @@ -716,7 +716,7 @@ linux_shmctl(struct thread *td, struct linux_shmctl_args *args) /* Perform shmctl wanting removed segments lookup */ error = kern_shmctl(td, args->shmid, IPC_INFO, - (void *)&bsd_shminfo, &bufsz, 1); + (void *)&bsd_shminfo, &bufsz); if (error) return error; @@ -731,7 +731,7 @@ linux_shmctl(struct thread *td, struct linux_shmctl_args *args) /* Perform shmctl wanting removed segments lookup */ error = kern_shmctl(td, args->shmid, SHM_INFO, - (void *)&bsd_shm_info, &bufsz, 1); + (void *)&bsd_shm_info, &bufsz); if (error) return error; @@ -744,7 +744,7 @@ linux_shmctl(struct thread *td, struct linux_shmctl_args *args) case LINUX_IPC_STAT: /* Perform shmctl wanting removed segments lookup */ error = kern_shmctl(td, args->shmid, IPC_STAT, - (void *)&bsd_shmid, &bufsz, 1); + (void *)&bsd_shmid, &bufsz); if (error) return error; @@ -756,7 +756,7 @@ linux_shmctl(struct thread *td, struct linux_shmctl_args *args) case LINUX_SHM_STAT: /* Perform shmctl wanting removed segments lookup */ error = kern_shmctl(td, args->shmid, IPC_STAT, - (void *)&bsd_shmid, &bufsz, 1); + (void *)&bsd_shmid, &bufsz); if (error) return error; @@ -775,7 +775,7 @@ linux_shmctl(struct thread *td, struct linux_shmctl_args *args) /* Perform shmctl wanting removed segments lookup */ return kern_shmctl(td, args->shmid, IPC_SET, - (void *)&bsd_shmid, &bufsz, 1); + (void *)&bsd_shmid, &bufsz); case LINUX_IPC_RMID: { void *buf; @@ -790,7 +790,7 @@ linux_shmctl(struct thread *td, struct linux_shmctl_args *args) linux_to_bsd_shmid_ds(&linux_shmid, &bsd_shmid); buf = (void *)&bsd_shmid; } - return kern_shmctl(td, args->shmid, IPC_RMID, buf, &bufsz, 1); + return kern_shmctl(td, args->shmid, IPC_RMID, buf, &bufsz); } case LINUX_SHM_LOCK: diff --git a/sys/kern/sysv_shm.c b/sys/kern/sysv_shm.c index e3f6b2c07668..5c056ebfc5d6 100644 --- a/sys/kern/sysv_shm.c +++ b/sys/kern/sysv_shm.c @@ -97,8 +97,8 @@ struct shmmap_state { static void shm_deallocate_segment(struct shmid_ds *); static int shm_find_segment_by_key(key_t); -static struct shmid_ds *shm_find_segment_by_shmid(int, int); -static struct shmid_ds *shm_find_segment_by_shmidx(int, int); +static struct shmid_ds *shm_find_segment_by_shmid(int); +static struct shmid_ds *shm_find_segment_by_shmidx(int); static int shm_delete_mapping(struct vmspace *vm, struct shmmap_state *); static void shmrealloc(void); static void shminit(void); @@ -139,6 +139,7 @@ struct shminfo shminfo = { }; static int shm_use_phys; +static int shm_allow_removed; SYSCTL_DECL(_kern_ipc); SYSCTL_INT(_kern_ipc, OID_AUTO, shmmax, CTLFLAG_RW, &shminfo.shmmax, 0, ""); @@ -148,6 +149,8 @@ SYSCTL_INT(_kern_ipc, OID_AUTO, shmseg, CTLFLAG_RDTUN, &shminfo.shmseg, 0, ""); SYSCTL_INT(_kern_ipc, OID_AUTO, shmall, CTLFLAG_RW, &shminfo.shmall, 0, ""); SYSCTL_INT(_kern_ipc, OID_AUTO, shm_use_phys, CTLFLAG_RW, &shm_use_phys, 0, ""); +SYSCTL_INT(_kern_ipc, OID_AUTO, shm_allow_removed, CTLFLAG_RW, + &shm_allow_removed, 0, ""); SYSCTL_PROC(_kern_ipc, OID_AUTO, shmsegs, CTLFLAG_RD, NULL, 0, sysctl_shmsegs, "", ""); @@ -165,7 +168,7 @@ shm_find_segment_by_key(key) } static struct shmid_ds * -shm_find_segment_by_shmid(int shmid, int wantrem) +shm_find_segment_by_shmid(int shmid) { int segnum; struct shmid_ds *shmseg; @@ -174,23 +177,25 @@ shm_find_segment_by_shmid(int shmid, int wantrem) if (segnum < 0 || segnum >= shmalloced) return (NULL); shmseg = &shmsegs[segnum]; - if (!((shmseg->shm_perm.mode & SHMSEG_ALLOCATED) || - (wantrem && !(shmseg->shm_perm.mode & SHMSEG_REMOVED))) || + if ((shmseg->shm_perm.mode & SHMSEG_ALLOCATED) == 0 || + (!shm_allow_removed && + (shmseg->shm_perm.mode & SHMSEG_REMOVED) != 0) || shmseg->shm_perm.seq != IPCID_TO_SEQ(shmid)) return (NULL); return (shmseg); } static struct shmid_ds * -shm_find_segment_by_shmidx(int segnum, int wantrem) +shm_find_segment_by_shmidx(int segnum) { struct shmid_ds *shmseg; if (segnum < 0 || segnum >= shmalloced) return (NULL); shmseg = &shmsegs[segnum]; - if (!((shmseg->shm_perm.mode & SHMSEG_ALLOCATED) || - (wantrem && !(shmseg->shm_perm.mode & SHMSEG_REMOVED)))) + if ((shmseg->shm_perm.mode & SHMSEG_ALLOCATED) == 0 || + (!shm_allow_removed && + (shmseg->shm_perm.mode & SHMSEG_REMOVED) != 0)) return (NULL); return (shmseg); } @@ -294,12 +299,11 @@ struct shmat_args { * MPSAFE */ int -kern_shmat(td, shmid, shmaddr, shmflg, wantrem) +kern_shmat(td, shmid, shmaddr, shmflg) struct thread *td; int shmid; const void *shmaddr; int shmflg; - int wantrem; { struct proc *p = td->td_proc; int i, flags; @@ -323,7 +327,7 @@ kern_shmat(td, shmid, shmaddr, shmflg, wantrem) shmmap_s[i].shmid = -1; p->p_vmspace->vm_shm = shmmap_s; } - shmseg = shm_find_segment_by_shmid(shmid, wantrem); + shmseg = shm_find_segment_by_shmid(shmid); if (shmseg == NULL) { error = EINVAL; goto done2; @@ -396,7 +400,7 @@ shmat(td, uap) struct thread *td; struct shmat_args *uap; { - return kern_shmat(td, uap->shmid, uap->shmaddr, uap->shmflg, 0); + return kern_shmat(td, uap->shmid, uap->shmaddr, uap->shmflg); } struct oshmid_ds { @@ -433,7 +437,7 @@ oshmctl(td, uap) if (!jail_sysvipc_allowed && jailed(td->td_ucred)) return (ENOSYS); mtx_lock(&Giant); - shmseg = shm_find_segment_by_shmid(uap->shmid, 0); + shmseg = shm_find_segment_by_shmid(uap->shmid); if (shmseg == NULL) { error = EINVAL; goto done2; @@ -481,13 +485,12 @@ struct shmctl_args { * MPSAFE */ int -kern_shmctl(td, shmid, cmd, buf, bufsz, wantrem) +kern_shmctl(td, shmid, cmd, buf, bufsz) struct thread *td; int shmid; int cmd; void *buf; size_t *bufsz; - int wantrem; { int error = 0; struct shmid_ds *shmseg; @@ -519,9 +522,9 @@ kern_shmctl(td, shmid, cmd, buf, bufsz, wantrem) } } if (cmd == SHM_STAT) - shmseg = shm_find_segment_by_shmidx(shmid, wantrem); + shmseg = shm_find_segment_by_shmidx(shmid); else - shmseg = shm_find_segment_by_shmid(shmid, wantrem); + shmseg = shm_find_segment_by_shmid(shmid); if (shmseg == NULL) { error = EINVAL; goto done2; @@ -592,7 +595,7 @@ shmctl(td, uap) goto done; } - error = kern_shmctl(td, uap->shmid, uap->cmd, (void *)&buf, &bufsz, 0); + error = kern_shmctl(td, uap->shmid, uap->cmd, (void *)&buf, &bufsz); if (error) goto done; diff --git a/sys/sys/syscallsubr.h b/sys/sys/syscallsubr.h index a58a07fecf22..8c5202738494 100644 --- a/sys/sys/syscallsubr.h +++ b/sys/sys/syscallsubr.h @@ -75,9 +75,9 @@ int kern_select(struct thread *td, int nd, fd_set *fd_in, fd_set *fd_ou, int kern_sendit(struct thread *td, int s, struct msghdr *mp, int flags, struct mbuf *control); int kern_shmat(struct thread *td, int shmid, const void *shmaddr, - int shmflg, int wantrem); + int shmflg); int kern_shmctl(struct thread *td, int shmid, int cmd, void *buf, - size_t *bufsz, int wantrem); + size_t *bufsz); int kern_sigaction(struct thread *td, int sig, struct sigaction *act, struct sigaction *oact, int flags); int kern_sigaltstack(struct thread *td, stack_t *ss, stack_t *oss);