summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authorrwatson <rwatson@FreeBSD.org>2000-09-01 18:40:52 +0000
committerrwatson <rwatson@FreeBSD.org>2000-09-01 18:40:52 +0000
commit997c80bdd827328f71fb9e7c1f5d96ad61ef4120 (patch)
tree65129cd19b79c2bb6a2fc73081f05c5200e32952 /sys
parent04045bb67de3e42f5825236d1611a2bc31debb30 (diff)
downloadFreeBSD-src-997c80bdd827328f71fb9e7c1f5d96ad61ef4120.zip
FreeBSD-src-997c80bdd827328f71fb9e7c1f5d96ad61ef4120.tar.gz
o Synchronize linprocfs authorization with procfs authorization improvements
(better hiding of hidden processes, more access checks, use vaccess(), et al) Approved by: des Obtained from: TrustedBSD Project
Diffstat (limited to 'sys')
-rw-r--r--sys/compat/linprocfs/linprocfs_vnops.c67
-rw-r--r--sys/i386/linux/linprocfs/linprocfs_vnops.c67
2 files changed, 58 insertions, 76 deletions
diff --git a/sys/compat/linprocfs/linprocfs_vnops.c b/sys/compat/linprocfs/linprocfs_vnops.c
index 3b2cf98..32862d3 100644
--- a/sys/compat/linprocfs/linprocfs_vnops.c
+++ b/sys/compat/linprocfs/linprocfs_vnops.c
@@ -227,12 +227,11 @@ linprocfs_ioctl(ap)
p = ap->a_p;
procp = pfind(pfs->pfs_pid);
- if (procp == NULL) {
+ if (procp == NULL)
return ENOTTY;
- }
- if (p_can(p, procp, P_CAN_DEBUG, NULL))
- return EPERM;
+ if ((error = p_can(p, procp, P_CAN_DEBUG, NULL)))
+ return (error == ESRCH ? ENOENT : error);
switch (ap->a_command) {
case PIOCBIS:
@@ -431,6 +430,9 @@ linprocfs_getattr(ap)
if (procp == 0 || procp->p_cred == NULL ||
procp->p_ucred == NULL)
return (ENOENT);
+
+ if (p_can(ap->a_p, procp, P_CAN_SEE, NULL))
+ return (ENOENT);
}
error = 0;
@@ -580,10 +582,6 @@ linprocfs_setattr(ap)
/*
* implement access checking.
*
- * something very similar to this code is duplicated
- * throughout the 4bsd kernel and should be moved
- * into kern/vfs_subr.c sometime.
- *
* actually, the check for super-user is slightly
* broken since it will allow read access to write-only
* objects. this doesn't cause any particular trouble
@@ -599,45 +597,34 @@ linprocfs_access(ap)
struct proc *a_p;
} */ *ap;
{
+ struct pfsnode *pfs = VTOPFS(ap->a_vp);
+ struct vnode *vp = ap->a_vp;
+ struct proc *procp;
struct vattr *vap;
struct vattr vattr;
int error;
- /*
- * If you're the super-user,
- * you always get access.
- */
- if (ap->a_cred->cr_uid == 0)
- return (0);
+ switch (pfs->pfs_type) {
+ case Proot:
+ case Pself:
+ case Pmeminfo:
+ case Pcpuinfo:
+ break;
+ default:
+ procp = PFIND(pfs->pfs_pid);
+ if (procp == NULL)
+ return (ENOENT);
+ if (p_can(ap->a_p, procp, P_CAN_SEE, NULL))
+ return (ENOENT);
+ }
vap = &vattr;
- error = VOP_GETATTR(ap->a_vp, vap, ap->a_cred, ap->a_p);
+ error = VOP_GETATTR(vp, vap, ap->a_cred, ap->a_p);
if (error)
return (error);
- /*
- * Access check is based on only one of owner, group, public.
- * If not owner, then check group. If not a member of the
- * group, then check public access.
- */
- if (ap->a_cred->cr_uid != vap->va_uid) {
- gid_t *gp;
- int i;
-
- ap->a_mode >>= 3;
- gp = ap->a_cred->cr_groups;
- for (i = 0; i < ap->a_cred->cr_ngroups; i++, gp++)
- if (vap->va_gid == *gp)
- goto found;
- ap->a_mode >>= 3;
-found:
- ;
- }
-
- if ((vap->va_mode & ap->a_mode) == ap->a_mode)
- return (0);
-
- return (EACCES);
+ return (vaccess(vp->v_type, vap->va_mode, vap->va_uid, vap->va_gid,
+ ap->a_mode, ap->a_cred, NULL));
}
/*
@@ -658,6 +645,7 @@ linprocfs_lookup(ap)
} */ *ap;
{
struct componentname *cnp = ap->a_cnp;
+ struct proc *curp = cnp->cn_proc;
struct vnode **vpp = ap->a_vpp;
struct vnode *dvp = ap->a_dvp;
char *pname = cnp->cn_nameptr;
@@ -701,6 +689,9 @@ linprocfs_lookup(ap)
if (p == 0)
break;
+ if (p_can(curp, p, P_CAN_SEE, NULL))
+ break;
+
return (linprocfs_allocvp(dvp->v_mount, vpp, pid, Pproc));
case Pproc:
diff --git a/sys/i386/linux/linprocfs/linprocfs_vnops.c b/sys/i386/linux/linprocfs/linprocfs_vnops.c
index 3b2cf98..32862d3 100644
--- a/sys/i386/linux/linprocfs/linprocfs_vnops.c
+++ b/sys/i386/linux/linprocfs/linprocfs_vnops.c
@@ -227,12 +227,11 @@ linprocfs_ioctl(ap)
p = ap->a_p;
procp = pfind(pfs->pfs_pid);
- if (procp == NULL) {
+ if (procp == NULL)
return ENOTTY;
- }
- if (p_can(p, procp, P_CAN_DEBUG, NULL))
- return EPERM;
+ if ((error = p_can(p, procp, P_CAN_DEBUG, NULL)))
+ return (error == ESRCH ? ENOENT : error);
switch (ap->a_command) {
case PIOCBIS:
@@ -431,6 +430,9 @@ linprocfs_getattr(ap)
if (procp == 0 || procp->p_cred == NULL ||
procp->p_ucred == NULL)
return (ENOENT);
+
+ if (p_can(ap->a_p, procp, P_CAN_SEE, NULL))
+ return (ENOENT);
}
error = 0;
@@ -580,10 +582,6 @@ linprocfs_setattr(ap)
/*
* implement access checking.
*
- * something very similar to this code is duplicated
- * throughout the 4bsd kernel and should be moved
- * into kern/vfs_subr.c sometime.
- *
* actually, the check for super-user is slightly
* broken since it will allow read access to write-only
* objects. this doesn't cause any particular trouble
@@ -599,45 +597,34 @@ linprocfs_access(ap)
struct proc *a_p;
} */ *ap;
{
+ struct pfsnode *pfs = VTOPFS(ap->a_vp);
+ struct vnode *vp = ap->a_vp;
+ struct proc *procp;
struct vattr *vap;
struct vattr vattr;
int error;
- /*
- * If you're the super-user,
- * you always get access.
- */
- if (ap->a_cred->cr_uid == 0)
- return (0);
+ switch (pfs->pfs_type) {
+ case Proot:
+ case Pself:
+ case Pmeminfo:
+ case Pcpuinfo:
+ break;
+ default:
+ procp = PFIND(pfs->pfs_pid);
+ if (procp == NULL)
+ return (ENOENT);
+ if (p_can(ap->a_p, procp, P_CAN_SEE, NULL))
+ return (ENOENT);
+ }
vap = &vattr;
- error = VOP_GETATTR(ap->a_vp, vap, ap->a_cred, ap->a_p);
+ error = VOP_GETATTR(vp, vap, ap->a_cred, ap->a_p);
if (error)
return (error);
- /*
- * Access check is based on only one of owner, group, public.
- * If not owner, then check group. If not a member of the
- * group, then check public access.
- */
- if (ap->a_cred->cr_uid != vap->va_uid) {
- gid_t *gp;
- int i;
-
- ap->a_mode >>= 3;
- gp = ap->a_cred->cr_groups;
- for (i = 0; i < ap->a_cred->cr_ngroups; i++, gp++)
- if (vap->va_gid == *gp)
- goto found;
- ap->a_mode >>= 3;
-found:
- ;
- }
-
- if ((vap->va_mode & ap->a_mode) == ap->a_mode)
- return (0);
-
- return (EACCES);
+ return (vaccess(vp->v_type, vap->va_mode, vap->va_uid, vap->va_gid,
+ ap->a_mode, ap->a_cred, NULL));
}
/*
@@ -658,6 +645,7 @@ linprocfs_lookup(ap)
} */ *ap;
{
struct componentname *cnp = ap->a_cnp;
+ struct proc *curp = cnp->cn_proc;
struct vnode **vpp = ap->a_vpp;
struct vnode *dvp = ap->a_dvp;
char *pname = cnp->cn_nameptr;
@@ -701,6 +689,9 @@ linprocfs_lookup(ap)
if (p == 0)
break;
+ if (p_can(curp, p, P_CAN_SEE, NULL))
+ break;
+
return (linprocfs_allocvp(dvp->v_mount, vpp, pid, Pproc));
case Pproc:
OpenPOWER on IntegriCloud