git: a7100ae23aca - main - capsicum: introduce cap_rights_is_empty Function
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Mon, 11 Dec 2023 11:17:45 UTC
The branch main has been updated by oshogbo: URL: https://cgit.FreeBSD.org/src/commit/?id=a7100ae23aca07976926bd8d50223c45149f65d6 commit a7100ae23aca07976926bd8d50223c45149f65d6 Author: Mariusz Zaborski <oshogbo@FreeBSD.org> AuthorDate: 2023-12-11 11:09:31 +0000 Commit: Mariusz Zaborski <oshogbo@FreeBSD.org> CommitDate: 2023-12-11 11:15:46 +0000 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 --- contrib/capsicum-test/capability-fd.cc | 15 +++++++++++++++ lib/libc/capability/Symbol.map | 4 ++++ lib/libc/capability/cap_rights_init.3 | 19 ++++++++++++++++++- sys/kern/subr_capability.c | 19 +++++++++++++++++++ sys/sys/capsicum.h | 2 ++ 5 files changed, 58 insertions(+), 1 deletion(-) 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 @@ -306,6 +306,25 @@ __cap_rights_is_set(const cap_rights_t *rights, ...) return (ret); } +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) { diff --git a/sys/sys/capsicum.h b/sys/sys/capsicum.h index b9eb61409613..3979fd718909 100644 --- a/sys/sys/capsicum.h +++ b/sys/sys/capsicum.h @@ -336,6 +336,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);