Create the stats file at its fixed, discoverable path without ever writing * through something another process planted there. Exclusive creation IS the * guarantee, so the predictable name stays safe: the unlink drops a stale file * from an earlier run with this pid (and, if a local attacker pre-created a * symlink, removes the link itself — never its target), and the O_EXCL create * that fol
| 149 | * O_NOFOLLOW is belt-and-braces for the same window on POSIX. Mode 0600: the |
| 150 | * snapshot describes this process's heap layout, so it is owner-only. */ |
| 151 | static FILE *diag_open_private_stats_file(const char *path) { |
| 152 | (void)cbm_unlink(path); |
| 153 | #ifdef _WIN32 |
| 154 | /* _wopen mirrors cbm_mkstemp's Windows contract — the ANSI CRT interprets |
| 155 | * the UTF-8 bytes of a non-ASCII %TEMP% in the local codepage and fails. */ |
| 156 | wchar_t *wide = cbm_path_to_wide(path); |
| 157 | if (!wide) { |
| 158 | return NULL; |
| 159 | } |
| 160 | int descriptor = _wopen(wide, _O_WRONLY | _O_CREAT | _O_EXCL | _O_BINARY | _O_NOINHERIT, |
| 161 | _S_IREAD | _S_IWRITE); |
| 162 | free(wide); |
| 163 | if (descriptor < 0) { |
| 164 | return NULL; |
| 165 | } |
| 166 | FILE *sink = _fdopen(descriptor, "wb"); |
| 167 | if (!sink) { |
| 168 | (void)_close(descriptor); |
| 169 | } |
| 170 | return sink; |
| 171 | #else |
| 172 | int flags = O_WRONLY | O_CREAT | O_EXCL | O_CLOEXEC; |
| 173 | #ifdef O_NOFOLLOW |
| 174 | flags |= O_NOFOLLOW; |
| 175 | #endif |
| 176 | int descriptor = open(path, flags, 0600); |
| 177 | if (descriptor < 0) { |
| 178 | return NULL; |
| 179 | } |
| 180 | FILE *sink = fdopen(descriptor, "wb"); |
| 181 | if (!sink) { |
| 182 | (void)close(descriptor); |
| 183 | } |
| 184 | return sink; |
| 185 | #endif |
| 186 | } |
| 187 | |
| 188 | static void diag_write_allocator_stats(void) { |
| 189 | char flag[CBM_SZ_16]; |
no test coverage detected