Lock access to proc members.
Glanced over by: marcel
This commit is contained in:
parent
48ecc0129d
commit
216af8221e
@ -124,14 +124,17 @@ linux_open(struct proc *p, struct linux_open_args *args)
|
|||||||
bsd_open_args.mode = args->mode;
|
bsd_open_args.mode = args->mode;
|
||||||
|
|
||||||
error = open(p, &bsd_open_args);
|
error = open(p, &bsd_open_args);
|
||||||
|
PROC_LOCK(p);
|
||||||
if (!error && !(bsd_open_args.flags & O_NOCTTY) &&
|
if (!error && !(bsd_open_args.flags & O_NOCTTY) &&
|
||||||
SESS_LEADER(p) && !(p->p_flag & P_CONTROLT)) {
|
SESS_LEADER(p) && !(p->p_flag & P_CONTROLT)) {
|
||||||
struct filedesc *fdp = p->p_fd;
|
struct filedesc *fdp = p->p_fd;
|
||||||
struct file *fp = fdp->fd_ofiles[p->p_retval[0]];
|
struct file *fp = fdp->fd_ofiles[p->p_retval[0]];
|
||||||
|
|
||||||
|
PROC_UNLOCK(p);
|
||||||
if (fp->f_type == DTYPE_VNODE)
|
if (fp->f_type == DTYPE_VNODE)
|
||||||
fo_ioctl(fp, TIOCSCTTY, (caddr_t) 0, p);
|
fo_ioctl(fp, TIOCSCTTY, (caddr_t) 0, p);
|
||||||
}
|
} else
|
||||||
|
PROC_UNLOCK(p);
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
printf("Linux-emul(%d): open returns error %d\n",
|
printf("Linux-emul(%d): open returns error %d\n",
|
||||||
p->p_pid, error);
|
p->p_pid, error);
|
||||||
@ -402,6 +405,7 @@ linux_getdents(struct proc *p, struct linux_getdents_args *args)
|
|||||||
int buflen, error, eofflag, nbytes, justone;
|
int buflen, error, eofflag, nbytes, justone;
|
||||||
u_long *cookies = NULL, *cookiep;
|
u_long *cookies = NULL, *cookiep;
|
||||||
int ncookies;
|
int ncookies;
|
||||||
|
struct ucred *uc;
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
printf("Linux-emul(%d): getdents(%d, *, %d)\n",
|
printf("Linux-emul(%d): getdents(%d, *, %d)\n",
|
||||||
@ -419,7 +423,13 @@ linux_getdents(struct proc *p, struct linux_getdents_args *args)
|
|||||||
if (vp->v_type != VDIR)
|
if (vp->v_type != VDIR)
|
||||||
return (EINVAL);
|
return (EINVAL);
|
||||||
|
|
||||||
if ((error = VOP_GETATTR(vp, &va, p->p_ucred, p))) {
|
PROC_LOCK(p);
|
||||||
|
uc = p->p_ucred;
|
||||||
|
crhold(uc);
|
||||||
|
PROC_UNLOCK(p);
|
||||||
|
error = VOP_GETATTR(vp, &va, uc, p);
|
||||||
|
crfree(uc);
|
||||||
|
if (error) {
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -185,6 +185,7 @@ linux_uselib(struct proc *p, struct linux_uselib_args *args)
|
|||||||
struct vnode *vp;
|
struct vnode *vp;
|
||||||
struct exec *a_out;
|
struct exec *a_out;
|
||||||
struct vattr attr;
|
struct vattr attr;
|
||||||
|
struct ucred *uc;
|
||||||
vm_offset_t vmaddr;
|
vm_offset_t vmaddr;
|
||||||
unsigned long file_offset;
|
unsigned long file_offset;
|
||||||
vm_offset_t buffer;
|
vm_offset_t buffer;
|
||||||
@ -236,14 +237,21 @@ linux_uselib(struct proc *p, struct linux_uselib_args *args)
|
|||||||
/*
|
/*
|
||||||
* Executable?
|
* Executable?
|
||||||
*/
|
*/
|
||||||
error = VOP_GETATTR(vp, &attr, p->p_ucred, p);
|
PROC_LOCK(p);
|
||||||
if (error)
|
uc = p->p_ucred;
|
||||||
|
crhold(uc);
|
||||||
|
PROC_UNLOCK(p);
|
||||||
|
error = VOP_GETATTR(vp, &attr, uc, p);
|
||||||
|
if (error) {
|
||||||
|
crfree(uc);
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
if ((vp->v_mount->mnt_flag & MNT_NOEXEC) ||
|
if ((vp->v_mount->mnt_flag & MNT_NOEXEC) ||
|
||||||
((attr.va_mode & 0111) == 0) ||
|
((attr.va_mode & 0111) == 0) ||
|
||||||
(attr.va_type != VREG)) {
|
(attr.va_type != VREG)) {
|
||||||
error = ENOEXEC;
|
error = ENOEXEC;
|
||||||
|
crfree(uc);
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -252,17 +260,21 @@ linux_uselib(struct proc *p, struct linux_uselib_args *args)
|
|||||||
*/
|
*/
|
||||||
if (attr.va_size == 0) {
|
if (attr.va_size == 0) {
|
||||||
error = ENOEXEC;
|
error = ENOEXEC;
|
||||||
|
crfree(uc);
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Can we access it?
|
* Can we access it?
|
||||||
*/
|
*/
|
||||||
error = VOP_ACCESS(vp, VEXEC, p->p_ucred, p);
|
error = VOP_ACCESS(vp, VEXEC, uc, p);
|
||||||
if (error)
|
if (error) {
|
||||||
|
crfree(uc);
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
error = VOP_OPEN(vp, FREAD, p->p_ucred, p);
|
error = VOP_OPEN(vp, FREAD, uc, p);
|
||||||
|
crfree(uc);
|
||||||
if (error)
|
if (error)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
@ -321,6 +333,9 @@ linux_uselib(struct proc *p, struct linux_uselib_args *args)
|
|||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* To protect p->p_rlimit in the if condition. */
|
||||||
|
mtx_assert(&Giant, MA_OWNED);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* text/data/bss must not exceed limits
|
* text/data/bss must not exceed limits
|
||||||
* XXX: this is not complete. it should check current usage PLUS
|
* XXX: this is not complete. it should check current usage PLUS
|
||||||
|
@ -231,20 +231,19 @@ static int
|
|||||||
linux_do_sigprocmask(struct proc *p, int how, linux_sigset_t *new,
|
linux_do_sigprocmask(struct proc *p, int how, linux_sigset_t *new,
|
||||||
linux_sigset_t *old)
|
linux_sigset_t *old)
|
||||||
{
|
{
|
||||||
int error, s;
|
int error;
|
||||||
sigset_t mask;
|
sigset_t mask;
|
||||||
|
|
||||||
error = 0;
|
error = 0;
|
||||||
p->p_retval[0] = 0;
|
p->p_retval[0] = 0;
|
||||||
|
|
||||||
|
PROC_LOCK(p);
|
||||||
if (old != NULL)
|
if (old != NULL)
|
||||||
bsd_to_linux_sigset(&p->p_sigmask, old);
|
bsd_to_linux_sigset(&p->p_sigmask, old);
|
||||||
|
|
||||||
if (new != NULL) {
|
if (new != NULL) {
|
||||||
linux_to_bsd_sigset(new, &mask);
|
linux_to_bsd_sigset(new, &mask);
|
||||||
|
|
||||||
s = splhigh();
|
|
||||||
|
|
||||||
switch (how) {
|
switch (how) {
|
||||||
case LINUX_SIG_BLOCK:
|
case LINUX_SIG_BLOCK:
|
||||||
SIGSETOR(p->p_sigmask, mask);
|
SIGSETOR(p->p_sigmask, mask);
|
||||||
@ -261,9 +260,8 @@ linux_do_sigprocmask(struct proc *p, int how, linux_sigset_t *new,
|
|||||||
error = EINVAL;
|
error = EINVAL;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
splx(s);
|
|
||||||
}
|
}
|
||||||
|
PROC_UNLOCK(p);
|
||||||
|
|
||||||
return (error);
|
return (error);
|
||||||
}
|
}
|
||||||
@ -343,7 +341,9 @@ linux_siggetmask(struct proc *p, struct linux_siggetmask_args *args)
|
|||||||
printf("Linux-emul(%d): siggetmask()\n", p->p_pid);
|
printf("Linux-emul(%d): siggetmask()\n", p->p_pid);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
PROC_LOCK(p);
|
||||||
bsd_to_linux_sigset(&p->p_sigmask, &mask);
|
bsd_to_linux_sigset(&p->p_sigmask, &mask);
|
||||||
|
PROC_UNLOCK(p);
|
||||||
p->p_retval[0] = mask.__bits[0];
|
p->p_retval[0] = mask.__bits[0];
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
@ -353,22 +353,21 @@ linux_sigsetmask(struct proc *p, struct linux_sigsetmask_args *args)
|
|||||||
{
|
{
|
||||||
linux_sigset_t lset;
|
linux_sigset_t lset;
|
||||||
sigset_t bset;
|
sigset_t bset;
|
||||||
int s;
|
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
printf("Linux-emul(%ld): sigsetmask(%08lx)\n",
|
printf("Linux-emul(%ld): sigsetmask(%08lx)\n",
|
||||||
(long)p->p_pid, (unsigned long)args->mask);
|
(long)p->p_pid, (unsigned long)args->mask);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
PROC_LOCK(p);
|
||||||
bsd_to_linux_sigset(&p->p_sigmask, &lset);
|
bsd_to_linux_sigset(&p->p_sigmask, &lset);
|
||||||
p->p_retval[0] = lset.__bits[0];
|
p->p_retval[0] = lset.__bits[0];
|
||||||
LINUX_SIGEMPTYSET(lset);
|
LINUX_SIGEMPTYSET(lset);
|
||||||
lset.__bits[0] = args->mask;
|
lset.__bits[0] = args->mask;
|
||||||
linux_to_bsd_sigset(&lset, &bset);
|
linux_to_bsd_sigset(&lset, &bset);
|
||||||
s = splhigh();
|
|
||||||
p->p_sigmask = bset;
|
p->p_sigmask = bset;
|
||||||
SIG_CANTMASK(p->p_sigmask);
|
SIG_CANTMASK(p->p_sigmask);
|
||||||
splx(s);
|
PROC_UNLOCK(p);
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -383,9 +382,11 @@ linux_sigpending(struct proc *p, struct linux_sigpending_args *args)
|
|||||||
printf("Linux-emul(%d): sigpending(*)\n", p->p_pid);
|
printf("Linux-emul(%d): sigpending(*)\n", p->p_pid);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
PROC_LOCK(p);
|
||||||
bset = p->p_siglist;
|
bset = p->p_siglist;
|
||||||
SIGSETAND(bset, p->p_sigmask);
|
SIGSETAND(bset, p->p_sigmask);
|
||||||
bsd_to_linux_sigset(&bset, &lset);
|
bsd_to_linux_sigset(&bset, &lset);
|
||||||
|
PROC_UNLOCK(p);
|
||||||
mask = lset.__bits[0];
|
mask = lset.__bits[0];
|
||||||
return (copyout(&mask, args->mask, sizeof(mask)));
|
return (copyout(&mask, args->mask, sizeof(mask)));
|
||||||
}
|
}
|
||||||
|
@ -62,6 +62,7 @@ linux_emul_find(p, sgp, prefix, path, pbuf, cflag)
|
|||||||
struct nameidata ndroot;
|
struct nameidata ndroot;
|
||||||
struct vattr vat;
|
struct vattr vat;
|
||||||
struct vattr vatroot;
|
struct vattr vatroot;
|
||||||
|
struct ucred *uc;
|
||||||
int error;
|
int error;
|
||||||
char *ptr, *buf, *cp;
|
char *ptr, *buf, *cp;
|
||||||
size_t sz, len;
|
size_t sz, len;
|
||||||
@ -140,12 +141,18 @@ linux_emul_find(p, sgp, prefix, path, pbuf, cflag)
|
|||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((error = VOP_GETATTR(nd.ni_vp, &vat, p->p_ucred, p)) != 0) {
|
PROC_LOCK(p);
|
||||||
|
uc = p->p_ucred;
|
||||||
|
crhold(uc);
|
||||||
|
PROC_UNLOCK(p);
|
||||||
|
if ((error = VOP_GETATTR(nd.ni_vp, &vat, uc, p)) != 0) {
|
||||||
|
crfree(uc);
|
||||||
goto bad;
|
goto bad;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((error = VOP_GETATTR(ndroot.ni_vp, &vatroot, p->p_ucred, p))
|
error = VOP_GETATTR(ndroot.ni_vp, &vatroot, uc, p);
|
||||||
!= 0) {
|
crfree(uc);
|
||||||
|
if (error != 0) {
|
||||||
goto bad;
|
goto bad;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user