Skip to content

Commit

Permalink
Merge pull request #1946 from github/mbg/unconditioal-go-warning
Browse files Browse the repository at this point in the history
Make Go path warning unconditional
  • Loading branch information
mbg authored Oct 13, 2023
2 parents 7e7f0cc + 325a0b0 commit d859d17
Show file tree
Hide file tree
Showing 9 changed files with 102 additions and 78 deletions.
18 changes: 10 additions & 8 deletions lib/analyze-action.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion lib/analyze-action.js.map

Large diffs are not rendered by default.

5 changes: 2 additions & 3 deletions lib/environment.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion lib/environment.js.map

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

50 changes: 30 additions & 20 deletions lib/init-action.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion lib/init-action.js.map

Large diffs are not rendered by default.

18 changes: 10 additions & 8 deletions src/analyze-action.ts
Original file line number Diff line number Diff line change
Expand Up @@ -233,21 +233,23 @@ async function run() {
logger,
);

// Check that `which go` still points at the wrapper script we installed in the `init` Action,
// if the corresponding environment variable is set. This is to ensure that there isn't a step
// in the workflow after the `init` step which installs a different version of Go and takes
// precedence in the PATH, thus potentially circumventing our workaround that allows tracing to work.
const goWrapperPath = process.env[EnvVar.GO_BINARY_LOCATION];
// Check that `which go` still points at the same path it did when the `init` Action ran to ensure that no steps
// in-between performed any setup. We encourage users to perform all setup tasks before initializing CodeQL so that
// the setup tasks do not interfere with our analysis.
// Furthermore, if we installed a wrapper script in the `init` Action, we need to ensure that there isn't a step
// in the workflow after the `init` step which installs a different version of Go and takes precedence in the PATH,
// thus potentially circumventing our workaround that allows tracing to work.
const goInitPath = process.env[EnvVar.GO_BINARY_LOCATION];

if (
process.env[EnvVar.DID_AUTOBUILD_GOLANG] !== "true" &&
goWrapperPath !== undefined
goInitPath !== undefined
) {
const goBinaryPath = await safeWhich("go");

if (goWrapperPath !== goBinaryPath) {
if (goInitPath !== goBinaryPath) {
core.warning(
`Expected \`which go\` to return ${goWrapperPath}, but got ${goBinaryPath}: please ensure that the correct version of Go is installed before the \`codeql-action/init\` Action is used.`,
`Expected \`which go\` to return ${goInitPath}, but got ${goBinaryPath}: please ensure that the correct version of Go is installed before the \`codeql-action/init\` Action is used.`,
);

addDiagnostic(
Expand Down
5 changes: 2 additions & 3 deletions src/environment.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,9 +64,8 @@ export enum EnvVar {
WORKFLOW_STARTED_AT = "CODEQL_WORKFLOW_STARTED_AT",

/**
* The path where we initially discovered the Go binary in the system path
* before replacing it with a wrapper script. We check this later to ensure
* that it hasn't been tampered with by a late e.g. `setup-go` step.
* The path where we initially discovered the Go binary in the system path.
* We check this later to ensure that it hasn't been tampered with by a late e.g. `setup-go` step.
*/
GO_BINARY_LOCATION = "CODEQL_ACTION_GO_BINARY",
}
78 changes: 45 additions & 33 deletions src/init-action.ts
Original file line number Diff line number Diff line change
Expand Up @@ -336,49 +336,61 @@ async function run() {
);
}

// Go 1.21 and above ships with statically linked binaries on Linux. CodeQL cannot currently trace custom builds
// where the entry point is a statically linked binary. Until that is fixed, we work around the problem by
// replacing the `go` binary with a shell script that invokes the actual `go` binary. Since the shell is typically
// dynamically linked, this provides a suitable entry point for the CodeQL tracer.
if (
config.languages.includes(Language.go) &&
process.platform === "linux" &&
!isSupportedToolsFeature(
versionInfo,
ToolsFeature.IndirectTracingSupportsStaticBinaries,
)
process.platform === "linux"
) {
try {
const goBinaryPath = await safeWhich("go");
const fileOutput = await getFileType(goBinaryPath);

if (fileOutput.includes("statically linked")) {
logger.debug(`Applying static binary workaround for Go`);

// Create a directory that we can add to the system PATH.
const tempBinPath = path.resolve(
getTemporaryDirectory(),
"codeql-action-go-tracing",
"bin",
);
fs.mkdirSync(tempBinPath, { recursive: true });
core.addPath(tempBinPath);

// Write the wrapper script to the directory we just added to the PATH.
const goWrapperPath = path.resolve(tempBinPath, "go");
fs.writeFileSync(
goWrapperPath,
`#!/bin/bash\n\nexec ${goBinaryPath} "$@"`,
);
fs.chmodSync(goWrapperPath, "755");

// Store the original location of our wrapper script somewhere where we can
// later retrieve it from and cross-check that it hasn't been changed.
core.exportVariable(EnvVar.GO_BINARY_LOCATION, goWrapperPath);
// Go 1.21 and above ships with statically linked binaries on Linux. CodeQL cannot currently trace custom builds
// where the entry point is a statically linked binary. Until that is fixed, we work around the problem by
// replacing the `go` binary with a shell script that invokes the actual `go` binary. Since the shell is
// typically dynamically linked, this provides a suitable entry point for the CodeQL tracer.
if (
fileOutput.includes("statically linked") &&
!isSupportedToolsFeature(
versionInfo,
ToolsFeature.IndirectTracingSupportsStaticBinaries,
)
) {
try {
logger.debug(`Applying static binary workaround for Go`);

// Create a directory that we can add to the system PATH.
const tempBinPath = path.resolve(
getTemporaryDirectory(),
"codeql-action-go-tracing",
"bin",
);
fs.mkdirSync(tempBinPath, { recursive: true });
core.addPath(tempBinPath);

// Write the wrapper script to the directory we just added to the PATH.
const goWrapperPath = path.resolve(tempBinPath, "go");
fs.writeFileSync(
goWrapperPath,
`#!/bin/bash\n\nexec ${goBinaryPath} "$@"`,
);
fs.chmodSync(goWrapperPath, "755");

// Store the original location of our wrapper script somewhere where we can
// later retrieve it from and cross-check that it hasn't been changed.
core.exportVariable(EnvVar.GO_BINARY_LOCATION, goWrapperPath);
} catch (e) {
logger.warning(
`Analyzing Go on Linux, but failed to install wrapper script. Tracing custom builds may fail: ${e}`,
);
}
} else {
// Store the location of the original Go binary, so we can check that no setup tasks were performed after the
// `init` Action ran.
core.exportVariable(EnvVar.GO_BINARY_LOCATION, goBinaryPath);
}
} catch (e) {
logger.warning(
`Analyzing Go on Linux, but failed to install wrapper script. Tracing custom builds may fail: ${e}`,
`Failed to determine the location of the Go binary: ${e}`,
);
}
}
Expand Down

0 comments on commit d859d17

Please sign in to comment.