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;
|
using BKernel::Team;
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// kernel private functions
|
// kernel private functions
|
||||||
|
|
||||||
void inherit_parent_user_and_group(Team* team, Team* parent);
|
void inherit_parent_user_and_group(Team* team, Team* parent);
|
||||||
status_t update_set_id_user_and_group(Team* team, const char* file);
|
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
|
// syscalls
|
||||||
|
|
||||||
|
|||||||
@@ -51,6 +51,7 @@
|
|||||||
#include <syscalls.h>
|
#include <syscalls.h>
|
||||||
#include <syscall_restart.h>
|
#include <syscall_restart.h>
|
||||||
#include <tracing.h>
|
#include <tracing.h>
|
||||||
|
#include <usergroup.h>
|
||||||
#include <util/atomic.h>
|
#include <util/atomic.h>
|
||||||
#include <util/AutoLock.h>
|
#include <util/AutoLock.h>
|
||||||
#include <util/ThreadAutoLock.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
|
static status_t
|
||||||
free_io_context(io_context* context)
|
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) {
|
} else if (uid == nodeUserID) {
|
||||||
// user is node owner
|
// user is node owner
|
||||||
permissions = userPermissions;
|
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
|
// user is in owning group
|
||||||
permissions = groupPermissions;
|
permissions = groupPermissions;
|
||||||
} else {
|
} 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)
|
common_getgroups(int groupCount, gid_t* groupList, bool kernel)
|
||||||
{
|
{
|
||||||
Team* team = thread_get_current_thread()->team;
|
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
|
gid_t
|
||||||
_kern_getgid(bool effective)
|
_kern_getgid(bool effective)
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user