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 */
|
/* 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:
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
@ -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);
|
||||||
|
Loading…
Reference in New Issue
Block a user