Skip to content
This repository has been archived by the owner on Oct 13, 2023. It is now read-only.

Commit

Permalink
add go wrapper script (#811)
Browse files Browse the repository at this point in the history
  • Loading branch information
Ximinhan committed Aug 11, 2023
1 parent 1dd3c14 commit 2963326
Show file tree
Hide file tree
Showing 2 changed files with 377 additions and 27 deletions.
344 changes: 344 additions & 0 deletions doozerlib/golang_builder_FIPS_wrapper.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,344 @@
#!/bin/sh

LOG_PREFIX="Go compliance shim [${__doozer_group}][${__doozer_key}]:"

echoerr() {
if [[ "${GO_COMPLIANCE_DEBUG}" == "1" || "${GO_COMPLIANCE_INFO}" == "1" ]]; then
echo -n "${LOG_PREFIX} " 1>&2
cat <<< "$@" 1>&2
fi
}

stricterror() {
echoerr "ERROR: terminating go build due to strict mode non-compliance"
if [[ "${SHIM_TEST}" == "1" ]]; then
echo "STRICTERROR"
fi
}

run_go() {
if [[ "${SHIM_TEST}" == "1" ]]; then
echoerr "running with SHIM_TEST=${SHIM_TEST}"
echo -n "GOEXPERIMENT=${GOEXPERIMENT} CGO_ENABLED=${CGO_ENABLED} "
for arg in "${ARGS[@]}"; do
echo -n "[${arg}]"
done
else
# The Dockerfile must ensure that "go.real" is in the current $PATH
echoerr "invoking real go binary"
go.real "${ARGS[@]}"
fi
}

# Create an array of command line arguments.
ARGS=("$@")

GO_COMPLIANCE_INFO=${GO_COMPLIANCE_INFO:-"1"}
GO_COMPLIANCE_FOD_MODE_INCLUDE=${GO_COMPLIANCE_FOD_MODE_INCLUDE:-'.*'}
GO_COMPLIANCE_CGO_ENABLED_INCLUDE=${GO_COMPLIANCE_CGO_ENABLED_INCLUDE:-'.*'}
GO_COMPLIANCE_DYNAMIC_LINKING_INCLUDE=${GO_COMPLIANCE_DYNAMIC_LINKING_INCLUDE:-'.*'}
GO_COMPLIANCE_OPENSSL_ENABLED_INCLUDE=${GO_COMPLIANCE_OPENSSL_ENABLED_INCLUDE:-'.*'}

if [[ -n "${OPENSHIFT_CI}" || "${__doozer_group}" == "openshift-"* ]]; then
GO_COMPLIANCE_POLICY="${GO_COMPLIANCE_POLICY:-exempt_darwin,exempt_windows,exempt_cross_compile}"
export GOTOOLCHAIN="local"
echoerr "Forcing GOTOOLCHAIN=${GOTOOLCHAIN}"
else
GO_COMPLIANCE_POLICY="exempt_all"
fi

if [[ "${GO_COMPLIANCE_DEBUG}" == "1" ]]; then
echoerr "config GO_COMPLIANCE_POLICY=\"${GO_COMPLIANCE_POLICY}\" GO_COMPLIANCE_CGO_ENABLED_INCLUDE=\"${GO_COMPLIANCE_CGO_ENABLED_INCLUDE}\" GO_COMPLIANCE_CGO_ENABLED_EXCLUDE=\"${GO_COMPLIANCE_CGO_ENABLED_EXCLUDE}\" GO_COMPLIANCE_DYNAMIC_LINKING_INCLUDE=\"${GO_COMPLIANCE_DYNAMIC_LINKING_INCLUDE}\" GO_COMPLIANCE_DYNAMIC_LINKING_EXCLUDE=\"${GO_COMPLIANCE_DYNAMIC_LINKING_EXCLUDE}\" GO_COMPLIANCE_OPENSSL_ENABLED_INCLUDE=\"${GO_COMPLIANCE_OPENSSL_ENABLED_INCLUDE}\" GO_COMPLIANCE_OPENSSL_ENABLED_EXCLUDE=\"${GO_COMPLIANCE_OPENSSL_ENABLED_EXCLUDE}\" GO_COMPLIANCE_FOD_MODE_INCLUDE=\"${GO_COMPLIANCE_FOD_MODE_INCLUDE}\" GO_COMPLIANCE_FOD_MODE_EXCLUDE=\"${GO_COMPLIANCE_FOD_MODE_EXCLUDE}\""

echo 1>&2
echo 1>&2
echo -n "${LOG_PREFIX} incoming command line arguments: " 1>&2
for arg in "$@"; do
echo -n "\"${arg}\" " 1>&2
done
echo 1>&2
echo 1>&2

echoerr "incoming environment: "
echoerr "---------------------"
env 1>&2
echoerr "---------------------"
echo 1>&2
fi

echoerr "assessment: CGO_ENABLED=${CGO_ENABLED:-1}"
if cat <<< "$@" | grep "-extldflags.*-static" > /dev/null; then
echoerr "assessment: static linking"
else
echoerr "assessment: dynamic linking"
fi

# Basic strict mode requires incoming compiler
# invocation to be compliant EXCEPT for strictfipsmode.
STRICT_MODE_BASIC="0"
if [[ "${GO_COMPLIANCE_STRICT}" == "basic" ]]; then
echoerr "setting strict_basic mode for FIPS compliance"
STRICT_MODE_BASIC="1"
fi

# Full strict mode requires incoming compiler
# invocation to be compliant, including GOEXPERIMENT
# with strictfipsmode.
STRICT_MODE_FULL="0"
if [[ "${GO_COMPLIANCE_STRICT}" == "full" ]]; then
echoerr "setting strict_full mode for FIPS compliance"
STRICT_MODE_FULL="1"
STRICT_MODE_BASIC="1"
fi

EXEMPT="0"
if [[ "${GO_COMPLIANCE_POLICY}" == *"exempt_darwin"* ]]; then
if [[ "$GOOS" == "darwin" ]]; then
echoerr "skipping forced compliance due to GOOS=${GOOS}"
EXEMPT="1"
fi
fi

if [[ "${GO_COMPLIANCE_POLICY}" == *"exempt_windows"* ]]; then
if [[ "$GOOS" == "windows" ]]; then
echoerr "skipping forced compliance due to GOOS=${GOOS}"
EXEMPT="1"
fi
fi

if [[ "${SHIM_TEST}" == "1" ]]; then
FOUND_HOST_ARCH="amd64"
else
FOUND_HOST_ARCH="$(go.real env GOHOSTARCH)"
fi

if [[ "${GO_COMPLIANCE_POLICY}" == *"exempt_cross_compile"* ]]; then
if [[ -n "${GOARCH}" && "${FOUND_HOST_ARCH}" != *"${GOARCH}"* ]]; then
echoerr "skipping forced compliance due to cross-compile ${FOUND_HOST_ARCH} vs ${GOARCH}"
EXEMPT="1"
fi
fi

if [[ "${GO_COMPLIANCE_POLICY}" == *"exempt_arch_${FOUND_HOST_ARCH}"* ]]; then
echoerr "skipping forced compliance due to FOUND_HOST_ARCH=${FOUND_HOST_ARCH}"
EXEMPT="1"
fi

if [[ "${GO_COMPLIANCE_POLICY}" == *"exempt_all"* ]]; then
echoerr "skipping forced compliance due to broad exemption"
EXEMPT="1"
fi

FORCE_CGO_ENABLED=1
if [[ -n "${GO_COMPLIANCE_CGO_ENABLED_INCLUDE}" ]]; then
if cat <<< "$@" | grep -E "${GO_COMPLIANCE_CGO_ENABLED_INCLUDE}" > /dev/null; then
FORCE_CGO_ENABLED="1"
else
FORCE_CGO_ENABLED="0"
fi
fi

if [[ -n "${GO_COMPLIANCE_CGO_ENABLED_EXCLUDE}" ]]; then
if cat <<< "$@" | grep -E "${GO_COMPLIANCE_CGO_ENABLED_EXCLUDE}" > /dev/null; then
FORCE_CGO_ENABLED="0"
fi
fi

FORCE_DYNAMIC=1
if [[ -n "${GO_COMPLIANCE_DYNAMIC_LINKING_INCLUDE}" ]]; then
if cat <<< "$@" | grep -E "${GO_COMPLIANCE_DYNAMIC_LINKING_INCLUDE}" > /dev/null; then
FORCE_DYNAMIC="1"
else
FORCE_DYNAMIC="0"
fi
fi

if [[ -n "${GO_COMPLIANCE_DYNAMIC_LINKING_EXCLUDE}" ]]; then
if cat <<< "$@" | grep -E "${GO_COMPLIANCE_DYNAMIC_LINKING_EXCLUDE}" > /dev/null; then
FORCE_DYNAMIC="0"
fi
fi

FORCE_OPENSSL=1
if [[ -n "${GO_COMPLIANCE_OPENSSL_ENABLED_INCLUDE}" ]]; then
if cat <<< "$@" | grep -E "${GO_COMPLIANCE_OPENSSL_ENABLED_INCLUDE}" > /dev/null; then
FORCE_OPENSSL="1"
else
FORCE_OPENSSL="0"
fi
fi

if [[ -n "${GO_COMPLIANCE_OPENSSL_ENABLED_EXCLUDE}" ]]; then
if cat <<< "$@" | grep -E "${GO_COMPLIANCE_OPENSSL_ENABLED_EXCLUDE}" > /dev/null; then
FORCE_OPENSSL="0"
fi
fi

FORCE_FOD_MODE=1
if [[ -n "${GO_COMPLIANCE_FOD_MODE_INCLUDE}" ]]; then
if cat <<< "$@" | grep -E "${GO_COMPLIANCE_FOD_MODE_INCLUDE}" > /dev/null; then
FORCE_FOD_MODE="1"
else
FORCE_FOD_MODE="0"
fi
fi

if [[ -n "${GO_COMPLIANCE_FOD_MODE_EXCLUDE}" ]]; then
if cat <<< "$@" | grep -E "${GO_COMPLIANCE_FOD_MODE_EXCLUDE}" > /dev/null; then
FORCE_FOD_MODE="0"
fi
fi

if [[ -n "${GO_COMPLIANCE_EXCLUDE}" ]]; then
if cat <<< "$@" | grep -E "${GO_COMPLIANCE_EXCLUDE}" > /dev/null; then
echoerr "command matched GO_COMPLIANCE_EXCLUDE -- setting EXEMPT=\"1\""
export EXEMPT="1"
fi
fi

HAS_TAGS=0
if cat <<< "$@" | grep "\-tags" > /dev/null; then # Note that go permits -tags or --tags
HAS_TAGS="1"
fi

echoerr "EXEMPT: ${EXEMPT}"
if [[ "${EXEMPT}" != "1" ]]; then

echoerr "not exempt: FORCE_CGO_ENABLED=\"${FORCE_CGO_ENABLED}\" FORCE_DYNAMIC=\"${FORCE_DYNAMIC}\" FORCE_OPENSSL=\"${FORCE_OPENSSL}\" FORCE_FOD_MODE=\"${FORCE_FOD_MODE}\""

IN_BUILD=0
IN_RUN=0
IN_TAGS=0
ARGS=() # We need to rebuild the argument list.
for arg in "$@"; do

if [[ "${arg}" == "run" ]]; then
IN_RUN="1"
fi

# prior to detecting 'IN_RUN', grafana failed because it ran
# 'go run build.go build' which caused the script to exec 'go run build.go build -tags strictfipsruntime'
if [[ "${arg}" == "build" && "${IN_RUN}" == "0" ]]; then
# -tags apparently cannot come after a build path
# e.g. "build ./cmd/cluster-openshift-apiserver-operator -tags strictfipsruntime" is invalid.
# So, if we see "build" and no "-tags" ahead, then go ahead and force FOD tag.

IN_BUILD="1" # This is a go build invocation
if [[ "${STRICT_MODE_FULL}" == "1" && "${GOEXPERIMENT}" != *"strictfipsruntime"* ]]; then
stricterror
exit 1
fi

ARGS+=("${arg}") # Add "build"
if [[ "${FORCE_FOD_MODE}" == "1" && "${HAS_TAGS}" == "0" ]]; then
ARGS+=("-tags")
ARGS+=("strictfipsruntime")
fi
continue # We've already added 'build', so don't reach the bottom of the loop where it would be added again.
fi

if [[ ( "${arg}" == "-tags="* || "${arg}" == "--tags="* ) && "${FORCE_FOD_MODE}" == "1" ]]; then
echoerr "adding strictfipsruntime tag to \"${arg}\""
arg=$(echo "${arg}" | tr -d "'" | tr -d "\"") # Delete any quotes which get passed in literally. grafana managed this.
if [[ "${arg}" == *" "* ]]; then # If the tags parameter is space delimited
arg="${arg} strictfipsruntime"
else
# Assume comma delimited
arg="${arg},strictfipsruntime"
fi
fi

if [[ "${IN_TAGS}" == "1" ]]; then
if [[ "${FORCE_FOD_MODE}" == "1" ]]; then
echoerr "adding strictfipsruntime tag to ${arg} (IN_TAGS=${IN_TAGS})"
arg=$(echo "${arg}" | tr -d "'" | tr -d "\"") # Delete any quotes which get passed in literally. prom-label-proxy managed this.
if [[ "${arg}" == *" "* ]]; then # If the tags parameter is space delimited
arg="${arg} strictfipsruntime"
else
# Assume comma delimited
arg="${arg},strictfipsruntime"
fi
fi
if [[ "${FORCE_OPENSSL}" == "1" ]]; then
pre_arg="${arg}"
arg=$(echo "${arg}" | sed 's/no_openssl/shim_prevented_no_openssl/g')
if [[ "${pre_arg}" != "${arg}" ]]; then
echoerr "non-compliant: eliminated no_openssl"
if [[ "${STRICT_MODE_BASIC}" == "1" ]]; then
stricterror
exit 1
fi
fi
fi
IN_TAGS=0
fi

if [[ "${arg}" == "-tags" || "${arg}" == "--tags" ]]; then
IN_TAGS=1
fi

# Compilation with -extldflags "-static" is problematic with
# CGO_ENABLED=1 because compilation tries to link against
# static libraries which don't exist. Remove -static flag
# when detected. This is tricky because extldflags can be simple
# or something like -ldflags '-X $(REPO_PATH)/pkg/version.Raw=$(VERSION) -extldflags "-lm -lstdc++ -static"'
# Note that extldflags is a flag embedded within the value of the
# -ldflags argument. From our script's perspective, it will be part of a single
# argument, but this argument might look like '-X $(REPO_PATH)/pkg/version.Raw=$(VERSION) -extldflags "-lm -lstdc++ -static"'.
if [[ "${arg}" == *"-extldflags"* && "${FORCE_DYNAMIC}" == "1" ]]; then
# We replace -static with -lc because '-lc' implies to link against stdlib. This is a default
# and should therefore be benign for virtually any compilation (unless -nostdlib or -nodefaultlibs
# is specified -- and we don't account for this).
# Why replace instead of remove? Consider the complex possible scenarios:
# -ldflags '-extldflags "-static"' # Removing -extldflags would mean we also need to remove ldflags.
# -ldflags '-X $(REPO_PATH)/pkg/version.Raw=$(VERSION) -extldflags "-static"' # Would remove extldflags but keep ldflags
# -ldflags '-X $(REPO_PATH)/pkg/version.Raw=$(VERSION) -extldflags "-static -lm"' # Would need to remove -static but keep extldflags
# In any scenario, replacing "-static" with something benign should work without the need for complex logic.
pre_arg="${arg}"
arg=$(echo "${arg}" | sed "s/-static/-lc/g")
if [[ "${pre_arg}" != "${arg}" ]]; then
echoerr "non-compliant: eliminated static"
if [[ "${STRICT_MODE_BASIC}" == "1" ]]; then
stricterror
exit 1
fi
fi
fi
ARGS+=("${arg}")
done

if [[ "${FORCE_CGO_ENABLED}" == "1" && "${IN_BUILD}" == "1" ]]; then
if [[ "${CGO_ENABLED}" == "0" ]]; then
echoerr "non-compliant: had to turn on CGO_ENABLED"
if [[ "${STRICT_MODE_BASIC}" == "1" ]]; then
stricterror
exit 1
fi
fi
export CGO_ENABLED="1"
echoerr "setting CGO_ENABLED=${CGO_ENABLED}"
fi

if [[ "${FORCE_FOD_MODE}" == "1" && "${GOEXPERIMENT}" != *"strictfipsruntime"* ]]; then
if [[ -n "${GOEXPERIMENT}" ]]; then
export GOEXPERIMENT="strictfipsruntime,${GOEXPERIMENT}"
else
export GOEXPERIMENT="strictfipsruntime"
fi
echoerr "setting GOEXPERIMENT=${GOEXPERIMENT}"
fi

fi

if [[ "${GO_COMPLIANCE_INFO}" == "1" ]]; then
echo 1>&2
echo 1>&2
echo -n "${LOG_PREFIX} final command line arguments: " 1>&2
for arg in "${ARGS[@]}"; do
echo -n "\"${arg}\" " 1>&2
done
echo 1>&2
echo 1>&2
fi

run_go "${ARGS[@]}"

0 comments on commit 2963326

Please sign in to comment.