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
This commit is contained in:
Max Khon 2003-11-05 01:53:10 +00:00
parent def19aab78
commit 2332251c6a
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=122088
3 changed files with 29 additions and 26 deletions

View file

@ -716,7 +716,7 @@ linux_shmctl(struct thread *td, struct linux_shmctl_args *args)
/* Perform shmctl wanting removed segments lookup */ /* Perform shmctl wanting removed segments lookup */
error = kern_shmctl(td, args->shmid, IPC_INFO, error = kern_shmctl(td, args->shmid, IPC_INFO,
(void *)&bsd_shminfo, &bufsz, 1); (void *)&bsd_shminfo, &bufsz);
if (error) if (error)
return error; return error;
@ -731,7 +731,7 @@ linux_shmctl(struct thread *td, struct linux_shmctl_args *args)
/* Perform shmctl wanting removed segments lookup */ /* Perform shmctl wanting removed segments lookup */
error = kern_shmctl(td, args->shmid, SHM_INFO, error = kern_shmctl(td, args->shmid, SHM_INFO,
(void *)&bsd_shm_info, &bufsz, 1); (void *)&bsd_shm_info, &bufsz);
if (error) if (error)
return error; return error;
@ -744,7 +744,7 @@ linux_shmctl(struct thread *td, struct linux_shmctl_args *args)
case LINUX_IPC_STAT: case LINUX_IPC_STAT:
/* Perform shmctl wanting removed segments lookup */ /* Perform shmctl wanting removed segments lookup */
error = kern_shmctl(td, args->shmid, IPC_STAT, error = kern_shmctl(td, args->shmid, IPC_STAT,
(void *)&bsd_shmid, &bufsz, 1); (void *)&bsd_shmid, &bufsz);
if (error) if (error)
return error; return error;
@ -756,7 +756,7 @@ linux_shmctl(struct thread *td, struct linux_shmctl_args *args)
case LINUX_SHM_STAT: case LINUX_SHM_STAT:
/* Perform shmctl wanting removed segments lookup */ /* Perform shmctl wanting removed segments lookup */
error = kern_shmctl(td, args->shmid, IPC_STAT, error = kern_shmctl(td, args->shmid, IPC_STAT,
(void *)&bsd_shmid, &bufsz, 1); (void *)&bsd_shmid, &bufsz);
if (error) if (error)
return error; return error;
@ -775,7 +775,7 @@ linux_shmctl(struct thread *td, struct linux_shmctl_args *args)
/* Perform shmctl wanting removed segments lookup */ /* Perform shmctl wanting removed segments lookup */
return kern_shmctl(td, args->shmid, IPC_SET, return kern_shmctl(td, args->shmid, IPC_SET,
(void *)&bsd_shmid, &bufsz, 1); (void *)&bsd_shmid, &bufsz);
case LINUX_IPC_RMID: { case LINUX_IPC_RMID: {
void *buf; 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); linux_to_bsd_shmid_ds(&linux_shmid, &bsd_shmid);
buf = (void *)&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: case LINUX_SHM_LOCK:

View file

@ -97,8 +97,8 @@ struct shmmap_state {
static void shm_deallocate_segment(struct shmid_ds *); static void shm_deallocate_segment(struct shmid_ds *);
static int shm_find_segment_by_key(key_t); 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_shmid(int);
static struct shmid_ds *shm_find_segment_by_shmidx(int, int); static struct shmid_ds *shm_find_segment_by_shmidx(int);
static int shm_delete_mapping(struct vmspace *vm, struct shmmap_state *); static int shm_delete_mapping(struct vmspace *vm, struct shmmap_state *);
static void shmrealloc(void); static void shmrealloc(void);
static void shminit(void); static void shminit(void);
@ -139,6 +139,7 @@ struct shminfo shminfo = {
}; };
static int shm_use_phys; static int shm_use_phys;
static int shm_allow_removed;
SYSCTL_DECL(_kern_ipc); SYSCTL_DECL(_kern_ipc);
SYSCTL_INT(_kern_ipc, OID_AUTO, shmmax, CTLFLAG_RW, &shminfo.shmmax, 0, ""); 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, shmall, CTLFLAG_RW, &shminfo.shmall, 0, "");
SYSCTL_INT(_kern_ipc, OID_AUTO, shm_use_phys, CTLFLAG_RW, SYSCTL_INT(_kern_ipc, OID_AUTO, shm_use_phys, CTLFLAG_RW,
&shm_use_phys, 0, ""); &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, SYSCTL_PROC(_kern_ipc, OID_AUTO, shmsegs, CTLFLAG_RD,
NULL, 0, sysctl_shmsegs, "", ""); NULL, 0, sysctl_shmsegs, "", "");
@ -165,7 +168,7 @@ shm_find_segment_by_key(key)
} }
static struct shmid_ds * static struct shmid_ds *
shm_find_segment_by_shmid(int shmid, int wantrem) shm_find_segment_by_shmid(int shmid)
{ {
int segnum; int segnum;
struct shmid_ds *shmseg; struct shmid_ds *shmseg;
@ -174,23 +177,25 @@ shm_find_segment_by_shmid(int shmid, int wantrem)
if (segnum < 0 || segnum >= shmalloced) if (segnum < 0 || segnum >= shmalloced)
return (NULL); return (NULL);
shmseg = &shmsegs[segnum]; shmseg = &shmsegs[segnum];
if (!((shmseg->shm_perm.mode & SHMSEG_ALLOCATED) || if ((shmseg->shm_perm.mode & SHMSEG_ALLOCATED) == 0 ||
(wantrem && !(shmseg->shm_perm.mode & SHMSEG_REMOVED))) || (!shm_allow_removed &&
(shmseg->shm_perm.mode & SHMSEG_REMOVED) != 0) ||
shmseg->shm_perm.seq != IPCID_TO_SEQ(shmid)) shmseg->shm_perm.seq != IPCID_TO_SEQ(shmid))
return (NULL); return (NULL);
return (shmseg); return (shmseg);
} }
static struct shmid_ds * static struct shmid_ds *
shm_find_segment_by_shmidx(int segnum, int wantrem) shm_find_segment_by_shmidx(int segnum)
{ {
struct shmid_ds *shmseg; struct shmid_ds *shmseg;
if (segnum < 0 || segnum >= shmalloced) if (segnum < 0 || segnum >= shmalloced)
return (NULL); return (NULL);
shmseg = &shmsegs[segnum]; shmseg = &shmsegs[segnum];
if (!((shmseg->shm_perm.mode & SHMSEG_ALLOCATED) || if ((shmseg->shm_perm.mode & SHMSEG_ALLOCATED) == 0 ||
(wantrem && !(shmseg->shm_perm.mode & SHMSEG_REMOVED)))) (!shm_allow_removed &&
(shmseg->shm_perm.mode & SHMSEG_REMOVED) != 0))
return (NULL); return (NULL);
return (shmseg); return (shmseg);
} }
@ -294,12 +299,11 @@ struct shmat_args {
* MPSAFE * MPSAFE
*/ */
int int
kern_shmat(td, shmid, shmaddr, shmflg, wantrem) kern_shmat(td, shmid, shmaddr, shmflg)
struct thread *td; struct thread *td;
int shmid; int shmid;
const void *shmaddr; const void *shmaddr;
int shmflg; int shmflg;
int wantrem;
{ {
struct proc *p = td->td_proc; struct proc *p = td->td_proc;
int i, flags; int i, flags;
@ -323,7 +327,7 @@ kern_shmat(td, shmid, shmaddr, shmflg, wantrem)
shmmap_s[i].shmid = -1; shmmap_s[i].shmid = -1;
p->p_vmspace->vm_shm = shmmap_s; 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) { if (shmseg == NULL) {
error = EINVAL; error = EINVAL;
goto done2; goto done2;
@ -396,7 +400,7 @@ shmat(td, uap)
struct thread *td; struct thread *td;
struct shmat_args *uap; 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 { struct oshmid_ds {
@ -433,7 +437,7 @@ oshmctl(td, uap)
if (!jail_sysvipc_allowed && jailed(td->td_ucred)) if (!jail_sysvipc_allowed && jailed(td->td_ucred))
return (ENOSYS); return (ENOSYS);
mtx_lock(&Giant); mtx_lock(&Giant);
shmseg = shm_find_segment_by_shmid(uap->shmid, 0); shmseg = shm_find_segment_by_shmid(uap->shmid);
if (shmseg == NULL) { if (shmseg == NULL) {
error = EINVAL; error = EINVAL;
goto done2; goto done2;
@ -481,13 +485,12 @@ struct shmctl_args {
* MPSAFE * MPSAFE
*/ */
int int
kern_shmctl(td, shmid, cmd, buf, bufsz, wantrem) kern_shmctl(td, shmid, cmd, buf, bufsz)
struct thread *td; struct thread *td;
int shmid; int shmid;
int cmd; int cmd;
void *buf; void *buf;
size_t *bufsz; size_t *bufsz;
int wantrem;
{ {
int error = 0; int error = 0;
struct shmid_ds *shmseg; struct shmid_ds *shmseg;
@ -519,9 +522,9 @@ kern_shmctl(td, shmid, cmd, buf, bufsz, wantrem)
} }
} }
if (cmd == SHM_STAT) if (cmd == SHM_STAT)
shmseg = shm_find_segment_by_shmidx(shmid, wantrem); shmseg = shm_find_segment_by_shmidx(shmid);
else else
shmseg = shm_find_segment_by_shmid(shmid, wantrem); shmseg = shm_find_segment_by_shmid(shmid);
if (shmseg == NULL) { if (shmseg == NULL) {
error = EINVAL; error = EINVAL;
goto done2; goto done2;
@ -592,7 +595,7 @@ shmctl(td, uap)
goto done; 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) if (error)
goto done; goto done;

View file

@ -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, int kern_sendit(struct thread *td, int s, struct msghdr *mp, int flags,
struct mbuf *control); struct mbuf *control);
int kern_shmat(struct thread *td, int shmid, const void *shmaddr, 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, 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, int kern_sigaction(struct thread *td, int sig, struct sigaction *act,
struct sigaction *oact, int flags); struct sigaction *oact, int flags);
int kern_sigaltstack(struct thread *td, stack_t *ss, stack_t *oss); int kern_sigaltstack(struct thread *td, stack_t *ss, stack_t *oss);