From fd22d5412a1070b4d246fd214adad09041a53661 Mon Sep 17 00:00:00 2001 From: phk Date: Sun, 21 Nov 1999 19:03:20 +0000 Subject: Introduce the new function p_trespass(struct proc *p1, struct proc *p2) which returns zero or an errno depending on the legality of p1 trespassing on p2. Replace kern_sig.c:CANSIGNAL() with call to p_trespass() and one extra signal related check. Replace procfs.h:CHECKIO() macros with calls to p_trespass(). Only show command lines to process which can trespass on the target process. --- sys/fs/procfs/procfs.h | 13 ------------- sys/fs/procfs/procfs_dbregs.c | 2 +- sys/fs/procfs/procfs_fpregs.c | 2 +- sys/fs/procfs/procfs_mem.c | 2 +- sys/fs/procfs/procfs_regs.c | 2 +- sys/fs/procfs/procfs_status.c | 2 +- sys/fs/procfs/procfs_vnops.c | 4 ++-- sys/kern/kern_proc.c | 2 +- sys/kern/kern_prot.c | 25 +++++++++++++++++++++++++ sys/kern/kern_sig.c | 18 ++++++------------ sys/kern/sys_process.c | 3 +-- sys/miscfs/procfs/procfs.h | 13 ------------- sys/miscfs/procfs/procfs_dbregs.c | 2 +- sys/miscfs/procfs/procfs_fpregs.c | 2 +- sys/miscfs/procfs/procfs_mem.c | 2 +- sys/miscfs/procfs/procfs_regs.c | 2 +- sys/miscfs/procfs/procfs_status.c | 2 +- sys/miscfs/procfs/procfs_vnops.c | 4 ++-- sys/sys/proc.h | 1 + 19 files changed, 48 insertions(+), 55 deletions(-) (limited to 'sys') diff --git a/sys/fs/procfs/procfs.h b/sys/fs/procfs/procfs.h index bd6a554..1402a7c 100644 --- a/sys/fs/procfs/procfs.h +++ b/sys/fs/procfs/procfs.h @@ -90,19 +90,6 @@ struct pfsnode { #define KMEM_GROUP 2 -/* - * Check to see whether access to target process is allowed - * Evaluates to 1 if access is allowed. - */ -#define CHECKIO(p1, p2) \ - ((p1) == (p2) || \ - (PRISON_CHECK(p1, p2) && \ - ((((p1)->p_ucred->cr_uid == (p2)->p_cred->p_ruid) && \ - ((p1)->p_cred->p_ruid == (p2)->p_cred->p_ruid) && \ - ((p1)->p_cred->p_svuid == (p2)->p_cred->p_ruid) && \ - ((p2)->p_flag & P_SUGID) == 0) || \ - (suser_xxx(0, (p1), PRISON_ROOT) == 0)))) - #define PROCFS_FILENO(pid, type) \ (((type) < Pproc) ? \ ((type) + 2) : \ diff --git a/sys/fs/procfs/procfs_dbregs.c b/sys/fs/procfs/procfs_dbregs.c index ce990e9..0df1c3e 100644 --- a/sys/fs/procfs/procfs_dbregs.c +++ b/sys/fs/procfs/procfs_dbregs.c @@ -63,7 +63,7 @@ procfs_dodbregs(curp, p, pfs, uio) char *kv; int kl; - if (!CHECKIO(curp, p)) + if (p_trespass(curp, p)) return (EPERM); kl = sizeof(r); kv = (char *) &r; diff --git a/sys/fs/procfs/procfs_fpregs.c b/sys/fs/procfs/procfs_fpregs.c index b3331e5..d4a4cfe 100644 --- a/sys/fs/procfs/procfs_fpregs.c +++ b/sys/fs/procfs/procfs_fpregs.c @@ -60,7 +60,7 @@ procfs_dofpregs(curp, p, pfs, uio) char *kv; int kl; - if (!CHECKIO(curp, p)) + if (p_trespass(curp, p)) return EPERM; kl = sizeof(r); kv = (char *) &r; diff --git a/sys/fs/procfs/procfs_mem.c b/sys/fs/procfs/procfs_mem.c index 521bd5b..e075a7a 100644 --- a/sys/fs/procfs/procfs_mem.c +++ b/sys/fs/procfs/procfs_mem.c @@ -296,7 +296,7 @@ procfs_domem(curp, p, pfs, uio) * All in all, quite yucky. */ - if (!CHECKIO(curp, p) && + if (p_trespass(curp, p) && !(uio->uio_rw == UIO_READ && procfs_kmemaccess(curp))) return EPERM; diff --git a/sys/fs/procfs/procfs_regs.c b/sys/fs/procfs/procfs_regs.c index 0edb9ad..88f85d3 100644 --- a/sys/fs/procfs/procfs_regs.c +++ b/sys/fs/procfs/procfs_regs.c @@ -60,7 +60,7 @@ procfs_doregs(curp, p, pfs, uio) char *kv; int kl; - if (!CHECKIO(curp, p)) + if (p_trespass(curp, p)) return EPERM; kl = sizeof(r); kv = (char *) &r; diff --git a/sys/fs/procfs/procfs_status.c b/sys/fs/procfs/procfs_status.c index 0eb3858..e63a12b 100644 --- a/sys/fs/procfs/procfs_status.c +++ b/sys/fs/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) { + if (p->p_args && !p_trespass(curp, p)) { bp = p->p_args->ar_args; buflen = p->p_args->ar_length; buf = 0; diff --git a/sys/fs/procfs/procfs_vnops.c b/sys/fs/procfs/procfs_vnops.c index c579d73..17075db 100644 --- a/sys/fs/procfs/procfs_vnops.c +++ b/sys/fs/procfs/procfs_vnops.c @@ -146,7 +146,7 @@ procfs_open(ap) return (EBUSY); p1 = ap->a_p; - if (!CHECKIO(p1, p2) && + if (p_trespass(p1, p2) && !procfs_kmemaccess(p1)) return (EPERM); @@ -238,7 +238,7 @@ procfs_ioctl(ap) return ENOTTY; } - if (!CHECKIO(p, procp)) + if (p_trespass(p, procp)) return EPERM; switch (ap->a_command) { diff --git a/sys/kern/kern_proc.c b/sys/kern/kern_proc.c index 124bf02..e0f9ec1 100644 --- a/sys/kern/kern_proc.c +++ b/sys/kern/kern_proc.c @@ -633,7 +633,7 @@ sysctl_kern_proc_args SYSCTL_HANDLER_ARGS if (!p) return (0); - if (!PRISON_CHECK(curproc, p)) + if (p_trespass(curproc, p)) return (0); if (req->newptr && curproc != p) diff --git a/sys/kern/kern_prot.c b/sys/kern/kern_prot.c index 63d4346..1611cc3 100644 --- a/sys/kern/kern_prot.c +++ b/sys/kern/kern_prot.c @@ -793,6 +793,31 @@ suser_xxx(cred, proc, flag) } /* + * Return zero if p1 can fondle p2, return errno (EPERM/ESRCH) otherwise. + */ + +int +p_trespass(struct proc *p1, struct proc *p2) +{ + + if (p1 == p2) + return (0); + if (!PRISON_CHECK(p1, p2)) + return (ESRCH); + if (p1->p_cred->p_ruid == p2->p_cred->p_ruid) + return (0); + if (p1->p_ucred->cr_uid == p2->p_cred->p_ruid) + return (0); + if (p1->p_cred->p_ruid == p2->p_ucred->cr_uid) + return (0); + if (p1->p_ucred->cr_uid == p2->p_ucred->cr_uid) + return (0); + if (!suser_xxx(0, p1, PRISON_ROOT)) + return (0); + return (EPERM); +} + +/* * Allocate a zeroed cred structure. */ struct ucred * diff --git a/sys/kern/kern_sig.c b/sys/kern/kern_sig.c index a7b6499..cf27029 100644 --- a/sys/kern/kern_sig.c +++ b/sys/kern/kern_sig.c @@ -88,13 +88,9 @@ SYSCTL_INT(_kern, KERN_LOGSIGEXIT, logsigexit, CTLFLAG_RW, /* * Can process p, with pcred pc, send the signal sig to process q? */ -#define CANSIGNAL(p, pc, q, sig) \ - (PRISON_CHECK(p, q) && ((pc)->pc_ucred->cr_uid == 0 || \ - (pc)->p_ruid == (q)->p_cred->p_ruid || \ - (pc)->pc_ucred->cr_uid == (q)->p_cred->p_ruid || \ - (pc)->p_ruid == (q)->p_ucred->cr_uid || \ - (pc)->pc_ucred->cr_uid == (q)->p_ucred->cr_uid || \ - ((sig) == SIGCONT && (q)->p_session == (p)->p_session))) +#define CANSIGNAL(p, q, sig) \ + (!p_trespass(p, q) || \ + ((sig) == SIGCONT && (q)->p_session == (p)->p_session)) /* * Policy -- Can real uid ruid with ucred uc send a signal to process q? @@ -799,7 +795,6 @@ killpg1(cp, sig, pgid, all) int sig, pgid, all; { register struct proc *p; - register struct pcred *pc = cp->p_cred; struct pgrp *pgrp; int nfound = 0; @@ -809,7 +804,7 @@ killpg1(cp, sig, pgid, all) */ LIST_FOREACH(p, &allproc, p_list) { if (p->p_pid <= 1 || p->p_flag & P_SYSTEM || - p == cp || !CANSIGNAL(cp, pc, p, sig)) + p == cp || !CANSIGNAL(cp, p, sig)) continue; nfound++; if (sig) @@ -829,7 +824,7 @@ killpg1(cp, sig, pgid, all) LIST_FOREACH(p, &pgrp->pg_members, p_pglist) { if (p->p_pid <= 1 || p->p_flag & P_SYSTEM || p->p_stat == SZOMB || - !CANSIGNAL(cp, pc, p, sig)) + !CANSIGNAL(cp, p, sig)) continue; nfound++; if (sig) @@ -852,7 +847,6 @@ kill(cp, uap) register struct kill_args *uap; { register struct proc *p; - register struct pcred *pc = cp->p_cred; if ((u_int)uap->signum > _SIG_MAXSIG) return (EINVAL); @@ -860,7 +854,7 @@ kill(cp, uap) /* kill single process */ if ((p = pfind(uap->pid)) == NULL) return (ESRCH); - if (!CANSIGNAL(cp, pc, p, uap->signum)) + if (!CANSIGNAL(cp, p, uap->signum)) return (EPERM); if (uap->signum) psignal(p, uap->signum); diff --git a/sys/kern/sys_process.c b/sys/kern/sys_process.c index 75b72fb..4740476 100644 --- a/sys/kern/sys_process.c +++ b/sys/kern/sys_process.c @@ -420,8 +420,7 @@ ptrace(curp, uap) return EFAULT; } if (ptrace_read_u_check(p,(vm_offset_t) uap->addr, - sizeof(int)) && - !procfs_kmemaccess(curp)) { + sizeof(int))) { return EFAULT; } error = 0; diff --git a/sys/miscfs/procfs/procfs.h b/sys/miscfs/procfs/procfs.h index bd6a554..1402a7c 100644 --- a/sys/miscfs/procfs/procfs.h +++ b/sys/miscfs/procfs/procfs.h @@ -90,19 +90,6 @@ struct pfsnode { #define KMEM_GROUP 2 -/* - * Check to see whether access to target process is allowed - * Evaluates to 1 if access is allowed. - */ -#define CHECKIO(p1, p2) \ - ((p1) == (p2) || \ - (PRISON_CHECK(p1, p2) && \ - ((((p1)->p_ucred->cr_uid == (p2)->p_cred->p_ruid) && \ - ((p1)->p_cred->p_ruid == (p2)->p_cred->p_ruid) && \ - ((p1)->p_cred->p_svuid == (p2)->p_cred->p_ruid) && \ - ((p2)->p_flag & P_SUGID) == 0) || \ - (suser_xxx(0, (p1), PRISON_ROOT) == 0)))) - #define PROCFS_FILENO(pid, type) \ (((type) < Pproc) ? \ ((type) + 2) : \ diff --git a/sys/miscfs/procfs/procfs_dbregs.c b/sys/miscfs/procfs/procfs_dbregs.c index ce990e9..0df1c3e 100644 --- a/sys/miscfs/procfs/procfs_dbregs.c +++ b/sys/miscfs/procfs/procfs_dbregs.c @@ -63,7 +63,7 @@ procfs_dodbregs(curp, p, pfs, uio) char *kv; int kl; - if (!CHECKIO(curp, p)) + if (p_trespass(curp, p)) 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 b3331e5..d4a4cfe 100644 --- a/sys/miscfs/procfs/procfs_fpregs.c +++ b/sys/miscfs/procfs/procfs_fpregs.c @@ -60,7 +60,7 @@ procfs_dofpregs(curp, p, pfs, uio) char *kv; int kl; - if (!CHECKIO(curp, p)) + if (p_trespass(curp, p)) 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 521bd5b..e075a7a 100644 --- a/sys/miscfs/procfs/procfs_mem.c +++ b/sys/miscfs/procfs/procfs_mem.c @@ -296,7 +296,7 @@ procfs_domem(curp, p, pfs, uio) * All in all, quite yucky. */ - if (!CHECKIO(curp, p) && + if (p_trespass(curp, p) && !(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 0edb9ad..88f85d3 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 (!CHECKIO(curp, p)) + if (p_trespass(curp, p)) 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 0eb3858..e63a12b 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) { + if (p->p_args && !p_trespass(curp, p)) { 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 c579d73..17075db 100644 --- a/sys/miscfs/procfs/procfs_vnops.c +++ b/sys/miscfs/procfs/procfs_vnops.c @@ -146,7 +146,7 @@ procfs_open(ap) return (EBUSY); p1 = ap->a_p; - if (!CHECKIO(p1, p2) && + if (p_trespass(p1, p2) && !procfs_kmemaccess(p1)) return (EPERM); @@ -238,7 +238,7 @@ procfs_ioctl(ap) return ENOTTY; } - if (!CHECKIO(p, procp)) + if (p_trespass(p, procp)) return EPERM; switch (ap->a_command) { diff --git a/sys/sys/proc.h b/sys/sys/proc.h index 9373d5d..6b1ae41 100644 --- a/sys/sys/proc.h +++ b/sys/sys/proc.h @@ -399,6 +399,7 @@ int inferior __P((struct proc *p)); int leavepgrp __P((struct proc *p)); void mi_switch __P((void)); void procinit __P((void)); +int p_trespass __P((struct proc *p1, struct proc *p2)); void resetpriority __P((struct proc *)); int roundrobin_interval __P((void)); void setrunnable __P((struct proc *)); -- cgit v1.1