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:
parent
def19aab78
commit
2332251c6a
@ -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:
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user