mirror of
https://github.com/actions/setup-java.git
synced 2026-09-10 04:34:21 +02:00
Avoid macOS GPG socket overflow on long runner paths (#1266)
* Initial plan * Fix signature verification GPG homes on long runner paths * Keep macOS GPG verification homes within socket limits Use /tmp for signature verification on macOS while preserving runner temp behavior elsewhere. Cover long and canonical OS temp paths and regenerate action bundles. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 32d31c8d-ddbc-4e57-a5c3-f70588fef3f3 --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: Bruno Borges <brborges@microsoft.com> Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 32d31c8d-ddbc-4e57-a5c3-f70588fef3f3
This commit is contained in:
co-authored by
Copilot App
copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Bruno Borges
parent
134912a529
commit
de7274f081
@@ -9,10 +9,18 @@ import {
|
|||||||
} from '@jest/globals';
|
} from '@jest/globals';
|
||||||
import {fileURLToPath} from 'url';
|
import {fileURLToPath} from 'url';
|
||||||
import * as fs from 'fs';
|
import * as fs from 'fs';
|
||||||
|
import * as os from 'os';
|
||||||
import * as path from 'path';
|
import * as path from 'path';
|
||||||
import * as io from '@actions/io';
|
import * as io from '@actions/io';
|
||||||
|
|
||||||
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
||||||
|
const mockTmpDir = jest.fn(os.tmpdir);
|
||||||
|
|
||||||
|
jest.unstable_mockModule('os', () => ({
|
||||||
|
...os,
|
||||||
|
default: {...os, tmpdir: mockTmpDir},
|
||||||
|
tmpdir: mockTmpDir
|
||||||
|
}));
|
||||||
|
|
||||||
jest.unstable_mockModule('@actions/exec', () => ({
|
jest.unstable_mockModule('@actions/exec', () => ({
|
||||||
exec: jest.fn()
|
exec: jest.fn()
|
||||||
@@ -34,6 +42,7 @@ describe('gpg tests', () => {
|
|||||||
await io.rmRF(tempDir);
|
await io.rmRF(tempDir);
|
||||||
await io.mkdirP(tempDir);
|
await io.mkdirP(tempDir);
|
||||||
jest.clearAllMocks();
|
jest.clearAllMocks();
|
||||||
|
mockTmpDir.mockImplementation(os.tmpdir);
|
||||||
(exec.exec as jest.Mock<any>).mockResolvedValue(0);
|
(exec.exec as jest.Mock<any>).mockResolvedValue(0);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -222,6 +231,77 @@ describe('gpg tests', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe('verifyPackageSignature', () => {
|
describe('verifyPackageSignature', () => {
|
||||||
|
describe.each(['long', 'canonical macOS'])('%s TMPDIR', tempDirKind => {
|
||||||
|
afterEach(() => {
|
||||||
|
process.env['RUNNER_TEMP'] = tempDir;
|
||||||
|
});
|
||||||
|
|
||||||
|
it.each(['success', 'import failure', 'verification failure'])(
|
||||||
|
'uses a short macOS home or RUNNER_TEMP elsewhere and cleans up after %s',
|
||||||
|
async outcome => {
|
||||||
|
const longRunnerTemp = path.join(
|
||||||
|
tempDir,
|
||||||
|
'long-runner-path-'.repeat(8)
|
||||||
|
);
|
||||||
|
const signaturePath = path.join(tempDir, 'jdk.tar.gz.sig');
|
||||||
|
const expectedParent =
|
||||||
|
process.platform === 'darwin' ? '/tmp' : longRunnerTemp;
|
||||||
|
let gpgHome = '';
|
||||||
|
process.env['RUNNER_TEMP'] = longRunnerTemp;
|
||||||
|
mockTmpDir.mockReturnValue(
|
||||||
|
tempDirKind === 'long'
|
||||||
|
? longRunnerTemp
|
||||||
|
: `/private/var/folders/ab/${'c'.repeat(31)}/T`
|
||||||
|
);
|
||||||
|
fs.mkdirSync(longRunnerTemp, {recursive: true});
|
||||||
|
fs.writeFileSync(signaturePath, 'signature');
|
||||||
|
(tc.downloadTool as jest.Mock<any>).mockResolvedValue(signaturePath);
|
||||||
|
(exec.exec as jest.Mock<any>).mockImplementation(
|
||||||
|
async (_command: string, args: string[]) => {
|
||||||
|
gpgHome = path.join(expectedParent, path.posix.basename(args[1]));
|
||||||
|
expect(args[1]).toBe(gpg.toGpgPath(gpgHome));
|
||||||
|
if (process.platform === 'darwin') {
|
||||||
|
expect(
|
||||||
|
Buffer.byteLength(path.join(gpgHome, 'S.gpg-agent.browser'))
|
||||||
|
).toBeLessThan(104);
|
||||||
|
}
|
||||||
|
expect(
|
||||||
|
fs.readFileSync(path.join(gpgHome, 'public-key-0.asc'), 'utf8')
|
||||||
|
).toBe('public key');
|
||||||
|
if (process.platform !== 'win32') {
|
||||||
|
expect(fs.statSync(gpgHome).mode & 0o777).toBe(0o700);
|
||||||
|
}
|
||||||
|
if (
|
||||||
|
(outcome === 'import failure' && args.includes('--import')) ||
|
||||||
|
(outcome === 'verification failure' &&
|
||||||
|
args.includes('--verify'))
|
||||||
|
) {
|
||||||
|
throw new Error(outcome);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
const verification = gpg.verifyPackageSignature(
|
||||||
|
path.join(tempDir, 'jdk.tar.gz'),
|
||||||
|
'https://example.com/jdk.tar.gz.sig',
|
||||||
|
'public key'
|
||||||
|
);
|
||||||
|
if (outcome === 'success') {
|
||||||
|
await verification;
|
||||||
|
} else {
|
||||||
|
await expect(verification).rejects.toThrow(outcome);
|
||||||
|
}
|
||||||
|
expect(exec.exec).toHaveBeenCalledTimes(
|
||||||
|
outcome === 'import failure' ? 1 : 2
|
||||||
|
);
|
||||||
|
expect(fs.existsSync(gpgHome)).toBe(false);
|
||||||
|
expect(fs.existsSync(signaturePath)).toBe(false);
|
||||||
|
expect(fs.readdirSync(longRunnerTemp)).toEqual([]);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
it('imports bundled key and verifies package', async () => {
|
it('imports bundled key and verifies package', async () => {
|
||||||
const publicKeyContent =
|
const publicKeyContent =
|
||||||
'-----BEGIN PGP PUBLIC KEY BLOCK-----\ntest\n-----END PGP PUBLIC KEY BLOCK-----';
|
'-----BEGIN PGP PUBLIC KEY BLOCK-----\ntest\n-----END PGP PUBLIC KEY BLOCK-----';
|
||||||
|
|||||||
Vendored
+5
-3
@@ -35784,8 +35784,8 @@ function toGpgPath(p) {
|
|||||||
.replace(/\\/g, '/')
|
.replace(/\\/g, '/')
|
||||||
.replace(/^([A-Za-z]):\//, (_, drive) => `/${drive.toLowerCase()}/`);
|
.replace(/^([A-Za-z]):\//, (_, drive) => `/${drive.toLowerCase()}/`);
|
||||||
}
|
}
|
||||||
function createGpgHome(prefix) {
|
function createGpgHome(prefix, tempDir = util.getTempDir()) {
|
||||||
const gpgHome = fs.mkdtempSync(path.join(util.getTempDir(), prefix));
|
const gpgHome = fs.mkdtempSync(path.join(tempDir, prefix));
|
||||||
if (process.platform !== 'win32') {
|
if (process.platform !== 'win32') {
|
||||||
fs.chmodSync(gpgHome, 0o700);
|
fs.chmodSync(gpgHome, 0o700);
|
||||||
}
|
}
|
||||||
@@ -35844,7 +35844,9 @@ async function verifyPackageSignature(archivePath, signatureUrl, publicKeyConten
|
|||||||
const signaturePath = await tc.downloadTool(signatureUrl);
|
const signaturePath = await tc.downloadTool(signatureUrl);
|
||||||
let gpgHome;
|
let gpgHome;
|
||||||
try {
|
try {
|
||||||
gpgHome = createGpgHome(VERIFY_GPG_HOME_PREFIX);
|
// Both RUNNER_TEMP and TMPDIR can exceed macOS's 104-byte agent socket limit.
|
||||||
|
const tempDir = process.platform === 'darwin' ? '/tmp' : util.getTempDir();
|
||||||
|
gpgHome = createGpgHome(VERIFY_GPG_HOME_PREFIX, tempDir);
|
||||||
}
|
}
|
||||||
catch (error) {
|
catch (error) {
|
||||||
try {
|
try {
|
||||||
|
|||||||
Vendored
+5
-3
@@ -215,8 +215,8 @@ function toGpgPath(p) {
|
|||||||
.replace(/\\/g, '/')
|
.replace(/\\/g, '/')
|
||||||
.replace(/^([A-Za-z]):\//, (_, drive) => `/${drive.toLowerCase()}/`);
|
.replace(/^([A-Za-z]):\//, (_, drive) => `/${drive.toLowerCase()}/`);
|
||||||
}
|
}
|
||||||
function createGpgHome(prefix) {
|
function createGpgHome(prefix, tempDir = _util_js__WEBPACK_IMPORTED_MODULE_6__/* .getTempDir */ .G4()) {
|
||||||
const gpgHome = fs__WEBPACK_IMPORTED_MODULE_0__.mkdtempSync(path__WEBPACK_IMPORTED_MODULE_1__.join(_util_js__WEBPACK_IMPORTED_MODULE_6__/* .getTempDir */ .G4(), prefix));
|
const gpgHome = fs__WEBPACK_IMPORTED_MODULE_0__.mkdtempSync(path__WEBPACK_IMPORTED_MODULE_1__.join(tempDir, prefix));
|
||||||
if (process.platform !== 'win32') {
|
if (process.platform !== 'win32') {
|
||||||
fs__WEBPACK_IMPORTED_MODULE_0__.chmodSync(gpgHome, 0o700);
|
fs__WEBPACK_IMPORTED_MODULE_0__.chmodSync(gpgHome, 0o700);
|
||||||
}
|
}
|
||||||
@@ -275,7 +275,9 @@ async function verifyPackageSignature(archivePath, signatureUrl, publicKeyConten
|
|||||||
const signaturePath = await _actions_tool_cache__WEBPACK_IMPORTED_MODULE_5__/* .downloadTool */ .bq(signatureUrl);
|
const signaturePath = await _actions_tool_cache__WEBPACK_IMPORTED_MODULE_5__/* .downloadTool */ .bq(signatureUrl);
|
||||||
let gpgHome;
|
let gpgHome;
|
||||||
try {
|
try {
|
||||||
gpgHome = createGpgHome(VERIFY_GPG_HOME_PREFIX);
|
// Both RUNNER_TEMP and TMPDIR can exceed macOS's 104-byte agent socket limit.
|
||||||
|
const tempDir = process.platform === 'darwin' ? '/tmp' : _util_js__WEBPACK_IMPORTED_MODULE_6__/* .getTempDir */ .G4();
|
||||||
|
gpgHome = createGpgHome(VERIFY_GPG_HOME_PREFIX, tempDir);
|
||||||
}
|
}
|
||||||
catch (error) {
|
catch (error) {
|
||||||
try {
|
try {
|
||||||
|
|||||||
Vendored
+5
-3
@@ -327,8 +327,8 @@ function toGpgPath(p) {
|
|||||||
.replace(/\\/g, '/')
|
.replace(/\\/g, '/')
|
||||||
.replace(/^([A-Za-z]):\//, (_, drive) => `/${drive.toLowerCase()}/`);
|
.replace(/^([A-Za-z]):\//, (_, drive) => `/${drive.toLowerCase()}/`);
|
||||||
}
|
}
|
||||||
function createGpgHome(prefix) {
|
function createGpgHome(prefix, tempDir = _util_js__WEBPACK_IMPORTED_MODULE_6__/* .getTempDir */ .G4()) {
|
||||||
const gpgHome = fs__WEBPACK_IMPORTED_MODULE_0__.mkdtempSync(path__WEBPACK_IMPORTED_MODULE_1__.join(_util_js__WEBPACK_IMPORTED_MODULE_6__/* .getTempDir */ .G4(), prefix));
|
const gpgHome = fs__WEBPACK_IMPORTED_MODULE_0__.mkdtempSync(path__WEBPACK_IMPORTED_MODULE_1__.join(tempDir, prefix));
|
||||||
if (process.platform !== 'win32') {
|
if (process.platform !== 'win32') {
|
||||||
fs__WEBPACK_IMPORTED_MODULE_0__.chmodSync(gpgHome, 0o700);
|
fs__WEBPACK_IMPORTED_MODULE_0__.chmodSync(gpgHome, 0o700);
|
||||||
}
|
}
|
||||||
@@ -387,7 +387,9 @@ async function verifyPackageSignature(archivePath, signatureUrl, publicKeyConten
|
|||||||
const signaturePath = await _actions_tool_cache__WEBPACK_IMPORTED_MODULE_5__/* .downloadTool */ .bq(signatureUrl);
|
const signaturePath = await _actions_tool_cache__WEBPACK_IMPORTED_MODULE_5__/* .downloadTool */ .bq(signatureUrl);
|
||||||
let gpgHome;
|
let gpgHome;
|
||||||
try {
|
try {
|
||||||
gpgHome = createGpgHome(VERIFY_GPG_HOME_PREFIX);
|
// Both RUNNER_TEMP and TMPDIR can exceed macOS's 104-byte agent socket limit.
|
||||||
|
const tempDir = process.platform === 'darwin' ? '/tmp' : _util_js__WEBPACK_IMPORTED_MODULE_6__/* .getTempDir */ .G4();
|
||||||
|
gpgHome = createGpgHome(VERIFY_GPG_HOME_PREFIX, tempDir);
|
||||||
}
|
}
|
||||||
catch (error) {
|
catch (error) {
|
||||||
try {
|
try {
|
||||||
|
|||||||
Vendored
+5
-3
@@ -302,8 +302,8 @@ function toGpgPath(p) {
|
|||||||
.replace(/\\/g, '/')
|
.replace(/\\/g, '/')
|
||||||
.replace(/^([A-Za-z]):\//, (_, drive) => `/${drive.toLowerCase()}/`);
|
.replace(/^([A-Za-z]):\//, (_, drive) => `/${drive.toLowerCase()}/`);
|
||||||
}
|
}
|
||||||
function createGpgHome(prefix) {
|
function createGpgHome(prefix, tempDir = _util_js__WEBPACK_IMPORTED_MODULE_6__/* .getTempDir */ .G4()) {
|
||||||
const gpgHome = fs__WEBPACK_IMPORTED_MODULE_0__.mkdtempSync(path__WEBPACK_IMPORTED_MODULE_1__.join(_util_js__WEBPACK_IMPORTED_MODULE_6__/* .getTempDir */ .G4(), prefix));
|
const gpgHome = fs__WEBPACK_IMPORTED_MODULE_0__.mkdtempSync(path__WEBPACK_IMPORTED_MODULE_1__.join(tempDir, prefix));
|
||||||
if (process.platform !== 'win32') {
|
if (process.platform !== 'win32') {
|
||||||
fs__WEBPACK_IMPORTED_MODULE_0__.chmodSync(gpgHome, 0o700);
|
fs__WEBPACK_IMPORTED_MODULE_0__.chmodSync(gpgHome, 0o700);
|
||||||
}
|
}
|
||||||
@@ -362,7 +362,9 @@ async function verifyPackageSignature(archivePath, signatureUrl, publicKeyConten
|
|||||||
const signaturePath = await _actions_tool_cache__WEBPACK_IMPORTED_MODULE_5__/* .downloadTool */ .bq(signatureUrl);
|
const signaturePath = await _actions_tool_cache__WEBPACK_IMPORTED_MODULE_5__/* .downloadTool */ .bq(signatureUrl);
|
||||||
let gpgHome;
|
let gpgHome;
|
||||||
try {
|
try {
|
||||||
gpgHome = createGpgHome(VERIFY_GPG_HOME_PREFIX);
|
// Both RUNNER_TEMP and TMPDIR can exceed macOS's 104-byte agent socket limit.
|
||||||
|
const tempDir = process.platform === 'darwin' ? '/tmp' : _util_js__WEBPACK_IMPORTED_MODULE_6__/* .getTempDir */ .G4();
|
||||||
|
gpgHome = createGpgHome(VERIFY_GPG_HOME_PREFIX, tempDir);
|
||||||
}
|
}
|
||||||
catch (error) {
|
catch (error) {
|
||||||
try {
|
try {
|
||||||
|
|||||||
+8
-3
@@ -26,8 +26,11 @@ export function toGpgPath(p: string): string {
|
|||||||
.replace(/^([A-Za-z]):\//, (_, drive) => `/${drive.toLowerCase()}/`);
|
.replace(/^([A-Za-z]):\//, (_, drive) => `/${drive.toLowerCase()}/`);
|
||||||
}
|
}
|
||||||
|
|
||||||
function createGpgHome(prefix: string): string {
|
function createGpgHome(
|
||||||
const gpgHome = fs.mkdtempSync(path.join(util.getTempDir(), prefix));
|
prefix: string,
|
||||||
|
tempDir: string = util.getTempDir()
|
||||||
|
): string {
|
||||||
|
const gpgHome = fs.mkdtempSync(path.join(tempDir, prefix));
|
||||||
if (process.platform !== 'win32') {
|
if (process.platform !== 'win32') {
|
||||||
fs.chmodSync(gpgHome, 0o700);
|
fs.chmodSync(gpgHome, 0o700);
|
||||||
}
|
}
|
||||||
@@ -107,7 +110,9 @@ export async function verifyPackageSignature(
|
|||||||
const signaturePath = await tc.downloadTool(signatureUrl);
|
const signaturePath = await tc.downloadTool(signatureUrl);
|
||||||
let gpgHome: string;
|
let gpgHome: string;
|
||||||
try {
|
try {
|
||||||
gpgHome = createGpgHome(VERIFY_GPG_HOME_PREFIX);
|
// Both RUNNER_TEMP and TMPDIR can exceed macOS's 104-byte agent socket limit.
|
||||||
|
const tempDir = process.platform === 'darwin' ? '/tmp' : util.getTempDir();
|
||||||
|
gpgHome = createGpgHome(VERIFY_GPG_HOME_PREFIX, tempDir);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
try {
|
try {
|
||||||
await io.rmRF(signaturePath);
|
await io.rmRF(signaturePath);
|
||||||
|
|||||||
Reference in New Issue
Block a user