]> Projects (at) Tadryanom (dot) Me - AdrOS.git/commitdiff
security: return ENAMETOOLONG on path truncation (Fase 5)
authorTulio A M Mendes <[email protected]>
Tue, 26 May 2026 05:29:30 +0000 (02:29 -0300)
committerTulio A M Mendes <[email protected]>
Wed, 3 Jun 2026 05:52:27 +0000 (02:52 -0300)
src/kernel/fs.c
src/kernel/syscall.c

index 94f63019571126e81fb31dd3d1a014ff085ae5c4..b80021602bc7f8dac9f0d4e679d049ef6b5b7d04 100644 (file)
@@ -475,7 +475,8 @@ fs_node_t* vfs_lookup_parent(const char* path, char* name_out, size_t name_sz) {
     char parent_path[128];
     size_t plen = (size_t)(last_slash - path);
     if (plen == 0) plen = 1; /* root "/" */
-    if (plen >= sizeof(parent_path)) plen = sizeof(parent_path) - 1;
+    /* L1: Check if parent path fits in buffer */
+    if (plen + 1 > sizeof(parent_path)) return NULL;
     memcpy(parent_path, path, plen);
     parent_path[plen] = 0;
 
@@ -483,7 +484,8 @@ fs_node_t* vfs_lookup_parent(const char* path, char* name_out, size_t name_sz) {
     const char* base = last_slash + 1;
     size_t blen = strlen(base);
     if (blen == 0) return NULL; /* trailing slash, no basename */
-    if (blen >= name_sz) blen = name_sz - 1;
+    /* L1: Check if basename fits in output buffer */
+    if (blen + 1 > name_sz) return NULL;
     memcpy(name_out, base, blen);
     name_out[blen] = 0;
 
index c9b764d9761946265444d1b9d06f5b3926a523f1..9c6e74e81a1389f4cb2f67f1a8437dc81bddac83 100644 (file)
@@ -2622,30 +2622,33 @@ static int path_resolve_user(const char* user_path, char* out, size_t out_sz) {
     }
 
     if (path_is_absolute(in)) {
-        // bounded copy
-        size_t i = 0;
-        while (in[i] != 0 && i + 1 < out_sz) {
-            out[i] = in[i];
-            i++;
-        }
-        out[i] = 0;
+        /* L1: Check if path fits in output buffer */
+        size_t in_len = strlen(in);
+        if (in_len + 1 > out_sz) return -ENAMETOOLONG;
+        strcpy(out, in);
         path_normalize_inplace(out);
         return 0;
     }
 
     const char* base = (current_process && current_process->cwd[0]) ? current_process->cwd : "/";
+    size_t base_len = strlen(base);
+    size_t in_len = strlen(in);
+    
+    /* L1: Check if combined path fits in output buffer */
+    size_t needed = base_len + 1 + in_len + 1; /* base + '/' + in + null */
+    if (needed > out_sz) return -ENAMETOOLONG;
+    
     size_t w = 0;
     if (strcmp(base, "/") == 0) {
-        if (out_sz < 2) return -ENAMETOOLONG;
         out[w++] = '/';
     } else {
-        for (size_t i = 0; base[i] != 0 && w + 1 < out_sz; i++) {
+        for (size_t i = 0; base[i] != 0; i++) {
             out[w++] = base[i];
         }
-        if (w + 1 < out_sz) out[w++] = '/';
+        out[w++] = '/';
     }
 
-    for (size_t i = 0; in[i] != 0 && w + 1 < out_sz; i++) {
+    for (size_t i = 0; in[i] != 0; i++) {
         out[w++] = in[i];
     }
     out[w] = 0;