]> Projects (at) Tadryanom (dot) Me - AdrOS.git/commitdiff
security: Round 5.3 execl/execlp varargs (U04)
authorTulio A M Mendes <[email protected]>
Mon, 25 May 2026 19:14:03 +0000 (16:14 -0300)
committerTulio A M Mendes <[email protected]>
Mon, 25 May 2026 19:14:03 +0000 (16:14 -0300)
U04: Fix varargs handling in execl/execlp
- execl: Use va_list instead of pointer arithmetic for portability
- execlp: Use va_list instead of pointer arithmetic for portability
- Both functions now use __builtin_va_start/va_arg/va_end properly

Tests: 119/119 PASS (smoke test, SMP=4)

user/ulibc/src/execvp.c

index 2ffbdbf524060fc8307dcd082049bc3fb87b9d09..8b56f15d0d074d050a5b5853f94c18640b87061c 100644 (file)
@@ -56,28 +56,35 @@ int execvp(const char* file, char* const argv[]) {
 }
 
 int execlp(const char* file, const char* arg, ...) {
-    /* Count args by walking the va_list manually via stack pointers.
-     * On i386, args are pushed right-to-left on the stack.
-     * We'll use a simple approach: max 32 args. */
+    /* U04: Use va_list instead of pointer arithmetic for portability */
     const char* args[33];
-    const char** p = &arg;
+    __builtin_va_list ap;
+    __builtin_va_start(ap, arg);
     int i = 0;
-    while (*p && i < 32) {
-        args[i++] = *p;
-        p++;
+    args[i++] = arg;
+    while (i < 32) {
+        const char* a = __builtin_va_arg(ap, const char*);
+        if (!a) break;
+        args[i++] = a;
     }
     args[i] = (const char*)0;
+    __builtin_va_end(ap);
     return execvp(file, (char* const*)args);
 }
 
 int execl(const char* path, const char* arg, ...) {
+    /* U04: Use va_list instead of pointer arithmetic for portability */
     const char* args[33];
-    const char** p = &arg;
+    __builtin_va_list ap;
+    __builtin_va_start(ap, arg);
     int i = 0;
-    while (*p && i < 32) {
-        args[i++] = *p;
-        p++;
+    args[i++] = arg;
+    while (i < 32) {
+        const char* a = __builtin_va_arg(ap, const char*);
+        if (!a) break;
+        args[i++] = a;
     }
     args[i] = (const char*)0;
+    __builtin_va_end(ap);
     return execve(path, (char* const*)args, environ);
 }