aboutsummaryrefslogtreecommitdiff
path: root/sys/miscfs
diff options
context:
space:
mode:
authorRobert Watson <rwatson@FreeBSD.org>2000-08-30 04:49:09 +0000
committerRobert Watson <rwatson@FreeBSD.org>2000-08-30 04:49:09 +0000
commit387d2c036bf02cf3a23705cc496577acdb829517 (patch)
tree78428c175dc964a36c8008000a09c7a1e0cef19f /sys/miscfs
parentc6fac29aff1f46a559899511e376d18b16f9c09d (diff)
downloadsrc-387d2c036bf02cf3a23705cc496577acdb829517.tar.gz
src-387d2c036bf02cf3a23705cc496577acdb829517.zip
o Centralize inter-process access control, introducing:
int p_can(p1, p2, operation, privused) which allows specification of subject process, object process, inter-process operation, and an optional call-by-reference privused flag, allowing the caller to determine if privilege was required for the call to succeed. This allows jail, kern.ps_showallprocs and regular credential-based interaction checks to occur in one block of code. Possible operations are P_CAN_SEE, P_CAN_SCHED, P_CAN_KILL, and P_CAN_DEBUG. p_can currently breaks out as a wrapper to a series of static function checks in kern_prot, which should not be invoked directly. o Commented out capabilities entries are included for some checks. o Update most inter-process authorization to make use of p_can() instead of manual checks, PRISON_CHECK(), P_TRESPASS(), and kern.ps_showallprocs. o Modify suser{,_xxx} to use const arguments, as it no longer modifies process flags due to the disabling of ASU. o Modify some checks/errors in procfs so that ENOENT is returned instead of ESRCH, further improving concealment of processes that should not be visible to other processes. Also introduce new access checks to improve hiding of processes for procfs_lookup(), procfs_getattr(), procfs_readdir(). Correct a bug reported by bp concerning not handling the CREATE case in procfs_lookup(). Remove volatile flag in procfs that caused apparently spurious qualifier warnigns (approved by bde). o Add comment noting that ktrace() has not been updated, as its access control checks are different from ptrace(), whereas they should probably be the same. Further discussion should happen on this topic. Reviewed by: bde, green, phk, freebsd-security, others Approved by: bde Obtained from: TrustedBSD Project
Notes
Notes: svn path=/head/; revision=65237
Diffstat (limited to 'sys/miscfs')
-rw-r--r--sys/miscfs/procfs/procfs_dbregs.c2
-rw-r--r--sys/miscfs/procfs/procfs_fpregs.c2
-rw-r--r--sys/miscfs/procfs/procfs_mem.c2
-rw-r--r--sys/miscfs/procfs/procfs_regs.c2
-rw-r--r--sys/miscfs/procfs/procfs_status.c2
-rw-r--r--sys/miscfs/procfs/procfs_vnops.c49
6 files changed, 38 insertions, 21 deletions
diff --git a/sys/miscfs/procfs/procfs_dbregs.c b/sys/miscfs/procfs/procfs_dbregs.c
index 158c3f4ab269..c7ad13014728 100644
--- a/sys/miscfs/procfs/procfs_dbregs.c
+++ b/sys/miscfs/procfs/procfs_dbregs.c
@@ -62,7 +62,7 @@ procfs_dodbregs(curp, p, pfs, uio)
char *kv;
int kl;
- if (p_trespass(curp, p))
+ if (p_can(curp, p, P_CAN_DEBUG, NULL))
return (EPERM);
kl = sizeof(r);
kv = (char *) &r;
diff --git a/sys/miscfs/procfs/procfs_fpregs.c b/sys/miscfs/procfs/procfs_fpregs.c
index 353b52bcac82..69dd527f6e8f 100644
--- a/sys/miscfs/procfs/procfs_fpregs.c
+++ b/sys/miscfs/procfs/procfs_fpregs.c
@@ -59,7 +59,7 @@ procfs_dofpregs(curp, p, pfs, uio)
char *kv;
int kl;
- if (p_trespass(curp, p))
+ if (p_can(curp, p, P_CAN_DEBUG, NULL))
return EPERM;
kl = sizeof(r);
kv = (char *) &r;
diff --git a/sys/miscfs/procfs/procfs_mem.c b/sys/miscfs/procfs/procfs_mem.c
index b7eed8503ea1..6f2c8cbb88e7 100644
--- a/sys/miscfs/procfs/procfs_mem.c
+++ b/sys/miscfs/procfs/procfs_mem.c
@@ -256,7 +256,7 @@ procfs_domem(curp, p, pfs, uio)
* All in all, quite yucky.
*/
- if (p_trespass(curp, p) &&
+ if (p_can(curp, p, P_CAN_DEBUG, NULL) &&
!(uio->uio_rw == UIO_READ &&
procfs_kmemaccess(curp)))
return EPERM;
diff --git a/sys/miscfs/procfs/procfs_regs.c b/sys/miscfs/procfs/procfs_regs.c
index 88f85d3d1857..c2b6d4b654fb 100644
--- a/sys/miscfs/procfs/procfs_regs.c
+++ b/sys/miscfs/procfs/procfs_regs.c
@@ -60,7 +60,7 @@ procfs_doregs(curp, p, pfs, uio)
char *kv;
int kl;
- if (p_trespass(curp, p))
+ if (p_can(curp, p, P_CAN_DEBUG, NULL))
return EPERM;
kl = sizeof(r);
kv = (char *) &r;
diff --git a/sys/miscfs/procfs/procfs_status.c b/sys/miscfs/procfs/procfs_status.c
index 03149e9776ce..c1adc60ada41 100644
--- a/sys/miscfs/procfs/procfs_status.c
+++ b/sys/miscfs/procfs/procfs_status.c
@@ -183,7 +183,7 @@ procfs_docmdline(curp, p, pfs, uio)
* Linux behaviour is to return zero-length in this case.
*/
- if (p->p_args && (ps_argsopen ||!p_trespass(curp, p))) {
+ if (p->p_args && (ps_argsopen || !p_can(curp, p, P_CAN_SEE, NULL))) {
bp = p->p_args->ar_args;
buflen = p->p_args->ar_length;
buf = 0;
diff --git a/sys/miscfs/procfs/procfs_vnops.c b/sys/miscfs/procfs/procfs_vnops.c
index 35b3afbded0e..df8e3ca24959 100644
--- a/sys/miscfs/procfs/procfs_vnops.c
+++ b/sys/miscfs/procfs/procfs_vnops.c
@@ -137,7 +137,7 @@ procfs_open(ap)
p2 = PFIND(pfs->pfs_pid);
if (p2 == NULL)
return (ENOENT);
- if (pfs->pfs_pid && !PRISON_CHECK(ap->a_p, p2))
+ if (pfs->pfs_pid && p_can(ap->a_p, p2, P_CAN_SEE, NULL))
return (ENOENT);
switch (pfs->pfs_type) {
@@ -147,7 +147,7 @@ procfs_open(ap)
return (EBUSY);
p1 = ap->a_p;
- if (p_trespass(p1, p2) &&
+ if (p_can(p1, p2, P_CAN_DEBUG, NULL) &&
!procfs_kmemaccess(p1))
return (EPERM);
@@ -239,8 +239,11 @@ procfs_ioctl(ap)
return ENOTTY;
}
- if (p_trespass(p, procp))
- return EPERM;
+ if ((error = p_can(p, procp, P_CAN_DEBUG, NULL))) {
+ if (error == ESRCH)
+ error = ENOENT;
+ return (error);
+ }
switch (ap->a_command) {
case PIOCBIS:
@@ -417,6 +420,9 @@ procfs_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;
@@ -612,16 +618,23 @@ procfs_access(ap)
struct proc *a_p;
} */ *ap;
{
+ struct pfsnode *pfs = VTOPFS(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 Pcurproc:
+ 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);
@@ -674,7 +687,7 @@ procfs_lookup(ap)
struct vnode **vpp = ap->a_vpp;
struct vnode *dvp = ap->a_dvp;
char *pname = cnp->cn_nameptr;
- /* struct proc *curp = cnp->cn_proc; */
+ struct proc *curp = cnp->cn_proc;
struct proc_target *pt;
pid_t pid;
struct pfsnode *pfs;
@@ -683,7 +696,8 @@ procfs_lookup(ap)
*vpp = NULL;
- if (cnp->cn_nameiop == DELETE || cnp->cn_nameiop == RENAME)
+ if (cnp->cn_nameiop == DELETE || cnp->cn_nameiop == RENAME ||
+ cnp->cn_nameiop == CREATE)
return (EROFS);
if (cnp->cn_namelen == 1 && *pname == '.') {
@@ -710,6 +724,9 @@ procfs_lookup(ap)
if (p == 0)
break;
+ if (p_can(curp, p, P_CAN_SEE, NULL))
+ break;
+
return (procfs_allocvp(dvp->v_mount, vpp, pid, Pproc));
case Pproc:
@@ -803,7 +820,7 @@ procfs_readdir(ap)
p = PFIND(pfs->pfs_pid);
if (p == NULL)
break;
- if (!PRISON_CHECK(curproc, p))
+ if (p_can(curproc, p, P_CAN_SEE, NULL))
break;
for (pt = &proc_targets[i];
@@ -838,7 +855,7 @@ procfs_readdir(ap)
int doingzomb = 0;
#endif
int pcnt = 0;
- volatile struct proc *p = allproc.lh_first;
+ struct proc *p = allproc.lh_first;
for (; p && uio->uio_resid >= delen; i++, pcnt++) {
bzero((char *) dp, delen);
@@ -866,11 +883,11 @@ procfs_readdir(ap)
p = p->p_list.le_next;
if (!p)
goto done;
- if (!PRISON_CHECK(curproc, p))
+ if (p_can(curproc, p, P_CAN_SEE, NULL))
continue;
pcnt++;
}
- while (!PRISON_CHECK(curproc, p)) {
+ while (p_can(curproc, p, P_CAN_SEE, NULL)) {
p = p->p_list.le_next;
if (!p)
goto done;