From: Lunaixsky Date: Sun, 30 Mar 2025 20:19:38 +0000 (+0100) Subject: syscalls: chroot, fchmodat, fchownat, faccessat X-Git-Url: https://scm.lunaixsky.com/lunaix-os.git/commitdiff_plain/b297c96099a08a9f2b7e20e80a8f43515fabd714?hp=5f4f16c074be65639b5c3333441d48b1d418104c syscalls: chroot, fchmodat, fchownat, faccessat enable access check in path walker add default directory permission for ramfs and devfs --- diff --git a/README.md b/README.md index 5dc1656..c4a4ea9 100644 --- a/README.md +++ b/README.md @@ -282,22 +282,22 @@ As a personal challenge, this project is independently developed by the author s 2. `mkdir(2)` 2. `lseek(2)` 2. `readdir(2)` -2. `readlink(2)`※ -2. `readlinkat(2)`※ -2. `rmdir(2)`※ -2. `unlink(2)`※ -2. `unlinkat(2)`※ -2. `link(2)`※ -2. `fsync(2)`※ +2. `readlink(2)` +2. `readlinkat(2)` +2. `rmdir(2)` +2. `unlink(2)` +2. `unlinkat(2)` +2. `link(2)` +2. `fsync(2)` 2. `dup(2)` 2. `dup2(2)` -2. `symlink(2)`※ +2. `symlink(2)` 2. `chdir(2)` 2. `fchdir(2)` 2. `getcwd(2)` 2. `rename(2)`※ 2. `mount(2)` -2. `unmount` (a.k.a `umount(2)`)※ +2. `unmount` (a.k.a `umount(2)`) 2. `getxattr(2)`※ 2. `setxattr(2)`※ 2. `fgetxattr(2)`※ @@ -319,6 +319,20 @@ As a personal challenge, this project is independently developed by the author s 4. `pthread_kill` 4. `pthread_detach` 4. `pthread_sigmask` +4. `getuid` +4. `getgid` +4. `geteuid` +4. `getegid` +4. `getgroups` +4. `setuid` +4. `setgid` +4. `seteuid` +4. `setegid` +4. `setgroups` +4. `chroot` +4. `fchmodat` +4. `fchownat` +4. `faccessat` **LunaixOS** diff --git a/lunaix-os/arch/generic/includes/asm-generic/syscall_nr.inc b/lunaix-os/arch/generic/includes/asm-generic/syscall_nr.inc index 7590c4b..0da2e62 100644 --- a/lunaix-os/arch/generic/includes/asm-generic/syscall_nr.inc +++ b/lunaix-os/arch/generic/includes/asm-generic/syscall_nr.inc @@ -75,4 +75,8 @@ SYSCALL __lxsys_setuid SYSCALL __lxsys_setgid SYSCALL __lxsys_seteuid SYSCALL __lxsys_setegid -SYSCALL __lxsys_setgroups \ No newline at end of file +SYSCALL __lxsys_setgroups +SYSCALL __lxsys_chroot +SYSCALL __lxsys_fchmodat +SYSCALL __lxsys_fchownat +SYSCALL __lxsys_faccessat \ No newline at end of file diff --git a/lunaix-os/includes/lunaix/exec.h b/lunaix-os/includes/lunaix/exec.h index 64e0f2d..50f9489 100644 --- a/lunaix-os/includes/lunaix/exec.h +++ b/lunaix-os/includes/lunaix/exec.h @@ -14,6 +14,7 @@ struct load_context { struct exec_host* container; + ptr_t base; ptr_t end; ptr_t mem_sz; @@ -36,6 +37,7 @@ struct exec_host ptr_t vms_mnt; struct load_context exe; + struct v_inode* inode; struct exec_arrptr argv; struct exec_arrptr envp; diff --git a/lunaix-os/includes/lunaix/fs.h b/lunaix-os/includes/lunaix/fs.h index b64cdcf..bba939c 100644 --- a/lunaix-os/includes/lunaix/fs.h +++ b/lunaix-os/includes/lunaix/fs.h @@ -395,6 +395,10 @@ vfs_walk_proc(const char* path, struct hstr* component, int options); +int +vfs_walkat(int fd, const char* path, int at_opts, + struct v_dnode** dnode_out); + int vfs_mount(const char* target, const char* fs_name, diff --git a/lunaix-os/includes/lunaix/fs_acl.h b/lunaix-os/includes/lunaix/fs_acl.h index c05080b..23aab23 100644 --- a/lunaix-os/includes/lunaix/fs_acl.h +++ b/lunaix-os/includes/lunaix/fs_acl.h @@ -8,6 +8,7 @@ #define FSACL_WRITE 2 #define FSACL_EXEC 1 +#define FSACL_RWXMASK 0777 #define FSACL_U(x) (((x) & 0b111) << 6) #define FSACL_G(x) (((x) & 0b111) << 3) #define FSACL_O(x) ((x) & 0b111) @@ -24,6 +25,10 @@ #define FSACL_oW FSACL_O(FSACL_WRITE) #define FSACL_oX FSACL_O(FSACL_EXEC) +#define FSACL_suid 04000 +#define FSACL_sgid 02000 +#define FSACL_svtx 01000 + // permitted read (any usr or group matched) #define FSACL_RD (FSACL_uRD | FSACL_gRD) // permitted write (any usr or group matched) @@ -52,6 +57,8 @@ #define FSACL_o(r, w, x) \ (v__(__fsacl_sel(o, r)) | v__(__fsacl_sel(o, w)) | v__(__fsacl_sel(o, x))) +#define fsacl_test(acl, type) ((acl) & (FSACL_##type)) + static inline bool must_inline fsacl_allow_ops(unsigned int ops, unsigned int acl, uid_t uid, gid_t gid) { diff --git a/lunaix-os/includes/lunaix/process.h b/lunaix-os/includes/lunaix/process.h index 8d4c70b..868a9fc 100644 --- a/lunaix-os/includes/lunaix/process.h +++ b/lunaix-os/includes/lunaix/process.h @@ -175,6 +175,7 @@ struct proc_info gid_t sgid; struct user_scope uscope; + struct v_dnode* root; int state; int exit_code; @@ -484,10 +485,28 @@ current_euid() return __current->euid; } +static inline bool must_inline +current_is_root() +{ + return current_euid() == 0; +} + static inline gid_t must_inline current_egid() { return __current->egid; } +static inline void must_inline +current_set_egid(gid_t gid) +{ + __current->egid = gid; +} + +static inline void must_inline +current_set_euid(uid_t uid) +{ + __current->euid = uid; +} + #endif /* __LUNAIX_PROCESS_H */ diff --git a/lunaix-os/includes/lunaix/usrscope.h b/lunaix-os/includes/lunaix/usrscope.h index 4d3c1f7..8de27b7 100644 --- a/lunaix-os/includes/lunaix/usrscope.h +++ b/lunaix-os/includes/lunaix/usrscope.h @@ -48,6 +48,9 @@ uscope_membership(struct user_scope* proc_usr, gid_t gid); enum acl_match check_current_acl(uid_t desired_u, gid_t desired_g); +enum acl_match +check_acl_between(uid_t u1, gid_t g1, uid_t u2, gid_t g2); + static inline bool uscope_with_capability(const struct user_scope* proc_usr, caps_t cap) { diff --git a/lunaix-os/includes/usr/lunaix/fcntl_defs.h b/lunaix-os/includes/usr/lunaix/fcntl_defs.h index 186f5f4..81be1e7 100644 --- a/lunaix-os/includes/usr/lunaix/fcntl_defs.h +++ b/lunaix-os/includes/usr/lunaix/fcntl_defs.h @@ -26,6 +26,16 @@ #define O_RDWR FO_RDWR #define O_TRUNC FO_TRUNC +#define AT_SYMLINK_FOLLOW 0b0000 +#define AT_SYMLINK_NOFOLLOW 0b0001 +#define AT_FDCWD 0b0010 +#define AT_EACCESS 0b0100 + +#define R_OK 0b100100100 +#define W_OK 0b010010010 +#define X_OK 0b001001001 +#define F_OK 0b111111111 + /* Mount with read-only flag */ #define MNT_RO (1 << 0) diff --git a/lunaix-os/includes/usr/lunaix/status.h b/lunaix-os/includes/usr/lunaix/status.h index ce0a571..e457232 100644 --- a/lunaix-os/includes/usr/lunaix/status.h +++ b/lunaix-os/includes/usr/lunaix/status.h @@ -37,5 +37,6 @@ #define EDEADLK -31 #define EDQUOT -32 #define EPERM -33 +#define EACCESS -34 #endif /* __LUNAIX_STATUS_H */ diff --git a/lunaix-os/kernel/device/devfs.c b/lunaix-os/kernel/device/devfs.c index c707b9f..7884617 100644 --- a/lunaix-os/kernel/device/devfs.c +++ b/lunaix-os/kernel/device/devfs.c @@ -183,7 +183,7 @@ devfs_init_inode(struct v_superblock* vsb, struct v_inode* inode) // we set default access right to be 0660. // TODO need a way to allow this to be changed - fsapi_inode_setaccess(inode, FSACL_u(R, W, _) | FSACL_g(R, W, _)); + fsapi_inode_setaccess(inode, FSACL_u(R, W, X) | FSACL_g(R, W, X) | FSACL_oX); fsapi_inode_setowner(inode, 0, 0); } diff --git a/lunaix-os/kernel/exe/exec.c b/lunaix-os/kernel/exe/exec.c index cc7ae82..5ac00b3 100644 --- a/lunaix-os/kernel/exe/exec.c +++ b/lunaix-os/kernel/exe/exec.c @@ -202,6 +202,7 @@ exec_load(struct exec_host* container, struct v_file* executable) } save_process_cmd(proc, argv); + container->inode = executable->inode; errno = load_executable(&container->exe, executable); if (errno) { @@ -285,6 +286,7 @@ __DEFINE_LXSYSCALL3(int, envp[]) { int errno = 0; + int acl; struct exec_host container; if (!argv || !envp) { @@ -308,6 +310,15 @@ __DEFINE_LXSYSCALL3(int, signal_reset_context(¤t_thread->sigctx); signal_reset_registry(__current->sigreg); + acl = container.inode->acl; + if (fsacl_test(acl, suid)) { + current_set_euid(container.inode->uid); + } + + if (fsacl_test(acl, sgid)) { + current_set_egid(container.inode->gid); + } + done: // set return value store_retval(DO_STATUS(errno)); diff --git a/lunaix-os/kernel/fs/path_walk.c b/lunaix-os/kernel/fs/path_walk.c index 84e04d0..7b49219 100644 --- a/lunaix-os/kernel/fs/path_walk.c +++ b/lunaix-os/kernel/fs/path_walk.c @@ -3,6 +3,8 @@ #include #include +#include + #include #define VFS_SYMLINK_DEPTH 16 @@ -29,11 +31,16 @@ __vfs_walk(struct v_dnode* start, if (path[0] == VFS_PATH_DELIM || !start) { if ((walk_options & VFS_WALK_FSRELATIVE) && start) { start = start->super_block->root; - } else { + } + else if (unlikely(!__current)) { start = vfs_sysroot; - if (!vfs_sysroot->mnt) { - fail("vfs: no root"); - } + } + else { + start = __current->root ?: vfs_sysroot; + } + + if (unlikely(!start || !start->mnt)) { + fail("vfs: no root"); } if (path[0] == VFS_PATH_DELIM) { @@ -50,9 +57,12 @@ __vfs_walk(struct v_dnode* start, struct hstr name = HSTR(fname_buffer, 0); char current = path[i++], lookahead; - while (current) { + while (current) + { lookahead = path[i++]; - if (current != VFS_PATH_DELIM) { + + if (current != VFS_PATH_DELIM) + { if (j >= VFS_NAME_MAXLEN - 1) { return ENAMETOOLONG; } @@ -83,9 +93,15 @@ __vfs_walk(struct v_dnode* start, lock_dnode(current_level); + if (!check_allow_execute(current_inode)) { + errno = EACCESS; + goto error; + } + dnode = vfs_dcache_lookup(current_level, &name); - if (!dnode) { + if (!dnode) + { dnode = vfs_d_alloc(current_level, &name); if (!dnode) { @@ -123,7 +139,8 @@ __vfs_walk(struct v_dnode* start, assert(current_inode); if (check_symlink_node(current_inode) && - !(walk_options & VFS_WALK_NOFOLLOW)) { + !(walk_options & VFS_WALK_NOFOLLOW)) + { const char* link; struct v_inode_ops* iops; @@ -169,6 +186,7 @@ __vfs_walk(struct v_dnode* start, cleanup: vfs_d_free(dnode); + error: *dentry = NULL; return errno; @@ -204,4 +222,36 @@ vfs_walk_proc(const char* path, int options) { return vfs_walk(__current->cwd, path, dentry, component, options); +} + +int +vfs_walkat(int fd, const char* path, int at_opts, struct v_dnode** dnode_out) +{ + int errno, options = 0; + struct v_dnode *root_dnode; + struct v_fd* _fd; + + if ((at_opts & AT_FDCWD)) { + root_dnode = __current->cwd; + } + else + { + errno = vfs_getfd(fd, &_fd); + if (errno) { + return errno; + } + + root_dnode = _fd->file->dnode; + } + + if ((at_opts & AT_SYMLINK_NOFOLLOW)) { + options |= VFS_WALK_NOFOLLOW; + } + + errno = vfs_walk(root_dnode, path, dnode_out, NULL, options); + if (errno) { + return errno; + } + + return 0; } \ No newline at end of file diff --git a/lunaix-os/kernel/fs/ramfs/ramfs.c b/lunaix-os/kernel/fs/ramfs/ramfs.c index b7512e5..d4e2f6f 100644 --- a/lunaix-os/kernel/fs/ramfs/ramfs.c +++ b/lunaix-os/kernel/fs/ramfs/ramfs.c @@ -132,7 +132,13 @@ ramfs_mount(struct v_superblock* vsb, struct v_dnode* mount_point) { vsb->ops.init_inode = ramfs_inode_init; - return __ramfs_mknod(mount_point, NULL, RAMF_DIR); + int errno = __ramfs_mknod(mount_point, NULL, RAMF_DIR); + + if (!errno) { + fsapi_inode_setaccess(mount_point->inode, FSACL_aX | FSACL_aR); + } + + return errno; } int diff --git a/lunaix-os/kernel/fs/vfs.c b/lunaix-os/kernel/fs/vfs.c index 53faa56..c117f18 100644 --- a/lunaix-os/kernel/fs/vfs.c +++ b/lunaix-os/kernel/fs/vfs.c @@ -57,13 +57,16 @@ #include +#define INODE_ACCESSED 0 +#define INODE_MODIFY 1 + static struct cake_pile* dnode_pile; static struct cake_pile* inode_pile; static struct cake_pile* file_pile; static struct cake_pile* superblock_pile; static struct cake_pile* fd_pile; -struct v_dnode* vfs_sysroot; +struct v_dnode* vfs_sysroot = NULL; struct lru_zone *dnode_lru, *inode_lru; @@ -152,6 +155,20 @@ vfs_dcache_lookup(struct v_dnode* parent, struct hstr* str) return NULL; } +static void +__vfs_touch_inode(struct v_inode* inode, const int type) +{ + if (type == INODE_MODIFY) { + inode->mtime = clock_unixtime(); + } + + else if (type == INODE_ACCESSED) { + inode->atime = clock_unixtime(); + } + + lru_use_one(inode_lru, &inode->lru); +} + void vfs_dcache_add(struct v_dnode* parent, struct v_dnode* dnode) { @@ -696,6 +713,31 @@ done: return errno; } + +static bool +__check_unlinkable(struct v_dnode* dnode) +{ + int acl; + bool wr_self, wr_parent; + struct v_dnode* parent; + + parent = dnode->parent; + acl = dnode->inode->acl; + + wr_self = check_allow_write(dnode->inode); + wr_parent = check_allow_write(parent->inode); + + if (!fsacl_test(acl, svtx)) { + return wr_self; + } + + if (current_euid() == dnode->inode->uid) { + return true; + } + + return wr_self && wr_parent; +} + int vfs_do_open(const char* path, int options) { @@ -814,6 +856,11 @@ __DEFINE_LXSYSCALL2(int, sys_readdir, int, fd, struct lx_dirent*, dent) goto unlock; } + if (!check_allow_read(inode)) { + errno = EPERM; + goto unlock; + } + struct dir_context dctx = (struct dir_context) { .cb_data = dent, .read_complete_callback = __vfs_readdir_callback @@ -836,6 +883,8 @@ __DEFINE_LXSYSCALL3(int, read, int, fd, void*, buf, size_t, count) { int errno = 0; struct v_fd* fd_s; + struct v_inode* inode; + if ((errno = vfs_getfd(fd, &fd_s))) { goto done; } @@ -851,23 +900,24 @@ __DEFINE_LXSYSCALL3(int, read, int, fd, void*, buf, size_t, count) goto done; } - lock_inode(file->inode); + inode = file->inode; + lock_inode(inode); - file->inode->atime = clock_unixtime(); + __vfs_touch_inode(inode, INODE_ACCESSED); - if (check_seqdev_node(file->inode) || (fd_s->flags & FO_DIRECT)) { - errno = file->ops->read(file->inode, buf, count, file->f_pos); + if (check_seqdev_node(inode) || (fd_s->flags & FO_DIRECT)) { + errno = file->ops->read(inode, buf, count, file->f_pos); } else { - errno = pcache_read(file->inode, buf, count, file->f_pos); + errno = pcache_read(inode, buf, count, file->f_pos); } if (errno > 0) { file->f_pos += errno; - unlock_inode(file->inode); + unlock_inode(inode); return errno; } - unlock_inode(file->inode); + unlock_inode(inode); done: return DO_STATUS(errno); @@ -896,7 +946,7 @@ __DEFINE_LXSYSCALL3(int, write, int, fd, void*, buf, size_t, count) inode = file->inode; lock_inode(inode); - inode->mtime = clock_unixtime(); + __vfs_touch_inode(inode, INODE_MODIFY); if ((fd_s->flags & O_APPEND)) { file->f_pos = inode->fsize; } @@ -1132,6 +1182,11 @@ __DEFINE_LXSYSCALL1(int, rmdir, const char*, pathname) lock_dnode(dnode); + if (!__check_unlinkable(dnode)) { + errno = EPERM; + goto done; + } + if ((errno = vfs_check_writable(dnode))) { goto done; } @@ -1228,7 +1283,7 @@ done: return DO_STATUS(errno); } -int +static int __vfs_do_unlink(struct v_dnode* dnode) { int errno; @@ -1238,6 +1293,10 @@ __vfs_do_unlink(struct v_dnode* dnode) return EBUSY; } + if (!__check_unlinkable(dnode)) { + return EPERM; + } + if ((errno = vfs_check_writable(dnode))) { return errno; } @@ -1448,16 +1507,11 @@ done: return DO_STATUS(errno); } -int -vfs_do_chdir(struct proc_info* proc, struct v_dnode* dnode) +static int +vfs_do_chdir_nolock(struct proc_info* proc, struct v_dnode* dnode) { - int errno = 0; - - lock_dnode(dnode); - if (!check_directory_node(dnode->inode)) { - errno = ENOTDIR; - goto done; + return ENOTDIR; } if (proc->cwd) { @@ -1467,9 +1521,20 @@ vfs_do_chdir(struct proc_info* proc, struct v_dnode* dnode) vfs_ref_dnode(dnode); proc->cwd = dnode; + return 0; +} + +static int +vfs_do_chdir(struct proc_info* proc, struct v_dnode* dnode) +{ + int errno = 0; + + lock_dnode(dnode); + + errno = vfs_do_chdir_nolock(proc, dnode); + unlock_dnode(dnode); -done: return errno; } @@ -1503,6 +1568,31 @@ done: return DO_STATUS(errno); } + +__DEFINE_LXSYSCALL1(int, chroot, const char*, path) +{ + int errno; + struct v_dnode* dnode; + if ((errno = vfs_walk_proc(path, &dnode, NULL, 0))) { + return errno; + } + + lock_dnode(dnode); + + errno = vfs_do_chdir_nolock(__current, dnode); + if (errno) { + unlock_dnode(dnode); + goto done; + } + + __current->root = dnode; + + unlock_dnode(dnode); + +done: + return DO_STATUS(errno); +} + __DEFINE_LXSYSCALL2(char*, getcwd, char*, buf, size_t, size) { int errno = 0; @@ -1668,6 +1758,108 @@ __DEFINE_LXSYSCALL2(int, fstat, int, fd, struct file_stat*, stat) .index = dev_uid(fdev) }; } +done: + return DO_STATUS(errno); +} + +__DEFINE_LXSYSCALL4(int, fchmodat, int, fd, + const char*, path, int, mode, int, flags) +{ + int errno; + struct v_dnode *dnode; + struct v_inode* inode; + + errno = vfs_walkat(fd, path, flags, &dnode); + if (errno) { + goto done; + } + + errno = vfs_check_writable(dnode); + if (errno) { + return errno; + } + + inode = dnode->inode; + lock_inode(inode); + + if (!current_is_root()) { + mode = mode & FSACL_RWXMASK; + } + + inode->acl = mode; + __vfs_touch_inode(inode, INODE_MODIFY); + + unlock_inode(inode); + +done: + return DO_STATUS(errno); +} + +__DEFINE_LXSYSCALL5(int, fchownat, int, fd, + const char*, path, uid_t, uid, gid_t, gid, int, flags) +{ + int errno; + struct v_dnode *dnode; + struct v_inode *inode; + + errno = vfs_walkat(fd, path, flags, &dnode); + if (errno) { + goto done; + } + + errno = vfs_check_writable(dnode); + if (errno) { + return errno; + } + + inode = dnode->inode; + lock_inode(inode); + + inode->uid = uid; + inode->gid = gid; + __vfs_touch_inode(inode, INODE_MODIFY); + + unlock_inode(inode); + +done: + return DO_STATUS(errno); +} + +__DEFINE_LXSYSCALL4(int, faccessat, int, fd, + const char*, path, int, amode, int, flags) +{ + int errno, acl; + struct v_dnode *dnode; + struct v_inode *inode; + struct user_scope* uscope; + + uid_t tuid; + gid_t tgid; + + errno = vfs_walkat(fd, path, flags, &dnode); + if (errno) { + goto done; + } + + if ((flags & AT_EACCESS)) { + tuid = current_euid(); + tgid = current_egid(); + } + else { + uscope = current_user_scope(); + tuid = uscope->ruid; + tgid = uscope->rgid; + } + + inode = dnode->inode; + + acl = inode->acl; + acl &= amode; + acl &= check_acl_between(inode->uid, inode->gid, tuid, tgid); + if (!acl) { + errno = EACCESS; + } + done: return DO_STATUS(errno); } \ No newline at end of file diff --git a/lunaix-os/kernel/process/process.c b/lunaix-os/kernel/process/process.c index e9fab24..2a24f50 100644 --- a/lunaix-os/kernel/process/process.c +++ b/lunaix-os/kernel/process/process.c @@ -249,4 +249,4 @@ __DEFINE_LXSYSCALL2(int, getgroups, gid_t*, out_buf, unsigned int, len) } return i + 1; -} \ No newline at end of file +} diff --git a/lunaix-os/kernel/process/sched.c b/lunaix-os/kernel/process/sched.c index e9f61b3..112741c 100644 --- a/lunaix-os/kernel/process/sched.c +++ b/lunaix-os/kernel/process/sched.c @@ -24,7 +24,7 @@ struct thread empty_thread_obj; -volatile struct proc_info* __current; +volatile struct proc_info* __current = NULL; volatile struct thread* current_thread = &empty_thread_obj; struct scheduler sched_ctx; @@ -393,6 +393,8 @@ alloc_process() proc->created = clock_systime(); proc->pgid = proc->pid; + proc->root = vfs_sysroot; + proc->sigreg = vzalloc(sizeof(struct sigregistry)); proc->fdtable = vzalloc(sizeof(struct v_fdtable)); diff --git a/lunaix-os/kernel/usrscope.c b/lunaix-os/kernel/usrscope.c index 5eba922..8a6bc99 100644 --- a/lunaix-os/kernel/usrscope.c +++ b/lunaix-os/kernel/usrscope.c @@ -115,19 +115,36 @@ uscope_copy(struct user_scope* to, struct user_scope* from) memcpy(to, from, sizeof(*to)); } +enum acl_match +check_acl_between(uid_t u1, gid_t g1, uid_t u2, gid_t g2) +{ + struct user_scope* uscope; + + if (!u1 || u1 == u2) + return ACL_MATCH_U; + + if (g1 == g2) + return ACL_MATCH_G; + + return ACL_NO_MATCH; +} + enum acl_match check_current_acl(uid_t desired_u, gid_t desired_g) { + enum acl_match match; struct user_scope* uscope; - if (!__current->euid || __current->euid == desired_u) - { - return ACL_MATCH_U; + if (unlikely(!__current)) { + return ACL_NO_MATCH; } - if (__current->egid == desired_g) { - return ACL_MATCH_G; + match = check_acl_between(__current->euid, __current->egid, + desired_u, desired_g); + + if (match != ACL_NO_MATCH) { + return match; } uscope = current_user_scope();