From: Tulio A M Mendes Date: Mon, 25 May 2026 19:13:02 +0000 (-0300) Subject: security: Round 5.2 mkstemp/tmpfile/tmpnam secure (U01) X-Git-Url: https://projects.tadryanom.me/?a=commitdiff_plain;h=a9bcec4f1339a2532efb3611f0ae06769d4e1391;p=AdrOS.git security: Round 5.2 mkstemp/tmpfile/tmpnam secure (U01) U01: Secure temporary file creation - mkstemp: Use /dev/urandom for randomness, fallback to pid+counter - mkstemp: Use alphanumeric charset (62 chars) instead of only digits - mkstemp: Always use O_CREAT|O_EXCL with mode 0600 - tmpfile: Use mkstemp for secure creation, unlink immediately for anonymity - tmpnam: Use mkstemp for secure name generation, don't leave file around Tests: 119/119 PASS (smoke test, SMP=4) --- diff --git a/user/ulibc/src/stdio.c b/user/ulibc/src/stdio.c index 34109fb3..163d51b4 100644 --- a/user/ulibc/src/stdio.c +++ b/user/ulibc/src/stdio.c @@ -590,19 +590,28 @@ int pclose(FILE* fp) { } FILE* tmpfile(void) { - static int tmpcount = 0; - char name[32]; + /* U01: Use mkstemp for secure temporary file creation */ + char name[64]; extern int getpid(void); - snprintf(name, sizeof(name), "/tmp/.tmpf_%d_%d", getpid(), tmpcount++); - return fopen(name, "w+"); + snprintf(name, sizeof(name), "/tmp/.tmpf_XXXXXX"); + int fd = mkstemp(name); + if (fd < 0) return NULL; + /* U01: Unlink immediately to make it anonymous (deleted on close) */ + unlink(name); + return fdopen(fd, "w+"); } char* tmpnam(char* s) { - static char buf[32]; - static int count = 0; - snprintf(buf, sizeof(buf), "/tmp/tmp_%d", count++); - if (s) { strcpy(s, buf); return s; } - return buf; + /* U01: Use mkstemp for secure temporary file name generation */ + static char buf[64]; + char* target = s ? s : buf; + snprintf(target, 64, "/tmp/tmpnam_XXXXXX"); + int fd = mkstemp(target); + if (fd >= 0) { + close(fd); + unlink(target); /* Don't leave the file around */ + } + return target; } int fscanf(FILE* fp, const char* fmt, ...) { diff --git a/user/ulibc/src/stdlib.c b/user/ulibc/src/stdlib.c index 19674eee..f1cc1d51 100644 --- a/user/ulibc/src/stdlib.c +++ b/user/ulibc/src/stdlib.c @@ -340,15 +340,27 @@ int mkstemp(char* tmpl) { /* Check template ends with XXXXXX */ for (int i = 0; i < 6; i++) if (suffix[i] != 'X') return -1; - /* Generate unique name using pid + counter */ - extern int getpid(void); - static int counter = 0; - int id = getpid() * 1000 + (counter++ % 1000); - for (int i = 5; i >= 0; i--) { - suffix[i] = (char)('0' + id % 10); - id /= 10; + /* U01: Try to use /dev/urandom for better randomness, fallback to pid+counter */ + int rand_bytes[2] = {0, 0}; + int rand_fd = open("/dev/urandom", 0); + if (rand_fd >= 0) { + read(rand_fd, rand_bytes, sizeof(rand_bytes)); + close(rand_fd); + } else { + extern int getpid(void); + static int counter = 0; + rand_bytes[0] = getpid(); + rand_bytes[1] = counter++; } - int fd = open(tmpl, 1 | 0x40 | 0x80 /* O_WRONLY|O_CREAT|O_EXCL */); + /* Use alphanumeric characters for XXXXXX */ + const char* charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; + unsigned int seed = (unsigned int)(rand_bytes[0] ^ rand_bytes[1]); + for (int i = 0; i < 6; i++) { + suffix[i] = charset[seed % 62]; + seed = seed * 1103515245 + 12345; /* LCG for variety */ + } + /* U01: Always use O_CREAT|O_EXCL to prevent race conditions */ + int fd = open(tmpl, 1 | 0x40 | 0x80 /* O_WRONLY|O_CREAT|O_EXCL */, 0600); return fd; }