]> Projects (at) Tadryanom (dot) Me - AdrOS.git/commitdiff
fix: diskfs kfree-on-static-root, mount syscall, user addr space 8MiB->1GiB
authorTulio A M Mendes <[email protected]>
Tue, 17 Feb 2026 06:50:42 +0000 (03:50 -0300)
committerTulio A M Mendes <[email protected]>
Tue, 17 Feb 2026 06:50:42 +0000 (03:50 -0300)
Bug 1: ls /disk heap corruption — diskfs_close_impl called kfree on
static g_root BSS variable. Added guard: skip kfree when node == g_root.

Bug 2: mount command only displayed mounts. Added SYSCALL_MOUNT (126)
with support for tmpfs and disk-based filesystems (diskfs/fat/ext2/persistfs).
Updated userspace mount to call the syscall with device, mountpoint, and
-t fstype args.

Bug 3: doom 'Unable to allocate 5 MiB' — user address space was capped
at 8 MiB (USER_STACK_BASE=0x00800000). Raised to 1 GiB (0x40000000) in
elf.c, usermode.c, and syscall_brk_impl.

include/syscall.h
src/arch/x86/elf.c
src/arch/x86/usermode.c
src/kernel/diskfs.c
src/kernel/syscall.c
user/mount.c
user/ulibc/include/syscall.h

index 68273a27c1698141748bd9cf967e12429f872ae5..3d44089bb85891815a679cc809b9e0cb20eea000 100644 (file)
@@ -154,6 +154,8 @@ enum {
     SYSCALL_AIO_ERROR   = 123,
     SYSCALL_AIO_RETURN  = 124,
     SYSCALL_AIO_SUSPEND = 125,
+
+    SYSCALL_MOUNT = 126,
 };
 
 #endif
index 27dae9bffe8fd2bb4ffdcaf5a04dd65b6394ef7b..08c94e1338b2940f05fd2d94af8b540322a9686f 100644 (file)
@@ -475,7 +475,7 @@ int elf32_load_user_from_initrd(const char* filename, uintptr_t* entry_out, uint
      * ASLR: randomize stack base by up to 256 pages (1 MB). */
     extern uint32_t kaslr_offset(uint32_t max_pages);
     const uintptr_t aslr_stack_slide = kaslr_offset(256);
-    const uintptr_t user_stack_base = 0x00800000U + aslr_stack_slide;
+    const uintptr_t user_stack_base = 0x40000000U + aslr_stack_slide;
     const size_t user_stack_size = 0x8000;       /* 8 pages = 32 KB */
 
     int src2 = elf32_map_user_range(new_as, user_stack_base, user_stack_size, VMM_FLAG_RW);
index 75c547ec6626085fd76071920f99fe108483c0ad..bd1312ce027f22e1678d88f688ba761f9925713c 100644 (file)
@@ -141,7 +141,7 @@ void x86_usermode_test_start(void) {
     kprintf("[USER] Starting ring3 test...\n");
 
     const uintptr_t user_code_vaddr = 0x00400000U;
-    const uintptr_t user_stack_vaddr = 0x00800000U;
+    const uintptr_t user_stack_vaddr = 0x40000000U;
 
     void* code_phys = pmm_alloc_page();
     void* stack_phys = pmm_alloc_page();
index 0ffbd8a63a6bb99f2b591a069e66049a1c80d382..4ce109526fe21df3d9e0fc095cb17de8e55f800e 100644 (file)
@@ -95,6 +95,7 @@ static void diskfs_strlcpy(char* dst, const char* src, size_t dst_sz) {
 static void diskfs_close_impl(fs_node_t* node) {
     if (!node) return;
     struct diskfs_node* dn = (struct diskfs_node*)node;
+    if (dn == &g_root) return;
     kfree(dn);
 }
 
index 145c830656652eba5be40662a649430dcdefc7bf..a110a0419a5190e855e033d4bc855a189d7e6a98 100644 (file)
@@ -2912,7 +2912,7 @@ static uintptr_t syscall_brk_impl(uintptr_t addr) {
     }
 
     const uintptr_t KERN_BASE = hal_mm_kernel_virt_base();
-    const uintptr_t USER_STACK_BASE = 0x00800000U;
+    const uintptr_t USER_STACK_BASE = 0x40000000U;
 
     if (addr < current_process->heap_start) return current_process->heap_break;
     if (addr >= USER_STACK_BASE) return current_process->heap_break;
@@ -4653,6 +4653,44 @@ static void socket_syscall_dispatch(struct registers* regs, uint32_t syscall_no)
         return;
     }
 
+    if (syscall_no == SYSCALL_MOUNT) {
+        if (!current_process || current_process->euid != 0) {
+            sc_ret(regs) = (uint32_t)-EPERM;
+            return;
+        }
+        const char* user_dev  = (const char*)sc_arg0(regs);
+        const char* user_mp   = (const char*)sc_arg1(regs);
+        const char* user_type = (const char*)sc_arg2(regs);
+        char kdev[64], kmp[128], ktype[32];
+        if (copy_from_user(kdev, user_dev, sizeof(kdev)) < 0 ||
+            path_resolve_user(user_mp, kmp, sizeof(kmp)) < 0 ||
+            copy_from_user(ktype, user_type, sizeof(ktype)) < 0) {
+            sc_ret(regs) = (uint32_t)-EFAULT;
+            return;
+        }
+        kdev[sizeof(kdev)-1] = '\0';
+        ktype[sizeof(ktype)-1] = '\0';
+
+        if (strcmp(ktype, "tmpfs") == 0) {
+            fs_node_t* tmp = tmpfs_create_root();
+            if (!tmp) { sc_ret(regs) = (uint32_t)-ENOMEM; return; }
+            sc_ret(regs) = (uint32_t)vfs_mount(kmp, tmp);
+            return;
+        }
+
+        /* Disk-based: parse /dev/hdX -> drive number */
+        const char* devname = kdev;
+        if (strncmp(devname, "/dev/", 5) == 0) devname += 5;
+        extern int ata_name_to_drive(const char* name);
+        int drive = ata_name_to_drive(devname);
+        if (drive < 0) { sc_ret(regs) = (uint32_t)-ENODEV; return; }
+
+        extern int init_mount_fs(const char* fstype, int drive, uint32_t lba, const char* mountpoint);
+        int rc = init_mount_fs(ktype, drive, 0, kmp);
+        sc_ret(regs) = (uint32_t)(rc < 0 ? -EIO : 0);
+        return;
+    }
+
     sc_ret(regs) = (uint32_t)-ENOSYS;
 }
 
index 970e3271893a97ae3cef4e7a52dd88e8655c9d7d..42cb54a15f04fa8c4df473c0e8e8442bb693a98e 100644 (file)
@@ -1,12 +1,12 @@
-/* AdrOS mount utility — display mounted filesystems */
+/* AdrOS mount utility — mount filesystems or display mounts */
 #include <stdio.h>
 #include <string.h>
 #include <unistd.h>
 #include <fcntl.h>
+#include <syscall.h>
+#include <errno.h>
 
-int main(int argc, char** argv) {
-    (void)argc; (void)argv;
-    /* Read /proc/mounts if available, otherwise show static info */
+static void show_mounts(void) {
     int fd = open("/proc/mounts", O_RDONLY);
     if (fd >= 0) {
         char buf[1024];
@@ -19,5 +19,29 @@ int main(int argc, char** argv) {
         printf("devfs on /dev type devfs (rw)\n");
         printf("procfs on /proc type procfs (ro)\n");
     }
+}
+
+int main(int argc, char** argv) {
+    if (argc < 3) {
+        show_mounts();
+        return 0;
+    }
+
+    const char* device = argv[1];
+    const char* mountpoint = argv[2];
+    const char* fstype = "diskfs";
+
+    /* Parse -t fstype option */
+    for (int i = 1; i < argc - 2; i++) {
+        if (strcmp(argv[i], "-t") == 0 && i + 1 < argc) {
+            fstype = argv[++i];
+        }
+    }
+
+    int rc = __syscall_ret(_syscall3(SYS_MOUNT, (int)device, (int)mountpoint, (int)fstype));
+    if (rc < 0) {
+        fprintf(stderr, "mount: mounting %s on %s failed: %d\n", device, mountpoint, rc);
+        return 1;
+    }
     return 0;
 }
index 5a5e214caa3bee997e2eba071ef4e900bc82e590..d9f62ad492e88bea8f0f7024764956aff3798535 100644 (file)
@@ -80,6 +80,7 @@ enum {
     SYS_SETEGID = 91,
     SYS_SETITIMER = 92,
     SYS_GETITIMER = 93,
+    SYS_MOUNT = 126,
 };
 
 /* Raw syscall wrappers — up to 5 args via INT 0x80 */