Multiuser, Capabilities and Access Controls (#54)
authorLunaixsky <lunaixsky@qq.com>
Tue, 1 Apr 2025 19:08:48 +0000 (20:08 +0100)
committerGitHub <noreply@github.com>
Tue, 1 Apr 2025 19:08:48 +0000 (20:08 +0100)
* basic user, group and capability housekeeping.

add usrscope for process-wise user management
implement {get,set}*{uid,euid,gid,egid,groups} syscalls
basic acl checking mechanism
move common syscall table to arch/generic.

* patch file systems with the acl checks

make sure the user scope is copied upon fork

* syscalls: chroot, fchmodat, fchownat, faccessat

enable access check in path walker
add default directory permission for ramfs and devfs

* release the dnode lock after EACCESS in path walk

make struct stats conforming to POSIX
minor tweaks stock shell environment for better look and feel

* allow specifiying access mode when creating twifs file node

twifs: refactor the interface for easy twimap/twifs export

cake: fix overflow of index guessing when freeing, causing false
positive and possibly failing double free assertion

58 files changed:
README.md
lunaix-os/arch/generic/includes/asm-generic/syscall_nr.inc [new file with mode: 0644]
lunaix-os/arch/x86/LBuild
lunaix-os/arch/x86/syscall32.S
lunaix-os/arch/x86/syscall64.S
lunaix-os/arch/x86/syscall_lut.S [new file with mode: 0644]
lunaix-os/arch/x86/syscall_nr.inc
lunaix-os/hal/ahci/hbadev_export.c
lunaix-os/hal/bus/pci.c
lunaix-os/hal/rtc/rtc_device.c
lunaix-os/includes/lunaix/compiler.h
lunaix-os/includes/lunaix/exec.h
lunaix-os/includes/lunaix/fs.h
lunaix-os/includes/lunaix/fs/api.h
lunaix-os/includes/lunaix/fs/twifs.h
lunaix-os/includes/lunaix/fs/twimap.h
lunaix-os/includes/lunaix/fs_acl.h [new file with mode: 0644]
lunaix-os/includes/lunaix/limits.h [new file with mode: 0644]
lunaix-os/includes/lunaix/process.h
lunaix-os/includes/lunaix/types.h
lunaix-os/includes/lunaix/usercaps.h [new file with mode: 0644]
lunaix-os/includes/lunaix/usrscope.h [new file with mode: 0644]
lunaix-os/includes/usr/lunaix/fcntl_defs.h
lunaix-os/includes/usr/lunaix/status.h
lunaix-os/includes/usr/lunaix/types.h
lunaix-os/kernel/LBuild
lunaix-os/kernel/block/blk_mapping.c
lunaix-os/kernel/device/devdb.c
lunaix-os/kernel/device/devfs.c
lunaix-os/kernel/ds/waitq.c
lunaix-os/kernel/exe/exec.c
lunaix-os/kernel/fs/ext2/ext2.h
lunaix-os/kernel/fs/ext2/inode.c
lunaix-os/kernel/fs/fs_export.c
lunaix-os/kernel/fs/fsm.c
lunaix-os/kernel/fs/iso9660/inode.c
lunaix-os/kernel/fs/iso9660/iso9660.h
lunaix-os/kernel/fs/mount.c
lunaix-os/kernel/fs/path_walk.c
lunaix-os/kernel/fs/ramfs/ramfs.c
lunaix-os/kernel/fs/twifs/twifs.c
lunaix-os/kernel/fs/vfs.c
lunaix-os/kernel/kprint/kprintf.c
lunaix-os/kernel/lrud.c
lunaix-os/kernel/mm/cake.c
lunaix-os/kernel/mm/cake_export.c
lunaix-os/kernel/process/fork.c
lunaix-os/kernel/process/process.c
lunaix-os/kernel/process/sched.c
lunaix-os/kernel/time/clock.c
lunaix-os/kernel/usrscope.c [new file with mode: 0644]
lunaix-os/usr/cat.c
lunaix-os/usr/init/init.c
lunaix-os/usr/libc/src/_vprintf.c
lunaix-os/usr/ls.c
lunaix-os/usr/rm.c
lunaix-os/usr/sh/sh.c
lunaix-os/usr/stat.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**
 
diff --git a/lunaix-os/arch/generic/includes/asm-generic/syscall_nr.inc b/lunaix-os/arch/generic/includes/asm-generic/syscall_nr.inc
new file mode 100644 (file)
index 0000000..0da2e62
--- /dev/null
@@ -0,0 +1,82 @@
+#ifndef SYSCALL
+#   error "SYSCALL missing pointer type"
+#endif
+
+SYSCALL 0
+SYSCALL __lxsys_fork          /* 1 */
+SYSCALL __lxsys_yield
+SYSCALL __lxsys_sbrk
+SYSCALL __lxsys_brk
+SYSCALL __lxsys_getpid        /* 5 */
+SYSCALL __lxsys_getppid
+SYSCALL __lxsys_sleep
+SYSCALL __lxsys_exit
+SYSCALL __lxsys_wait          
+SYSCALL __lxsys_waitpid       /* 10 */
+SYSCALL __lxsys_sigreturn
+SYSCALL __lxsys_sigprocmask
+SYSCALL __lxsys_sys_sigaction
+SYSCALL __lxsys_pause
+SYSCALL __lxsys_kill          /* 15 */
+SYSCALL __lxsys_alarm
+SYSCALL __lxsys_sigpending
+SYSCALL __lxsys_sigsuspend
+SYSCALL __lxsys_open
+SYSCALL __lxsys_close         /* 20 */
+SYSCALL __lxsys_read
+SYSCALL __lxsys_write
+SYSCALL __lxsys_sys_readdir
+SYSCALL __lxsys_mkdir
+SYSCALL __lxsys_lseek         /* 25 */
+SYSCALL __lxsys_geterrno
+SYSCALL __lxsys_readlink
+SYSCALL __lxsys_readlinkat
+SYSCALL __lxsys_rmdir
+SYSCALL __lxsys_unlink        /* 30 */
+SYSCALL __lxsys_unlinkat
+SYSCALL __lxsys_link
+SYSCALL __lxsys_fsync
+SYSCALL __lxsys_dup
+SYSCALL __lxsys_dup2          /* 35 */
+SYSCALL __lxsys_realpathat
+SYSCALL __lxsys_symlink
+SYSCALL __lxsys_chdir
+SYSCALL __lxsys_fchdir
+SYSCALL __lxsys_getcwd        /* 40 */
+SYSCALL __lxsys_rename
+SYSCALL __lxsys_mount
+SYSCALL __lxsys_unmount
+SYSCALL __lxsys_getxattr
+SYSCALL __lxsys_setxattr      /* 45 */
+SYSCALL __lxsys_fgetxattr
+SYSCALL __lxsys_fsetxattr
+SYSCALL __lxsys_ioctl
+SYSCALL __lxsys_getpgid
+SYSCALL __lxsys_setpgid       /* 50 */
+SYSCALL __lxsys_syslog
+SYSCALL __lxsys_sys_mmap
+SYSCALL __lxsys_munmap
+SYSCALL __lxsys_execve
+SYSCALL __lxsys_fstat         /* 55 */
+SYSCALL __lxsys_pollctl
+SYSCALL __lxsys_th_create
+SYSCALL __lxsys_th_self
+SYSCALL __lxsys_th_exit
+SYSCALL __lxsys_th_join       /* 60 */
+SYSCALL __lxsys_th_kill
+SYSCALL __lxsys_th_detach
+SYSCALL __lxsys_th_sigmask
+SYSCALL __lxsys_getuid
+SYSCALL __lxsys_getgid
+SYSCALL __lxsys_geteuid
+SYSCALL __lxsys_getegid
+SYSCALL __lxsys_getgroups
+SYSCALL __lxsys_setuid
+SYSCALL __lxsys_setgid
+SYSCALL __lxsys_seteuid
+SYSCALL __lxsys_setegid
+SYSCALL __lxsys_setgroups
+SYSCALL __lxsys_chroot
+SYSCALL __lxsys_fchmodat
+SYSCALL __lxsys_fchownat
+SYSCALL __lxsys_faccessat
\ No newline at end of file
index 941453b42c8eea2e2ddc29f7377b357d0087b323..ed4b4f8ac9e10f4396fbd1b7b9f0470f311ce447 100644 (file)
@@ -29,7 +29,8 @@ sources([
     "gdbstub.c",
     "trace.c",
     "hart.c",
-    "failsafe.S"
+    "failsafe.S",
+    "syscall_lut.S"
 ])
 
 sources({
index b8915ed8a0b165f5e1701c5b650a44d2dcf88d5a..3fb96b4f68ad4e44d394a2887ba6b7c650a811f5 100644 (file)
@@ -1,6 +1,5 @@
 #define __ASM__
 #include <lunaix/syscall.h>
-#include "syscall_nr.inc"
 
 .section .text
     .type syscall_hndlr, @function
@@ -16,7 +15,7 @@
         jae     2f
 
         shll    $2, %eax
-        addl    $syscall_table, %eax
+        addl    $__syscall_table, %eax
         cmpl    $0, (%eax)
         jne     1f
     2:    
index 6125a84f5252d08d05306756febaa4cae0fe6710..cce528a937a69c82d4ab24a5ca2587874a33d6aa 100644 (file)
@@ -1,6 +1,5 @@
 #define __ASM__
 #include <lunaix/syscall.h>
-#include "syscall_nr.inc"
 #include "asm/variants/interrupt64.S.inc"
 
 .section .text
@@ -18,7 +17,7 @@
         jae     2f
 
         shlq    $3, %rax               // %rax * 8
-        movabsq $syscall_table, %r8
+        movabsq $__syscall_table, %r8
         addq    %r8, %rax
         cmpq    $0, (%rax)
         jne     1f
diff --git a/lunaix-os/arch/x86/syscall_lut.S b/lunaix-os/arch/x86/syscall_lut.S
new file mode 100644 (file)
index 0000000..4bee0b4
--- /dev/null
@@ -0,0 +1,20 @@
+#define __ASM__
+#include <lunaix/syscall.h>
+
+#ifdef CONFIG_ARCH_X86_64
+#   define SYSCALL     .8byte
+#   define SIZE    8
+#else
+#   define SIZE    4
+#   define SYSCALL     .4byte
+#endif
+
+.section .data
+    .global __syscall_table
+    __syscall_table:
+        1:
+        #include "syscall_nr.inc"
+        2:
+        .rept __SYSCALL_MAX - (2b - 1b) / SIZE
+            .long 0
+        .endr
\ No newline at end of file
index c30a720180d3019ffd0892e38c7c81ae453d090a..85762da739e14c82307136f994eaa94f1bad10bb 100644 (file)
@@ -1,79 +1,3 @@
-#ifdef CONFIG_ARCH_X86_64
-#   define PTR     .8byte
-#   define SIZE    8
-#else
-#   define PTR     .4byte
-#   define SIZE    4
-#endif
+#include <asm-generic/syscall_nr.inc>
 
-.section .data
-    syscall_table:
-        1:
-        PTR 0
-        PTR __lxsys_fork          /* 1 */
-        PTR __lxsys_yield
-        PTR __lxsys_sbrk
-        PTR __lxsys_brk
-        PTR __lxsys_getpid        /* 5 */
-        PTR __lxsys_getppid
-        PTR __lxsys_sleep
-        PTR __lxsys_exit
-        PTR __lxsys_wait          
-        PTR __lxsys_waitpid       /* 10 */
-        PTR __lxsys_sigreturn
-        PTR __lxsys_sigprocmask
-        PTR __lxsys_sys_sigaction
-        PTR __lxsys_pause
-        PTR __lxsys_kill          /* 15 */
-        PTR __lxsys_alarm
-        PTR __lxsys_sigpending
-        PTR __lxsys_sigsuspend
-        PTR __lxsys_open
-        PTR __lxsys_close         /* 20 */
-        PTR __lxsys_read
-        PTR __lxsys_write
-        PTR __lxsys_sys_readdir
-        PTR __lxsys_mkdir
-        PTR __lxsys_lseek         /* 25 */
-        PTR __lxsys_geterrno
-        PTR __lxsys_readlink
-        PTR __lxsys_readlinkat
-        PTR __lxsys_rmdir
-        PTR __lxsys_unlink        /* 30 */
-        PTR __lxsys_unlinkat
-        PTR __lxsys_link
-        PTR __lxsys_fsync
-        PTR __lxsys_dup
-        PTR __lxsys_dup2          /* 35 */
-        PTR __lxsys_realpathat
-        PTR __lxsys_symlink
-        PTR __lxsys_chdir
-        PTR __lxsys_fchdir
-        PTR __lxsys_getcwd        /* 40 */
-        PTR __lxsys_rename
-        PTR __lxsys_mount
-        PTR __lxsys_unmount
-        PTR __lxsys_getxattr
-        PTR __lxsys_setxattr      /* 45 */
-        PTR __lxsys_fgetxattr
-        PTR __lxsys_fsetxattr
-        PTR __lxsys_ioctl
-        PTR __lxsys_getpgid
-        PTR __lxsys_setpgid       /* 50 */
-        PTR __lxsys_syslog
-        PTR __lxsys_sys_mmap
-        PTR __lxsys_munmap
-        PTR __lxsys_execve
-        PTR __lxsys_fstat         /* 55 */
-        PTR __lxsys_pollctl
-        PTR __lxsys_th_create
-        PTR __lxsys_th_self
-        PTR __lxsys_th_exit
-        PTR __lxsys_th_join       /* 60 */
-        PTR __lxsys_th_kill
-        PTR __lxsys_th_detach
-        PTR __lxsys_th_sigmask
-        2:
-        .rept __SYSCALL_MAX - (2b - 1b) / SIZE
-            .long 0
-        .endr
\ No newline at end of file
+// arch specifics syscalls goes here
index 3fea81d9c4c736f0c944a66a4ec904faf2ad341c..f6c52bf19d965b566bbdcea7e6310be5e958cf1d 100644 (file)
@@ -3,14 +3,14 @@
 #include <lunaix/fs/twifs.h>
 
 void
-__blk_rd_serial(struct twimap* map)
+__twimap_read_serial(struct twimap* map)
 {
     struct hba_device* hbadev = twimap_data(map, struct hba_device*);
     twimap_printf(map, "%s", hbadev->serial_num);
 }
 
 void
-__blk_rd_last_status(struct twimap* map)
+__twimap_read_last_status(struct twimap* map)
 {
     struct hba_device* hbadev = twimap_data(map, struct hba_device*);
     twimap_printf(map,
@@ -21,21 +21,21 @@ __blk_rd_last_status(struct twimap* map)
 }
 
 void
-__blk_rd_capabilities(struct twimap* map)
+__twimap_read_capabilities(struct twimap* map)
 {
     struct hba_device* hbadev = twimap_data(map, struct hba_device*);
     twimap_printf(map, "%p", hbadev->capabilities);
 }
 
 void
-__blk_rd_aoffset(struct twimap* map)
+__twimap_read_alignment(struct twimap* map)
 {
     struct hba_device* hbadev = twimap_data(map, struct hba_device*);
     twimap_printf(map, "%d", hbadev->alignment_offset);
 }
 
 void
-__blk_rd_wwid(struct twimap* map)
+__twimap_read_wwid(struct twimap* map)
 {
     struct hba_device* hbadev = twimap_data(map, struct hba_device*);
     u32_t h = hbadev->wwn >> 32;
@@ -53,18 +53,9 @@ ahci_fsexport(struct block_dev* bdev, void* fs_node)
     struct twifs_node* dev_root = (struct twifs_node*)fs_node;
     struct twimap* map;
 
-    map = twifs_mapping(dev_root, bdev->driver, "serial");
-    map->read = __blk_rd_serial;
-
-    map = twifs_mapping(dev_root, bdev->driver, "last_status");
-    map->read = __blk_rd_last_status;
-
-    map = twifs_mapping(dev_root, bdev->driver, "wwid");
-    map->read = __blk_rd_wwid;
-
-    map = twifs_mapping(dev_root, bdev->driver, "capabilities");
-    map->read = __blk_rd_capabilities;
-
-    map = twifs_mapping(dev_root, bdev->driver, "alignment_offset");
-    map->read = __blk_rd_aoffset;
+    twimap_export_value(dev_root, serial,       FSACL_aR, bdev->driver);
+    twimap_export_value(dev_root, last_status,  FSACL_aR, bdev->driver);
+    twimap_export_value(dev_root, wwid,         FSACL_aR, bdev->driver);
+    twimap_export_value(dev_root, capabilities, FSACL_aR, bdev->driver);
+    twimap_export_value(dev_root, alignment,    FSACL_aR, bdev->driver);
 }
\ No newline at end of file
index 0543d0aef8e9ba943e58845b5ab8d1ab1ac22c0e..cbad1793c8ba653eaff05f92f0cda33766988da0 100644 (file)
@@ -371,7 +371,7 @@ pci_apply_command(struct pci_probe* probe, pci_reg_t cmd)
 }
 
 static void
-__pci_read_cspace(struct twimap* map)
+__twimap_read_config(struct twimap* map)
 {
     struct pci_probe* probe;
 
@@ -388,7 +388,7 @@ __pci_read_cspace(struct twimap* map)
 /*---------- TwiFS interface definition ----------*/
 
 static void
-__pci_read_revid(struct twimap* map)
+__twimap_read_revision(struct twimap* map)
 {
     struct pci_probe* probe;
 
@@ -397,7 +397,7 @@ __pci_read_revid(struct twimap* map)
 }
 
 static void
-__pci_read_class(struct twimap* map)
+__twimap_read_class(struct twimap* map)
 {
     struct pci_probe* probe;
 
@@ -406,7 +406,7 @@ __pci_read_class(struct twimap* map)
 }
 
 static void
-__pci_read_devinfo(struct twimap* map)
+__twimap_read_pci_devinfo(struct twimap* map)
 {
     struct pci_probe* probe;
 
@@ -417,7 +417,7 @@ __pci_read_devinfo(struct twimap* map)
 }
 
 static void
-__pci_bar_read(struct twimap* map)
+__twimap_read_io_bases(struct twimap* map)
 {
     struct pci_probe* probe;
     int bar_index;
@@ -448,7 +448,7 @@ __pci_bar_read(struct twimap* map)
 }
 
 static int
-__pci_bar_gonext(struct twimap* map)
+__twimap_gonext_io_bases(struct twimap* map)
 {
     if (twimap_index(map, int) >= 5) {
         return 0;
@@ -458,7 +458,13 @@ __pci_bar_gonext(struct twimap* map)
 }
 
 static void
-__pci_read_binding(struct twimap* map)
+__twimap_reset_io_bases(struct twimap* map)
+{
+    map->index = 0;
+}
+
+static void
+__twimap_read_binding(struct twimap* map)
 {
     struct pci_probe* probe;
     struct devident* devid;
@@ -499,21 +505,11 @@ pci_build_fsmapping()
         probe = changeling_reveal(pos, pci_probe_morpher);
         pci_dev = twifs_dir_node(pci_class, "%x", probe->loc);
 
-        map = twifs_mapping(pci_dev, probe, "config");
-        map->read = __pci_read_cspace;
-
-        map = twifs_mapping(pci_dev, probe, "revision");
-        map->read = __pci_read_revid;
-
-        map = twifs_mapping(pci_dev, probe, "class");
-        map->read = __pci_read_class;
-
-        map = twifs_mapping(pci_dev, probe, "binding");
-        map->read = __pci_read_binding;
-
-        map = twifs_mapping(pci_dev, probe, "io_bases");
-        map->read = __pci_bar_read;
-        map->go_next = __pci_bar_gonext;
+        twimap_export_value(pci_dev, config,    FSACL_aR, probe);
+        twimap_export_value(pci_dev, revision,  FSACL_aR, probe);
+        twimap_export_value(pci_dev, class,     FSACL_aR, probe);
+        twimap_export_value(pci_dev, binding,   FSACL_aR, probe);
+        twimap_export_list (pci_dev, io_bases,  FSACL_aR, probe);
     }
 }
 EXPORT_TWIFS_PLUGIN(pci_devs, pci_build_fsmapping);
index 396c9bbf83c90684944bf3e9f7c8e4acfc2db066..8676b3fce733ad52fed8c5674fd5af313b093a79 100644 (file)
@@ -166,7 +166,9 @@ static void
 hwrtc_twifs_export(struct hwrtc_potens* pot)
 {
     const char* name = pot->rtc_proxy->name_val;
-    struct twimap* rtc_mapping = twifs_mapping(NULL, pot, name);
+    struct twimap* rtc_mapping;
+    
+    rtc_mapping = twifs_mapping(NULL, pot, FSACL_aR, name);
     rtc_mapping->read = __hwrtc_readinfo;
 }
 
index a41c741b6dd111d5685e41b4fca3922169cee2e6..aea7e5829c656c0c4566d50041bd59013a25819e 100644 (file)
@@ -39,8 +39,9 @@
 #define prefetch_rd(ptr, ll)    __builtin_prefetch((ptr), 0, ll)
 #define prefetch_wr(ptr, ll)    __builtin_prefetch((ptr), 1, ll)
 
-#define stringify(v) #v
-#define stringify__(v) stringify(v)
+#define v__(v)                  (v)
+#define stringify(v)            #v
+#define stringify__(v)          stringify(v)
 
 #define compact                 __attribute__((packed))
 #define align(v)                __attribute__((aligned (v)))
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 6feb2aa0447769b7f5d68fda278936774036d8a8..bba939cadc997221427692dad2caebfec4d41e11 100644 (file)
@@ -13,6 +13,7 @@
 #include <lunaix/status.h>
 #include <lunaix/spike.h>
 #include <lunaix/bcache.h>
+#include <lunaix/fs_acl.h>
 
 #include <usr/lunaix/fstypes.h>
 
@@ -248,6 +249,11 @@ struct v_inode
     u32_t link_count;
     u32_t lb_usage;
     u32_t fsize;
+
+    u32_t acl;
+    uid_t uid;
+    gid_t gid;
+
     void* data; // 允许底层FS绑定他的一些专有数据
     struct llist_header aka_dnodes;
     struct llist_header xattrs;
@@ -389,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,
@@ -707,4 +717,28 @@ check_symlink_node(struct v_inode* inode)
     return check_itype(inode->itype, VFS_IFSYMLINK);
 }
 
+static inline bool
+check_allow_ops(struct v_inode* inode, unsigned int perm)
+{
+    return fsacl_allow_ops(perm, inode->acl, inode->uid, inode->gid);
+}
+
+static inline bool
+check_allow_read(struct v_inode* inode)
+{
+    return check_allow_ops(inode, FSACL_aR);
+}
+
+static inline bool
+check_allow_write(struct v_inode* inode)
+{
+    return check_allow_ops(inode, FSACL_aW);
+}
+
+static inline bool
+check_allow_execute(struct v_inode* inode)
+{
+    return check_allow_ops(inode, FSACL_aX);
+}
+
 #endif /* __LUNAIX_VFS_H */
index d00277415115f4044fc28f96f07894eabdb3f8c5..e9c1437fbad306724f8c956962fbdbbbd89748b4 100644 (file)
@@ -160,6 +160,19 @@ fsapi_inode_settime(struct v_inode* inode,
     inode->atime = atime;
 }
 
+static inline void
+fsapi_inode_setaccess(struct v_inode* inode, unsigned int acl)
+{
+    inode->acl = acl;
+}
+
+static inline void
+fsapi_inode_setowner(struct v_inode* inode, uid_t uid, gid_t gid)
+{
+    inode->uid = uid;
+    inode->gid = gid;
+}
+
 static inline void
 fsapi_dnode_setdector(struct v_dnode* dnode, 
                       dnode_free free_cb)
index 50579aeed5d6eb580a3af755cfd98116eb785e62..733db19c1770692b7e7e3b88202a3d2a20ad5809 100644 (file)
@@ -6,26 +6,44 @@
 #include <lunaix/fs/twimap.h>
 #include <lunaix/spike.h>
 
+struct twifs_ops
+{
+    int (*write)(struct v_inode* inode,
+                    void* buffer,
+                    size_t len,
+                    size_t fpos);
+    int (*read)(struct v_inode* inode,
+                void* buffer,
+                size_t len,
+                size_t fpos);
+};
+
 struct twifs_node
 {
     struct hstr name;
     inode_t ino_id;
     void* data;
     u32_t itype;
+    int acl;
+
     char name_val[VFS_NAME_MAXLEN];
     struct llist_header children;
     struct llist_header siblings;
-    struct
-    {
-        int (*write)(struct v_inode* inode,
-                     void* buffer,
-                     size_t len,
-                     size_t fpos);
-        int (*read)(struct v_inode* inode,
-                    void* buffer,
-                    size_t len,
-                    size_t fpos);
-    } ops;
+    struct twifs_ops ops;
+};
+
+struct twifs_export
+{
+    char* name;
+    int acl;
+    struct twifs_ops ops;
+};
+
+struct twimap_export
+{
+    char* name;
+    int acl;
+    struct twimap_ops ops;
 };
 
 #define twinode_getdata(inode, type)                                           \
@@ -38,32 +56,78 @@ struct twifs_node
 #define EXPORT_TWIFS_PLUGIN(label, plg_init)                                   \
     export_ldga_el(twiplugin_inits, label, ptr_t, plg_init)
 
-void
-twifs_register_plugins();
+#define __twifs_export_base(name_, acl_) \
+            .name=stringify(name_), .acl=(acl_)
+
+#define twifs_node_ro(name_, acl_)                        \
+        struct twifs_export __twifs_exp_##name_ =           \
+            { __twifs_export_base(name_, acl_),             \
+                .ops = { .read =  __twifs_read_##name_ }}
+
+#define twifs_node_rw(name_, acl_)                        \
+        struct twifs_export __twifs_exp_##name_ =           \
+            { __twifs_export_base(name_, acl_),             \
+                .ops = { .read =  __twifs_read_##name_,         \
+                         .write =  __twifs_write_##name_ }}
+
+#define twimap_value_export(name_, acl_)                    \
+        struct twimap_export __twimap_exp_##name_ =          \
+            { __twifs_export_base(name_, acl_),             \
+                .ops = { .read =  __twimap_read_##name_ }}
+
+#define twimap_list_export(name_, acl_)                     \
+        struct twimap_export __twimap_exp_##name_ =          \
+            { __twifs_export_base(name_, acl_),             \
+                .ops = { .read =  __twimap_read_##name_,         \
+                         .go_next =  __twimap_gonext_##name_,   \
+                         .reset =  __twimap_reset_##name_, }}
+
+#define twifs_export(parent, name_, data_)      \
+        twifs_basic_node_from(parent, &__twifs_exp_##name_, data_)
+
+#define twimap_export(parent, name_, data_)      \
+        twifs_mapped_node_from(parent, &__twimap_exp_##name_, data_)
+
+#define twifs_export_ro(parent, name_, acl_, data_)                     \
+        ({                                                              \
+            twifs_node_ro(name_, acl_);                                 \
+            twifs_export(parent, name_, data_);                        \
+        })
+
+#define twimap_export_value(parent, name_, acl_, data_)                 \
+        ({                                                              \
+            twimap_value_export(name_, acl_);                           \
+            twimap_export(parent, name_, data_);                        \
+        })
+
+#define twimap_export_list(parent, name_, acl_, data_)                  \
+        ({                                                              \
+            twimap_list_export(name_, acl_);                            \
+            twimap_export(parent, name_, data_);                        \
+        })
 
 void
-twifs_init();
+twifs_register_plugins();
 
 struct twifs_node*
 twifs_file_node_vargs(struct twifs_node* parent, const char* fmt, va_list args);
 
-struct twifs_node*
-twifs_file_node(struct twifs_node* parent, const char* fmt, ...);
-
 struct twifs_node*
 twifs_dir_node(struct twifs_node* parent, const char* fmt, ...);
 
 int
 twifs_rm_node(struct twifs_node* node);
 
-struct twimap*
-twifs_mapping(struct twifs_node* parent, void* data, const char* fmt, ...);
+struct twifs_node*
+twifs_basic_node_from(struct twifs_node* parent, 
+                        struct twifs_export* exp_def, void* data);
 
-#define twimap_entry_simple(parent, name, data, read_cb)                       \
-    ({                                                                         \
-        struct twimap* map = twifs_mapping((parent), (data), (name));          \
-        map->read = (read_cb);                                                 \
-        map;                                                                   \
-    })
+struct twifs_node*
+twifs_mapped_node_from(struct twifs_node* parent, 
+                        struct twimap_export* exp_def, void* data);
+
+struct twimap*
+twifs_mapping(struct twifs_node* parent, 
+                void* data, int acl, const char* fmt, ...);
 
 #endif /* __LUNAIX_TWIFS_H */
index c9d56a2aaa6a1de1dcd8a8a29cdf74ed88b43808..3086c633c44d41b46be2e7ffadd9cd8a9f60a76b 100644 (file)
@@ -8,15 +8,29 @@
 
 extern struct v_file_ops twimap_file_ops;
 
+#define __TWIMAP_OPS    \
+        void (*read)(struct twimap* mapping);   \
+        int (*go_next)(struct twimap* mapping); \
+        void (*reset)(struct twimap* mapping);
+
+struct twimap;
+struct twimap_ops
+{
+    __TWIMAP_OPS
+};
+
 struct twimap
 {
     void* index;
     void* buffer;
     void* data;
     size_t size_acc;
-    void (*read)(struct twimap* mapping);
-    int (*go_next)(struct twimap* mapping);
-    void (*reset)(struct twimap* mapping);
+    union
+    {
+        struct twimap_ops ops;
+        struct { __TWIMAP_OPS };
+    };
+    
 };
 
 int
diff --git a/lunaix-os/includes/lunaix/fs_acl.h b/lunaix-os/includes/lunaix/fs_acl.h
new file mode 100644 (file)
index 0000000..43ab5e2
--- /dev/null
@@ -0,0 +1,76 @@
+#ifndef __LUNAIX_FS_ACL_H
+#define __LUNAIX_FS_ACL_H
+
+#include <lunaix/usrscope.h>
+#include "compiler.h"
+
+#define FSACL_READ     4
+#define FSACL_WRITE    2
+#define FSACL_EXEC     1
+
+#define FSACL_MASK     03777
+#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_uR      FSACL_U(FSACL_READ)
+#define FSACL_uW      FSACL_U(FSACL_WRITE)
+#define FSACL_uX      FSACL_U(FSACL_EXEC)
+
+#define FSACL_gR      FSACL_G(FSACL_READ)
+#define FSACL_gW      FSACL_G(FSACL_WRITE)
+#define FSACL_gX      FSACL_G(FSACL_EXEC)
+
+#define FSACL_oR      FSACL_O(FSACL_READ)
+#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)
+#define FSACL_WR      (FSACL_uWR | FSACL_gWR)
+// permitted execute (any usr or group matched)
+#define FSACL_X       (FSACL_uX | FSACL_gX)
+
+#define FSACL_u_      0
+#define FSACL_g_      0
+#define FSACL_o_      0
+
+// any
+#define FSACL_aR      (FSACL_uR | FSACL_gR | FSACL_oR)
+#define FSACL_aW      (FSACL_uW | FSACL_gW | FSACL_oW)
+#define FSACL_aX      (FSACL_uX | FSACL_gX | FSACL_oX)
+
+// user/group
+#define FSACL_ugR      (FSACL_uR | FSACL_gR)
+#define FSACL_ugW      (FSACL_uW | FSACL_gW)
+#define FSACL_ugX      (FSACL_uX | FSACL_gX)
+
+
+#define __fsacl_sel(scope, type)    (FSACL_##scope##type)
+#define FSACL_u(r, w, x)            \
+        (v__(__fsacl_sel(u, r)) | v__(__fsacl_sel(u, w)) | v__(__fsacl_sel(u, x)))
+
+#define FSACL_g(r, w, x)            \
+        (v__(__fsacl_sel(g, r)) | v__(__fsacl_sel(g, w)) | v__(__fsacl_sel(g, x)))
+
+#define FSACL_o(r, w, x)            \
+        (v__(__fsacl_sel(o, r)) | v__(__fsacl_sel(o, w)) | v__(__fsacl_sel(o, x)))
+
+#define FSACL_DEFAULT               \
+        (FSACL_u(R, W, X) | FSACL_g(R, W, X) | FSACL_o(R, _, 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)
+{
+    return !!(acl & ops & check_current_acl(uid, gid));
+}
+
+#endif /* __LUNAIX_FS_ACL_H */
diff --git a/lunaix-os/includes/lunaix/limits.h b/lunaix-os/includes/lunaix/limits.h
new file mode 100644 (file)
index 0000000..9855801
--- /dev/null
@@ -0,0 +1,6 @@
+#ifndef __LUNAIX_LIMITS_H
+#define __LUNAIX_LIMITS_H
+
+#define NGROUPS_MAX     128
+
+#endif /* __LUNAIX_LIMITS_H */
index 86e485e27a599d78c051d1d9879e3f4b8153f87c..868a9fc290bc97a53ee3bac804b401cf87da54fd 100644 (file)
@@ -13,6 +13,8 @@
 #include <lunaix/types.h>
 #include <lunaix/spike.h>
 #include <lunaix/hart_state.h>
+#include <lunaix/usrscope.h>
+
 #include <stdint.h>
 
 
@@ -113,7 +115,7 @@ struct thread
 {
     /*
         Any change to *critical section*, including layout, size
-        must be reflected in arch/x86/interrupt.S.inc to avoid
+        must be reflected in arch/<arch>/interrupt.S.inc to avoid
         disaster!
      */
     struct
@@ -167,6 +169,14 @@ struct proc_info
         pid_t pgid;
         time_t created;
 
+        uid_t euid;
+        uid_t suid;
+        gid_t egid;
+        gid_t sgid;
+
+        struct user_scope uscope;
+        struct v_dnode* root;
+
         int state;
         int exit_code;
     };
@@ -463,5 +473,40 @@ thread_stats_user_elapse(struct thread* thread)
     return stats->last_entry - stats->last_leave;
 }
 
+static inline struct user_scope*
+current_user_scope()
+{
+    return &__current->uscope;
+}
+
+static inline uid_t must_inline
+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 e065273ce93a20ef00d8a2e53aed9f30963711a0..6ce5fcf3b71873e3ea2b7ce4243c03bff658aac0 100644 (file)
@@ -2,6 +2,7 @@
 #define __LUNAIX_TYPES_H
 
 #include <lunaix/compiler.h>
+#include <lunaix/limits.h>
 #include <stdarg.h>
 #include <usr/lunaix/types.h>
 
diff --git a/lunaix-os/includes/lunaix/usercaps.h b/lunaix-os/includes/lunaix/usercaps.h
new file mode 100644 (file)
index 0000000..b30aea9
--- /dev/null
@@ -0,0 +1,19 @@
+#ifndef __LUNAIX_USERCAPS_H
+#define __LUNAIX_USERCAPS_H
+
+typedef unsigned long caps_t;
+
+/*
+ *  Definition of user capabilities (withdrawn draft POSIX.1e) 
+ */
+
+#define CAP_SETUID          0
+#define CAP_SETGID          1
+#define CAP_CHOWN           2
+#define CAP_DAC_OVERRIDE    3
+#define CAP_FSETID          4
+#define CAP_KILL            5
+#define CAP_SYS_CHROOT      6
+#define CAP_SYS_TIM         7
+
+#endif /* __LUNAIX_USERCAPS_H */
diff --git a/lunaix-os/includes/lunaix/usrscope.h b/lunaix-os/includes/lunaix/usrscope.h
new file mode 100644 (file)
index 0000000..8de27b7
--- /dev/null
@@ -0,0 +1,60 @@
+#ifndef __LUNAIX_USRSCOPE_H
+#define __LUNAIX_USRSCOPE_H
+
+#include <lunaix/types.h>
+#include "usercaps.h"
+
+struct ugroup_obj
+{
+    gid_t* list;
+    unsigned int maxcap;
+    unsigned int refs;
+};
+
+struct user_scope
+{
+    uid_t ruid;
+    gid_t rgid;
+    caps_t capabilities;
+
+    struct ugroup_obj* grps;
+};
+
+/*
+    Process ACL check result. 
+    The encoding here is designed to be the mask for file ACL value
+*/
+enum acl_match
+{
+    ACL_MATCH_U  = 0b111000000, // (U)ser
+    ACL_MATCH_G  = 0b000111000, // (G)roup
+    ACL_NO_MATCH = 0b000000111, // (O)ther
+};
+
+#define user_groups(uscope)     ((uscope)->grps)
+
+#define grp_list_end       ((gid_t)-1)
+
+int 
+uscope_setgroups(struct user_scope* proc_usr, 
+                 const gid_t* grps, unsigned int len);
+
+void 
+uscope_copy(struct user_scope* from, struct user_scope* to);
+
+bool
+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)
+{
+    return !!(proc_usr->capabilities & (1UL << cap));
+}
+
+#endif /* __LUNAIX_USRSCOPE_H */
index 186f5f48fa20f24c57a3bbdae2173ff747550a3a..36af62e74467fe38dda4297286299a412f9ffad5 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)
 
 /* Mount with block-cache-disabled flag */
 #define MNT_NC (1 << 1)
 
+typedef unsigned int mode_t;
+typedef unsigned int nlink_t;
+
 struct file_stat
 {
-    dev_t st_dev;
-    ino_t st_ino;
-    unsigned int mode;
-    dev_t st_rdev;
-    off_t st_size;
-    size_t st_blksize;
-    size_t st_ioblksize;
-    size_t st_blocks;
+    dev_t   st_dev;
+    ino_t   st_ino;
+    mode_t  st_mode;
+    nlink_t st_nlink;
+    uid_t   st_uid;
+    gid_t   st_gid;
+    dev_t   st_rdev;
+    off_t   st_size;
+    size_t  st_blksize;
+    size_t  st_blocks;
+
+    unsigned long st_atim;
+    unsigned long st_ctim;
+    unsigned long st_mtim;
+
+    size_t  st_ioblksize;
 };
 
 #endif /* __LUNAIX_FNCTL_DEFS_H */
index df37b6163e2901aee20adb5d44dc9bb322568ba6..e4572322c0f019988fd15c4ce86ec77f158b8592 100644 (file)
@@ -36,5 +36,7 @@
 #define EAGAIN -30
 #define EDEADLK -31
 #define EDQUOT -32
+#define EPERM -33
+#define EACCESS -34
 
 #endif /* __LUNAIX_STATUS_H */
index 19094e97fd9fc8426edc11e3a01aa123242208c9..3dbddb528c7d6f3a53019644229e4db94ce4002e 100644 (file)
@@ -24,6 +24,8 @@ typedef signed long ssize_t;
 
 typedef int pid_t;
 typedef int tid_t;
+typedef int uid_t;
+typedef int gid_t;
 
 typedef __SIZE_TYPE__ size_t;
 
index 8e92773e54fba9df8055ca8b172a14a8b0348151..3e0a7be39e3a5e81495d66da3d00be896944f868 100644 (file)
@@ -17,6 +17,7 @@ sources([
     "bcache.c",
     "syscall.c",
     "changeling.c",
+    "usrscope.c",
     "kprint/kp_records.c",
     "kprint/kprintf.c",
     "time/clock.c",
index 7dae2b8c67f2548f4f1a21c41f0a3a721fa62d61..ddc360a4e952a9250bb96b6b032d663585753812 100644 (file)
@@ -9,37 +9,37 @@ blk_mapping_init()
     blk_root = twifs_dir_node(NULL, "block");
 }
 
-void
-__blk_rd_lblksz(struct twimap* map)
+static void
+__twimap_read_lblk_size(struct twimap* map)
 {
     struct block_dev* bdev = twimap_data(map, struct block_dev*);
     size_t lblksz = bdev->blk_size;
     twimap_printf(map, "%u", lblksz);
 }
 
-void
-__blk_rd_name(struct twimap* map)
+static void
+__twimap_read_name(struct twimap* map)
 {
     struct block_dev* bdev = twimap_data(map, struct block_dev*);
     twimap_printf(map, "%s", bdev->name);
 }
 
-void
-__blk_rd_start_lba(struct twimap* map)
+static void
+__twimap_read_lba_begin(struct twimap* map)
 {
     struct block_dev* bdev = twimap_data(map, struct block_dev*);
     twimap_printf(map, "%d", bdev->start_lba);
 }
 
-void
-__blk_rd_end_lba(struct twimap* map)
+static void
+__twimap_read_lba_end(struct twimap* map)
 {
     struct block_dev* bdev = twimap_data(map, struct block_dev*);
     twimap_printf(map, "%d", bdev->end_lba);
 }
 
-void
-__blk_rd_size(struct twimap* map)
+static void
+__twimap_read_size(struct twimap* map)
 {
     struct block_dev* bdev = twimap_data(map, struct block_dev*);
     twimap_printf(
@@ -49,22 +49,15 @@ __blk_rd_size(struct twimap* map)
 void
 __map_internal(struct block_dev* bdev, void* fsnode)
 {
-    struct twifs_node* dev_root = (struct twifs_node*)fsnode;
-
-    struct twimap* map = twifs_mapping(dev_root, bdev, "size");
-    map->read = __blk_rd_size;
-
-    map = twifs_mapping(dev_root, bdev, "lblk_size");
-    map->read = __blk_rd_lblksz;
-
-    map = twifs_mapping(dev_root, bdev, "name");
-    map->read = __blk_rd_name;
-
-    map = twifs_mapping(dev_root, bdev, "begin");
-    map->read = __blk_rd_start_lba;
-
-    map = twifs_mapping(dev_root, bdev, "end");
-    map->read = __blk_rd_end_lba;
+    struct twifs_node* dev_root;
+    
+    dev_root = (struct twifs_node*)fsnode;
+    
+    twimap_export_value(dev_root, size,      FSACL_aR, bdev);
+    twimap_export_value(dev_root, lblk_size, FSACL_aR, bdev);
+    twimap_export_value(dev_root, name,      FSACL_aR, bdev);
+    twimap_export_value(dev_root, lba_begin, FSACL_aR, bdev);
+    twimap_export_value(dev_root, lba_end,   FSACL_aR, bdev);
 }
 
 void
index a41364df5557f799da79f3715c65aebf1a223118..42452f859899acead12d94cf50ba3196919aa1c0 100644 (file)
@@ -133,7 +133,7 @@ device_sysconf_load()
 }
 
 static int
-__devdb_db_gonext(struct twimap* mapping)
+__twimap_gonext_devtab(struct twimap* mapping)
 {
     struct device_def* current = twimap_index(mapping, struct device_def*);
     if (current->dev_list.next == &dev_registry_flat) {
@@ -145,7 +145,7 @@ __devdb_db_gonext(struct twimap* mapping)
 }
 
 static void
-__devdb_twifs_lsdb(struct twimap* mapping)
+__twimap_read_devtab(struct twimap* mapping)
 {
     char flags[64];
     struct device_def* def = twimap_index(mapping, struct device_def*);
@@ -161,8 +161,8 @@ __devdb_twifs_lsdb(struct twimap* mapping)
                   flags);
 }
 
-void
-__devdb_reset(struct twimap* map)
+static void
+__twimap_reset_devtab(struct twimap* map)
 {
     map->index =
       container_of(dev_registry_flat.next, struct device_def, dev_list);
@@ -171,9 +171,6 @@ __devdb_reset(struct twimap* map)
 static void
 devdb_twifs_plugin()
 {
-    struct twimap* map = twifs_mapping(NULL, NULL, "devtab");
-    map->reset = __devdb_reset;
-    map->read = __devdb_twifs_lsdb;
-    map->go_next = __devdb_db_gonext;
+    twimap_export_list(NULL, devtab, FSACL_aR, NULL);
 }
 EXPORT_TWIFS_PLUGIN(devdb, devdb_twifs_plugin);
\ No newline at end of file
index c105f66a71bbed5072e6544de25b3bea75b9c27e..969c8288b2f0b58b91d8c6183e16dc017f770284 100644 (file)
@@ -179,6 +179,12 @@ devfs_init_inode(struct v_superblock* vsb, struct v_inode* inode)
 {
     inode->ops = &devfs_inode_ops;
     inode->default_fops = &devfs_file_ops;
+
+    // we set default access right to be 0775.
+    // TODO need a way to allow this to be changed
+    
+    fsapi_inode_setaccess(inode, FSACL_DEFAULT);
+    fsapi_inode_setowner(inode, 0, 0);
 }
 
 int
index c1028828543d4d39dd081ab5f00f9b0c93a5d33f..e67c44d7c1ca7e37c32281f450f3e454e1c63928 100644 (file)
@@ -12,7 +12,7 @@ __try_wait(bool check_stall)
     if (waitq_empty(current_wq)) {
         return;
     }
-    
+
     block_current_thread();
 
     if (!check_stall) {
@@ -54,7 +54,7 @@ pwait_check_stall(waitq_t* queue)
 void
 pwake_one(waitq_t* queue)
 {
-    if (llist_empty(&queue->waiters)) {
+    if (waitq_empty(queue)) {
         return;
     }
 
@@ -69,7 +69,7 @@ pwake_one(waitq_t* queue)
 void
 pwake_all(waitq_t* queue)
 {
-    if (llist_empty(&queue->waiters)) {
+    if (waitq_empty(queue)) {
         return;
     }
 
index 0dace13e9352ec6d2e2009968972846c01bcb8b5..3c1fb42d8c2385b4be5729c45b9fdb91c9d21814 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) {
@@ -223,7 +224,8 @@ exec_load_byname(struct exec_host* container, const char* filename)
         goto done;
     }
 
-    if ((errno = vfs_open(dnode, &file))) {
+    if (!check_allow_execute(dnode->inode)) {
+        errno = EPERM;
         goto done;
     }
 
@@ -231,6 +233,10 @@ exec_load_byname(struct exec_host* container, const char* filename)
         errno = EISDIR;
         goto done;
     }
+    
+    if ((errno = vfs_open(dnode, &file))) {
+        goto done;
+    }
 
     errno = exec_load(container, file);
 
@@ -270,16 +276,11 @@ exec_kexecve(const char* filename, const char* argv[], const char* envp[])
     return errno;
 }
 
-__DEFINE_LXSYSCALL3(int,
-                    execve,
-                    const char*,
-                    filename,
-                    const char*,
-                    argv[],
-                    const char*,
-                    envp[])
+__DEFINE_LXSYSCALL3(int, execve, const char*, filename,
+                    const char*, argv[], const char*, envp[])
 {
     int errno = 0;
+    int acl;
     struct exec_host container;
 
     if (!argv || !envp) {
@@ -303,6 +304,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));
@@ -310,6 +320,5 @@ done:
     // Always yield the process that want execve!
     schedule();
 
-    // this will never get executed!
-    return -1;
+    unreachable;
 }
\ No newline at end of file
index 14b2218fdfe265474654d36b1ff69dfb88b0562e..1f123151eac9ef08527bce3757202dfc339637df 100644 (file)
@@ -30,6 +30,7 @@
 #define IMODE_ORD             0x0004
 #define IMODE_OWR             0x0002
 #define IMODE_OEX             0x0001
+#define IMODE_ACL_MASK        0x01ff
 
 #define ext2_aligned                    compact align(4)
 #define to_ext2ino_id(fsblock_id)       ((fsblock_id) + 1)
index 389bdeadb6a38bcceed054957c9b41d0c95f2c95..5871d07d8f6822b79c479c3f30e0dfc305487eeb 100644 (file)
@@ -295,6 +295,10 @@ ext2ino_fill(struct v_inode* inode, ino_t ino_id)
                                b_ino->i_mtime, 
                                b_ino->i_atime);
     
+    fsapi_inode_setaccess(inode, b_ino->i_mode & IMODE_ACL_MASK);
+    fsapi_inode_setowner(inode, b_ino->i_uid,
+                                b_ino->i_gid);
+    
     __ext2ino_fill_common(inode, ino_id);
 
     if (check_itype(b_ino->i_mode, IMODE_IFLNK)) {
index 1fedef6505c0fc1edb85e6131cba9a2286f74f37..452bcdf724516eab54590b9ee8063c869121c85a 100644 (file)
@@ -4,8 +4,8 @@
 
 extern struct llist_header all_mnts;
 
-void
-__mount_read(struct twimap* map)
+static void
+__twimap_read_mounts(struct twimap* map)
 {
     char path[512];
     struct v_mount* mnt = twimap_index(map, struct v_mount*);
@@ -20,8 +20,8 @@ __mount_read(struct twimap* map)
     twimap_printf(map, "\n");
 }
 
-int
-__mount_next(struct twimap* map)
+static int
+__twimap_gonext_mounts(struct twimap* map)
 {
     struct v_mount* mnt = twimap_index(map, struct v_mount*);
     if (mnt->list.next == &all_mnts) {
@@ -31,14 +31,14 @@ __mount_next(struct twimap* map)
     return 1;
 }
 
-void
-__mount_reset(struct twimap* map)
+static void
+__twimap_reset_mounts(struct twimap* map)
 {
     map->index = container_of(all_mnts.next, struct v_mount, list);
 }
 
 void
-__version_rd(struct twimap* map)
+__twimap_read_version(struct twimap* map)
 {
     twimap_printf(map,
                   "Lunaix "
@@ -49,12 +49,7 @@ __version_rd(struct twimap* map)
 void
 vfs_export_attributes()
 {
-    struct twimap* map = twifs_mapping(NULL, NULL, "mounts");
-    map->read = __mount_read;
-    map->go_next = __mount_next;
-    map->reset = __mount_reset;
-
-    map = twifs_mapping(NULL, NULL, "version");
-    map->read = __version_rd;
+    twimap_export_list (NULL, mounts,  FSACL_ugR, NULL);
+    twimap_export_value(NULL, version, FSACL_ugR, NULL);
 }
 EXPORT_TWIFS_PLUGIN(vfs_general, vfs_export_attributes);
\ No newline at end of file
index 722ffd0e212de5289fcf38b75f8289dfa41ac542..8638905b44a9bb2ff46853324c7a971e8b34f91d 100644 (file)
@@ -80,7 +80,7 @@ fsm_itnext(struct fs_iter* iterator)
 }
 
 static void
-read_fslist(struct twimap *mapping)
+__twimap_read_fstab(struct twimap *mapping)
 {
     struct filesystem *pos, *n;
     llist_for_each(pos, n, &fs_flatlist, fs_flat)
@@ -92,7 +92,6 @@ read_fslist(struct twimap *mapping)
 static void
 fstab_twifs_plugin()
 {
-    struct twimap* map = twifs_mapping(NULL, NULL, "fstab");
-    map->read = read_fslist;
+    twimap_export_value(NULL, fstab, FSACL_ugR, NULL);
 }
 EXPORT_TWIFS_PLUGIN(fstab, fstab_twifs_plugin);
\ No newline at end of file
index ab66ca45a933b76e68cd4a86226d636f6186b5e8..ab6a396e1000b2035a0522fece687c5bbf9a0e0e 100644 (file)
@@ -1,5 +1,5 @@
 #include <klibc/string.h>
-#include <lunaix/fs.h>
+#include <lunaix/fs/api.h>
 #include "iso9660.h"
 #include <lunaix/mm/cake.h>
 #include <lunaix/mm/valloc.h>
@@ -87,10 +87,17 @@ iso9660_fill_inode(struct v_inode* inode, struct iso_drecache* dir, int ino)
         inode->ctime = iso9660_dt2unix(&xattr->ctime);
         inode->mtime = iso9660_dt2unix(&xattr->mtime);
 
+        fsapi_inode_setaccess(inode, xattr->perm);
+        fsapi_inode_setowner(inode, xattr->owner.le, xattr->group.le);
+
         inode->lb_addr += dir->xattr_len * dir->fu_size;
 
         vfree(xattr);
     }
+    else {
+        fsapi_inode_setaccess(inode, FSACL_u(R, W, _) | FSACL_g(R, W, _));
+        fsapi_inode_setowner(inode,  0, 0);
+    }
 
     inode->ctime = dir->ctime ? dir->ctime : inode->ctime;
     inode->mtime = dir->mtime ? dir->mtime : inode->mtime;
index 708a28a03ca32dd35863fcda00bec294aa49545e..754301be8148433f29f3feecff4ceabf78c7588a 100644 (file)
@@ -289,6 +289,7 @@ struct iso_drecache
     time_t ctime;
     time_t atime;
     time_t mtime;
+
     struct hstr name;
     char name_val[ISO9660_IDLEN];
 };
index 282ae784ec2bdaa4a1ee12b0a32a7497dbb884b6..b62b77faa8788d273888a7828933a56b0c1ffa13 100644 (file)
@@ -293,6 +293,11 @@ vfs_check_writable(struct v_dnode* dnode)
     if ((dnode->mnt->flags & MNT_RO)) {
         return EROFS;
     }
+
+    if (!check_allow_write(dnode->inode)) {
+        return EPERM;
+    }
+
     return 0;
 }
 
index 84e04d0e9bb0eed8ae229e7818f259951b24ead3..246e90327cc3219af3f03d418c0fba366dc4aea6 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,13 +93,21 @@ __vfs_walk(struct v_dnode* start,
 
         lock_dnode(current_level);
 
+        if (!check_allow_execute(current_inode)) {
+            errno = EACCESS;
+            unlock_dnode(current_level);
+            goto error;
+        }
+
         dnode = vfs_dcache_lookup(current_level, &name);
 
-        if (!dnode) {
+        if (!dnode) 
+        {
             dnode = vfs_d_alloc(current_level, &name);
 
             if (!dnode) {
                 errno = ENOMEM;
+                unlock_dnode(current_level);
                 goto error;
             }
 
@@ -123,7 +141,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 +188,7 @@ __vfs_walk(struct v_dnode* start,
 
 cleanup:
     vfs_d_free(dnode);
+
 error:
     *dentry = NULL;
     return errno;
@@ -204,4 +224,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..094408876320adc47c955f34b346555465280589 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_DEFAULT);
+    }
+
+    return errno;
 }
 
 int
index 165d0bd0a17070c6099717ec06c3d11cff21a85c..2fdf02354042898501ba26ef320d6fbf223b7822 100644 (file)
 #include <asm/pagetable.h>
 
 static struct twifs_node* fs_root;
-
 static struct cake_pile* twi_pile;
-
 static volatile u32_t inode_id = 0;
 
 extern const struct v_file_ops twifs_file_ops;
 extern const struct v_inode_ops twifs_inode_ops;
 
-struct twifs_node*
+static struct twifs_node*
 __twifs_new_node(struct twifs_node* parent,
-                 const char* name,
-                 int name_len,
-                 u32_t itype)
+                 const char* name, int name_len, u32_t itype)
 {
     struct twifs_node* node = cake_grab(twi_pile);
     memset(node, 0, sizeof(*node));
@@ -53,14 +49,21 @@ __twifs_new_node(struct twifs_node* parent,
     return node;
 }
 
-void
+static void
 __twifs_init_inode(struct v_superblock* vsb, struct v_inode* inode)
 {
     inode->ops = (struct v_inode_ops*)&twifs_inode_ops;
     inode->default_fops = (struct v_file_ops*)&twifs_file_ops;
+
+
+    // we set default access right to be 0660.
+    // TODO need a way to allow this to be changed
+    
+    fsapi_inode_setaccess(inode, FSACL_DEFAULT);
+    fsapi_inode_setowner(inode, 0, 0);
 }
 
-int
+static int
 __twifs_mount(struct v_superblock* vsb, struct v_dnode* mount_point)
 {
     vsb->ops.init_inode = __twifs_init_inode;
@@ -79,13 +82,13 @@ __twifs_mount(struct v_superblock* vsb, struct v_dnode* mount_point)
     return 0;
 }
 
-int
+static int
 __twifs_unmount(struct v_superblock* vsb)
 {
     return 0;
 }
 
-int
+static int
 __twifs_fwrite(struct v_inode* inode, void* buffer, size_t len, size_t fpos)
 {
     struct twifs_node* twi_node = (struct twifs_node*)inode->data;
@@ -95,13 +98,13 @@ __twifs_fwrite(struct v_inode* inode, void* buffer, size_t len, size_t fpos)
     return twi_node->ops.write(inode, buffer, len, fpos);
 }
 
-int
+static int
 __twifs_fwrite_pg(struct v_inode* inode, void* buffer, size_t fpos)
 {
     return __twifs_fwrite(inode, buffer, PAGE_SIZE, fpos);
 }
 
-int
+static int
 __twifs_fread(struct v_inode* inode, void* buffer, size_t len, size_t fpos)
 {
     struct twifs_node* twi_node = (struct twifs_node*)inode->data;
@@ -111,13 +114,13 @@ __twifs_fread(struct v_inode* inode, void* buffer, size_t len, size_t fpos)
     return twi_node->ops.read(inode, buffer, len, fpos);
 }
 
-int
+static int
 __twifs_fread_pg(struct v_inode* inode, void* buffer, size_t fpos)
 {
     return __twifs_fread(inode, buffer, PAGE_SIZE, fpos);
 }
 
-struct twifs_node*
+static struct twifs_node*
 __twifs_get_node(struct twifs_node* parent, struct hstr* name)
 {
     if (!parent)
@@ -133,7 +136,7 @@ __twifs_get_node(struct twifs_node* parent, struct hstr* name)
     return NULL;
 }
 
-int
+static int
 __twifs_dirlookup(struct v_inode* inode, struct v_dnode* dnode)
 {
     struct twifs_node* twi_node = (struct twifs_node*)inode->data;
@@ -142,9 +145,9 @@ __twifs_dirlookup(struct v_inode* inode, struct v_dnode* dnode)
         return ENOTDIR;
     }
 
-    struct twifs_node* child_node = __twifs_get_node(twi_node, &dnode->name);
-    if (child_node) {
-        struct v_inode* child_inode = vfs_i_find(inode->sb, child_node->ino_id);
+    struct twifs_node* twinode = __twifs_get_node(twi_node, &dnode->name);
+    if (twinode) {
+        struct v_inode* child_inode = vfs_i_find(inode->sb, twinode->ino_id);
         if (child_inode) {
             goto done;
         }
@@ -153,21 +156,25 @@ __twifs_dirlookup(struct v_inode* inode, struct v_dnode* dnode)
             return ENOENT;
         }
 
-        child_inode->id = child_node->ino_id;
-        child_inode->itype = child_node->itype;
-        child_inode->data = child_node;
+        child_inode->id = twinode->ino_id;
+        child_inode->itype = twinode->itype;
+        child_inode->data = twinode;
+
+        if (twinode->acl != -1) {
+            fsapi_inode_setaccess(child_inode, twinode->acl);
+        }
 
         vfs_i_addhash(child_inode);
 
     done:
-        dnode->data = child_node->data;
+        dnode->data = twinode->data;
         vfs_assign_inode(dnode, child_inode);
         return 0;
     }
     return ENOENT;
 }
 
-int
+static int
 __twifs_iterate_dir(struct v_file* file, struct dir_context* dctx)
 {
     struct twifs_node* twi_node = (struct twifs_node*)(file->inode->data);
@@ -190,7 +197,7 @@ __twifs_iterate_dir(struct v_file* file, struct dir_context* dctx)
     return 0;
 }
 
-int
+static int
 __twifs_openfile(struct v_inode* inode, struct v_file* file)
 {
     struct twifs_node* twi_node = (struct twifs_node*)inode->data;
@@ -200,6 +207,30 @@ __twifs_openfile(struct v_inode* inode, struct v_file* file)
     return ENOTSUP;
 }
 
+static inline struct twifs_node*
+__twifs_create_node(struct twifs_node* parent,
+                    const char* name, int acl)
+{
+    struct twifs_node* twi_node;
+    unsigned int size;
+
+    size = strlen(name);
+    parent = parent ?: fs_root;
+    twi_node = __twifs_new_node(parent, name, size, F_FILE);
+    twi_node->acl = acl;
+
+    return twi_node;
+}
+
+static int
+__twifs_twimap_file_read(struct v_inode* inode, 
+                         void* buf, size_t len, size_t fpos)
+{
+    struct twimap* map = twinode_getdata(inode, struct twimap*);
+    return twimap_read(map, buf, len, fpos);
+}
+
+
 int
 twifs_rm_node(struct twifs_node* node)
 {
@@ -221,78 +252,90 @@ twifs_file_node_vargs(struct twifs_node* parent, const char* fmt, va_list args)
 }
 
 struct twifs_node*
-twifs_file_node(struct twifs_node* parent, const char* fmt, ...)
+twifs_dir_node(struct twifs_node* parent, const char* fmt, ...)
 {
+    size_t len;
+    char buf[VFS_NAME_MAXLEN];
+    struct twifs_node* twi_node;
+
     va_list args;
     va_start(args, fmt);
 
-    struct twifs_node* twi_node = twifs_file_node_vargs(parent, fmt, args);
+    len = ksnprintfv(buf, fmt, VFS_NAME_MAXLEN, args);
+    twi_node =
+      __twifs_new_node(parent ? parent : fs_root, buf, len, VFS_IFDIR);
+
+    twi_node->acl = FSACL_aR | FSACL_aX;
 
     va_end(args);
 
     return twi_node;
 }
 
+
 struct twifs_node*
-twifs_dir_node(struct twifs_node* parent, const char* fmt, ...)
+twifs_basic_node_from(struct twifs_node* parent, 
+                        struct twifs_export* def, void* data)
 {
-    va_list args;
-    va_start(args, fmt);
-
-    char buf[VFS_NAME_MAXLEN];
-    size_t len = ksnprintfv(buf, fmt, VFS_NAME_MAXLEN, args);
-    struct twifs_node* twi_node =
-      __twifs_new_node(parent ? parent : fs_root, buf, len, VFS_IFDIR);
-
-    va_end(args);
+    struct twifs_node* twi_node;
+    
+    twi_node = __twifs_create_node(parent, def->name, def->acl);
+    twi_node->ops = def->ops;
+    twi_node->data = data;
 
     return twi_node;
 }
 
-void
-twifs_init()
+struct twifs_node*
+twifs_mapped_node_from(struct twifs_node* parent, 
+                        struct twimap_export* def, void* data)
 {
-    struct filesystem* fs;
-    fs = fsapi_fs_declare("twifs", FSTYPE_PSEUDO | FSTYPE_ROFS);
+    struct twifs_node* twi_node;
+    struct twimap* map_;
     
-    fsapi_fs_set_mntops(fs, __twifs_mount, __twifs_unmount);
-    fsapi_fs_finalise(fs);
+    map_     = twimap_create(data);
+    twi_node = __twifs_create_node(parent, def->name, def->acl);
 
-    twi_pile = cake_new_pile("twifs_node", sizeof(struct twifs_node), 1, 0);
-    fs_root = twifs_dir_node(NULL, NULL, 0, 0);
-}
-EXPORT_FILE_SYSTEM(twifs, twifs_init);
+    twi_node->data = map_;
+    twi_node->ops.read = __twifs_twimap_file_read;
+    // twi_node->ops.write = __twifs_twimap_file_write;
 
-void
-twifs_register_plugins()
-{
-    ldga_invoke_fn0(twiplugin_inits);
-}
+    if (def->ops.go_next) {
+        map_->ops.go_next = def->ops.go_next;
+    }
 
-int
-__twifs_twimap_file_read(struct v_inode* inode,
-                         void* buf,
-                         size_t len,
-                         size_t fpos)
-{
-    struct twimap* map = twinode_getdata(inode, struct twimap*);
-    return twimap_read(map, buf, len, fpos);
+    if (def->ops.reset) {
+        map_->ops.reset = def->ops.reset;
+    }
+
+    map_->ops.read = def->ops.read;
+
+    return twi_node;
 }
 
 struct twimap*
-twifs_mapping(struct twifs_node* parent, void* data, const char* fmt, ...)
+twifs_mapping(struct twifs_node* parent, 
+                void* data, int acl, const char* fmt, ...)
 {
     va_list args;
     va_start(args, fmt);
 
     struct twimap* map = twimap_create(data);
     struct twifs_node* node = twifs_file_node_vargs(parent, fmt, args);
+    
     node->ops.read = __twifs_twimap_file_read;
     node->data = map;
+    node->acl = acl;
 
     return map;
 }
 
+void
+twifs_register_plugins()
+{
+    ldga_invoke_fn0(twiplugin_inits);
+}
+
 const struct v_file_ops twifs_file_ops = { .close = default_file_close,
                                            .read = __twifs_fread,
                                            .read_page = __twifs_fread_pg,
@@ -303,4 +346,19 @@ const struct v_file_ops twifs_file_ops = { .close = default_file_close,
 const struct v_inode_ops twifs_inode_ops = { .dir_lookup = __twifs_dirlookup,
                                              .mkdir = default_inode_mkdir,
                                              .rmdir = default_inode_rmdir,
-                                             .open = __twifs_openfile };
\ No newline at end of file
+                                             .open = __twifs_openfile };
+
+
+static void
+twifs_init()
+{
+    struct filesystem* fs;
+    fs = fsapi_fs_declare("twifs", FSTYPE_PSEUDO | FSTYPE_ROFS);
+    
+    fsapi_fs_set_mntops(fs, __twifs_mount, __twifs_unmount);
+    fsapi_fs_finalise(fs);
+
+    twi_pile = cake_new_pile("twifs_node", sizeof(struct twifs_node), 1, 0);
+    fs_root = twifs_dir_node(NULL, NULL, 0, 0);
+}
+EXPORT_FILE_SYSTEM(twifs, twifs_init);
\ No newline at end of file
index 1696d6e961ace4b3ac092809db67cd9dddd42183..32014d34a871e2783ff696ef0bffdce663b4386e 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)
 {
@@ -192,12 +209,12 @@ vfs_dcache_rehash(struct v_dnode* new_parent, struct v_dnode* dnode)
 int
 vfs_open(struct v_dnode* dnode, struct v_file** file)
 {
-    if (!dnode->inode || !dnode->inode->ops->open) {
+    struct v_inode* inode = dnode->inode;
+    
+    if (!inode || !inode->ops->open) {
         return ENOTSUP;
     }
 
-    struct v_inode* inode = dnode->inode;
-
     lock_inode(inode);
 
     struct v_file* vfile = cake_grab(file_pile);
@@ -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;
     }
@@ -846,23 +895,29 @@ __DEFINE_LXSYSCALL3(int, read, int, fd, void*, buf, size_t, count)
         goto done;
     }
 
-    lock_inode(file->inode);
+    if (!check_allow_read(file->inode)) {
+        errno = EPERM;
+        goto done;
+    }
 
-    file->inode->atime = clock_unixtime();
+    inode = file->inode;
+    lock_inode(inode);
 
-    if (check_seqdev_node(file->inode) || (fd_s->flags & FO_DIRECT)) {
-        errno = file->ops->read(file->inode, buf, count, file->f_pos);
+    __vfs_touch_inode(inode, INODE_ACCESSED);
+
+    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);
@@ -891,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;
     }
@@ -932,6 +987,11 @@ __DEFINE_LXSYSCALL3(int, lseek, int, fd, int, offset, int, options)
         goto done;
     }
 
+    if (!check_allow_read(inode)) {
+        errno = EPERM;
+        goto done;
+    }
+
     lock_inode(inode);
 
     int overflow = 0;
@@ -1012,6 +1072,10 @@ vfs_readlink(struct v_dnode* dnode, char* buf, size_t size)
         return ENOTSUP;
     }
 
+    if (!check_allow_read(inode)) {
+        return EPERM;
+    }
+
     lock_inode(inode);
 
     int errno = inode->ops->read_symlink(inode, &link);
@@ -1118,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;
     }
@@ -1214,7 +1283,7 @@ done:
     return DO_STATUS(errno);
 }
 
-int
+static int
 __vfs_do_unlink(struct v_dnode* dnode)
 {
     int errno;
@@ -1224,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;
     }
@@ -1434,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) {
@@ -1453,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;
 }
 
@@ -1489,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;
@@ -1629,12 +1733,21 @@ __DEFINE_LXSYSCALL2(int, fstat, int, fd, struct file_stat*, stat)
     struct v_inode* vino = fds->file->inode;
     struct device* fdev = vino->sb->dev;
 
-    *stat = (struct file_stat){.st_ino = vino->id,
-                               .st_blocks = vino->lb_usage,
-                               .st_size = vino->fsize,
-                               .mode = vino->itype,
-                               .st_ioblksize = PAGE_SIZE,
-                               .st_blksize = vino->sb->blksize};
+    stat->st_ino     = vino->id;
+    stat->st_blocks  = vino->lb_usage;
+    stat->st_size    = vino->fsize;
+    stat->st_blksize = vino->sb->blksize;
+    stat->st_nlink   = vino->link_count;
+    stat->st_uid     = vino->uid;
+    stat->st_gid     = vino->gid;
+
+    stat->st_ctim    = vino->ctime;
+    stat->st_atim    = vino->atime;
+    stat->st_mtim    = vino->mtime;
+
+    stat->st_mode    = (vino->itype << 16) | vino->acl;
+
+    stat->st_ioblksize = PAGE_SIZE;
 
     if (check_device_node(vino)) {
         struct device* rdev = resolve_device(vino->data);
@@ -1654,6 +1767,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 363abc687b5d770113e74fd98f848e529dbe8a7c..dc466287d11019888b77889669c6fe134e6a1a7e 100644 (file)
@@ -99,7 +99,7 @@ kprintf_v(const char* component, const char* fmt, ...)
 }
 
 static void
-__twimap_kprintf_read(struct twimap* map)
+__twimap_read_kmsg(struct twimap* map)
 {
     struct kp_records* __kprecs = twimap_data(map, struct kp_records*);
 
@@ -112,14 +112,14 @@ __twimap_kprintf_read(struct twimap* map)
     {
         time_t s = pos->time / 1000;
         time_t ms = pos->time % 1000;
-        twimap_printf(map, "[%05d.%03d] %s\n", s, ms, pos->content);
+        twimap_printf(map, "[%05d.%03d] %s", s, ms, pos->content);
     }
 }
 
 static void
 kprintf_mapping_init()
 {
-    twimap_entry_simple(NULL, "kmsg", &kprecs, __twimap_kprintf_read);
+    twimap_export_value(NULL, kmsg, FSACL_ugR, &kprecs);
 }
 EXPORT_TWIFS_PLUGIN(kprintf, kprintf_mapping_init);
 
index dc9ee34aae6c94ff768cc5a04bead99c31156993..0395e42da500b12fc04f54e46ea12ef77840fb71 100644 (file)
@@ -159,7 +159,7 @@ lru_remove(struct lru_zone* zone, struct lru_node* node)
 }
 
 static void
-read_lrulist_entry(struct twimap* map)
+__twimap_read_lru_pool(struct twimap* map)
 {
     struct lru_zone* zone;
 
@@ -181,14 +181,14 @@ read_lrulist_entry(struct twimap* map)
 }
 
 static void
-read_lrulist_reset(struct twimap* map)
+__twimap_reset_lru_pool(struct twimap* map)
 {
     map->index = container_of(&zone_lead, struct lru_zone, zones);
     twimap_printf(map, "name, n_objs, hot, n_evt, n_half, n_full, status\n");
 }
 
 static int
-read_lrulist_next(struct twimap* map)
+__twimap_gonext_lru_pool(struct twimap* map)
 {
     struct lru_zone* zone;
     struct llist_header* next;
@@ -206,11 +206,6 @@ read_lrulist_next(struct twimap* map)
 static void
 lru_pool_twimappable()
 {
-    struct twimap* map;
-
-    map = twifs_mapping(NULL, NULL, "lru_pool");
-    map->read = read_lrulist_entry;
-    map->reset = read_lrulist_reset;
-    map->go_next = read_lrulist_next;
+    twimap_export_list(NULL, lru_pool, FSACL_aR, NULL);
 }
 EXPORT_TWIFS_PLUGIN(__lru_twimap, lru_pool_twimappable);
\ No newline at end of file
index b1e699f5307f67f43aae9d5dc60701ba921436d2..179145ace0034f7c93bc599412be0b797e2857c5 100644 (file)
@@ -303,7 +303,7 @@ cake_grab(struct cake_pile* pile)
 
     if (!pos)
         return NULL;
-    
+
     void* piece;
     piece_t found_index, *fl_slot;
     
@@ -337,7 +337,9 @@ int
 cake_release(struct cake_pile* pile, void* area)
 {
     piece_t piece_index;
-    size_t dsize = 0;
+    size_t dsize = 0, maybe_index;
+
+    piece_t *fl_slot;
     struct cake_s *pos, *n;
     struct llist_header* hdrs[2] = { &pile->full, &pile->partial };
 
@@ -347,9 +349,12 @@ cake_release(struct cake_pile* pile, void* area)
             if (pos->first_piece > area) {
                 continue;
             }
-            dsize = (ptr_t)(area - pos->first_piece);
-            piece_index = dsize / pile->piece_size;
-            if (piece_index < pile->pieces_per_cake) {
+            
+            dsize = __ptr(area - pos->first_piece);
+            maybe_index = dsize / pile->piece_size;
+
+            if (maybe_index < pile->pieces_per_cake) {
+                piece_index = (piece_t)maybe_index;
                 goto found;
             }
         }
@@ -360,14 +365,12 @@ cake_release(struct cake_pile* pile, void* area)
 found:
     assert(!(dsize % pile->piece_size));
 
-    piece_t *fl_slot;
+    assert_msg(piece_index != pos->next_free, "double free");
 
     fl_slot = __fl_slot(pos, piece_index);
     *fl_slot = pos->next_free;
     pos->next_free = piece_index;
 
-    assert_msg(*fl_slot != pos->next_free, "double free");
-
     pos->used_pieces--;
     pile->alloced_pieces--;
 
index e2ecb3a54eb5d15da635f4be7f99b3140a25c6d5..cde255c4fdc2201568b027bcb427cfaf2175b5b3 100644 (file)
@@ -3,8 +3,8 @@
 
 extern struct llist_header piles;
 
-int
-__cake_stat_gonext(struct twimap* map)
+static int
+__twimap_gonext_pinkiepie(struct twimap* map)
 {
     struct cake_pile* pile = twimap_index(map, struct cake_pile*);
     if (pile->piles.next == &piles) {
@@ -14,15 +14,15 @@ __cake_stat_gonext(struct twimap* map)
     return 1;
 }
 
-void
-__cake_stat_reset(struct twimap* map)
+static void
+__twimap_reset_pinkiepie(struct twimap* map)
 {
     map->index = container_of(&piles, struct cake_pile, piles);
     twimap_printf(map, "name cakes pages size slices actives\n");
 }
 
-void
-__cake_rd_stat(struct twimap* map)
+static void
+__twimap_read_pinkiepie(struct twimap* map)
 {
     struct cake_pile* pos = twimap_index(map, struct cake_pile*);
     twimap_printf(map,
@@ -35,36 +35,36 @@ __cake_rd_stat(struct twimap* map)
                   pos->alloced_pieces);
 }
 
-void
-__cake_rd_psize(struct twimap* map)
+static void
+__twimap_read_piece_size(struct twimap* map)
 {
     struct cake_pile* pile = twimap_data(map, struct cake_pile*);
     twimap_printf(map, "%u", pile->piece_size);
 }
 
-void
-__cake_rd_ccount(struct twimap* map)
+static void
+__twimap_read_cake_count(struct twimap* map)
 {
     struct cake_pile* pile = twimap_data(map, struct cake_pile*);
     twimap_printf(map, "%u", pile->cakes_count);
 }
 
-void
-__cake_rd_alloced(struct twimap* map)
+static void
+__twimap_read_grabbed(struct twimap* map)
 {
     struct cake_pile* pile = twimap_data(map, struct cake_pile*);
     twimap_printf(map, "%u", pile->alloced_pieces);
 }
 
-void
-__cake_rd_ppc(struct twimap* map)
+static void
+__twimap_read_pieces_per_cake(struct twimap* map)
 {
     struct cake_pile* pile = twimap_data(map, struct cake_pile*);
     twimap_printf(map, "%u", pile->pieces_per_cake);
 }
 
-void
-__cake_rd_ppg(struct twimap* map)
+static void
+__twimap_read_page_per_cake(struct twimap* map)
 {
     struct cake_pile* pile = twimap_data(map, struct cake_pile*);
     twimap_printf(map, "%u", pile->pg_per_cake);
@@ -73,37 +73,28 @@ __cake_rd_ppg(struct twimap* map)
 void
 cake_export_pile(struct twifs_node* root, struct cake_pile* pile)
 {
-    struct twifs_node* pile_rt = twifs_dir_node(root, pile->pile_name);
-
-    struct twimap* map = twifs_mapping(pile_rt, pile, "piece_size");
-    map->read = __cake_rd_psize;
-
-    map = twifs_mapping(pile_rt, pile, "cake_count");
-    map->read = __cake_rd_ccount;
-
-    map = twifs_mapping(pile_rt, pile, "grabbed");
-    map->read = __cake_rd_alloced;
-
-    map = twifs_mapping(pile_rt, pile, "pieces_per_cake");
-    map->read = __cake_rd_ppc;
-
-    map = twifs_mapping(pile_rt, pile, "page_per_cake");
-    map->read = __cake_rd_ppg;
+    struct twifs_node* pile_rt;
+    
+    pile_rt = twifs_dir_node(root, pile->pile_name);
+
+    twimap_export_value(pile_rt, piece_size,        FSACL_ugR, pile);
+    twimap_export_value(pile_rt, cake_count,        FSACL_ugR, pile);
+    twimap_export_value(pile_rt, grabbed,           FSACL_ugR, pile);
+    twimap_export_value(pile_rt, pieces_per_cake,   FSACL_ugR, pile);
+    twimap_export_value(pile_rt, page_per_cake,     FSACL_ugR, pile);
 }
 
 void
 cake_export()
 {
-    struct twifs_node* cake_root = twifs_dir_node(NULL, "cake");
+    struct cake_pile *pos, *n;
+    struct twifs_node* cake_root;
+    
+    cake_root = twifs_dir_node(NULL, "cake");
 
-    struct twimap* map = twifs_mapping(cake_root, NULL, "pinkiepie");
-    map->reset = __cake_stat_reset;
-    map->go_next = __cake_stat_gonext;
-    map->read = __cake_rd_stat;
+    twimap_export_list(cake_root, pinkiepie, FSACL_ugR, NULL);
 
-    struct cake_pile *pos, *n;
-    llist_for_each(pos, n, &piles, piles)
-    {
+    llist_for_each(pos, n, &piles, piles) {
         cake_export_pile(cake_root, pos);
     }
 }
index 6a6be4b3c15ae2321d9d67c49f8f714c69ff8793..674e5c64b43199ad5651cde82d00010f94e0aca3 100644 (file)
@@ -173,6 +173,7 @@ dup_proc()
     }
 
     __dup_fdtable(pcb);
+    uscope_copy(&pcb->uscope, current_user_scope());
 
     struct proc_mm* mm = vmspace(pcb);
     procvm_dupvms_mount(mm);
index bb5008df3dee688bf1de4d6c0a9eea511b18db02..2a24f50bbb6c9791144cb5376c3471178ba3de2d 100644 (file)
 
 LOG_MODULE("PROC")
 
-__DEFINE_LXSYSCALL(pid_t, getpid)
-{
-    return __current->pid;
-}
-
-__DEFINE_LXSYSCALL(pid_t, getppid)
-{
-    return __current->parent->pid;
-}
-
-__DEFINE_LXSYSCALL(pid_t, getpgid)
-{
-    return __current->pgid;
-}
-
-__DEFINE_LXSYSCALL2(int, setpgid, pid_t, pid, pid_t, pgid)
-{
-    struct proc_info* proc = pid ? get_process(pid) : __current;
-
-    if (!proc) {
-        syscall_result(EINVAL);
-        return -1;
-    }
-
-    pgid = pgid ? pgid : proc->pid;
-
-    struct proc_info* gruppenfuhrer = get_process(pgid);
-
-    if (!gruppenfuhrer || proc->pgid == gruppenfuhrer->pid) {
-        syscall_result(EINVAL);
-        return -1;
-    }
-
-    llist_delete(&proc->grp_member);
-    llist_append(&gruppenfuhrer->grp_member, &proc->grp_member);
-
-    proc->pgid = pgid;
-    return 0;
-}
-
 int
 spawn_process(struct thread** created, ptr_t entry, bool with_ustack) 
 {
@@ -130,4 +90,163 @@ fail:
 
 ptr_t proc_vmroot() {
     return __current->mm->vmroot;
-}
\ No newline at end of file
+}
+
+__DEFINE_LXSYSCALL(pid_t, getpid)
+{
+    return __current->pid;
+}
+
+__DEFINE_LXSYSCALL(pid_t, getppid)
+{
+    return __current->parent->pid;
+}
+
+__DEFINE_LXSYSCALL(pid_t, getpgid)
+{
+    return __current->pgid;
+}
+
+__DEFINE_LXSYSCALL2(int, setpgid, pid_t, pid, pid_t, pgid)
+{
+    struct proc_info* proc = pid ? get_process(pid) : __current;
+
+    if (!proc) {
+        syscall_result(EINVAL);
+        return -1;
+    }
+
+    pgid = pgid ? pgid : proc->pid;
+
+    struct proc_info* gruppenfuhrer = get_process(pgid);
+
+    if (!gruppenfuhrer || proc->pgid == gruppenfuhrer->pid) {
+        syscall_result(EINVAL);
+        return -1;
+    }
+
+    llist_delete(&proc->grp_member);
+    llist_append(&gruppenfuhrer->grp_member, &proc->grp_member);
+
+    proc->pgid = pgid;
+    return 0;
+}
+
+static inline bool
+__can_change_real_id(const struct user_scope* procu, caps_t id_cap) {
+    if (uscope_with_capability(procu, id_cap)) {
+        return true;
+    }
+
+    if (check_current_acl(0, 0) != ACL_NO_MATCH) {
+        return true;
+    }
+
+    return false;
+}
+
+__DEFINE_LXSYSCALL1(int, setuid, uid_t, uid)
+{
+    struct user_scope* procu;
+
+    procu = current_user_scope();
+
+    if (__can_change_real_id(procu, CAP_SETUID)) 
+    {
+        procu->ruid = uid;
+    }
+
+    __current->suid = uid;
+    __current->euid = uid;
+
+    return 0;
+}
+
+__DEFINE_LXSYSCALL1(int, setgid, gid_t, gid)
+{
+    struct user_scope* procu;
+
+    procu = current_user_scope();
+
+    if (__can_change_real_id(procu, CAP_SETGID)) 
+    {
+        procu->rgid = gid;
+    }
+
+    __current->sgid = gid;
+    __current->egid = gid;
+
+    return 0;
+}
+
+__DEFINE_LXSYSCALL1(int, seteuid, uid_t, euid)
+{
+    __current->euid = euid;
+
+    return 0;
+}
+
+__DEFINE_LXSYSCALL1(int, setegid, gid_t, egid)
+{
+    __current->egid = egid;
+
+    return 0;
+}
+
+__DEFINE_LXSYSCALL2(int, setgroups, const gid_t*, gids, unsigned int, len)
+{
+    struct user_scope* procu;
+
+    procu = current_user_scope();
+
+    if (check_current_acl(0, 0) == ACL_NO_MATCH) {
+        return EPERM;
+    }
+
+    if (uscope_with_capability(procu, CAP_SETGID)) {
+        return EPERM;
+    }
+
+    return uscope_setgroups(procu, gids, len);
+}
+
+
+__DEFINE_LXSYSCALL(uid_t, getuid)
+{
+    return current_user_scope()->ruid;
+}
+
+__DEFINE_LXSYSCALL(gid_t, getgid)
+{
+    return current_user_scope()->rgid;
+}
+
+__DEFINE_LXSYSCALL(uid_t, geteuid)
+{
+    return __current->euid;
+}
+
+__DEFINE_LXSYSCALL(gid_t, getegid)
+{
+    return __current->egid;
+}
+
+__DEFINE_LXSYSCALL2(int, getgroups, gid_t*, out_buf, unsigned int, len)
+{
+    struct user_scope* procu;
+    struct ugroup_obj* gobj;
+
+    procu = current_user_scope();
+    gobj  = user_groups(procu);
+
+    assert(gobj);
+    len = MIN(gobj->maxcap, len);
+
+    unsigned i = 0;
+    for (; i < len && gobj->list[i] != grp_list_end; i++)
+    {
+        out_buf[i] = gobj->list[i];
+    }
+    
+    return i + 1;
+}
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 a5b9dd838a6a04e119f3ef28a082d0ddec455d5e..93354bbbf645737ab63b8061c7528b7bb7dab1b4 100644 (file)
@@ -5,15 +5,15 @@
 
 #include <klibc/string.h>
 
-void
-__clock_read_systime(struct twimap* map)
+static void
+__twimap_read_systime(struct twimap* map)
 {
     ticks_t sys_time = clock_systime();
     twimap_printf(map, "%u", sys_time);
 }
 
-void
-__clock_read_datetime(struct twimap* map)
+static void
+__twimap_read_datetime(struct twimap* map)
 {
     datetime_t dt;
     clock_walltime(&dt);
@@ -23,29 +23,12 @@ __clock_read_datetime(struct twimap* map)
                   dt.hour, dt.minute, dt.second);
 }
 
-void
-__clock_read_unix(struct twimap* map)
+static void
+__twimap_read_unixtime(struct twimap* map)
 {
     twimap_printf(map, "%u", clock_unixtime());
 }
 
-void
-clock_build_mapping()
-{
-    struct twifs_node* root = twifs_dir_node(NULL, "clock");
-    struct twimap* map;
-
-    map = twifs_mapping(root, NULL, "systime");
-    map->read = __clock_read_systime;
-
-    map = twifs_mapping(root, NULL, "unix");
-    map->read = __clock_read_unix;
-
-    map = twifs_mapping(root, NULL, "datetime");
-    map->read = __clock_read_datetime;
-}
-EXPORT_TWIFS_PLUGIN(sys_clock, clock_build_mapping);
-
 time_t
 clock_unixtime()
 {
@@ -75,4 +58,18 @@ void
 clock_walltime(datetime_t* datetime)
 {
     sysrtc->ops->get_walltime(sysrtc, datetime);
-}
\ No newline at end of file
+}
+
+static void
+clock_build_mapping()
+{
+    struct twifs_node* root;
+    struct twimap* map;
+
+    root = twifs_dir_node(NULL, "clock");
+    
+    twimap_export_value(root, systime, FSACL_ugR, NULL);
+    twimap_export_value(root, unixtime, FSACL_ugR, NULL);
+    twimap_export_value(root, datetime, FSACL_ugR, NULL);
+}
+EXPORT_TWIFS_PLUGIN(sys_clock, clock_build_mapping);
diff --git a/lunaix-os/kernel/usrscope.c b/lunaix-os/kernel/usrscope.c
new file mode 100644 (file)
index 0000000..8a6bc99
--- /dev/null
@@ -0,0 +1,156 @@
+#include <lunaix/usrscope.h>
+#include <lunaix/mm/valloc.h>
+#include <lunaix/status.h>
+#include <lunaix/spike.h>
+#include <lunaix/process.h>
+
+#include <klibc/string.h>
+
+#define GLIST_INIT_LEN      8
+
+static struct ugroup_obj*
+__alloc_groups_obj(unsigned int len)
+{
+    unsigned int size;
+    struct ugroup_obj* ugo;
+
+    assert(len >= GLIST_INIT_LEN);
+    
+    ugo = valloc(sizeof(*ugo));
+    ugo->refs = 1;
+
+    size = len * sizeof(gid_t);
+    ugo->list = valloc(size);
+    ugo->maxcap = size;
+
+    memset(ugo->list, grp_list_end, size);
+    return ugo;
+}
+
+static inline void
+__ref_groups_obj(struct ugroup_obj* ugo)
+{
+    if (unlikely(!ugo)) {
+        return;
+    }
+
+    ugo->refs++;
+}
+
+static void
+__unref_groups_obj(struct ugroup_obj* ugo)
+{
+    ugo->refs--;
+    if (ugo->refs) {
+        return;
+    }
+
+    vfree_safe(ugo->list);
+    vfree(ugo);
+}
+
+static struct ugroup_obj*
+__modify_group_obj(struct user_scope* procu, unsigned int new_len)
+{
+    struct ugroup_obj* ugo;
+
+    ugo = procu->grps;
+    if (!ugo) {
+        return __alloc_groups_obj(GLIST_INIT_LEN);
+    }
+
+    __unref_groups_obj(ugo);
+
+    new_len = MAX(new_len, ugo->maxcap);
+    ugo = __alloc_groups_obj(new_len);
+    procu->grps = ugo;
+
+    return ugo;
+}
+
+int 
+uscope_setgroups(struct user_scope* proc_usr, 
+                 const gid_t* grps, unsigned int len)
+{
+    struct ugroup_obj* ugo;
+
+    if (len > NGROUPS_MAX) {
+        return E2BIG;
+    }
+
+    ugo = __modify_group_obj(proc_usr, len);
+    memcpy(ugo->list, grps, len * sizeof(gid_t));
+
+    return 0;
+}
+
+bool
+uscope_membership(struct user_scope* proc_usr, gid_t gid)
+{
+    struct ugroup_obj* ugo;
+    
+    ugo = proc_usr->grps;
+    if (unlikely(!ugo)) {
+        return false;
+    }
+
+    for (unsigned i = 0; i < ugo->maxcap; i++)
+    {
+        if (ugo->list[i] != grp_list_end) {
+            break;
+        }
+        
+        if (ugo->list[i] == gid) {
+            return true;
+        }
+    }
+    
+    return false;
+}
+
+void 
+uscope_copy(struct user_scope* to, struct user_scope* from)
+{
+    __ref_groups_obj(from->grps);
+    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 (unlikely(!__current)) {
+        return ACL_NO_MATCH;
+    }
+
+    match = check_acl_between(__current->euid, __current->egid,
+                              desired_u, desired_g);
+    
+    if (match != ACL_NO_MATCH) {
+        return match;
+    }
+
+    uscope = current_user_scope();
+    if (uscope_membership(uscope, desired_g)) {
+        return ACL_MATCH_G;
+    }
+
+    return ACL_NO_MATCH;
+}
\ No newline at end of file
index cd8cad08ebdfaa18f05f9de1c73fb2244639502f..1fe6c1610bfb12a11d9690b71290df4d24be4c7e 100644 (file)
@@ -26,7 +26,7 @@ main(int argc, const char* argv[])
             return 1;
         }
 
-        if ((stat.mode & F_DIR)) {
+        if (((stat.st_mode >> 16) & F_DIR)) {
             printf("%s is a directory", argv[i]);
             return 1;
         }
index 25996ce6c03b368b1d5d57d1a66532bc7c89af55..804b8f82199a210660ba6ff5029073e710429b95 100644 (file)
@@ -39,7 +39,7 @@ init_termios(int fd) {
 
     check(tcgetattr(fd, &term));
 
-    term.c_lflag = ICANON | IEXTEN | ISIG | ECHO | ECHOE | ECHONL;
+    term.c_lflag = ICANON | IEXTEN | ISIG | ECHO | ECHOE;
     term.c_iflag = ICRNL | IGNBRK;
     term.c_oflag = ONLCR | OPOST;
     term.c_cflag = CREAD | CLOCAL | CS8 | CPARENB;
index 16d81338b90bdb9f9c1aff5779e0bd8d5836e885..7659e28c283586bc31905610cc3cf66a8d03ac6b 100644 (file)
@@ -112,6 +112,9 @@ __vprintf_internal(char* buffer, const char* fmt, size_t max_len, va_list vargs)
                 flags = flags | FLAG_CAPS;
                 base = 16;
                 goto format_unsigned;
+            case 'o':
+                base = 8;
+                goto format_unsigned;
             case 'p':
                 num = (uintptr_t)va_arg(vargs, void*);
                 base = 16;
index caea32d8f63c481b14da836ed616dad61a603a69..3fdfc6eb772475633321d1543e2476cefe98a0d7 100644 (file)
@@ -13,27 +13,43 @@ main(int argc, const char* argv[])
     DIR* dir = opendir(path);
 
     if (!dir) {
-        return errno;
+        goto done;
     }
 
     struct dirent* dent;
+    int i = 0, sz;
+    char bf[100];
 
     while ((dent = readdir(dir))) {
         if (dent->d_type == DT_DIR) {
-            printf(" %s/\n", dent->d_name);
+            sz = snprintf(bf, 100, "%s/", dent->d_name);
         } else if (dent->d_type == DT_SYMLINK) {
-            printf(" %s@\n", dent->d_name);
+            sz = snprintf(bf, 100, "%s@", dent->d_name);
         } else {
-            printf(" %s\n", dent->d_name);
+            sz = snprintf(bf, 100, "%s", dent->d_name);
         }
+
+        bf[sz] = 0;
+        printf("%-15s ", bf);
+
+        i++;
+        if ((i % 4) == 0) {
+            printf("\n");
+        }
+    }
+
+    if ((i % 4) != 0) {
+        printf("\n");
     }
 
+done:
     int err = errno;
     if (err) {
         printf("failed: %d\n",err);
     }
 
-    closedir(dir);
+    if (dir)
+        closedir(dir);
 
     return err;
 }
\ No newline at end of file
index 7fea8332528af9e30baa0542fd4178b30da3d342..c6046ce695c608d5c3b10d7bf51797213e6b40c2 100644 (file)
@@ -29,7 +29,7 @@ main(int argc, const char* argv[])
 
     close(fd);
 
-    if ((stat.mode & F_DIR)) {
+    if (((stat.st_mode >> 16) & F_DIR)) {
         err = rmdir(path);
     }
     else {
index 5ca47ed093bc0495a25c5dd65558b11676539280..764404b0910a54fe50c33891b20967388c3de20e 100644 (file)
@@ -182,7 +182,7 @@ sh_loop()
 
     while (1) {
         getcwd(pwd, 512);
-        printf("[%s]$ ", pwd);
+        printf("%s # ", pwd);
         int sz = read(stdin, buf, 511);
 
         if (sz < 0) {
@@ -195,8 +195,7 @@ sh_loop()
 
         // currently, this shell only support single argument
         if (!parse_cmdline(buf, argv)) {
-            printf("\n");
-            goto cont;
+             continue;
         }
 
         // cmd=="exit"
@@ -204,9 +203,7 @@ sh_loop()
             break;
         }
 
-        sh_exec((const char**)argv);
-    cont:
-        printf("\n");
+        sh_exec((const char**)argv);       
     }
 }
 
index ea402000553e3273fe3d060205e623784f269b7d..1bd79f3a25a270720b0ff8b9a509f41819c3808c 100644 (file)
@@ -28,7 +28,7 @@ main(int argc, char* argv[])
     printf("File: %s ", argv[1]);
 
     char* ftype = "directory";
-    int mode = stat.mode;
+    int mode = stat.st_mode >> 16;
     if ((mode & F_DEV)) {
         ftype = "mappable (sequential) device";
 
@@ -53,16 +53,25 @@ main(int argc, char* argv[])
            stat.st_blocks,
            stat.st_blksize,
            stat.st_ioblksize);
-    printf("Inode: %d;  ", stat.st_ino);
 
     dev_t* dev;
-    if (!(stat.mode & F_DEV)) {
+    if (!(mode & F_DEV)) {
         dev = &stat.st_dev;
     } else {
         dev = &stat.st_rdev;
     }
+    printf("Device: %xh:%xh@%d;  Inode: %d;  Links: %d\n", 
+           dev->meta, dev->unique, dev->index,
+           stat.st_ino, stat.st_nlink);
 
-    printf("Device: %xh:%xh@%d;\n", dev->meta, dev->unique, dev->index);
+    printf("Access: 0%o;  Uid: %d;  Gid: %d\n",
+           stat.st_mode & 0xffff,
+           stat.st_uid,
+           stat.st_gid);
+
+    printf("Access: %lu\n", stat.st_atim);
+    printf("Modify: %lu\n", stat.st_mtim);
+    printf("Create: %lu\n", stat.st_ctim);
 
     close(fd);
     return 0;