|
| 1 | +#!/bin/sh |
| 2 | +# Copyright 2025 syzkaller project authors. All rights reserved. |
| 3 | +# Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file. |
| 4 | +# |
| 5 | +# This script scans the syz-executor binary for data relocations accesses |
| 6 | +# within the "guest" ELF section that are problematic for the SYZOS guest |
| 7 | +# code. |
| 8 | +# |
| 9 | +# It uses $TARGETOS and $TARGETARCH to locate the binary and determine the |
| 10 | +# correct architecture. |
| 11 | +# |
| 12 | + |
| 13 | +set -e |
| 14 | + |
| 15 | +SECTION_TO_CHECK="guest" |
| 16 | + |
| 17 | +echoerr() { |
| 18 | + echo "$@" >&2 |
| 19 | +} |
| 20 | + |
| 21 | +if [ "$TARGETOS" != "linux" ]; then |
| 22 | + echo "[INFO] TARGETOS is '$TARGETOS', not 'linux'. Skipping check." |
| 23 | + exit 0 |
| 24 | +fi |
| 25 | + |
| 26 | +if [ -z "$TARGETARCH" ]; then |
| 27 | + echoerr "Error: \$TARGETARCH environment variable is not set." |
| 28 | + exit 1 |
| 29 | +fi |
| 30 | + |
| 31 | +BINARY="bin/${TARGETOS}_${TARGETARCH}/syz-executor" |
| 32 | + |
| 33 | +if [ ! -f "$BINARY" ]; then |
| 34 | + echoerr "Error: Binary not found at '$BINARY'" |
| 35 | + exit 1 |
| 36 | +fi |
| 37 | + |
| 38 | +echoerr "--> Analyzing architecture '$TARGETARCH'..." |
| 39 | +OBJDUMP_CMD="" |
| 40 | + |
| 41 | +if [ "$TARGETARCH" = "amd64" ]; then |
| 42 | + ARCH="x86_64" |
| 43 | + PATTERNS_TO_FIND='\(%rip\)' |
| 44 | + if command -v x86_64-linux-gnu-objdump > /dev/null; then |
| 45 | + OBJDUMP_CMD="x86_64-linux-gnu-objdump" |
| 46 | + fi |
| 47 | +elif [ "$TARGETARCH" = "arm64" ]; then |
| 48 | + ARCH="aarch64" |
| 49 | + PATTERNS_TO_FIND='adrp' |
| 50 | + if command -v aarch64-linux-gnu-objdump > /dev/null; then |
| 51 | + OBJDUMP_CMD="aarch64-linux-gnu-objdump" |
| 52 | + fi |
| 53 | +else |
| 54 | + echo "[INFO] Unsupported architecture '$TARGETARCH', skipping check." |
| 55 | + exit 0 |
| 56 | +fi |
| 57 | +echoerr "--> Detected architecture: $ARCH" |
| 58 | + |
| 59 | +if [ -z "$OBJDUMP_CMD" ]; then |
| 60 | + echoerr "--> Arch-specific objdump not found, falling back to generic 'objdump'..." |
| 61 | + if command -v objdump > /dev/null; then |
| 62 | + OBJDUMP_CMD="objdump" |
| 63 | + fi |
| 64 | +fi |
| 65 | + |
| 66 | +if [ -z "$OBJDUMP_CMD" ]; then |
| 67 | + echoerr "Error: Could not find a usable objdump binary." |
| 68 | + exit 1 |
| 69 | +fi |
| 70 | +echoerr "--> Using objdump: $OBJDUMP_CMD" |
| 71 | + |
| 72 | +echoerr "--> Verifying existence of section '$SECTION_TO_CHECK' in '$BINARY'..." |
| 73 | +if ! "$OBJDUMP_CMD" -h --section="$SECTION_TO_CHECK" "$BINARY" >/dev/null 2>&1; then |
| 74 | + echo |
| 75 | + echo "[INFO] Section '$SECTION_TO_CHECK' not found in '$BINARY'. Skipping check." |
| 76 | + exit 0 |
| 77 | +fi |
| 78 | + |
| 79 | +echoerr "--> Disassembling section '$SECTION_TO_CHECK' and scanning for patterns ('$PATTERNS_TO_FIND')..." |
| 80 | + |
| 81 | +DISASSEMBLY_STATUS=0 |
| 82 | +DISASSEMBLY_OUTPUT=$("$OBJDUMP_CMD" -d --section="$SECTION_TO_CHECK" "$BINARY" 2>/dev/null) || DISASSEMBLY_STATUS=$? |
| 83 | + |
| 84 | +if [ $DISASSEMBLY_STATUS -ne 0 ]; then |
| 85 | + echoerr "Error: '$OBJDUMP_CMD' failed to disassemble the '$SECTION_TO_CHECK' section." |
| 86 | + # Attempt to show the actual error to the user |
| 87 | + "$OBJDUMP_CMD" -d --section="$SECTION_TO_CHECK" "$BINARY" >/dev/null |
| 88 | + exit 1 |
| 89 | +fi |
| 90 | + |
| 91 | +FOUND_INSTRUCTIONS=$(echo "$DISASSEMBLY_OUTPUT" | awk -v pattern="$PATTERNS_TO_FIND" ' |
| 92 | + # Match a function header, e.g., "0000000000401136 <my_func>:" |
| 93 | + /^[0-9a-f]+ <.*>:$/ { |
| 94 | + match($0, /<.*>/) |
| 95 | + current_func = substr($0, RSTART, RLENGTH) |
| 96 | + } |
| 97 | + # If the line matches the instruction pattern, print the context. |
| 98 | + $0 ~ pattern { |
| 99 | + if (current_func) { |
| 100 | + print "In function " current_func ":" |
| 101 | + } |
| 102 | + print "\t" $0 |
| 103 | + } |
| 104 | +' || true) |
| 105 | + |
| 106 | +if [ -n "$FOUND_INSTRUCTIONS" ]; then |
| 107 | + echo |
| 108 | + echo "------------------------------------------------------------------" |
| 109 | + echo "[FAIL] Found problematic data access instructions in '$SECTION_TO_CHECK'." |
| 110 | + echo "The following instructions are likely to cause crashes in SyzOS:" |
| 111 | + echo "$FOUND_INSTRUCTIONS" | sed 's/^/ /' |
| 112 | + echo "------------------------------------------------------------------" |
| 113 | + echo |
| 114 | + echo "This typically happens when the C compiler emits read-only constants for" |
| 115 | + echo "zero-initializing structs or for jump tables in switch statements." |
| 116 | + exit 1 |
| 117 | +else |
| 118 | + echo |
| 119 | + echo "[OK] No problematic data access instructions found in '$SECTION_TO_CHECK'." |
| 120 | + exit 0 |
| 121 | +fi |
0 commit comments