]> 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 de7825f414b650e6a1d2622eeca8ba76d9aaf14c..fe8a8bcfdbc22ac0cdbb9c95fefe640cd9daddbe 100644 (file)
@@ -23,6 +23,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 3328cff42fbc0668939b9d852e27fb8d391a80a4..7fc64f8f6fc0709275f3e6e4e8c31ed1f235d6f6 100644 (file)
@@ -39,6 +39,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 6dc89d186084a11bf664d0bef9b74bb1887426e8..5ea55d6b3d8f009b741ffc9a963cc6da2bddc215 100644 (file)
 #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 dc997f3e3a3a482f12d5c46ff0de03b57411ad80..f31cd3274ab688bbdc1b4c6bf555e6a795eb768c 100644 (file)
@@ -76,6 +76,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 135165ac3f68856e46707f320111cc80d53601bd..5991f6ada53f835a23f75d3ef96b581202c6264f 100644 (file)
@@ -536,11 +536,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;
 }
@@ -1615,6 +1618,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;
 
@@ -1997,6 +2029,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 b6c2ca4e75b7f5f31cab0f7e0057bd811dd0622b..7e2fb085af86983068cb1b94043475cbc15679c9 100644 (file)
@@ -168,6 +168,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;
 };