summaryrefslogtreecommitdiffstats
path: root/sys/compat
diff options
context:
space:
mode:
authorjhb <jhb@FreeBSD.org>2000-12-15 19:41:27 +0000
committerjhb <jhb@FreeBSD.org>2000-12-15 19:41:27 +0000
commit81c40ecc9ceba6e061fd35e0d08c8c37d3121aee (patch)
tree7e104248a7cb66a32e98b1b0efcd4193e1b3433e /sys/compat
parente761ef905bfe40800a70e05c7023a3a4acaa364b (diff)
downloadFreeBSD-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.c14
-rw-r--r--sys/compat/linux/linux_misc.c25
-rw-r--r--sys/compat/linux/linux_signal.c17
-rw-r--r--sys/compat/linux/linux_util.c13
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;
}
OpenPOWER on IntegriCloud