From: Tulio A M Mendes Date: Tue, 26 May 2026 05:29:30 +0000 (-0300) Subject: security: return ENAMETOOLONG on path truncation (Fase 5) X-Git-Url: https://projects.tadryanom.me/?a=commitdiff_plain;h=51580840b13a4c213c5fcf474072b2f7a6c1c46e;p=AdrOS.git security: return ENAMETOOLONG on path truncation (Fase 5) --- diff --git a/src/kernel/fs.c b/src/kernel/fs.c index 94f63019..b8002160 100644 --- a/src/kernel/fs.c +++ b/src/kernel/fs.c @@ -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; diff --git a/src/kernel/syscall.c b/src/kernel/syscall.c index c9b764d9..9c6e74e8 100644 --- a/src/kernel/syscall.c +++ b/src/kernel/syscall.c @@ -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;