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:
@@ -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
|
||||
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user