]> Projects (at) Tadryanom (dot) Me - AdrOS.git/commitdiff
feat: permissions support (uid/gid/mode, chmod, chown, getuid, getgid)
authorTulio A M Mendes <[email protected]>
Wed, 11 Feb 2026 22:46:34 +0000 (19:46 -0300)
committerTulio A M Mendes <[email protected]>
Fri, 13 Feb 2026 02:20:50 +0000 (23:20 -0300)
- include/fs.h: added uid, gid, mode fields to fs_node_t
- include/process.h: added uid, gid fields to struct process
- include/stat.h: added st_uid, st_gid to struct stat, permission bit defines
- include/syscall.h: added SYSCALL_CHMOD(50), SYSCALL_CHOWN(51), SYSCALL_GETUID(52), SYSCALL_GETGID(53)
- src/kernel/syscall.c: chmod_impl, chown_impl, getuid/getgid dispatch; stat_from_node now populates uid/gid/mode
- user/init.c: updated struct stat to match kernel layout
- cppcheck clean, 19/19 smoke tests pass

include/fs.h
include/process.h
include/stat.h
include/syscall.h
src/kernel/syscall.c
user/init.c

index db4f9044918634923b972df44e2d533808462f08..a7fda112c6ba0d4a8de5b614a0c63cfbb84f1f71 100644 (file)
@@ -14,6 +14,9 @@ typedef struct fs_node {
     uint32_t flags;
     uint32_t inode;
     uint32_t length;
+    uint32_t uid;
+    uint32_t gid;
+    uint32_t mode;
     
     // Function pointers for operations (Polymorphism in C)
     uint32_t (*read)(struct fs_node* node, uint32_t offset, uint32_t size, uint8_t* buffer);
index a8e6dca802918c3a925476a802278aae1efa5a05..b329aceb45fbeca0d5dcf588f21bf789884931b5 100644 (file)
@@ -30,6 +30,8 @@ struct process {
     uint32_t parent_pid;
     uint32_t session_id;
     uint32_t pgrp_id;
+    uint32_t uid;
+    uint32_t gid;
     uintptr_t sp;
     uintptr_t addr_space;
     uint32_t* kernel_stack;
index 710dc9191cfa39e3265b6d201ca722a67158b233..77941b86e7fbcb7769f9a38f4cd32b6f8cf0f24b 100644 (file)
@@ -8,10 +8,25 @@
 #define S_IFDIR 0040000
 #define S_IFCHR 0020000
 
+#define S_IRWXU 00700
+#define S_IRUSR 00400
+#define S_IWUSR 00200
+#define S_IXUSR 00100
+#define S_IRWXG 00070
+#define S_IRGRP 00040
+#define S_IWGRP 00020
+#define S_IXGRP 00010
+#define S_IRWXO 00007
+#define S_IROTH 00004
+#define S_IWOTH 00002
+#define S_IXOTH 00001
+
 struct stat {
     uint32_t st_ino;
     uint32_t st_mode;
     uint32_t st_nlink;
+    uint32_t st_uid;
+    uint32_t st_gid;
     uint32_t st_size;
 };
 
index a6b89ec5d7d618ce3fd732956bc4062c99c42baa..3fbaf68091362efacdcc43c09c618f1f0eb93e14 100644 (file)
@@ -67,6 +67,11 @@ enum {
     SYSCALL_SHMAT  = 47,
     SYSCALL_SHMDT  = 48,
     SYSCALL_SHMCTL = 49,
+
+    SYSCALL_CHMOD  = 50,
+    SYSCALL_CHOWN  = 51,
+    SYSCALL_GETUID = 52,
+    SYSCALL_GETGID = 53,
 };
 
 #endif
index 263cdc900c9b5a5b8a43a061b7002644d074e8d1..a22344d53c41f305610d7b04c193dc724af727c4 100644 (file)
@@ -527,11 +527,14 @@ static int stat_from_node(const fs_node_t* node, struct stat* st) {
     st->st_ino = node->inode;
     st->st_nlink = 1;
     st->st_size = node->length;
+    st->st_uid = node->uid;
+    st->st_gid = node->gid;
 
-    uint32_t mode = 0;
+    uint32_t mode = node->mode & 07777;
     if (node->flags == FS_DIRECTORY) mode |= S_IFDIR;
     else if (node->flags == FS_CHARDEVICE) mode |= S_IFCHR;
     else mode |= S_IFREG;
+    if ((mode & 07777) == 0) mode |= 0755;
     st->st_mode = mode;
     return 0;
 }
@@ -1606,6 +1609,35 @@ static uintptr_t syscall_brk_impl(uintptr_t addr) {
     return addr;
 }
 
+static int syscall_chmod_impl(const char* user_path, uint32_t mode) {
+    if (!user_path) return -EFAULT;
+
+    char path[128];
+    int prc = path_resolve_user(user_path, path, sizeof(path));
+    if (prc < 0) return prc;
+
+    fs_node_t* node = vfs_lookup(path);
+    if (!node) return -ENOENT;
+
+    node->mode = mode & 07777;
+    return 0;
+}
+
+static int syscall_chown_impl(const char* user_path, uint32_t uid, uint32_t gid) {
+    if (!user_path) return -EFAULT;
+
+    char path[128];
+    int prc = path_resolve_user(user_path, path, sizeof(path));
+    if (prc < 0) return prc;
+
+    fs_node_t* node = vfs_lookup(path);
+    if (!node) return -ENOENT;
+
+    node->uid = uid;
+    node->gid = gid;
+    return 0;
+}
+
 void syscall_handler(struct registers* regs) {
     uint32_t syscall_no = regs->eax;
 
@@ -1988,6 +2020,31 @@ void syscall_handler(struct registers* regs) {
         return;
     }
 
+    if (syscall_no == SYSCALL_CHMOD) {
+        const char* path = (const char*)regs->ebx;
+        uint32_t mode = regs->ecx;
+        regs->eax = (uint32_t)syscall_chmod_impl(path, mode);
+        return;
+    }
+
+    if (syscall_no == SYSCALL_CHOWN) {
+        const char* path = (const char*)regs->ebx;
+        uint32_t uid = regs->ecx;
+        uint32_t gid = regs->edx;
+        regs->eax = (uint32_t)syscall_chown_impl(path, uid, gid);
+        return;
+    }
+
+    if (syscall_no == SYSCALL_GETUID) {
+        regs->eax = current_process ? current_process->uid : 0;
+        return;
+    }
+
+    if (syscall_no == SYSCALL_GETGID) {
+        regs->eax = current_process ? current_process->gid : 0;
+        return;
+    }
+
     regs->eax = (uint32_t)-ENOSYS;
 }
 
index dbcfcd171d6f58a3cf01005457f9ed42aafc5db5..10dd94df7d28bf4e7cad2158c4cc5453178d14b0 100644 (file)
@@ -159,6 +159,8 @@ struct stat {
     uint32_t st_ino;
     uint32_t st_mode;
     uint32_t st_nlink;
+    uint32_t st_uid;
+    uint32_t st_gid;
     uint32_t st_size;
 };