syscalls: chroot, fchmodat, fchownat, faccessat
authorLunaixsky <lunaixsky@qq.com>
Sun, 30 Mar 2025 20:19:38 +0000 (21:19 +0100)
committerLunaixsky <lunaixsky@qq.com>
Tue, 1 Apr 2025 13:32:02 +0000 (14:32 +0100)
enable access check in path walker
add default directory permission for ramfs and devfs

17 files changed:
README.md
lunaix-os/arch/generic/includes/asm-generic/syscall_nr.inc
lunaix-os/includes/lunaix/exec.h
lunaix-os/includes/lunaix/fs.h
lunaix-os/includes/lunaix/fs_acl.h
lunaix-os/includes/lunaix/process.h
lunaix-os/includes/lunaix/usrscope.h
lunaix-os/includes/usr/lunaix/fcntl_defs.h
lunaix-os/includes/usr/lunaix/status.h
lunaix-os/kernel/device/devfs.c
lunaix-os/kernel/exe/exec.c
lunaix-os/kernel/fs/path_walk.c
lunaix-os/kernel/fs/ramfs/ramfs.c
lunaix-os/kernel/fs/vfs.c
lunaix-os/kernel/process/process.c
lunaix-os/kernel/process/sched.c
lunaix-os/kernel/usrscope.c

index 5dc1656691d102f0527caab21e2a09f04e7f6e82..c4a4ea9579fd3f61f0c310e746abc6bfffa76814 100644 (file)
--- 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**
 
index 7590c4b032f6bf2dd2aea9bf7f0e3daa86a876d5..0da2e62dff3b70f9c4ba70e3f87146d094dde43c 100644 (file)
@@ -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
index 64e0f2dd681f9d6a8d9c4753ccc8747e89a4056b..50f94898a4b0ae4cb7daf0abe9d93c11e0ea7527 100644 (file)
@@ -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;
index b64cdcff5925b6087b0bcad0701800ecee51c7fe..bba939cadc997221427692dad2caebfec4d41e11 100644 (file)
@@ -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,
index c05080bf19de799b38e071b693e1ba4898967afe..23aab232dc13da401712647dca1fb5a9b5b7633d 100644 (file)
@@ -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)
 #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)
 {
index 8d4c70baf1230a6f09125d9e55f3d6a28db68033..868a9fc290bc97a53ee3bac804b401cf87da54fd 100644 (file)
@@ -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 */
index 4d3c1f7a87135f1c68966d533787abe1f7d7d602..8de27b787a979c2f59cc0ee65c062ed120abe756 100644 (file)
@@ -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)
 {
index 186f5f48fa20f24c57a3bbdae2173ff747550a3a..81be1e7a889767f00fe9fa24fedfd51f6316f8d3 100644 (file)
 #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)
 
index ce0a57109fed0927584e2ca60b75671411d75367..e4572322c0f019988fd15c4ce86ec77f158b8592 100644 (file)
@@ -37,5 +37,6 @@
 #define EDEADLK -31
 #define EDQUOT -32
 #define EPERM -33
+#define EACCESS -34
 
 #endif /* __LUNAIX_STATUS_H */
index c707b9f6bdb9973ae52106f389ce024b85857cc9..78846177a4c957fa6ef719c9f610833b19f8a7ec 100644 (file)
@@ -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);
 }
 
index cc7ae82b62cb094752ceacae305c08f43c68f80e..5ac00b3dbb99577bdd7f5a13281b073bdf13bd85 100644 (file)
@@ -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(&current_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));
index 84e04d0e9bb0eed8ae229e7818f259951b24ead3..7b49219edbad435fd1c9892676be55d110e2bf68 100644 (file)
@@ -3,6 +3,8 @@
 #include <lunaix/process.h>
 #include <lunaix/spike.h>
 
+#include <usr/lunaix/fcntl_defs.h>
+
 #include <klibc/string.h>
 
 #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
index b7512e5eefa1f534acafee81bf2b6f005df80a97..d4e2f6fe662d578f481acc62f65c6df359ea3348 100644 (file)
@@ -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
index 53faa560341f16b55ecb6964946d42b16880431b..c117f18044d71e3ff66880f66ab82c2977827245 100644 (file)
 
 #include <usr/lunaix/dirent_defs.h>
 
+#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
index e9fab24e0851148c5ff27e3009dbff81e8eb70eb..2a24f50bbb6c9791144cb5376c3471178ba3de2d 100644 (file)
@@ -249,4 +249,4 @@ __DEFINE_LXSYSCALL2(int, getgroups, gid_t*, out_buf, unsigned int, len)
     }
     
     return i + 1;
-}
\ No newline at end of file
+}
index e9f61b313af2bf466cb71656ccb27dd3cd1dfea1..112741c553de299db541357d39baca3487d9f373 100644 (file)
@@ -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));
 
index 5eba922345559b2f8e681a74f42411be8be45d42..8a6bc99096a1fa29a1f439e985ebd5ea7919c98c 100644 (file)
@@ -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();