From f21355636628bd18aeea361486881fe2d17e409a Mon Sep 17 00:00:00 2001 From: Justine Tunney Date: Mon, 31 Aug 2020 19:31:11 -0700 Subject: [PATCH] Add binfmt_misc workaround detector to builds This is a recently introduced Linux Kernel feature that gives people like Debian package mantainers the power to arbitrarily redefine how executables are interpreted by the kernel. If your system gets tuned this way and you're not able to disable it, then you need to restore default behavior for the APE MZqFpD prefix as follows: sudo sh -c "echo ':APE:M::MZqFpD::/bin/sh:' >/proc/sys/fs/binfmt_misc/register" This prefix will cover all .com executables built with this tooling. Please don't run the above command unless you're certain you need it. See #2 for additional context. --- Makefile | 5 ++-- build/actuallynice | 1 + build/archive | 1 + build/assemble | 1 + build/bochs-debugger | 1 + build/catcode | 1 + build/compile | 1 + build/do | 1 + build/getccname | 1 + build/getccversion | 1 + build/getlogfmt | 1 + build/htags | 1 + build/includeall | 1 + build/link | 1 + build/mkdeps | 1 + build/objdump | 1 + build/package | 1 + build/rollup | 1 + build/runcom | 1 + build/sanitycheck | 57 ++++++++++++++++++++++++++++++++++++++++++++ build/sanitycheck2 | 9 +++++++ build/ssh | 1 + build/zipobj | 1 + tool/decode/pe2.c | 15 ------------ 24 files changed, 89 insertions(+), 17 deletions(-) create mode 100755 build/sanitycheck create mode 100755 build/sanitycheck2 diff --git a/Makefile b/Makefile index 534291f3f..274fe19df 100644 --- a/Makefile +++ b/Makefile @@ -60,8 +60,9 @@ # # build/config.mk -SHELL = /bin/sh -HOSTS ?= freebsd openbsd alpine +SHELL = /bin/sh +HOSTS ?= freebsd openbsd alpine +SANITY := $(shell build/sanitycheck $$PPID) .SUFFIXES: .DELETE_ON_ERROR: diff --git a/build/actuallynice b/build/actuallynice index e68dcc2d5..e03739e33 100755 --- a/build/actuallynice +++ b/build/actuallynice @@ -1,3 +1,4 @@ +#!/bin/sh #-*-mode:sh;indent-tabs-mode:nil;tab-width:2;coding:utf-8-*-┐ #───vi: set net ft=sh ts=2 sts=2 fenc=utf-8 :vi─────────────┘ # diff --git a/build/archive b/build/archive index 1ba83e1d3..a72c39c46 100755 --- a/build/archive +++ b/build/archive @@ -1,3 +1,4 @@ +#!/bin/sh #-*-mode:sh;indent-tabs-mode:nil;tab-width:2;coding:utf-8-*-┐ #───vi: set net ft=sh ts=2 sts=2 fenc=utf-8 :vi─────────────┘ # diff --git a/build/assemble b/build/assemble index 27e92a3b7..802147ef4 100755 --- a/build/assemble +++ b/build/assemble @@ -1,3 +1,4 @@ +#!/bin/sh #-*-mode:sh;indent-tabs-mode:nil;tab-width:2;coding:utf-8-*-┐ #───vi: set net ft=sh ts=2 sts=2 fenc=utf-8 :vi─────────────┘ # diff --git a/build/bochs-debugger b/build/bochs-debugger index 37c11d8f2..9a3097a6b 100755 --- a/build/bochs-debugger +++ b/build/bochs-debugger @@ -1,3 +1,4 @@ +#!/bin/sh # -*- mode:sh;indent-tabs-mode:nil;tab-width:2;coding:utf-8 -*- # vi: set net ft=sh ts=2 sts=2 sw=2 fenc=utf-8 :vi diff --git a/build/catcode b/build/catcode index e957f841d..b3364e6d9 100755 --- a/build/catcode +++ b/build/catcode @@ -1,3 +1,4 @@ +#!/bin/sh #-*-mode:sh;indent-tabs-mode:nil;tab-width:2;coding:utf-8-*-┐ #───vi: set net ft=sh ts=2 sts=2 fenc=utf-8 :vi─────────────┘ # diff --git a/build/compile b/build/compile index 6989f2257..521cc5a8a 100755 --- a/build/compile +++ b/build/compile @@ -1,3 +1,4 @@ +#!/bin/sh #-*-mode:sh;indent-tabs-mode:nil;tab-width:2;coding:utf-8-*-┐ #───vi: set net ft=sh ts=2 sts=2 fenc=utf-8 :vi─────────────┘ # diff --git a/build/do b/build/do index 36d4745d3..e6b39f29f 100755 --- a/build/do +++ b/build/do @@ -1,3 +1,4 @@ +#!/bin/sh #-*-mode:sh;indent-tabs-mode:nil;tab-width:2;coding:utf-8-*-┐ #───vi: set net ft=sh ts=2 sts=2 fenc=utf-8 :vi─────────────┘ # diff --git a/build/getccname b/build/getccname index 83f6210e1..2d9fb168a 100755 --- a/build/getccname +++ b/build/getccname @@ -1,3 +1,4 @@ +#!/bin/sh #-*-mode:sh;indent-tabs-mode:nil;tab-width:2;coding:utf-8-*-┐ #───vi: set net ft=sh ts=2 sts=2 fenc=utf-8 :vi─────────────┘ # diff --git a/build/getccversion b/build/getccversion index 0024e3dbe..ed74ba39a 100755 --- a/build/getccversion +++ b/build/getccversion @@ -1,3 +1,4 @@ +#!/bin/sh #-*-mode:sh;indent-tabs-mode:nil;tab-width:2;coding:utf-8-*-┐ #───vi: set net ft=sh ts=2 sts=2 fenc=utf-8 :vi─────────────┘ # diff --git a/build/getlogfmt b/build/getlogfmt index d168d42b0..87a828adb 100755 --- a/build/getlogfmt +++ b/build/getlogfmt @@ -1,3 +1,4 @@ +#!/usr/bin/env bash #-*-mode:sh;indent-tabs-mode:nil;tab-width:2;coding:utf-8-*-┐ #───vi: set net ft=sh ts=2 sts=2 fenc=utf-8 :vi─────────────┘ # diff --git a/build/htags b/build/htags index d8266fa19..6ce02de71 100755 --- a/build/htags +++ b/build/htags @@ -1,3 +1,4 @@ +#!/bin/sh #-*-mode:sh;indent-tabs-mode:nil;tab-width:2;coding:utf-8-*-┐ #───vi: set net ft=sh ts=2 sts=2 fenc=utf-8 :vi─────────────┘ # diff --git a/build/includeall b/build/includeall index c9882a7e8..bd7142610 100755 --- a/build/includeall +++ b/build/includeall @@ -1,3 +1,4 @@ +#!/bin/sh #-*-mode:sh;indent-tabs-mode:nil;tab-width:2;coding:utf-8-*-┐ #───vi: set net ft=sh ts=2 sts=2 fenc=utf-8 :vi─────────────┘ diff --git a/build/link b/build/link index 42e50cb91..7439197ca 100755 --- a/build/link +++ b/build/link @@ -1,3 +1,4 @@ +#!/bin/sh #-*-mode:sh;indent-tabs-mode:nil;tab-width:2;coding:utf-8-*-┐ #───vi: set net ft=sh ts=2 sts=2 fenc=utf-8 :vi─────────────┘ # diff --git a/build/mkdeps b/build/mkdeps index 28be70659..b6919ca4b 100755 --- a/build/mkdeps +++ b/build/mkdeps @@ -1,3 +1,4 @@ +#!/bin/sh #-*-mode:sh;indent-tabs-mode:nil;tab-width:2;coding:utf-8-*-┐ #───vi: set net ft=sh ts=2 sts=2 fenc=utf-8 :vi─────────────┘ diff --git a/build/objdump b/build/objdump index 7fca2eab9..c1443828e 100755 --- a/build/objdump +++ b/build/objdump @@ -1,3 +1,4 @@ +#!/bin/sh #-*-mode:sh;indent-tabs-mode:nil;tab-width:2;coding:utf-8-*-┐ #───vi: set net ft=sh ts=2 sts=2 fenc=utf-8 :vi─────────────┘ # diff --git a/build/package b/build/package index 082ac816a..41fa5fbb4 100755 --- a/build/package +++ b/build/package @@ -1,3 +1,4 @@ +#!/bin/sh #-*-mode:sh;indent-tabs-mode:nil;tab-width:2;coding:utf-8-*-┐ #───vi: set net ft=sh ts=2 sts=2 fenc=utf-8 :vi─────────────┘ diff --git a/build/rollup b/build/rollup index c9882a7e8..bd7142610 100755 --- a/build/rollup +++ b/build/rollup @@ -1,3 +1,4 @@ +#!/bin/sh #-*-mode:sh;indent-tabs-mode:nil;tab-width:2;coding:utf-8-*-┐ #───vi: set net ft=sh ts=2 sts=2 fenc=utf-8 :vi─────────────┘ diff --git a/build/runcom b/build/runcom index 71ea44ff4..d3268efbc 100755 --- a/build/runcom +++ b/build/runcom @@ -1,3 +1,4 @@ +#!/bin/sh #-*-mode:sh;indent-tabs-mode:nil;tab-width:2;coding:utf-8-*-┐ #───vi: set net ft=sh ts=2 sts=2 fenc=utf-8 :vi─────────────┘ diff --git a/build/sanitycheck b/build/sanitycheck new file mode 100755 index 000000000..c2da2d263 --- /dev/null +++ b/build/sanitycheck @@ -0,0 +1,57 @@ +#!/bin/sh +# +# OVERVIEW +# +# System Sanity Check +# +# DESCRIPTION +# +# This script is launched at the start of Makefile to detect if +# binfmt_misc was tuned to launch 'MZ' shell scripts under WINE + +if [ x`uname -s` != xLinux ]; then + cat <<'EOF' >&2 + +ERROR + + Want Linux Build Environment + +DETAILS + + Cosmopolitan builds binaries that run on all major platforms. + You need to compile them on Linux, using any distro you like. + Consider setting up Alpine, Debian, or Ubuntu in a VMWare VM. + +EOF + kill $1 + exit 1 +fi + +build/sanitycheck2 +if [ $? -ne 123 ]; then + cat <<'EOF' >&2 + +ERROR + + Thompson Shell Backwards Compatibility Issue Detected + +DETAILS + + Actually Portable Executable assumes stock Linux configuration. + Normal behavior is non-ELF files with x bit are run by /bin/sh. + Linux lets people globally define arbitrary magic interpreters. + Your computer couldve been tuned to run MZ scripts inside WINE. + So if you use binfmt_misc you need to explicitly register this. + +WORKAROUND + + sudo sh -c "echo ':APE:M::MZqFpD::/bin/sh:' >/proc/sys/fs/binfmt_misc/register" + +SEE ALSO + + https://justine.storage.googleapis.com/ape.html + +EOF + kill $1 + exit 1 +fi diff --git a/build/sanitycheck2 b/build/sanitycheck2 new file mode 100755 index 000000000..4b1b3a539 --- /dev/null +++ b/build/sanitycheck2 @@ -0,0 +1,9 @@ +PE=123 +exit $PE + + + + + + + diff --git a/build/ssh b/build/ssh index 17a09fb6b..81c14c80f 100755 --- a/build/ssh +++ b/build/ssh @@ -1,3 +1,4 @@ +#!/bin/sh #-*-mode:sh;indent-tabs-mode:nil;tab-width:2;coding:utf-8-*-┐ #───vi: set net ft=sh ts=2 sts=2 fenc=utf-8 :vi─────────────┘ # diff --git a/build/zipobj b/build/zipobj index f2f61f27b..dfa1a89aa 100755 --- a/build/zipobj +++ b/build/zipobj @@ -1,3 +1,4 @@ +#!/bin/sh #-*-mode:sh;indent-tabs-mode:nil;tab-width:2;coding:utf-8-*-┐ #───vi: set net ft=sh ts=2 sts=2 fenc=utf-8 :vi─────────────┘ diff --git a/tool/decode/pe2.c b/tool/decode/pe2.c index 99c614c18..3d4904754 100644 --- a/tool/decode/pe2.c +++ b/tool/decode/pe2.c @@ -110,21 +110,6 @@ static void showmzheader(void) { } static void showdosstub(void) { - unsigned char *p = (unsigned char *)mz + sizeof(struct NtImageDosHeader); - unsigned char *pe = (mz->e_lfanew ? p + mz->e_lfanew : p + mzsize); - pe = min(pe, p + mzsize - XED_MAX_INSTRUCTION_BYTES); - while (p < pe) { - struct XedDecodedInst *inst = ildreal(p); - if (p + inst->length > pe) break; - printf("\t.byte\t"); - for (unsigned i = 0; i < inst->length; ++i) { - if (i) printf(","); - printf("%#hhx", inst->bytes[i]); - } - printf("\n"); - p += inst->length; - } - printf("\n"); } static void showpeoptionalheader(struct NtImageOptionalHeader *opt) {