From bc789426588ddba4ca5881e62efde2a84ba10e9d Mon Sep 17 00:00:00 2001 From: rwatson Date: Tue, 18 Sep 2001 21:03:53 +0000 Subject: [PATCH] o Introduce two new calls, securelevel_gt() and securelevel_ge(), which abstract the securelevel implementation details from the checking code. The call in -CURRENT accepts a struct ucred--in -STABLE, it will accept struct proc. This facilitates the upcoming commit of per-jail securelevel support. The calls will also generate a kernel printf if the calls are made with NULL ucred/proc pointers: generally speaking, there are few instances of this, and they should be fixed. o Update p_candebug() to use securelevel_gt(); future updates to the remainder of the kernel tree will be committed soon. Obtained from: TrustedBSD Project --- sys/kern/kern_prot.c | 60 +++++++++++++++++++++++++++++++++++++++++--- sys/sys/proc.h | 2 ++ 2 files changed, 59 insertions(+), 3 deletions(-) diff --git a/sys/kern/kern_prot.c b/sys/kern/kern_prot.c index 0c2939c44dbb..d8cb8491b6db 100644 --- a/sys/kern/kern_prot.c +++ b/sys/kern/kern_prot.c @@ -1299,6 +1299,57 @@ suser_xxx(cred, proc, flag) return (0); } + +/* + * Test securelevel values against passed required securelevel. + * _gt implements (level > securelevel), _ge implements (level <= + * securelevel). Returns 0 or EPERM. + * + * cr is permitted to be NULL for the time being, as there were some + * existing securelevel checks that occurred without a process/credential + * context. In the future this will be disallowed, so a kernel + * message is displayed. + * + * XXX: The redundant construction below is to facilitate the merging + * of support for per-jail securelevels, which maintain a local + * jail securelevel in the process credential. + */ +int +securelevel_gt(struct ucred *cr, int level) +{ + + if (cr == NULL) { + printf("securelevel_gt: cr is NULL\n"); + if (securelevel > level) + return (0); + else + return (EPERM); + } else { + if (securelevel > level) + return (0); + else + return (EPERM); + } +} + +int +securelevel_ge(struct ucred *cr, int level) +{ + + if (cr == NULL) { + printf("securelevel_ge: cr is NULL\n"); + if (securelevel >= level) + return (0); + else + return (EPERM); + } else { + if (securelevel >= level) + return (0); + else + return (EPERM); + } +} + /*- * Determine if u1 "can see" the subject specified by u2. * Returns: 0 for permitted, an errno value otherwise @@ -1491,9 +1542,12 @@ p_candebug(struct proc *p1, struct proc *p2) return (error); } - /* Can't trace init when securelevel > 0. */ - if (securelevel > 0 && p2->p_pid == 1) - return (EPERM); + /* can't trace init when securelevel > 0 */ + if (p2->p_pid == 1) { + error = securelevel_gt(p1->p_ucred, 0); + if (error) + return (error); + } return (0); } diff --git a/sys/sys/proc.h b/sys/sys/proc.h index 0a7608a97fe9..ff598f05096d 100644 --- a/sys/sys/proc.h +++ b/sys/sys/proc.h @@ -676,6 +676,8 @@ void remrunqueue __P((struct thread *)); void resetpriority __P((struct ksegrp *)); int roundrobin_interval __P((void)); void schedclock __P((struct thread *)); +int securelevel_ge __P((struct ucred *cr, int level)); +int securelevel_gt __P((struct ucred *cr, int level)); void setrunnable __P((struct thread *)); void setrunqueue __P((struct thread *)); void setsugid __P((struct proc *p));