Repository navigation
lib: windows: Keep the owner execute bit in the nova.exec stream - #6
Merged
Merged
Conversation
malloc rounds __brk up to max_align_t before it places the header, but only for compilers other than M2-Planet, which has no uintptr_t or max_align_t. Built by M2-Planet, as mes-m2 is on Linux and on Windows, it handed out __brk plus a long, so a request whose size is not a multiple of a long left the next block misaligned, and an odd one left it at an odd address. Linux's syscalls take a buffer at any address, so nothing noticed. Windows does not: the kernel captures the object name a file call is given with a probe that fails a UTF-16 buffer at an odd address with STATUS_DATATYPE_MISALIGNMENT. Every such name has come from RtlDosPathNameToNtPathName_U, which allocates on the process heap; one built in memory from malloc would pass or fail depending on what was allocated before it. M2libc's Windows malloc had the same failure, and rounds to 8 since its commit 13e57eb. Under M2-Planet __brk is now rounded up to the size of a long, its widest type, which holds a pointer on every target it compiles for, so what malloc gives back is aligned to a long, as it is for the other compilers. Their branch is unchanged. * lib/linux/malloc.c (M2_MALLOC_ALIGN): New macro. (malloc): Round __brk up to it under M2-Planet. Say why the header starts aligned.
lib/windows/chmod.c returned 0 having done nothing, and _open3 ignored its mode. nova-nix, which builds Nix derivations on Windows, takes a file's execute bit for its Nix archive from an NTFS alternate data stream named nova.exec, whose presence is the bit, so a program built on Mes libc could not mark its output executable. M2libc's Windows chmod writes that stream from the owner execute bit, the bit upstream Nix reads. chmod now does the same. It fails for a file that is not there, leaves a directory alone, and otherwise creates the stream holding "1" when the mode has S_IXUSR and deletes it when it does not. The stream is named on the NT path, since Win32 reads "a:nova.exec" as a path on drive A. Where M2libc queries the stream before deleting it, this deletes it and takes STATUS_OBJECT_NAME_NOT_FOUND as already clear, so chmod returns -1 for a failure other than absence. _open3 marks a file it creates whose mode has S_IXUSR, since the mode counts only when the open creates the file, and writes no stream for any other file. This C library keeps no umask on Windows (lib/stub/umask.c), so the mode is used as given. A file it creates but cannot mark is closed and the open fails, and the file stays. The S_IXUSR test is in chmod.c because kaem.windows.run compiles _open3.c before <sys/stat.h>. * lib/windows/chmod.c (__exec_stream, __exec_mark, __exec_create): New functions. (chmod): Set or clear the nova.exec stream from the owner execute bit. * lib/windows/_open3.c (_open3): Mark a file it creates with __exec_create. * include/windows/ntdll.h (__exec_create): Declare.
On windows-latest and windows-11-arm, scaffold/exec-bit.scm has mes-m2 make a file with open-output-file and mode 0755, make one with 0644, then chmod the second to 0755 and back to 0644. After each step the job reads the file's nova.exec stream through its Win32 name, as nova-nix does, and fails unless the stream is there, holding "1", exactly when the mode had S_IXUSR. The files have one-letter names, so the check also fails if the stream is named on the path chmod was given, which Win32 reads as a drive. * .github/workflows/windows.yml (mes-m2): Add the check. * scaffold/exec-bit.scm: New file.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
On Windows nova-nix reads a file's execute bit from its
nova.execalternate data stream. Mes libc'schmoddid nothing and_open3ignored its mode, so a program built on Mes libc could not mark its output.mallocnow aligns to a long under M2-Planet too. mes-m2's blocks could sit at odd addresses, and the kernel fails a file call whose UTF-16 object name is misaligned (STATUS_DATATYPE_MISALIGNMENT); the stream name is the first such name built withmalloc.chmodfollows M2libc's (x86/windows/sys/stat.cat 13e57eb): it fails for a missing file, leaves a directory alone, and writes the stream holding "1" when the mode hasS_IXUSRor deletes it, takingSTATUS_OBJECT_NAME_NOT_FOUNDas clear. The name goes on the NT path, since Win32 readsa:nova.execas drive A._open3marks a file it creates whose mode hasS_IXUSR; Mes libc keeps no umask on Windows.scaffold/exec-bit.scmto create files with 0755 and 0644, chmod one 0755 then 0644, and read the stream after each step.Not covered: M2libc's
open; the MesCC-built libc (nova-nix's Mes job); an existing file_open3rewrites withFILE_OVERWRITE_IF, whose named streams NTFS is reported to drop.Refs Novavero-AI/nova-nix#366.