Make Go binary path check unconditional

This commit is contained in:
Michael B. Gale 2023-10-13 10:25:54 +01:00
parent 632d58cb60
commit 325a0b06e9
No known key found for this signature in database
GPG key ID: FF5E2765BD00628F
6 changed files with 78 additions and 58 deletions

5
lib/environment.js generated
View file

@ -52,9 +52,8 @@ var EnvVar;
*/ */
EnvVar["WORKFLOW_STARTED_AT"] = "CODEQL_WORKFLOW_STARTED_AT"; EnvVar["WORKFLOW_STARTED_AT"] = "CODEQL_WORKFLOW_STARTED_AT";
/** /**
* The path where we initially discovered the Go binary in the system path * 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 * We check this later to ensure that it hasn't been tampered with by a late e.g. `setup-go` step.
* that it hasn't been tampered with by a late e.g. `setup-go` step.
*/ */
EnvVar["GO_BINARY_LOCATION"] = "CODEQL_ACTION_GO_BINARY"; EnvVar["GO_BINARY_LOCATION"] = "CODEQL_ACTION_GO_BINARY";
})(EnvVar || (exports.EnvVar = EnvVar = {})); })(EnvVar || (exports.EnvVar = EnvVar = {}));

View file

@ -1 +1 @@
{"version":3,"file":"environment.js","sourceRoot":"","sources":["../src/environment.ts"],"names":[],"mappings":";;;AAAA,IAAY,MAuEX;AAvED,WAAY,MAAM;IAChB,2DAA2D;IAC3D,+FAAqF,CAAA;IAErF,gEAAgE;IAChE,qEAA2D,CAAA;IAE3D;;;OAGG;IACH,yFAA+E,CAAA;IAE/E;;;OAGG;IACH,yEAA+D,CAAA;IAE/D,gFAAgF;IAChF,6DAAmD,CAAA;IAEnD;;;OAGG;IACH,uEAA6D,CAAA;IAE7D,gEAAgE;IAChE,mEAAyD,CAAA;IAEzD,kFAAkF;IAClF,mFAAyE,CAAA;IAEzE,6CAA6C;IAC7C,uCAA6B,CAAA;IAE7B,mEAAyD,CAAA;IAEzD;;;OAGG;IACH,2FAAiF,CAAA;IAEjF,mFAAmF;IACnF,6FAAmF,CAAA;IAEnF,qFAAqF;IACrF,+CAAqC,CAAA;IAErC,mEAAyD,CAAA;IAEzD,kEAAkE;IAClE,2CAAiC,CAAA;IAEjC;;;;;;OAMG;IACH,4DAAkD,CAAA;IAElD;;;;OAIG;IACH,wDAA8C,CAAA;AAChD,CAAC,EAvEW,MAAM,sBAAN,MAAM,QAuEjB"} {"version":3,"file":"environment.js","sourceRoot":"","sources":["../src/environment.ts"],"names":[],"mappings":";;;AAAA,IAAY,MAsEX;AAtED,WAAY,MAAM;IAChB,2DAA2D;IAC3D,+FAAqF,CAAA;IAErF,gEAAgE;IAChE,qEAA2D,CAAA;IAE3D;;;OAGG;IACH,yFAA+E,CAAA;IAE/E;;;OAGG;IACH,yEAA+D,CAAA;IAE/D,gFAAgF;IAChF,6DAAmD,CAAA;IAEnD;;;OAGG;IACH,uEAA6D,CAAA;IAE7D,gEAAgE;IAChE,mEAAyD,CAAA;IAEzD,kFAAkF;IAClF,mFAAyE,CAAA;IAEzE,6CAA6C;IAC7C,uCAA6B,CAAA;IAE7B,mEAAyD,CAAA;IAEzD;;;OAGG;IACH,2FAAiF,CAAA;IAEjF,mFAAmF;IACnF,6FAAmF,CAAA;IAEnF,qFAAqF;IACrF,+CAAqC,CAAA;IAErC,mEAAyD,CAAA;IAEzD,kEAAkE;IAClE,2CAAiC,CAAA;IAEjC;;;;;;OAMG;IACH,4DAAkD,CAAA;IAElD;;;OAGG;IACH,wDAA8C,CAAA;AAChD,CAAC,EAtEW,MAAM,sBAAN,MAAM,QAsEjB"}

50
lib/init-action.js generated
View file

@ -171,33 +171,43 @@ async function run() {
core.exportVariable("GOFLAGS", goFlags); core.exportVariable("GOFLAGS", goFlags);
core.warning("Passing the GOFLAGS env parameter to the init action is deprecated. Please move this to the analyze action."); core.warning("Passing the GOFLAGS env parameter to the init action is deprecated. Please move this to the analyze action.");
} }
// 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(languages_1.Language.go) && if (config.languages.includes(languages_1.Language.go) &&
process.platform === "linux" && process.platform === "linux") {
!(0, tools_features_1.isSupportedToolsFeature)(versionInfo, tools_features_1.ToolsFeature.IndirectTracingSupportsStaticBinaries)) {
try { try {
const goBinaryPath = await (0, safe_which_1.safeWhich)("go"); const goBinaryPath = await (0, safe_which_1.safeWhich)("go");
const fileOutput = await (0, actions_util_1.getFileType)(goBinaryPath); const fileOutput = await (0, actions_util_1.getFileType)(goBinaryPath);
if (fileOutput.includes("statically linked")) { // Go 1.21 and above ships with statically linked binaries on Linux. CodeQL cannot currently trace custom builds
logger.debug(`Applying static binary workaround for Go`); // where the entry point is a statically linked binary. Until that is fixed, we work around the problem by
// Create a directory that we can add to the system PATH. // replacing the `go` binary with a shell script that invokes the actual `go` binary. Since the shell is
const tempBinPath = path.resolve((0, actions_util_1.getTemporaryDirectory)(), "codeql-action-go-tracing", "bin"); // typically dynamically linked, this provides a suitable entry point for the CodeQL tracer.
fs.mkdirSync(tempBinPath, { recursive: true }); if (fileOutput.includes("statically linked") &&
core.addPath(tempBinPath); !(0, tools_features_1.isSupportedToolsFeature)(versionInfo, tools_features_1.ToolsFeature.IndirectTracingSupportsStaticBinaries)) {
// Write the wrapper script to the directory we just added to the PATH. try {
const goWrapperPath = path.resolve(tempBinPath, "go"); logger.debug(`Applying static binary workaround for Go`);
fs.writeFileSync(goWrapperPath, `#!/bin/bash\n\nexec ${goBinaryPath} "$@"`); // Create a directory that we can add to the system PATH.
fs.chmodSync(goWrapperPath, "755"); const tempBinPath = path.resolve((0, actions_util_1.getTemporaryDirectory)(), "codeql-action-go-tracing", "bin");
// Store the original location of our wrapper script somewhere where we can fs.mkdirSync(tempBinPath, { recursive: true });
// later retrieve it from and cross-check that it hasn't been changed. core.addPath(tempBinPath);
core.exportVariable(environment_1.EnvVar.GO_BINARY_LOCATION, goWrapperPath); // 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(environment_1.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(environment_1.EnvVar.GO_BINARY_LOCATION, goBinaryPath);
} }
} }
catch (e) { catch (e) {
logger.warning(`Analyzing Go on Linux, but failed to install wrapper script. Tracing custom builds may fail: ${e}`); logger.warning(`Failed to determine the location of the Go binary: ${e}`);
} }
} }
// Limit RAM and threads for extractors. When running extractors, the CodeQL CLI obeys the // Limit RAM and threads for extractors. When running extractors, the CodeQL CLI obeys the

File diff suppressed because one or more lines are too long

View file

@ -64,9 +64,8 @@ export enum EnvVar {
WORKFLOW_STARTED_AT = "CODEQL_WORKFLOW_STARTED_AT", WORKFLOW_STARTED_AT = "CODEQL_WORKFLOW_STARTED_AT",
/** /**
* The path where we initially discovered the Go binary in the system path * 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 * We check this later to ensure that it hasn't been tampered with by a late e.g. `setup-go` step.
* that it hasn't been tampered with by a late e.g. `setup-go` step.
*/ */
GO_BINARY_LOCATION = "CODEQL_ACTION_GO_BINARY", GO_BINARY_LOCATION = "CODEQL_ACTION_GO_BINARY",
} }

View file

@ -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 ( if (
config.languages.includes(Language.go) && config.languages.includes(Language.go) &&
process.platform === "linux" && process.platform === "linux"
!isSupportedToolsFeature(
versionInfo,
ToolsFeature.IndirectTracingSupportsStaticBinaries,
)
) { ) {
try { try {
const goBinaryPath = await safeWhich("go"); const goBinaryPath = await safeWhich("go");
const fileOutput = await getFileType(goBinaryPath); const fileOutput = await getFileType(goBinaryPath);
if (fileOutput.includes("statically linked")) { // Go 1.21 and above ships with statically linked binaries on Linux. CodeQL cannot currently trace custom builds
logger.debug(`Applying static binary workaround for Go`); // 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. // Create a directory that we can add to the system PATH.
const tempBinPath = path.resolve( const tempBinPath = path.resolve(
getTemporaryDirectory(), getTemporaryDirectory(),
"codeql-action-go-tracing", "codeql-action-go-tracing",
"bin", "bin",
); );
fs.mkdirSync(tempBinPath, { recursive: true }); fs.mkdirSync(tempBinPath, { recursive: true });
core.addPath(tempBinPath); core.addPath(tempBinPath);
// Write the wrapper script to the directory we just added to the PATH. // Write the wrapper script to the directory we just added to the PATH.
const goWrapperPath = path.resolve(tempBinPath, "go"); const goWrapperPath = path.resolve(tempBinPath, "go");
fs.writeFileSync( fs.writeFileSync(
goWrapperPath, goWrapperPath,
`#!/bin/bash\n\nexec ${goBinaryPath} "$@"`, `#!/bin/bash\n\nexec ${goBinaryPath} "$@"`,
); );
fs.chmodSync(goWrapperPath, "755"); fs.chmodSync(goWrapperPath, "755");
// Store the original location of our wrapper script somewhere where we can // 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. // later retrieve it from and cross-check that it hasn't been changed.
core.exportVariable(EnvVar.GO_BINARY_LOCATION, goWrapperPath); 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) { } catch (e) {
logger.warning( 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}`,
); );
} }
} }