diff --git a/libc/calls/mkntenvblock.c b/libc/calls/mkntenvblock.c index e3fbefa9d..0c5d10d88 100644 --- a/libc/calls/mkntenvblock.c +++ b/libc/calls/mkntenvblock.c @@ -18,11 +18,13 @@ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/calls/ntspawn.h" #include "libc/fmt/conv.h" +#include "libc/intrin/_getenv.internal.h" #include "libc/intrin/bits.h" #include "libc/macros.internal.h" #include "libc/mem/alloca.h" #include "libc/mem/arraylist2.internal.h" #include "libc/mem/mem.h" +#include "libc/runtime/runtime.h" #include "libc/str/str.h" #include "libc/str/thompike.h" #include "libc/str/utf16.h" @@ -91,12 +93,15 @@ static textwindows void FixPath(char *path) { } static textwindows void InsertString(char **a, size_t i, char *s, - char buf[ARG_MAX], size_t *bufi) { + char buf[ARG_MAX], size_t *bufi, + bool *have_systemroot) { char *v; size_t j, k; + v = StrChr(s, '='); + // apply fixups to var=/c/... - if ((v = StrChr(s, '=')) && v[1] == '/' && IsAlpha(v[2]) && v[3] == '/') { + if (v && v[1] == '/' && IsAlpha(v[2]) && v[3] == '/') { v = buf + *bufi; for (k = 0; s[k]; ++k) { if (*bufi + 1 < ARG_MAX) { @@ -136,11 +141,25 @@ textwindows int mkntenvblock(char16_t envvars[ARG_MAX / 2], char *const envp[], uint64_t w; char **vars; wint_t x, y; + bool have_systemroot = false; size_t i, j, k, n, m, bufi = 0; for (n = 0; envp[n];) n++; vars = alloca((n + 1) * sizeof(char *)); - for (i = 0; i < n; ++i) InsertString(vars, i, envp[i], buf, &bufi); - if (extravar) InsertString(vars, n++, extravar, buf, &bufi); + for (i = 0; i < n; ++i) { + InsertString(vars, i, envp[i], buf, &bufi, &have_systemroot); + } + if (extravar) { + InsertString(vars, n++, extravar, buf, &bufi, &have_systemroot); + } + if (!have_systemroot && environ) { + // https://jpassing.com/2009/12/28/the-hidden-danger-of-forgetting-to-specify-systemroot-in-a-custom-environment-block/ + struct Env systemroot; + systemroot = _getenv(environ, "SYSTEMROOT"); + if (systemroot.s) { + InsertString(vars, n++, environ[systemroot.i], buf, &bufi, + &have_systemroot); + } + } for (k = i = 0; i < n; ++i) { j = 0; v = false; diff --git a/libc/elf/getelfsectionaddress.c b/libc/elf/getelfsectionaddress.c index 2db192053..8c5f4168e 100644 --- a/libc/elf/getelfsectionaddress.c +++ b/libc/elf/getelfsectionaddress.c @@ -31,17 +31,15 @@ * @param shdr is from GetElfSectionHeaderAddress(), or null * @return pointer to section data within image, or null if * 1. `shdr` was null, or - * 2. `sh_size` was zero, or - * 3, `sh_type` was `SHT_NOBITS`, or - * 4. content wasn't contained within `[elf,elf+mapsize)`, or - * 5. an arithmetic overflow occurred + * 2. content wasn't contained within `[elf,elf+mapsize)`, or + * 3. an arithmetic overflow occurred */ void *GetElfSectionAddress(const Elf64_Ehdr *elf, // validated size_t mapsize, // validated const Elf64_Shdr *shdr) { // foreign Elf64_Off last; if (!shdr) return 0; - if (shdr->sh_size <= 0) return 0; + if (!shdr->sh_size) return elf; if (shdr->sh_type == SHT_NOBITS) return 0; if (ckd_add(&last, shdr->sh_offset, shdr->sh_size)) return 0; if (last > mapsize) return 0; diff --git a/libc/intrin/describentpipeopenflags.c b/libc/intrin/describentpipeopenflags.c index ebb81c990..8ef16ddff 100644 --- a/libc/intrin/describentpipeopenflags.c +++ b/libc/intrin/describentpipeopenflags.c @@ -18,16 +18,24 @@ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/intrin/describeflags.internal.h" #include "libc/macros.internal.h" +#include "libc/nt/enum/accessmask.h" +#include "libc/nt/enum/fileflagandattributes.h" #include "libc/nt/enum/filemapflags.h" #include "libc/nt/ipc.h" static const struct DescribeFlags kPipeOpenFlags[] = { - {kNtPipeAccessDuplex, "Duplex"}, // 0x00000003 - {kNtPipeAccessOutbound, "Outbound"}, // 0x00000002 - {kNtPipeAccessInbound, "Inbound"}, // 0x00000001 + {kNtPipeAccessDuplex, "kNtPipeAccessDuplex"}, + {kNtPipeAccessOutbound, "kNtPipeAccessOutbound"}, + {kNtPipeAccessInbound, "kNtPipeAccessInbound"}, + {kNtFileFlagOverlapped, "kNtFileFlagOverlapped"}, + {kNtFileFlagFirstPipeInstance, "kNtFileFlagFirstPipeInstance"}, + {kNtFileFlagWriteThrough, "kNtFileFlagWriteThrough"}, + {kNtWriteDac, "kNtWriteDac"}, + {kNtWriteOwner, "kNtWriteOwner"}, + {kNtAccessSystemSecurity, "kNtAccessSystemSecurity"}, }; const char *(DescribeNtPipeOpenFlags)(char buf[64], uint32_t x) { - return DescribeFlags(buf, 64, kPipeOpenFlags, ARRAYLEN(kPipeOpenFlags), - "kNtPipeAccess", x); + return DescribeFlags(buf, 64, kPipeOpenFlags, ARRAYLEN(kPipeOpenFlags), "", + x); } diff --git a/libc/intrin/describentsecurityattributes.c b/libc/intrin/describentsecurityattributes.c index 141483677..5e1cd0eef 100644 --- a/libc/intrin/describentsecurityattributes.c +++ b/libc/intrin/describentsecurityattributes.c @@ -17,10 +17,13 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/calls/state.internal.h" +#include "libc/fmt/itoa.h" #include "libc/intrin/describeflags.internal.h" #include "libc/nt/struct/securityattributes.h" -const char *DescribeNtSecurityAttributes(struct NtSecurityAttributes *p) { +const char *(DescribeNtSecurityAttributes)(char buf[32], + struct NtSecurityAttributes *p) { if (p == &kNtIsInheritable) return "&kNtIsInheritable"; - return "0"; + FormatInt64(buf, (uintptr_t)p); + return buf; } diff --git a/libc/nt/struct/securityattributes.h b/libc/nt/struct/securityattributes.h index 604bd95c3..6487df652 100644 --- a/libc/nt/struct/securityattributes.h +++ b/libc/nt/struct/securityattributes.h @@ -1,5 +1,6 @@ #ifndef COSMOPOLITAN_LIBC_NT_STRUCT_SECURITYATTRIBUTES_H_ #define COSMOPOLITAN_LIBC_NT_STRUCT_SECURITYATTRIBUTES_H_ +#include "libc/mem/alloca.h" #include "libc/nt/struct/securitydescriptor.h" #if !(__ASSEMBLER__ + __LINKER__ + 0) @@ -9,7 +10,10 @@ struct NtSecurityAttributes { bool32 bInheritHandle; }; -const char *DescribeNtSecurityAttributes(struct NtSecurityAttributes *); +const char *DescribeNtSecurityAttributes(char[32], + struct NtSecurityAttributes *); +#define DescribeNtSecurityAttributes(x) \ + DescribeNtSecurityAttributes(alloca(32), x) #endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ #endif /* COSMOPOLITAN_LIBC_NT_STRUCT_SECURITYATTRIBUTES_H_ */ diff --git a/test/libc/calls/ioctl_test.c b/test/libc/calls/ioctl_test.c index 380de276f..a504d8ef6 100644 --- a/test/libc/calls/ioctl_test.c +++ b/test/libc/calls/ioctl_test.c @@ -24,6 +24,7 @@ #include "libc/log/log.h" #include "libc/mem/gc.internal.h" #include "libc/mem/mem.h" +#include "libc/runtime/runtime.h" #include "libc/sock/sock.h" #include "libc/sock/struct/ifconf.h" #include "libc/sock/struct/ifreq.h" @@ -32,6 +33,7 @@ #include "libc/sysv/consts/ipproto.h" #include "libc/sysv/consts/sio.h" #include "libc/sysv/consts/sock.h" +#include "libc/testlib/subprocess.h" #include "libc/testlib/testlib.h" TEST(siocgifconf, test) { @@ -70,3 +72,12 @@ TEST(siocgifconf, test) { EXPECT_TRUE(foundloopback); ASSERT_NE(-1, close(socketfd)); } + +TEST(siocgifconf, mkntenvblock_systemroot) { + if (__argc != 1) return; + SPAWN(fork); + execve(GetProgramExecutableName(), + (char *[]){GetProgramExecutableName(), "hi", NULL}, (char *[]){NULL}); + abort(); + EXITS(0); +} diff --git a/tool/build/compile.c b/tool/build/compile.c index 205ca3e28..3a09cf656 100644 --- a/tool/build/compile.c +++ b/tool/build/compile.c @@ -201,17 +201,18 @@ char buf[PAGESIZE]; char tmpout[PATH_MAX]; const char *const kSafeEnv[] = { - "ADDR2LINE", // needed by GetAddr2linePath - "HOME", // needed by ~/.runit.psk - "HOMEDRIVE", // needed by ~/.runit.psk - "HOMEPATH", // needed by ~/.runit.psk - "MAKEFLAGS", // needed by IsRunningUnderMake - "MODE", // needed by test scripts - "PATH", // needed by clang - "PWD", // just seems plain needed - "STRACE", // useful for troubleshooting - "TERM", // needed to detect colors - "TMPDIR", // needed by compiler + "ADDR2LINE", // needed by GetAddr2linePath + "HOME", // needed by ~/.runit.psk + "HOMEDRIVE", // needed by ~/.runit.psk + "HOMEPATH", // needed by ~/.runit.psk + "MAKEFLAGS", // needed by IsRunningUnderMake + "MODE", // needed by test scripts + "PATH", // needed by clang + "PWD", // just seems plain needed + "STRACE", // useful for troubleshooting + "TERM", // needed to detect colors + "TMPDIR", // needed by compiler + "SYSTEMROOT", // needed by socket() }; const char *const kGccOnlyFlags[] = { @@ -373,7 +374,11 @@ bool IsSafeEnv(const char *s) { r = ARRAYLEN(kSafeEnv) - 1; while (l <= r) { m = (l & r) + ((l ^ r) >> 1); // floor((a+b)/2) - x = strncmp(s, kSafeEnv[m], n); + if (IsWindows()) { + x = strncasecmp(s, kSafeEnv[m], n); + } else { + x = strncmp(s, kSafeEnv[m], n); + } if (x < 0) { r = m - 1; } else if (x > 0) { @@ -643,10 +648,6 @@ int Launch(void) { close(pipefds[1]); for (;;) { - if (gotchld) { - rc = 0; - break; - } if (gotalrm) { PrintRed(); appends(&output, "\n\n`"); diff --git a/tool/build/fixupobj.c b/tool/build/fixupobj.c index ed8fd7af1..c5012a307 100644 --- a/tool/build/fixupobj.c +++ b/tool/build/fixupobj.c @@ -176,13 +176,13 @@ static void RewriteTlsCode(void) { uint32_t *p, *pe; for (i = 0; i < elf->e_shnum; ++i) { if (!(shdr = GetElfSectionHeaderAddress(elf, esize, i))) { - Die("elf header overflow"); + Die("elf header overflow #1"); } if (shdr->sh_type == SHT_PROGBITS && // (shdr->sh_flags & SHF_ALLOC) && // (shdr->sh_flags & SHF_EXECINSTR)) { if (!(p = GetElfSectionAddress(elf, esize, shdr))) { - Die("elf header overflow"); + Die("elf header overflow #2"); } for (pe = p + shdr->sh_size / 4; p <= pe; ++p) { if ((*p & -32) == MRS_TPIDR_EL0) { @@ -213,11 +213,11 @@ static void OptimizePatchableFunctionEntries(void) { if (!syms[i].st_size) continue; if (ELF64_ST_TYPE(syms[i].st_info) != STT_FUNC) continue; if (!(shdr = GetElfSectionHeaderAddress(elf, esize, syms[i].st_shndx))) { - Die("elf header overflow"); + Die("elf header overflow #3"); } if (shdr->sh_type != SHT_PROGBITS) continue; if (!(p = GetElfSectionAddress(elf, esize, shdr))) { - Die("elf header overflow"); + Die("elf header overflow #4"); } if (syms[i].st_value < shdr->sh_addr) { Die("elf symbol beneath section"); diff --git a/tool/build/package.c b/tool/build/package.c index 953c40882..865f8e097 100644 --- a/tool/build/package.c +++ b/tool/build/package.c @@ -651,9 +651,9 @@ int main(int argc, char *argv[]) { if (argc == 2 && !strcmp(argv[1], "-n")) { exit(0); } - if (!IsOptimized()) { - ShowCrashReports(); - } +#ifndef NDEBUG + ShowCrashReports(); +#endif bzero(&pkg, sizeof(pkg)); bzero(&deps, sizeof(deps)); Package(argc, argv, &pkg, &deps); diff --git a/tool/build/zipobj.c b/tool/build/zipobj.c index cb91014e5..29f4a18b6 100644 --- a/tool/build/zipobj.c +++ b/tool/build/zipobj.c @@ -16,6 +16,7 @@ │ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/assert.h" #include "libc/calls/calls.h" #include "libc/calls/struct/stat.h" #include "libc/elf/def.h" @@ -139,16 +140,27 @@ void ProcessFile(struct ElfWriter *elf, const char *path) { size_t pathlen; struct stat st; const char *name; - CHECK_NE(-1, (fd = open(path, O_RDONLY))); - CHECK_NE(-1, fstat(fd, &st)); + if (stat(path, &st)) { + perror(path); + exit(1); + } if (S_ISDIR(st.st_mode)) { + if ((fd = open(path, O_RDONLY | O_DIRECTORY)) == -1) { + perror(path); + exit(1); + } map = ""; st.st_size = 0; } else if (st.st_size) { - CHECK_NE(MAP_FAILED, - (map = mmap(NULL, st.st_size, PROT_READ, MAP_SHARED, fd, 0))); + if ((fd = open(path, O_RDONLY)) == -1 || + (map = mmap(0, st.st_size, PROT_READ, MAP_SHARED, fd, 0)) == + MAP_FAILED) { + perror(path); + exit(1); + } } else { - map = NULL; + fd = -1; + map = 0; } if (name_) { name = name_; @@ -166,7 +178,9 @@ void ProcessFile(struct ElfWriter *elf, const char *path) { } elfwriter_zip(elf, name, name, strlen(name), map, st.st_size, st.st_mode, timestamp, timestamp, timestamp, nocompress_); - if (st.st_size) CHECK_NE(-1, munmap(map, st.st_size)); + if (st.st_size) { + unassert(!munmap(map, st.st_size)); + } close(fd); }