From: Tulio A M Mendes Date: Wed, 11 Feb 2026 22:46:34 +0000 (-0300) Subject: feat: permissions support (uid/gid/mode, chmod, chown, getuid, getgid) X-Git-Url: https://projects.tadryanom.me/docs/POSIX_ROADMAP.md?a=commitdiff_plain;h=41b8a83da2d0c5df67311966c392ae695f47f328;p=AdrOS.git feat: permissions support (uid/gid/mode, chmod, chown, getuid, getgid) - 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 --- diff --git a/include/fs.h b/include/fs.h index db4f904..a7fda11 100644 --- a/include/fs.h +++ b/include/fs.h @@ -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); diff --git a/include/process.h b/include/process.h index a8e6dca..b329ace 100644 --- a/include/process.h +++ b/include/process.h @@ -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; diff --git a/include/stat.h b/include/stat.h index 710dc91..77941b8 100644 --- a/include/stat.h +++ b/include/stat.h @@ -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; }; diff --git a/include/syscall.h b/include/syscall.h index a6b89ec..3fbaf68 100644 --- a/include/syscall.h +++ b/include/syscall.h @@ -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 diff --git a/src/kernel/syscall.c b/src/kernel/syscall.c index 263cdc9..a22344d 100644 --- a/src/kernel/syscall.c +++ b/src/kernel/syscall.c @@ -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; } diff --git a/user/init.c b/user/init.c index dbcfcd1..10dd94d 100644 --- a/user/init.c +++ b/user/init.c @@ -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; };