patch file systems with the acl checks
authorLunaixsky <lunaixsky@qq.com>
Wed, 19 Mar 2025 00:56:38 +0000 (00:56 +0000)
committerLunaixsky <lunaixsky@qq.com>
Tue, 1 Apr 2025 13:32:02 +0000 (14:32 +0100)
make sure the user scope is copied upon fork

15 files changed:
lunaix-os/includes/lunaix/compiler.h
lunaix-os/includes/lunaix/fs.h
lunaix-os/includes/lunaix/fs/api.h
lunaix-os/includes/lunaix/fs_acl.h [new file with mode: 0644]
lunaix-os/kernel/device/devfs.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/iso9660/inode.c
lunaix-os/kernel/fs/iso9660/iso9660.h
lunaix-os/kernel/fs/mount.c
lunaix-os/kernel/fs/twifs/twifs.c
lunaix-os/kernel/fs/vfs.c
lunaix-os/kernel/process/fork.c
lunaix-os/kernel/usrscope.c

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 6feb2aa0447769b7f5d68fda278936774036d8a8..b64cdcff5925b6087b0bcad0701800ecee51c7fe 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;
@@ -707,4 +713,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)
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..c05080b
--- /dev/null
@@ -0,0 +1,61 @@
+#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_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)
+
+// 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 read
+#define FSACL_aR      (FSACL_uR | FSACL_gR | FSACL_oR)
+// any write
+#define FSACL_aW      (FSACL_uW | FSACL_gW | FSACL_oW)
+// any execute
+#define FSACL_aX      (FSACL_uX | FSACL_gX | FSACL_oX)
+
+#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)))
+
+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 */
index c105f66a71bbed5072e6544de25b3bea75b9c27e..c707b9f6bdb9973ae52106f389ce024b85857cc9 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 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_setowner(inode, 0, 0);
 }
 
 int
index 0dace13e9352ec6d2e2009968972846c01bcb8b5..cc7ae82b62cb094752ceacae305c08f43c68f80e 100644 (file)
@@ -223,7 +223,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 +232,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);
 
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 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 165d0bd0a17070c6099717ec06c3d11cff21a85c..3679ee1303f70bc5517544dfc4b0de60d8f34ce8 100644 (file)
@@ -58,6 +58,13 @@ __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_u(R, W, _) | FSACL_g(R, W, _));
+    fsapi_inode_setowner(inode, 0, 0);
 }
 
 int
index 1696d6e961ace4b3ac092809db67cd9dddd42183..53faa560341f16b55ecb6964946d42b16880431b 100644 (file)
@@ -192,12 +192,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);
@@ -846,6 +846,11 @@ __DEFINE_LXSYSCALL3(int, read, int, fd, void*, buf, size_t, count)
         goto done;
     }
 
+    if (!check_allow_read(file->inode)) {
+        errno = EPERM;
+        goto done;
+    }
+
     lock_inode(file->inode);
 
     file->inode->atime = clock_unixtime();
@@ -932,6 +937,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 +1022,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);
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 334cad7c18a7ea404395b876c75b537d10caf79b..5eba922345559b2f8e681a74f42411be8be45d42 100644 (file)
@@ -30,6 +30,10 @@ __alloc_groups_obj(unsigned int len)
 static inline void
 __ref_groups_obj(struct ugroup_obj* ugo)
 {
+    if (unlikely(!ugo)) {
+        return;
+    }
+
     ugo->refs++;
 }