aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMariusz Zaborski <oshogbo@FreeBSD.org>2023-12-11 11:09:31 +0000
committerEd Maste <emaste@FreeBSD.org>2024-06-05 15:55:17 +0000
commite77813f7e4a32be5d0278c5cb38bcc0a759025d0 (patch)
tree70844d09ae182eda7bb3231f787f844df60155d0
parent91badda4a2ddf243b654269c0689d748557d2be1 (diff)
downloadsrc-e77813f7e4a32be5d0278c5cb38bcc0a759025d0.tar.gz
src-e77813f7e4a32be5d0278c5cb38bcc0a759025d0.zip
capsicum: introduce cap_rights_is_empty Function
Before this commit, we only had the capability to check if a specific capability was set (using cap_rights_is_set function). However, there was no efficient method to determine if a cap_rights_t structure doesn't contain any capability. The cap_rights_is_empty function addresses this gap. PR: 275330 Reported by: vini.ipsmaker@gmail.com Reviewed by: emaste, markj Differential Revision: https://reviews.freebsd.org/D42780 (cherry picked from commit a7100ae23aca07976926bd8d50223c45149f65d6)
-rw-r--r--contrib/capsicum-test/capability-fd.cc15
-rw-r--r--lib/libc/capability/Symbol.map4
-rw-r--r--lib/libc/capability/cap_rights_init.319
-rw-r--r--sys/kern/subr_capability.c19
-rw-r--r--sys/sys/capsicum.h2
5 files changed, 58 insertions, 1 deletions
diff --git a/contrib/capsicum-test/capability-fd.cc b/contrib/capsicum-test/capability-fd.cc
index f255c6425cdd..0551d9bd81ef 100644
--- a/contrib/capsicum-test/capability-fd.cc
+++ b/contrib/capsicum-test/capability-fd.cc
@@ -1342,3 +1342,18 @@ TEST(Capability, NoBypassDACIfRoot) {
close(fd);
unlink(TmpFile("cap_root_owned"));
}
+
+TEST(Capability, CheckIsEmpty) {
+ cap_rights_t rights;
+
+ cap_rights_init(&rights);
+ EXPECT_TRUE(cap_rights_is_empty(&rights));
+
+ size_t num_known = (sizeof(known_rights)/sizeof(known_rights[0]));
+ for (size_t ii = 0; ii < num_known; ii++) {
+ cap_rights_init(&rights, known_rights[ii].right);
+ EXPECT_FALSE(cap_rights_is_empty(&rights));
+ cap_rights_clear(&rights, known_rights[ii].right);
+ EXPECT_TRUE(cap_rights_is_empty(&rights));
+ }
+}
diff --git a/lib/libc/capability/Symbol.map b/lib/libc/capability/Symbol.map
index 0deff024a046..8bf11670a5a8 100644
--- a/lib/libc/capability/Symbol.map
+++ b/lib/libc/capability/Symbol.map
@@ -8,3 +8,7 @@ FBSD_1.3 {
cap_rights_remove;
__cap_rights_set;
};
+
+FBSD_1.8 {
+ cap_rights_is_empty;
+};
diff --git a/lib/libc/capability/cap_rights_init.3 b/lib/libc/capability/cap_rights_init.3
index 80b522820097..98b50f653f2c 100644
--- a/lib/libc/capability/cap_rights_init.3
+++ b/lib/libc/capability/cap_rights_init.3
@@ -25,7 +25,7 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.Dd May 5, 2020
+.Dd November 25, 2023
.Dt CAP_RIGHTS_INIT 3
.Os
.Sh NAME
@@ -33,6 +33,7 @@
.Nm cap_rights_set ,
.Nm cap_rights_clear ,
.Nm cap_rights_is_set ,
+.Nm cap_rights_is_empty ,
.Nm cap_rights_is_valid ,
.Nm cap_rights_merge ,
.Nm cap_rights_remove ,
@@ -51,6 +52,8 @@
.Ft bool
.Fn cap_rights_is_set "const cap_rights_t *rights" "..."
.Ft bool
+.Fn cap_rights_is_empty "const cap_rights_t *rights"
+.Ft bool
.Fn cap_rights_is_valid "const cap_rights_t *rights"
.Ft cap_rights_t *
.Fn cap_rights_merge "cap_rights_t *dst" "const cap_rights_t *src"
@@ -118,6 +121,12 @@ function checks if all the given capability rights are set for the given
structure.
.Pp
The
+.Fn cap_rights_is_empty
+function checks if the
+.Fa rights
+structure is empty.
+.Pp
+The
.Fn cap_rights_is_valid
function verifies if the given
.Vt cap_rights_t
@@ -182,6 +191,14 @@ if all the given capability rights are set in the
argument.
.Pp
The
+.Fn cap_rights_is_empty
+function returns
+.Va true
+if none of the capability rights are set in the
+.Fa rights
+structure.
+.Pp
+The
.Fn cap_rights_is_valid
function performs various checks to see if the given
.Vt cap_rights_t
diff --git a/sys/kern/subr_capability.c b/sys/kern/subr_capability.c
index e40c57c5307d..1f3a181a91cb 100644
--- a/sys/kern/subr_capability.c
+++ b/sys/kern/subr_capability.c
@@ -307,6 +307,25 @@ __cap_rights_is_set(const cap_rights_t *rights, ...)
}
bool
+cap_rights_is_empty(const cap_rights_t *rights)
+{
+#ifndef _KERNEL
+ cap_rights_t cap_no_rights;
+ cap_rights_init(&cap_no_rights);
+#endif
+
+ assert(CAPVER(rights) == CAP_RIGHTS_VERSION_00);
+ assert(CAPVER(&cap_no_rights) == CAP_RIGHTS_VERSION_00);
+
+ for (int i = 0; i < CAPARSIZE(rights); i++) {
+ if (rights->cr_rights[i] != cap_no_rights.cr_rights[i])
+ return (false);
+ }
+
+ return (true);
+}
+
+bool
cap_rights_is_valid(const cap_rights_t *rights)
{
cap_rights_t allrights;
diff --git a/sys/sys/capsicum.h b/sys/sys/capsicum.h
index e2f305462f0d..405a7af419bf 100644
--- a/sys/sys/capsicum.h
+++ b/sys/sys/capsicum.h
@@ -337,6 +337,8 @@ cap_rights_t *__cap_rights_clear(cap_rights_t *rights, ...);
__cap_rights_is_set(__VA_ARGS__, 0ULL)
bool __cap_rights_is_set(const cap_rights_t *rights, ...);
+bool cap_rights_is_empty(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);