build-winchecksec.sh (7641B)
1 #!/bin/bash 2 set -e -v -x 3 4 mkdir -p $UPLOAD_DIR 5 6 cd $MOZ_FETCHES_DIR/winchecksec 7 8 SUFFIX= 9 10 case "$1" in 11 x86_64-pc-windows-msvc) 12 SUFFIX=.exe 13 export PATH="$MOZ_FETCHES_DIR/clang/bin:$PATH" 14 15 . $GECKO_PATH/taskcluster/scripts/misc/vs-setup.sh 16 17 # Patch pe-parse because clang-cl doesn't support /analyze. 18 patch -p1 <<'EOF' 19 --- a/pe-parse/cmake/compilation_flags.cmake 20 +++ b/pe-parse/cmake/compilation_flags.cmake 21 @@ -1,5 +1,5 @@ 22 if (MSVC) 23 - list(APPEND DEFAULT_CXX_FLAGS /W4 /analyze) 24 + list(APPEND DEFAULT_CXX_FLAGS /W4) 25 26 if (CMAKE_BUILD_TYPE STREQUAL "Debug" OR CMAKE_BUILD_TYPE STREQUAL "RelWithDebInfo") 27 list(APPEND DEFAULT_CXX_FLAGS /Zi) 28 EOF 29 30 CMAKE_FLAGS=' 31 -DCMAKE_CXX_COMPILER=clang-cl 32 -DCMAKE_C_COMPILER=clang-cl 33 -DCMAKE_LINKER=lld-link 34 -DCMAKE_C_FLAGS="-fuse-ld=lld -Xclang -ivfsoverlay -Xclang $MOZ_FETCHES_DIR/vs/overlay.yaml" 35 -DCMAKE_CXX_FLAGS="-fuse-ld=lld -EHsc -Xclang -ivfsoverlay -Xclang $MOZ_FETCHES_DIR/vs/overlay.yaml" 36 -DCMAKE_RC_COMPILER=llvm-rc 37 -DCMAKE_MT=llvm-mt 38 -DCMAKE_SYSTEM_NAME=Windows 39 -DCMAKE_MSVC_RUNTIME_LIBRARY=MultiThreaded 40 ' 41 ;; 42 esac 43 44 # Apply https://github.com/trailofbits/pe-parse/commit/d9e72af81e832330c111e07b98d34877469445f5 45 # And https://github.com/trailofbits/pe-parse/commit/eecdb3d36eb44e306398a2e66e85490f9bdcc74c 46 patch -p1 <<'EOF' 47 --- a/pe-parse/pe-parser-library/src/buffer.cpp 48 +++ b/pe-parse/pe-parser-library/src/buffer.cpp 49 @@ -112,11 +112,12 @@ bool readWord(bounded_buffer *b, std::uint32_t offset, std::uint16_t &out) { 50 return false; 51 } 52 53 - std::uint16_t *tmp = reinterpret_cast<std::uint16_t *>(b->buf + offset); 54 + std::uint16_t tmp; 55 + memcpy(&tmp, (b->buf + offset), sizeof(std::uint16_t)); 56 if (b->swapBytes) { 57 - out = byteSwapUint16(*tmp); 58 + out = byteSwapUint16(tmp); 59 } else { 60 - out = *tmp; 61 + out = tmp; 62 } 63 64 return true; 65 @@ -133,11 +134,12 @@ bool readDword(bounded_buffer *b, std::uint32_t offset, std::uint32_t &out) { 66 return false; 67 } 68 69 - std::uint32_t *tmp = reinterpret_cast<std::uint32_t *>(b->buf + offset); 70 + std::uint32_t tmp; 71 + memcpy(&tmp, (b->buf + offset), sizeof(std::uint32_t)); 72 if (b->swapBytes) { 73 - out = byteSwapUint32(*tmp); 74 + out = byteSwapUint32(tmp); 75 } else { 76 - out = *tmp; 77 + out = tmp; 78 } 79 80 return true; 81 @@ -154,11 +156,12 @@ bool readQword(bounded_buffer *b, std::uint32_t offset, std::uint64_t &out) { 82 return false; 83 } 84 85 - std::uint64_t *tmp = reinterpret_cast<std::uint64_t *>(b->buf + offset); 86 + std::uint64_t tmp; 87 + memcpy(&tmp, (b->buf + offset), sizeof(std::uint64_t)); 88 if (b->swapBytes) { 89 - out = byteSwapUint64(*tmp); 90 + out = byteSwapUint64(tmp); 91 } else { 92 - out = *tmp; 93 + out = tmp; 94 } 95 96 return true; 97 @@ -175,16 +178,16 @@ bool readChar16(bounded_buffer *b, std::uint32_t offset, char16_t &out) { 98 return false; 99 } 100 101 - char16_t *tmp = nullptr; 102 + char16_t tmp; 103 if (b->swapBytes) { 104 std::uint8_t tmpBuf[2]; 105 tmpBuf[0] = *(b->buf + offset + 1); 106 tmpBuf[1] = *(b->buf + offset); 107 - tmp = reinterpret_cast<char16_t *>(tmpBuf); 108 + memcpy(&tmp, tmpBuf, sizeof(std::uint16_t)); 109 } else { 110 - tmp = reinterpret_cast<char16_t *>(b->buf + offset); 111 + memcpy(&tmp, (b->buf + offset), sizeof(std::uint16_t)); 112 } 113 - out = *tmp; 114 + out = tmp; 115 116 return true; 117 } 118 --- a/pe-parse/pe-parser-library/include/parser-library/parse.h 119 +++ b/pe-parse/pe-parser-library/include/parser-library/parse.h 120 @@ -40,28 +40,38 @@ THE SOFTWARE. 121 err_loc.assign(__func__); \ 122 err_loc += ":" + to_string<std::uint32_t>(__LINE__, std::dec); 123 124 -#define READ_WORD(b, o, inst, member) \ 125 - if (!readWord(b, o + _offset(__typeof__(inst), member), inst.member)) { \ 126 - PE_ERR(PEERR_READ); \ 127 - return false; \ 128 +#define READ_WORD(b, o, inst, member) \ 129 + if (!readWord(b, \ 130 + o + static_cast<uint32_t>(offsetof(__typeof__(inst), member)), \ 131 + inst.member)) { \ 132 + PE_ERR(PEERR_READ); \ 133 + return false; \ 134 } 135 136 -#define READ_DWORD(b, o, inst, member) \ 137 - if (!readDword(b, o + _offset(__typeof__(inst), member), inst.member)) { \ 138 - PE_ERR(PEERR_READ); \ 139 - return false; \ 140 +#define READ_DWORD(b, o, inst, member) \ 141 + if (!readDword( \ 142 + b, \ 143 + o + static_cast<uint32_t>(offsetof(__typeof__(inst), member)), \ 144 + inst.member)) { \ 145 + PE_ERR(PEERR_READ); \ 146 + return false; \ 147 } 148 149 -#define READ_QWORD(b, o, inst, member) \ 150 - if (!readQword(b, o + _offset(__typeof__(inst), member), inst.member)) { \ 151 - PE_ERR(PEERR_READ); \ 152 - return false; \ 153 +#define READ_QWORD(b, o, inst, member) \ 154 + if (!readQword( \ 155 + b, \ 156 + o + static_cast<uint32_t>(offsetof(__typeof__(inst), member)), \ 157 + inst.member)) { \ 158 + PE_ERR(PEERR_READ); \ 159 + return false; \ 160 } 161 162 -#define READ_BYTE(b, o, inst, member) \ 163 - if (!readByte(b, o + _offset(__typeof__(inst), member), inst.member)) { \ 164 - PE_ERR(PEERR_READ); \ 165 - return false; \ 166 +#define READ_BYTE(b, o, inst, member) \ 167 + if (!readByte(b, \ 168 + o + static_cast<uint32_t>(offsetof(__typeof__(inst), member)), \ 169 + inst.member)) { \ 170 + PE_ERR(PEERR_READ); \ 171 + return false; \ 172 } 173 174 #define TEST_MACHINE_CHARACTERISTICS(h, m, ch) \ 175 --- a/pe-parse/pe-parser-library/src/parse.cpp 176 +++ b/pe-parse/pe-parser-library/src/parse.cpp 177 @@ -1777,7 +1777,7 @@ bool getRelocations(parsed_pe *p) { 178 // Mask out the type and assign 179 type = entry >> 12; 180 // Mask out the offset and assign 181 - offset = entry & ~0xf000; 182 + offset = entry & static_cast<std::uint16_t>(~0xf000); 183 184 // Produce the VA of the relocation 185 VA relocVA; 186 EOF 187 188 eval cmake \ 189 -GNinja \ 190 -DCMAKE_BUILD_TYPE=Release \ 191 -DBUILD_SHARED_LIBS=Off \ 192 $CMAKE_FLAGS 193 194 ninja -v 195 196 cd .. 197 tar -caf winchecksec.tar.zst winchecksec/winchecksec${SUFFIX} 198 cp winchecksec.tar.zst $UPLOAD_DIR/