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 534291f3..274fe19d 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 e68dcc2d..e03739e3 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 1ba83e1d..a72c39c4 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 27e92a3b..802147ef 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 37c11d8f..9a3097a6 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 e957f841..b3364e6d 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 6989f225..521cc5a8 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 36d4745d..e6b39f29 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 83f6210e..2d9fb168 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 0024e3db..ed74ba39 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 d168d42b..87a828ad 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 d8266fa1..6ce02de7 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 c9882a7e..bd714261 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 42e50cb9..7439197c 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 28be7065..b6919ca4 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 7fca2eab..c1443828 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 082ac816..41fa5fbb 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 c9882a7e..bd714261 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 71ea44ff..d3268efb 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 00000000..c2da2d26 --- /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 00000000..4b1b3a53 --- /dev/null +++ b/build/sanitycheck2 @@ -0,0 +1,9 @@ +PE=123 +exit $PE + + + + + + + diff --git a/build/ssh b/build/ssh index 17a09fb6..81c14c80 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 f2f61f27..dfa1a89a 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 99c614c1..3d490475 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) {