Date: Thu, 13 Feb 2020 22:19:18 +0000 (UTC) From: Mateusz Guzik <mjg@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r357887 - head/sys/security/mac Message-ID: <202002132219.01DMJIq4059919@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: mjg Date: Thu Feb 13 22:19:17 2020 New Revision: 357887 URL: https://svnweb.freebsd.org/changeset/base/357887 Log: mac: implement fast path for checks All checking routines walk a linked list of all modules in order to determine if given hook is installed. This became a significant problem after mac_ntpd started being loaded by default. Implement a way perform checks for select hooks by testing a boolean. Use it for priv_check and priv_grant, which are constantly called from priv_check. The real fix would use hotpatching, but the above provides a way to know when to do it. Modified: head/sys/security/mac/mac_framework.c head/sys/security/mac/mac_framework.h head/sys/security/mac/mac_priv.c Modified: head/sys/security/mac/mac_framework.c ============================================================================== --- head/sys/security/mac/mac_framework.c Thu Feb 13 22:16:30 2020 (r357886) +++ head/sys/security/mac/mac_framework.c Thu Feb 13 22:19:17 2020 (r357887) @@ -118,6 +118,17 @@ SYSCTL_UINT(_security_mac, OID_AUTO, version, CTLFLAG_ ""); /* + * Flags for inlined checks. + */ +#define FPFLAG(f) \ +bool __read_frequently mac_##f##_fp_flag + +FPFLAG(priv_check); +FPFLAG(priv_grant); + +#undef FPFLAG + +/* * Labels consist of a indexed set of "slots", which are allocated policies * as required. The MAC Framework maintains a bitmask of slots allocated so * far to prevent reuse. Slots cannot be reused, as the MAC Framework @@ -376,6 +387,84 @@ mac_policy_update(void) } } +/* + * There are frequently used code paths which check for rarely installed + * policies. Gross hack below enables doing it in a cheap manner. + */ + +#define FPO(f) (offsetof(struct mac_policy_ops, mpo_##f) / sizeof(uintptr_t)) + +struct mac_policy_fastpath_elem { + int count; + bool *flag; + size_t offset; +}; + +struct mac_policy_fastpath_elem mac_policy_fastpath_array[] = { + { .offset = FPO(priv_check), .flag = &mac_priv_check_fp_flag }, + { .offset = FPO(priv_grant), .flag = &mac_priv_grant_fp_flag }, +}; + +static void +mac_policy_fastpath_enable(struct mac_policy_fastpath_elem *mpfe) +{ + + MPASS(mpfe->count >= 0); + mpfe->count++; + if (mpfe->count == 1) { + MPASS(*mpfe->flag == false); + *mpfe->flag = true; + } +} + +static void +mac_policy_fastpath_disable(struct mac_policy_fastpath_elem *mpfe) +{ + + MPASS(mpfe->count >= 1); + mpfe->count--; + if (mpfe->count == 0) { + MPASS(*mpfe->flag == true); + *mpfe->flag = false; + } +} + +static void +mac_policy_fastpath_register(struct mac_policy_conf *mpc) +{ + struct mac_policy_fastpath_elem *mpfe; + uintptr_t **ops; + int i; + + mac_policy_xlock_assert(); + + ops = (uintptr_t **)mpc->mpc_ops; + for (i = 0; i < nitems(mac_policy_fastpath_array); i++) { + mpfe = &mac_policy_fastpath_array[i]; + if (ops[mpfe->offset] != NULL) + mac_policy_fastpath_enable(mpfe); + } +} + +static void +mac_policy_fastpath_unregister(struct mac_policy_conf *mpc) +{ + struct mac_policy_fastpath_elem *mpfe; + uintptr_t **ops; + int i; + + mac_policy_xlock_assert(); + + ops = (uintptr_t **)mpc->mpc_ops; + for (i = 0; i < nitems(mac_policy_fastpath_array); i++) { + mpfe = &mac_policy_fastpath_array[i]; + if (ops[mpfe->offset] != NULL) + mac_policy_fastpath_disable(mpfe); + } +} + +#undef FPO + static int mac_policy_register(struct mac_policy_conf *mpc) { @@ -446,6 +535,9 @@ mac_policy_register(struct mac_policy_conf *mpc) */ if (mpc->mpc_ops->mpo_init != NULL) (*(mpc->mpc_ops->mpo_init))(mpc); + + mac_policy_fastpath_register(mpc); + mac_policy_update(); SDT_PROBE1(mac, , policy, register, mpc); @@ -487,6 +579,9 @@ mac_policy_unregister(struct mac_policy_conf *mpc) mac_policy_xunlock(); return (EBUSY); } + + mac_policy_fastpath_unregister(mpc); + if (mpc->mpc_ops->mpo_destroy != NULL) (*(mpc->mpc_ops->mpo_destroy))(mpc); Modified: head/sys/security/mac/mac_framework.h ============================================================================== --- head/sys/security/mac/mac_framework.h Thu Feb 13 22:16:30 2020 (r357886) +++ head/sys/security/mac/mac_framework.h Thu Feb 13 22:19:17 2020 (r357887) @@ -258,8 +258,27 @@ void mac_posixshm_create(struct ucred *cred, struct s void mac_posixshm_destroy(struct shmfd *); void mac_posixshm_init(struct shmfd *); -int mac_priv_check(struct ucred *cred, int priv); -int mac_priv_grant(struct ucred *cred, int priv); +int mac_priv_check_impl(struct ucred *cred, int priv); +extern bool mac_priv_check_fp_flag; +static inline int +mac_priv_check(struct ucred *cred, int priv) +{ + + if (__predict_false(mac_priv_check_fp_flag)) + return (mac_priv_check_impl(cred, priv)); + return (0); +} + +int mac_priv_grant_impl(struct ucred *cred, int priv); +extern bool mac_priv_grant_fp_flag; +static inline int +mac_priv_grant(struct ucred *cred, int priv) +{ + + if (__predict_false(mac_priv_grant_fp_flag)) + return (mac_priv_grant_impl(cred, priv)); + return (EPERM); +} int mac_proc_check_debug(struct ucred *cred, struct proc *p); int mac_proc_check_sched(struct ucred *cred, struct proc *p); Modified: head/sys/security/mac/mac_priv.c ============================================================================== --- head/sys/security/mac/mac_priv.c Thu Feb 13 22:16:30 2020 (r357886) +++ head/sys/security/mac/mac_priv.c Thu Feb 13 22:19:17 2020 (r357887) @@ -67,7 +67,7 @@ MAC_CHECK_PROBE_DEFINE2(priv_check, "struct ucred *", * policy denies access. */ int -mac_priv_check(struct ucred *cred, int priv) +mac_priv_check_impl(struct ucred *cred, int priv) { int error; @@ -84,7 +84,7 @@ MAC_GRANT_PROBE_DEFINE2(priv_grant, "struct ucred *", * policy grants access. */ int -mac_priv_grant(struct ucred *cred, int priv) +mac_priv_grant_impl(struct ucred *cred, int priv) { int error;
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202002132219.01DMJIq4059919>