diff options
author | jhb <jhb@FreeBSD.org> | 2000-12-15 19:41:27 +0000 |
---|---|---|
committer | jhb <jhb@FreeBSD.org> | 2000-12-15 19:41:27 +0000 |
commit | 81c40ecc9ceba6e061fd35e0d08c8c37d3121aee (patch) | |
tree | 7e104248a7cb66a32e98b1b0efcd4193e1b3433e /sys/compat | |
parent | e761ef905bfe40800a70e05c7023a3a4acaa364b (diff) | |
download | FreeBSD-src-81c40ecc9ceba6e061fd35e0d08c8c37d3121aee.zip FreeBSD-src-81c40ecc9ceba6e061fd35e0d08c8c37d3121aee.tar.gz |
Lock access to proc members.
Glanced over by: marcel
Diffstat (limited to 'sys/compat')
-rw-r--r-- | sys/compat/linux/linux_file.c | 14 | ||||
-rw-r--r-- | sys/compat/linux/linux_misc.c | 25 | ||||
-rw-r--r-- | sys/compat/linux/linux_signal.c | 17 | ||||
-rw-r--r-- | sys/compat/linux/linux_util.c | 13 |
4 files changed, 51 insertions, 18 deletions
diff --git a/sys/compat/linux/linux_file.c b/sys/compat/linux/linux_file.c index d0e531b..1bbe4cc 100644 --- a/sys/compat/linux/linux_file.c +++ b/sys/compat/linux/linux_file.c @@ -124,14 +124,17 @@ linux_open(struct proc *p, struct linux_open_args *args) bsd_open_args.mode = args->mode; error = open(p, &bsd_open_args); + PROC_LOCK(p); if (!error && !(bsd_open_args.flags & O_NOCTTY) && SESS_LEADER(p) && !(p->p_flag & P_CONTROLT)) { struct filedesc *fdp = p->p_fd; struct file *fp = fdp->fd_ofiles[p->p_retval[0]]; + PROC_UNLOCK(p); if (fp->f_type == DTYPE_VNODE) fo_ioctl(fp, TIOCSCTTY, (caddr_t) 0, p); - } + } else + PROC_UNLOCK(p); #ifdef DEBUG printf("Linux-emul(%d): open returns error %d\n", p->p_pid, error); @@ -402,6 +405,7 @@ linux_getdents(struct proc *p, struct linux_getdents_args *args) int buflen, error, eofflag, nbytes, justone; u_long *cookies = NULL, *cookiep; int ncookies; + struct ucred *uc; #ifdef DEBUG 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) 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; } diff --git a/sys/compat/linux/linux_misc.c b/sys/compat/linux/linux_misc.c index 8e1b7b1..86c14d1 100644 --- a/sys/compat/linux/linux_misc.c +++ b/sys/compat/linux/linux_misc.c @@ -185,6 +185,7 @@ linux_uselib(struct proc *p, struct linux_uselib_args *args) struct vnode *vp; struct exec *a_out; struct vattr attr; + struct ucred *uc; vm_offset_t vmaddr; unsigned long file_offset; vm_offset_t buffer; @@ -236,14 +237,21 @@ linux_uselib(struct proc *p, struct linux_uselib_args *args) /* * Executable? */ - error = VOP_GETATTR(vp, &attr, p->p_ucred, p); - if (error) + PROC_LOCK(p); + uc = p->p_ucred; + crhold(uc); + PROC_UNLOCK(p); + error = VOP_GETATTR(vp, &attr, uc, p); + if (error) { + crfree(uc); goto cleanup; + } if ((vp->v_mount->mnt_flag & MNT_NOEXEC) || ((attr.va_mode & 0111) == 0) || (attr.va_type != VREG)) { error = ENOEXEC; + crfree(uc); goto cleanup; } @@ -252,17 +260,21 @@ linux_uselib(struct proc *p, struct linux_uselib_args *args) */ if (attr.va_size == 0) { error = ENOEXEC; + crfree(uc); goto cleanup; } /* * Can we access it? */ - error = VOP_ACCESS(vp, VEXEC, p->p_ucred, p); - if (error) + error = VOP_ACCESS(vp, VEXEC, uc, p); + if (error) { + crfree(uc); goto cleanup; + } - error = VOP_OPEN(vp, FREAD, p->p_ucred, p); + error = VOP_OPEN(vp, FREAD, uc, p); + crfree(uc); if (error) goto cleanup; @@ -321,6 +333,9 @@ linux_uselib(struct proc *p, struct linux_uselib_args *args) goto cleanup; } + /* To protect p->p_rlimit in the if condition. */ + mtx_assert(&Giant, MA_OWNED); + /* * text/data/bss must not exceed limits * XXX: this is not complete. it should check current usage PLUS diff --git a/sys/compat/linux/linux_signal.c b/sys/compat/linux/linux_signal.c index 2bd755a..7d2d52b 100644 --- a/sys/compat/linux/linux_signal.c +++ b/sys/compat/linux/linux_signal.c @@ -231,20 +231,19 @@ static int linux_do_sigprocmask(struct proc *p, int how, linux_sigset_t *new, linux_sigset_t *old) { - int error, s; + int error; sigset_t mask; error = 0; p->p_retval[0] = 0; + PROC_LOCK(p); if (old != NULL) bsd_to_linux_sigset(&p->p_sigmask, old); if (new != NULL) { linux_to_bsd_sigset(new, &mask); - s = splhigh(); - switch (how) { case LINUX_SIG_BLOCK: SIGSETOR(p->p_sigmask, mask); @@ -261,9 +260,8 @@ linux_do_sigprocmask(struct proc *p, int how, linux_sigset_t *new, error = EINVAL; break; } - - splx(s); } + PROC_UNLOCK(p); 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); #endif + PROC_LOCK(p); bsd_to_linux_sigset(&p->p_sigmask, &mask); + PROC_UNLOCK(p); p->p_retval[0] = mask.__bits[0]; return (0); } @@ -353,22 +353,21 @@ linux_sigsetmask(struct proc *p, struct linux_sigsetmask_args *args) { linux_sigset_t lset; sigset_t bset; - int s; #ifdef DEBUG printf("Linux-emul(%ld): sigsetmask(%08lx)\n", (long)p->p_pid, (unsigned long)args->mask); #endif + PROC_LOCK(p); bsd_to_linux_sigset(&p->p_sigmask, &lset); p->p_retval[0] = lset.__bits[0]; LINUX_SIGEMPTYSET(lset); lset.__bits[0] = args->mask; linux_to_bsd_sigset(&lset, &bset); - s = splhigh(); p->p_sigmask = bset; SIG_CANTMASK(p->p_sigmask); - splx(s); + PROC_UNLOCK(p); 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); #endif + PROC_LOCK(p); bset = p->p_siglist; SIGSETAND(bset, p->p_sigmask); bsd_to_linux_sigset(&bset, &lset); + PROC_UNLOCK(p); mask = lset.__bits[0]; return (copyout(&mask, args->mask, sizeof(mask))); } diff --git a/sys/compat/linux/linux_util.c b/sys/compat/linux/linux_util.c index 6399805..f4fe8d7 100644 --- a/sys/compat/linux/linux_util.c +++ b/sys/compat/linux/linux_util.c @@ -62,6 +62,7 @@ linux_emul_find(p, sgp, prefix, path, pbuf, cflag) struct nameidata ndroot; struct vattr vat; struct vattr vatroot; + struct ucred *uc; int error; char *ptr, *buf, *cp; size_t sz, len; @@ -140,12 +141,18 @@ linux_emul_find(p, sgp, prefix, path, pbuf, cflag) 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; } - if ((error = VOP_GETATTR(ndroot.ni_vp, &vatroot, p->p_ucred, p)) - != 0) { + error = VOP_GETATTR(ndroot.ni_vp, &vatroot, uc, p); + crfree(uc); + if (error != 0) { goto bad; } |