svn commit: r357452 - in head/sys: kern sys
Mateusz Guzik
mjg at FreeBSD.org
Mon Feb 3 17:08:12 UTC 2020
Author: mjg
Date: Mon Feb 3 17:08:11 2020
New Revision: 357452
URL: https://svnweb.freebsd.org/changeset/base/357452
Log:
capsicum: faster cap_rights_contains
Instead of doing a 2 iteration loop (determined at runeimt), take advantage
of the fact that the size is already known.
While here provdie cap_check_inline so that fget_unlocked does not have to
do a function call.
Verified with the capsicum suite /usr/tests.
Modified:
head/sys/kern/kern_descrip.c
head/sys/kern/subr_capability.c
head/sys/kern/sys_capability.c
head/sys/sys/capsicum.h
Modified: head/sys/kern/kern_descrip.c
==============================================================================
--- head/sys/kern/kern_descrip.c Mon Feb 3 17:06:21 2020 (r357451)
+++ head/sys/kern/kern_descrip.c Mon Feb 3 17:08:11 2020 (r357452)
@@ -2724,7 +2724,7 @@ fget_unlocked(struct filedesc *fdp, int fd, cap_rights
if (fp == NULL)
return (EBADF);
#ifdef CAPABILITIES
- error = cap_check(&haverights, needrightsp);
+ error = cap_check_inline(&haverights, needrightsp);
if (error != 0)
return (error);
#endif
Modified: head/sys/kern/subr_capability.c
==============================================================================
--- head/sys/kern/subr_capability.c Mon Feb 3 17:06:21 2020 (r357451)
+++ head/sys/kern/subr_capability.c Mon Feb 3 17:08:11 2020 (r357452)
@@ -394,25 +394,3 @@ cap_rights_remove(cap_rights_t *dst, const cap_rights_
return (dst);
}
-
-bool
-cap_rights_contains(const cap_rights_t *big, const cap_rights_t *little)
-{
- unsigned int i, n;
-
- assert(CAPVER(big) == CAP_RIGHTS_VERSION_00);
- assert(CAPVER(little) == CAP_RIGHTS_VERSION_00);
- assert(CAPVER(big) == CAPVER(little));
-
- n = CAPARSIZE(big);
- assert(n >= CAPARSIZE_MIN && n <= CAPARSIZE_MAX);
-
- for (i = 0; i < n; i++) {
- if ((big->cr_rights[i] & little->cr_rights[i]) !=
- little->cr_rights[i]) {
- return (false);
- }
- }
-
- return (true);
-}
Modified: head/sys/kern/sys_capability.c
==============================================================================
--- head/sys/kern/sys_capability.c Mon Feb 3 17:06:21 2020 (r357451)
+++ head/sys/kern/sys_capability.c Mon Feb 3 17:08:11 2020 (r357452)
@@ -179,6 +179,17 @@ cap_check(const cap_rights_t *havep, const cap_rights_
return (_cap_check(havep, needp, CAPFAIL_NOTCAPABLE));
}
+int
+cap_check_failed_notcapable(const cap_rights_t *havep, const cap_rights_t *needp)
+{
+
+#ifdef KTRACE
+ if (KTRPOINT(curthread, KTR_CAPFAIL))
+ ktrcapfail(CAPFAIL_NOTCAPABLE, needp, havep);
+#endif
+ return (ENOTCAPABLE);
+}
+
/*
* Convert capability rights into VM access flags.
*/
Modified: head/sys/sys/capsicum.h
==============================================================================
--- head/sys/sys/capsicum.h Mon Feb 3 17:06:21 2020 (r357451)
+++ head/sys/sys/capsicum.h Mon Feb 3 17:08:11 2020 (r357452)
@@ -342,8 +342,37 @@ bool __cap_rights_is_set(const cap_rights_t *rights, .
bool cap_rights_is_valid(const cap_rights_t *rights);
cap_rights_t *cap_rights_merge(cap_rights_t *dst, const cap_rights_t *src);
cap_rights_t *cap_rights_remove(cap_rights_t *dst, const cap_rights_t *src);
-bool cap_rights_contains(const cap_rights_t *big, const cap_rights_t *little);
void __cap_rights_sysinit(void *arg);
+
+
+/*
+ * We only support one size to reduce branching.
+ */
+_Static_assert(CAP_RIGHTS_VERSION == CAP_RIGHTS_VERSION_00,
+ "unsupported version of capsicum rights");
+
+static inline bool
+cap_rights_contains(const cap_rights_t *big, const cap_rights_t *little)
+{
+
+ if (__predict_true(
+ (big->cr_rights[0] & little->cr_rights[0]) == little->cr_rights[0] &&
+ (big->cr_rights[1] & little->cr_rights[1]) == little->cr_rights[1]))
+ return (true);
+ return (false);
+}
+
+int cap_check_failed_notcapable(const cap_rights_t *havep,
+ const cap_rights_t *needp);
+
+static inline int
+cap_check_inline(const cap_rights_t *havep, const cap_rights_t *needp)
+{
+
+ if (__predict_false(!cap_rights_contains(havep, needp)))
+ return (cap_check_failed_notcapable(havep, needp));
+ return (0);
+}
__END_DECLS
struct cap_rights_init_args {
More information about the svn-src-all
mailing list