Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/miscfs/procfs At mount/unmount time, add an exec hook to...
details: https://anonhg.NetBSD.org/src/rev/1295093fddba
branches: trunk
changeset: 481301:1295093fddba
user: fvdl <fvdl%NetBSD.org@localhost>
date: Tue Jan 25 21:52:04 2000 +0000
description:
At mount/unmount time, add an exec hook to revoke all vnodes iff the
process is about to exec a sugid binary.
To speed up things, use hashing for vnode allocation, like other filesystems
do. This avoids walking the whole procfs node list in the revoke case too.
diffstat:
sys/miscfs/procfs/procfs.h | 14 ++-
sys/miscfs/procfs/procfs_subr.c | 158 ++++++++++++++++++++++++++-----------
sys/miscfs/procfs/procfs_vfsops.c | 19 ++++-
3 files changed, 138 insertions(+), 53 deletions(-)
diffs (truncated from 318 to 300 lines):
diff -r 054eae22f253 -r 1295093fddba sys/miscfs/procfs/procfs.h
--- a/sys/miscfs/procfs/procfs.h Tue Jan 25 21:50:30 2000 +0000
+++ b/sys/miscfs/procfs/procfs.h Tue Jan 25 21:52:04 2000 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: procfs.h,v 1.27 1999/09/02 23:33:45 thorpej Exp $ */
+/* $NetBSD: procfs.h,v 1.28 2000/01/25 21:52:04 fvdl Exp $ */
/*
* Copyright (c) 1993 Jan-Simon Pendry
@@ -63,7 +63,7 @@
* control data for the proc file system.
*/
struct pfsnode {
- struct pfsnode *pfs_next; /* next on list */
+ LIST_ENTRY(pfsnode) pfs_hash; /* hash chain */
struct vnode *pfs_vnode; /* vnode associated with this pfsnode */
pfstype pfs_type; /* type of procfs node */
pid_t pfs_pid; /* associated process */
@@ -90,6 +90,14 @@
((type) + 2) : \
((((pid)+1) << 4) + ((int) (type))))
+struct procfsmount {
+ void *pmnt_exechook;
+ struct mount *pmnt_mp;
+};
+
+#define VFSTOPROC(mp) ((struct procfsmount *)(mp)->mnt_data)
+#define PROCTOVFS(pp) ((pp)->pmnt_mp)
+
/*
* Convert between pfsnode vnode
*/
@@ -127,6 +135,8 @@
struct uio *));
int procfs_checkioperm __P((struct proc *, struct proc *));
+void procfs_revoke_vnodes __P((struct proc *, void *));
+void procfs_hashinit __P((void));
/* functions to check whether or not files should be displayed */
int procfs_validfile __P((struct proc *));
diff -r 054eae22f253 -r 1295093fddba sys/miscfs/procfs/procfs_subr.c
--- a/sys/miscfs/procfs/procfs_subr.c Tue Jan 25 21:50:30 2000 +0000
+++ b/sys/miscfs/procfs/procfs_subr.c Tue Jan 25 21:52:04 2000 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: procfs_subr.c,v 1.28 1999/09/02 23:33:45 thorpej Exp $ */
+/* $NetBSD: procfs_subr.c,v 1.29 2000/01/25 21:52:04 fvdl Exp $ */
/*
* Copyright (c) 1994 Christopher G. Demetriou. All rights reserved.
@@ -51,8 +51,16 @@
#include <miscfs/procfs/procfs.h>
-static struct pfsnode *pfshead;
-static int pfsvplock;
+void procfs_hashins __P((struct pfsnode *));
+void procfs_hashrem __P((struct pfsnode *));
+struct vnode *procfs_hashget __P((pid_t, pfstype, struct mount *));
+
+LIST_HEAD(pfs_hashhead, pfsnode) *pfs_hashtbl;
+u_long ihash; /* size of hash table - 1 */
+#define PFSPIDHASH(pid) (&pfs_hashtbl[(pid) & ihash])
+
+struct lock pfs_hashlock;
+struct simplelock pfs_hash_slock;
#define ISSET(t, f) ((t) & (f))
@@ -91,41 +99,23 @@
{
struct pfsnode *pfs;
struct vnode *vp;
- struct pfsnode **pp;
int error;
-loop:
- for (pfs = pfshead; pfs != 0; pfs = pfs->pfs_next) {
- vp = PFSTOV(pfs);
- if (pfs->pfs_pid == pid &&
- pfs->pfs_type == pfs_type &&
- vp->v_mount == mp) {
- if (vget(vp, LK_EXCLUSIVE))
- goto loop;
- *vpp = vp;
+ do {
+ if ((*vpp = procfs_hashget(pid, pfs_type, mp)) != NULL)
return (0);
- }
- }
+ } while (lockmgr(&pfs_hashlock, LK_EXCLUSIVE|LK_SLEEPFAIL, 0));
- /*
- * otherwise lock the vp list while we call getnewvnode
- * since that can block.
- */
- if (pfsvplock & PROCFS_LOCKED) {
- pfsvplock |= PROCFS_WANT;
- sleep((caddr_t) &pfsvplock, PINOD);
- goto loop;
+ if ((error = getnewvnode(VT_PROCFS, mp, procfs_vnodeop_p, vpp)) != 0) {
+ *vpp = NULL;
+ lockmgr(&pfs_hashlock, LK_RELEASE, 0);
+ return (error);
}
- pfsvplock |= PROCFS_LOCKED;
-
- if ((error = getnewvnode(VT_PROCFS, mp, procfs_vnodeop_p, vpp)) != 0)
- goto out;
vp = *vpp;
MALLOC(pfs, void *, sizeof(struct pfsnode), M_TEMP, M_WAITOK);
vp->v_data = pfs;
- pfs->pfs_next = 0;
pfs->pfs_pid = (pid_t) pid;
pfs->pfs_type = pfs_type;
pfs->pfs_vnode = vp;
@@ -176,20 +166,8 @@
panic("procfs_allocvp");
}
- VOP_LOCK(vp, LK_EXCLUSIVE);
-
- /* add to procfs vnode list */
- for (pp = &pfshead; *pp; pp = &(*pp)->pfs_next)
- continue;
- *pp = pfs;
-
-out:
- pfsvplock &= ~PROCFS_LOCKED;
-
- if (pfsvplock & PROCFS_WANT) {
- pfsvplock &= ~PROCFS_WANT;
- wakeup((caddr_t) &pfsvplock);
- }
+ procfs_hashins(pfs);
+ lockmgr(&pfs_hashlock, LK_RELEASE, 0);
return (error);
}
@@ -198,15 +176,9 @@
procfs_freevp(vp)
struct vnode *vp;
{
- struct pfsnode **pfspp;
struct pfsnode *pfs = VTOPFS(vp);
- for (pfspp = &pfshead; *pfspp != 0; pfspp = &(*pfspp)->pfs_next) {
- if (*pfspp == pfs) {
- *pfspp = pfs->pfs_next;
- break;
- }
- }
+ procfs_hashrem(pfs);
FREE(vp->v_data, M_TEMP);
vp->v_data = 0;
@@ -336,3 +308,91 @@
return (0);
}
+
+/*
+ * Initialize pfsnode hash table.
+ */
+void
+procfs_hashinit()
+{
+ lockinit(&pfs_hashlock, PINOD, "pfs_hashlock", 0, 0);
+ pfs_hashtbl = hashinit(desiredvnodes / 4, M_UFSMNT, M_WAITOK, &ihash);
+ simple_lock_init(&pfs_hash_slock);
+}
+
+struct vnode *
+procfs_hashget(pid, type, mp)
+ pid_t pid;
+ pfstype type;
+ struct mount *mp;
+{
+ struct pfsnode *pp;
+ struct vnode *vp;
+
+loop:
+ simple_lock(&pfs_hash_slock);
+ for (pp = PFSPIDHASH(pid)->lh_first; pp; pp = pp->pfs_hash.le_next) {
+ vp = PFSTOV(pp);
+ if (pid == pp->pfs_pid && pp->pfs_type == type &&
+ vp->v_mount == mp) {
+ simple_lock(&vp->v_interlock);
+ simple_unlock(&pfs_hash_slock);
+ if (vget(vp, LK_EXCLUSIVE | LK_INTERLOCK))
+ goto loop;
+ return (vp);
+ }
+ }
+ simple_unlock(&pfs_hash_slock);
+ return (NULL);
+}
+
+/*
+ * Insert the pfsnode into the hash table and lock it.
+ */
+void
+procfs_hashins(pp)
+ struct pfsnode *pp;
+{
+ struct pfs_hashhead *ppp;
+
+ /* lock the pfsnode, then put it on the appropriate hash list */
+ lockmgr(&pp->pfs_vnode->v_lock, LK_EXCLUSIVE, (struct simplelock *)0);
+
+ simple_lock(&pfs_hash_slock);
+ ppp = PFSPIDHASH(pp->pfs_pid);
+ LIST_INSERT_HEAD(ppp, pp, pfs_hash);
+ simple_unlock(&pfs_hash_slock);
+}
+
+/*
+ * Remove the pfsnode from the hash table.
+ */
+void
+procfs_hashrem(pp)
+ struct pfsnode *pp;
+{
+ simple_lock(&pfs_hash_slock);
+ LIST_REMOVE(pp, pfs_hash);
+ simple_unlock(&pfs_hash_slock);
+}
+
+void
+procfs_revoke_vnodes(p, arg)
+ struct proc *p;
+ void *arg;
+{
+ struct pfsnode *pfs, *pnext;
+ struct vnode *vp;
+ struct mount *mp = (struct mount *)arg;
+
+ if (!(p->p_flag & P_SUGID))
+ return;
+
+ for (pfs = PFSPIDHASH(p->p_pid)->lh_first; pfs; pfs = pnext) {
+ vp = PFSTOV(pfs);
+ pnext = pfs->pfs_hash.le_next;
+ if (vp->v_usecount > 0 && pfs->pfs_pid == p->p_pid &&
+ vp->v_mount == mp)
+ VOP_REVOKE(vp, REVOKEALL);
+ }
+}
diff -r 054eae22f253 -r 1295093fddba sys/miscfs/procfs/procfs_vfsops.c
--- a/sys/miscfs/procfs/procfs_vfsops.c Tue Jan 25 21:50:30 2000 +0000
+++ b/sys/miscfs/procfs/procfs_vfsops.c Tue Jan 25 21:52:04 2000 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: procfs_vfsops.c,v 1.31 1999/02/26 23:44:46 wrstuden Exp $ */
+/* $NetBSD: procfs_vfsops.c,v 1.32 2000/01/25 21:52:04 fvdl Exp $ */
/*
* Copyright (c) 1993 Jan-Simon Pendry
@@ -57,6 +57,7 @@
#include <sys/mount.h>
#include <sys/signalvar.h>
#include <sys/vnode.h>
+#include <sys/malloc.h>
#include <miscfs/procfs/procfs.h>
#include <vm/vm.h> /* for PAGE_SIZE */
@@ -91,6 +92,7 @@
struct proc *p;
{
size_t size;
+ struct procfsmount *pmnt;
if (UIO_MX & (UIO_MX-1)) {
log(LOG_ERR, "procfs: invalid directory entry size");
@@ -101,13 +103,20 @@
return (EOPNOTSUPP);
mp->mnt_flag |= MNT_LOCAL;
- mp->mnt_data = 0;
+ pmnt = (struct procfsmount *) malloc(sizeof(struct procfsmount),
+ M_UFSMNT, M_WAITOK); /* XXX need new malloc type */
+
+ mp->mnt_data = (qaddr_t)pmnt;
vfs_getnewfsid(mp, MOUNT_PROCFS);
(void) copyinstr(path, mp->mnt_stat.f_mntonname, MNAMELEN, &size);
memset(mp->mnt_stat.f_mntonname + size, 0, MNAMELEN - size);
memset(mp->mnt_stat.f_mntfromname, 0, MNAMELEN);
memcpy(mp->mnt_stat.f_mntfromname, "procfs", sizeof("procfs"));
+
+ pmnt->pmnt_exechook = exechook_establish(procfs_revoke_vnodes, mp);
+ pmnt->pmnt_mp = mp;
+
return (0);
}
@@ -129,6 +138,11 @@
if ((error = vflush(mp, 0, flags)) != 0)
Home |
Main Index |
Thread Index |
Old Index