From: Tulio A M Mendes Date: Tue, 17 Feb 2026 06:50:42 +0000 (-0300) Subject: fix: diskfs kfree-on-static-root, mount syscall, user addr space 8MiB->1GiB X-Git-Url: https://projects.tadryanom.me/docs/static/gitweb.js?a=commitdiff_plain;h=5e0e159916de9ecb99cc114f7f08cc9f24c3a777;p=AdrOS.git fix: diskfs kfree-on-static-root, mount syscall, user addr space 8MiB->1GiB 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. --- diff --git a/include/syscall.h b/include/syscall.h index 68273a2..3d44089 100644 --- a/include/syscall.h +++ b/include/syscall.h @@ -154,6 +154,8 @@ enum { SYSCALL_AIO_ERROR = 123, SYSCALL_AIO_RETURN = 124, SYSCALL_AIO_SUSPEND = 125, + + SYSCALL_MOUNT = 126, }; #endif diff --git a/src/arch/x86/elf.c b/src/arch/x86/elf.c index 27dae9b..08c94e1 100644 --- a/src/arch/x86/elf.c +++ b/src/arch/x86/elf.c @@ -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); diff --git a/src/arch/x86/usermode.c b/src/arch/x86/usermode.c index 75c547e..bd1312c 100644 --- a/src/arch/x86/usermode.c +++ b/src/arch/x86/usermode.c @@ -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(); diff --git a/src/kernel/diskfs.c b/src/kernel/diskfs.c index 0ffbd8a..4ce1095 100644 --- a/src/kernel/diskfs.c +++ b/src/kernel/diskfs.c @@ -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); } diff --git a/src/kernel/syscall.c b/src/kernel/syscall.c index 145c830..a110a04 100644 --- a/src/kernel/syscall.c +++ b/src/kernel/syscall.c @@ -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; } diff --git a/user/mount.c b/user/mount.c index 970e327..42cb54a 100644 --- a/user/mount.c +++ b/user/mount.c @@ -1,12 +1,12 @@ -/* AdrOS mount utility — display mounted filesystems */ +/* AdrOS mount utility — mount filesystems or display mounts */ #include #include #include #include +#include +#include -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; } diff --git a/user/ulibc/include/syscall.h b/user/ulibc/include/syscall.h index 5a5e214..d9f62ad 100644 --- a/user/ulibc/include/syscall.h +++ b/user/ulibc/include/syscall.h @@ -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 */