]> Projects (at) Tadryanom (dot) Me - AdrOS.git/commitdiff
fix: heap coalesce early-return, process_create_kernel leak, pipe double-free, path...
authorTulio A M Mendes <[email protected]>
Tue, 10 Feb 2026 02:35:38 +0000 (23:35 -0300)
committerTulio A M Mendes <[email protected]>
Tue, 10 Feb 2026 02:35:38 +0000 (23:35 -0300)
src/kernel/scheduler.c
src/kernel/syscall.c
src/mm/heap.c

index 2adbe024fd9c432ff564a606b623d023d118a73e..7405a5645f0023a18a92ceaeb4b9a32b7940068b 100644 (file)
@@ -402,6 +402,7 @@ struct process* process_create_kernel(void (*entry_point)(void)) {
     
     void* stack = kmalloc(4096);
     if (!stack) {
+        kfree(proc);
         spin_unlock_irqrestore(&sched_lock, flags);
         return NULL;
     }
index 865e8bfb5e2d647b8b84a4cc069d9e0cddf03a85..f9a0480151356f231529c8340704cdfdcdbcacea 100644 (file)
@@ -406,13 +406,15 @@ static int pipe_create_kfds(int kfds[2]) {
 
     fs_node_t* rnode = NULL;
     fs_node_t* wnode = NULL;
-    if (pipe_node_create(ps, 1, &rnode) < 0 || pipe_node_create(ps, 0, &wnode) < 0) {
-        if (rnode) vfs_close(rnode);
-        if (wnode) vfs_close(wnode);
-        if (ps->buf) kfree(ps->buf);
+    if (pipe_node_create(ps, 1, &rnode) < 0) {
+        kfree(ps->buf);
         kfree(ps);
         return -ENOMEM;
     }
+    if (pipe_node_create(ps, 0, &wnode) < 0) {
+        vfs_close(rnode);
+        return -ENOMEM;
+    }
 
     struct file* rf = (struct file*)kmalloc(sizeof(*rf));
     struct file* wf = (struct file*)kmalloc(sizeof(*wf));
@@ -878,33 +880,72 @@ static int path_is_absolute(const char* p) {
 
 static void path_normalize_inplace(char* s) {
     if (!s) return;
-    // Collapse duplicate slashes and remove trailing slash (except for root).
-    char tmp[128];
-    size_t w = 0;
-    size_t r = 0;
     if (s[0] == 0) {
         strcpy(s, "/");
         return;
     }
 
-    while (s[r] != 0 && w + 1 < sizeof(tmp)) {
-        char c = s[r++];
-        if (c == '/') {
-            if (w == 0 || tmp[w - 1] != '/') {
-                tmp[w++] = '/';
+    // Phase 1: split into components, resolve '.' and '..'
+    char tmp[128];
+    // Stack of component start offsets within tmp
+    size_t comp_start[32];
+    int depth = 0;
+    size_t w = 0;
+
+    const char* p = s;
+    int absolute = (*p == '/');
+    if (absolute) {
+        tmp[w++] = '/';
+        while (*p == '/') p++;
+    }
+
+    while (*p != 0) {
+        // Extract next component
+        const char* seg = p;
+        while (*p != 0 && *p != '/') p++;
+        size_t seg_len = (size_t)(p - seg);
+        while (*p == '/') p++;
+
+        if (seg_len == 1 && seg[0] == '.') {
+            continue; // skip '.'
+        }
+
+        if (seg_len == 2 && seg[0] == '.' && seg[1] == '.') {
+            // Go up one level
+            if (depth > 0) {
+                depth--;
+                w = comp_start[depth];
             }
-        } else {
-            tmp[w++] = c;
+            continue;
+        }
+
+        // Record start of this component
+        if (depth < 32) {
+            comp_start[depth++] = w;
+        }
+
+        // Append separator if needed
+        if (w > 1 || (w == 1 && tmp[0] != '/')) {
+            if (w + 1 < sizeof(tmp)) tmp[w++] = '/';
+        }
+
+        // Append component
+        for (size_t i = 0; i < seg_len && w + 1 < sizeof(tmp); i++) {
+            tmp[w++] = seg[i];
         }
     }
-    tmp[w] = 0;
 
-    size_t l = strlen(tmp);
-    while (l > 1 && tmp[l - 1] == '/') {
-        tmp[l - 1] = 0;
-        l--;
+    // Handle empty result
+    if (w == 0) {
+        tmp[w++] = '/';
     }
 
+    // Remove trailing slash (except root)
+    while (w > 1 && tmp[w - 1] == '/') {
+        w--;
+    }
+
+    tmp[w] = 0;
     strcpy(s, tmp);
 }
 
index 61208ea09a28553e9ff780aff9e1a6b38c71bba1..e5c7315280f0c914fb55e03f5499384a997aa540 100644 (file)
@@ -173,18 +173,15 @@ void kfree(void* ptr) {
 
         // Only coalesce if physically adjacent.
         heap_header_t* expected_next = (heap_header_t*)((uint8_t*)header + sizeof(heap_header_t) + header->size);
-        if (next_block != expected_next) {
-            spin_unlock_irqrestore(&heap_lock, flags);
-            return;
-        }
-        
-        header->size += sizeof(heap_header_t) + next_block->size;
-        header->next = next_block->next;
-        
-        if (header->next) {
-            header->next->prev = header;
-        } else {
-            tail = header; // If next was tail, now current is tail
+        if (next_block == expected_next) {
+            header->size += sizeof(heap_header_t) + next_block->size;
+            header->next = next_block->next;
+
+            if (header->next) {
+                header->next->prev = header;
+            } else {
+                tail = header;
+            }
         }
     }
     
@@ -194,20 +191,16 @@ void kfree(void* ptr) {
 
         // Only coalesce if physically adjacent.
         heap_header_t* expected_hdr = (heap_header_t*)((uint8_t*)prev_block + sizeof(heap_header_t) + prev_block->size);
-        if (expected_hdr != header) {
-            spin_unlock_irqrestore(&heap_lock, flags);
-            return;
-        }
-        
-        prev_block->size += sizeof(heap_header_t) + header->size;
-        prev_block->next = header->next;
-        
-        if (header->next) {
-            header->next->prev = prev_block;
-        } else {
-            tail = prev_block;
+        if (expected_hdr == header) {
+            prev_block->size += sizeof(heap_header_t) + header->size;
+            prev_block->next = header->next;
+
+            if (header->next) {
+                header->next->prev = prev_block;
+            } else {
+                tail = prev_block;
+            }
         }
-        // No need to update 'header' anymore, prev_block is the merged one
     }
 
     spin_unlock_irqrestore(&heap_lock, flags);