kernel: Add is_in_group(Team*) private utility method and use it in the VFS.

Slightly more efficient than using getegid() and getgroups().

While at it, make the user-group utility methods C++-only.
This commit is contained in:
Augustin Cavalier
2025-07-07 15:02:17 -04:00
parent 8e086795b2
commit 7ed202f9ed
3 changed files with 29 additions and 23 deletions
+6 -4
View File
@@ -18,14 +18,16 @@ namespace BKernel {
using BKernel::Team;
#ifdef __cplusplus
extern "C" {
#endif
// kernel private functions
void inherit_parent_user_and_group(Team* team, Team* parent);
status_t update_set_id_user_and_group(Team* team, const char* file);
bool is_in_group(Team* team, gid_t gid);
#ifdef __cplusplus
extern "C" {
#endif
// syscalls
+2 -18
View File
@@ -51,6 +51,7 @@
#include <syscalls.h>
#include <syscall_restart.h>
#include <tracing.h>
#include <usergroup.h>
#include <util/atomic.h>
#include <util/AutoLock.h>
#include <util/ThreadAutoLock.h>
@@ -3622,23 +3623,6 @@ common_file_io_vec_pages(struct vnode* vnode, void* cookie,
}
static bool
is_user_in_group(gid_t gid)
{
if (gid == getegid())
return true;
gid_t groups[NGROUPS_MAX];
int groupCount = getgroups(NGROUPS_MAX, groups);
for (int i = 0; i < groupCount; i++) {
if (gid == groups[i])
return true;
}
return false;
}
static status_t
free_io_context(io_context* context)
{
@@ -4011,7 +3995,7 @@ check_access_permissions(int accessMode, mode_t mode, gid_t nodeGroupID,
} else if (uid == nodeUserID) {
// user is node owner
permissions = userPermissions;
} else if (is_user_in_group(nodeGroupID)) {
} else if (is_in_group(thread_get_current_thread()->team, nodeGroupID)) {
// user is in owning group
permissions = groupPermissions;
} else {
+21 -1
View File
@@ -162,7 +162,7 @@ common_setreuid(uid_t ruid, uid_t euid, bool setAllIfPrivileged, bool kernel)
}
ssize_t
static ssize_t
common_getgroups(int groupCount, gid_t* groupList, bool kernel)
{
Team* team = thread_get_current_thread()->team;
@@ -288,6 +288,26 @@ update_set_id_user_and_group(Team* team, const char* file)
}
bool
is_in_group(Team* team, gid_t gid)
{
TeamLocker teamLocker(team);
if (team->effective_gid == gid)
return true;
if (team->supplementary_groups == NULL)
return false;
for (int i = 0; i < team->supplementary_groups->count; i++) {
if (gid == team->supplementary_groups->groups[i])
return true;
}
return false;
}
gid_t
_kern_getgid(bool effective)
{