From d40b41f5197894373b9e76a3241aa7722aeca117 Mon Sep 17 00:00:00 2001 From: Jesse Schwartzentruber Date: Wed, 11 Dec 2019 13:50:24 +0100 Subject: [PATCH 1/4] Add a feature disableSeccomp to disable the seccomp system call filter. This is required to run `rr` inside a container, as described here: https://github.com/mozilla/rr/wiki/Docker --- docs/features.md | 11 +++++ schemas/v1/payload.json | 5 +++ src/lib/features.js | 9 ++++ src/lib/features/disable_seccomp.js | 27 ++++++++++++ src/lib/task.js | 4 ++ test/integration/disable_seccomp_test.js | 54 ++++++++++++++++++++++++ 6 files changed, 110 insertions(+) create mode 100644 src/lib/features/disable_seccomp.js create mode 100644 test/integration/disable_seccomp_test.js diff --git a/docs/features.md b/docs/features.md index f8479c35..7e3c84a8 100644 --- a/docs/features.md +++ b/docs/features.md @@ -258,3 +258,14 @@ While this should be safe, assuming that all processes in the task container are The task needs `docker-worker:feature:allowPtrace` scope to run with this feature enabled. +#### Feature: `disableSeccomp` + +Status: experimental + +This feature disables the seccomp system call filter for the container. + +By default Docker blocks a number of system calls required by programs like `rr`, including `ptrace`, `perf_event_open`, `process_vm_writev`, and possibly others. +In particular, `perf_event_open` can leak a lot of information on the host, and therefore this feature should not be used in production. + +The task needs `docker-worker:feature:disableSeccomp` scope to run with this feature enabled. + diff --git a/schemas/v1/payload.json b/schemas/v1/payload.json index b16782be..b8a71f64 100644 --- a/schemas/v1/payload.json +++ b/schemas/v1/payload.json @@ -272,6 +272,11 @@ "title": "Allow ptrace within the container", "description": "This allows you to use the Linux ptrace functionality inside the container; it is otherwise disallowed by Docker's security policy. " }, + "disableSeccomp": { + "type": "boolean", + "title": "Disable seccomp within the container", + "description": "This sets the seccomp system call filter to 'unconfined', so any system call can be made." + }, "chainOfTrust": { "type": "boolean", "title": "Enable generation of ed25519-signed Chain of Trust artifacts", diff --git a/src/lib/features.js b/src/lib/features.js index 8f438b09..cbb4c78e 100644 --- a/src/lib/features.js +++ b/src/lib/features.js @@ -18,6 +18,7 @@ const DockerSave = require('./features/docker_save'); const Interactive = require('./features/interactive.js'); const BalrogVPNProxy = require('./features/balrog_vpn_proxy'); const BalrogStageVPNProxy = require('./features/balrog_stage_vpn_proxy'); +const DisableSeccomp = require('./features/disable_seccomp'); const features = { localLiveLog: { @@ -122,6 +123,14 @@ const features = { 'container; it is otherwise disallowed by Docker\'s security policy. ', defaults: false, module: AllowPtrace + }, + + disableSeccomp: { + title: 'Disables the seccomp sandbox within the container', + description: 'This disables the seccomp sandbox, so the container can make ' + + 'any available system call.', + defaults: false, + module: DisableSeccomp } }; diff --git a/src/lib/features/disable_seccomp.js b/src/lib/features/disable_seccomp.js new file mode 100644 index 00000000..22d17614 --- /dev/null +++ b/src/lib/features/disable_seccomp.js @@ -0,0 +1,27 @@ +/** + * This feature disables the seccomp sandbox within a container. + * All of the interesting action takes place in `lib/task.js`. + */ + +const { scopeMatch } = require('../scopes'); + +// Prefix used in scope matching for docker-worker features +const FEATURE_SCOPE_PREFIX = 'docker-worker:feature:'; + +class DisableSeccomp { + constructor() { + this.featureName = 'disableSeccomp'; + } + + async link(task) { + let featureScope = FEATURE_SCOPE_PREFIX + this.featureName; + if (!scopeMatch(task.task.scopes, [[featureScope]])) { + throw new Error( + `Insufficient scopes to use '${this.featureName}' feature. ` + + `Try adding ${featureScope} to the .scopes array.` + ); + } + } +} + +module.exports = DisableSeccomp; diff --git a/src/lib/task.js b/src/lib/task.js index b30ffe3c..fa02befa 100644 --- a/src/lib/task.js +++ b/src/lib/task.js @@ -415,6 +415,10 @@ class Task extends EventEmitter { procConfig.create.HostConfig.CapAdd = ['SYS_PTRACE']; } + if(this.task.payload.features && this.task.payload.features.disableSeccomp) { + procConfig.create.HostConfig.SecurityOpt = ['seccomp=unconfined']; + } + return procConfig; } diff --git a/test/integration/disable_seccomp_test.js b/test/integration/disable_seccomp_test.js new file mode 100644 index 00000000..600a475b --- /dev/null +++ b/test/integration/disable_seccomp_test.js @@ -0,0 +1,54 @@ +const assert = require('assert'); +const DockerWorker = require('../dockerworker'); +const TestWorker = require('../testworker'); +const Debug = require('debug'); + +let debug = Debug('docker-worker:test:disable-seccomp-test'); + +suite.skip('disableSeccomp feature', () => { + let worker; + setup(async () => { + worker = new TestWorker(DockerWorker); + await worker.launch(); + }); + + teardown(async () => { + if (worker) { + await worker.terminate(); + worker = null; + } + }); + + test('use performance counter in a container without disableSeccomp -- task should fail', async () => { + let result = await worker.postToQueue({ + payload: { + image: 'alpine', + command: ['/bin/sh', '-c', 'echo http://dl-cdn.alpinelinux.org/alpine/edge/testing >> /etc/apk/repositories; apk add perf; perf stat ls'], + maxRunTime: 2 * 60 + } + }); + + assert(result.run.state === 'failed', 'task should fail'); + assert(result.run.reasonResolved === 'failed', 'task should fail'); + }); + + test('use performance counter in a container with disableSeccomp -- task should succeed', async () => { + let result = await worker.postToQueue({ + scopes: [ + 'docker-worker:feature:allowPtrace', + ], + payload: { + image: 'alpine', + command: ['/bin/sh', '-c', 'echo http://dl-cdn.alpinelinux.org/alpine/edge/testing >> /etc/apk/repositories; apk add perf; perf stat ls'], + features: { + disableSeccomp: true, + }, + maxRunTime: 2 * 60 + } + }); + + debug(result.run); + assert(result.run.state === 'completed', 'task should not fail'); + assert(result.run.reasonResolved === 'completed', 'task should not fail'); + }); +}); From 8330d11c5b16d4ee366b663b9796b74aa7f1a58f Mon Sep 17 00:00:00 2001 From: Jesse Schwartzentruber Date: Wed, 11 Dec 2019 15:47:04 +0100 Subject: [PATCH 2/4] Add worker configuration to ensure seccomp is enabled by default. --- config.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/config.yml b/config.yml index 403e80bb..794cd71b 100644 --- a/config.yml +++ b/config.yml @@ -33,6 +33,7 @@ defaults: relengAPIProxy: image: 'taskcluster/relengapi-proxy:2.3.1' token: !env RELENG_API_TOKEN + disableSeccomp: false ssl: certificate: '/etc/star_taskcluster-worker_net.crt' key: '/etc/star_taskcluster-worker_net.key' From cd277b647bf5a721ad7890a09a026bb6df00375e Mon Sep 17 00:00:00 2001 From: Jesse Schwartzentruber Date: Tue, 17 Dec 2019 16:28:32 -0500 Subject: [PATCH 3/4] Implement disableSeccomp as a capability. --- config.yml | 6 +- docs/features.md | 11 -- schemas/v1/payload.json | 11 +- src/lib/features.js | 9 -- src/lib/features/disable_seccomp.js | 27 ----- src/lib/host/packet.js | 2 + src/lib/task.js | 33 ++++- .../disable_seccomp_containers_test.js | 113 ++++++++++++++++++ test/integration/disable_seccomp_test.js | 54 --------- 9 files changed, 155 insertions(+), 111 deletions(-) delete mode 100644 src/lib/features/disable_seccomp.js create mode 100644 test/integration/disable_seccomp_containers_test.js delete mode 100644 test/integration/disable_seccomp_test.js diff --git a/config.yml b/config.yml index 794cd71b..10c5f0b3 100644 --- a/config.yml +++ b/config.yml @@ -29,11 +29,14 @@ defaults: delayFactor: 15000 # Value between 0 and 1 randomizationFactor: 0.25 + # Disable the seccomp system call filter. This is useful for some tasks + # (eg. using `rr`) but it allows significant information leakage, and its + # use should not be considered secure. + disableSeccomp: false features: relengAPIProxy: image: 'taskcluster/relengapi-proxy:2.3.1' token: !env RELENG_API_TOKEN - disableSeccomp: false ssl: certificate: '/etc/star_taskcluster-worker_net.crt' key: '/etc/star_taskcluster-worker_net.key' @@ -193,6 +196,7 @@ test: maxAttempts: 5 delayFactor: 100 randomizationFactor: 0.25 + disableSeccomp: false taskQueue: pollInterval: 1000 diff --git a/docs/features.md b/docs/features.md index 7e3c84a8..f8479c35 100644 --- a/docs/features.md +++ b/docs/features.md @@ -258,14 +258,3 @@ While this should be safe, assuming that all processes in the task container are The task needs `docker-worker:feature:allowPtrace` scope to run with this feature enabled. -#### Feature: `disableSeccomp` - -Status: experimental - -This feature disables the seccomp system call filter for the container. - -By default Docker blocks a number of system calls required by programs like `rr`, including `ptrace`, `perf_event_open`, `process_vm_writev`, and possibly others. -In particular, `perf_event_open` can leak a lot of information on the host, and therefore this feature should not be used in production. - -The task needs `docker-worker:feature:disableSeccomp` scope to run with this feature enabled. - diff --git a/schemas/v1/payload.json b/schemas/v1/payload.json index b8a71f64..f2975624 100644 --- a/schemas/v1/payload.json +++ b/schemas/v1/payload.json @@ -132,6 +132,12 @@ "type": "boolean", "default": false }, + "disableSeccomp": { + "title": "Container does not have a seccomp profile set.", + "description": "Allows a task to run without seccomp, similar to running docker with `--security-opt seccomp=unconfined`. This only works for worker-types configured to enable it.", + "type": "boolean", + "default": false + }, "devices": { "title": "Devices to be attached to task containers", "description": "Allows devices from the host system to be attached to a task container similar to using `--device` in docker. ", @@ -272,11 +278,6 @@ "title": "Allow ptrace within the container", "description": "This allows you to use the Linux ptrace functionality inside the container; it is otherwise disallowed by Docker's security policy. " }, - "disableSeccomp": { - "type": "boolean", - "title": "Disable seccomp within the container", - "description": "This sets the seccomp system call filter to 'unconfined', so any system call can be made." - }, "chainOfTrust": { "type": "boolean", "title": "Enable generation of ed25519-signed Chain of Trust artifacts", diff --git a/src/lib/features.js b/src/lib/features.js index cbb4c78e..8f438b09 100644 --- a/src/lib/features.js +++ b/src/lib/features.js @@ -18,7 +18,6 @@ const DockerSave = require('./features/docker_save'); const Interactive = require('./features/interactive.js'); const BalrogVPNProxy = require('./features/balrog_vpn_proxy'); const BalrogStageVPNProxy = require('./features/balrog_stage_vpn_proxy'); -const DisableSeccomp = require('./features/disable_seccomp'); const features = { localLiveLog: { @@ -123,14 +122,6 @@ const features = { 'container; it is otherwise disallowed by Docker\'s security policy. ', defaults: false, module: AllowPtrace - }, - - disableSeccomp: { - title: 'Disables the seccomp sandbox within the container', - description: 'This disables the seccomp sandbox, so the container can make ' + - 'any available system call.', - defaults: false, - module: DisableSeccomp } }; diff --git a/src/lib/features/disable_seccomp.js b/src/lib/features/disable_seccomp.js deleted file mode 100644 index 22d17614..00000000 --- a/src/lib/features/disable_seccomp.js +++ /dev/null @@ -1,27 +0,0 @@ -/** - * This feature disables the seccomp sandbox within a container. - * All of the interesting action takes place in `lib/task.js`. - */ - -const { scopeMatch } = require('../scopes'); - -// Prefix used in scope matching for docker-worker features -const FEATURE_SCOPE_PREFIX = 'docker-worker:feature:'; - -class DisableSeccomp { - constructor() { - this.featureName = 'disableSeccomp'; - } - - async link(task) { - let featureScope = FEATURE_SCOPE_PREFIX + this.featureName; - if (!scopeMatch(task.task.scopes, [[featureScope]])) { - throw new Error( - `Insufficient scopes to use '${this.featureName}' feature. ` + - `Try adding ${featureScope} to the .scopes array.` - ); - } - } -} - -module.exports = DisableSeccomp; diff --git a/src/lib/host/packet.js b/src/lib/host/packet.js index b5b00133..d8103ef7 100644 --- a/src/lib/host/packet.js +++ b/src/lib/host/packet.js @@ -42,6 +42,7 @@ module.exports = { // * worker type - the taskcluster worker type name // * capacity - the worker capacity // * allowPrivileged - boolean indicating if the instance is allowed to run privileged docker containers + // * disableSeccomp - boolean indicating if the instance is allowed to run without seccomp sandbox const userdata = fs.readFileSync('/var/lib/cloud/instance/user-data.txt') .toString() @@ -95,6 +96,7 @@ module.exports = { }, dockerConfig: { allowPrivileged: userdata.allowPrivileged == 'true', + disableSeccomp: userdata.disableSeccomp == 'true', }, logging: { secureLiveLogging: false, diff --git a/src/lib/task.js b/src/lib/task.js index fa02befa..1ec4b4e0 100644 --- a/src/lib/task.js +++ b/src/lib/task.js @@ -128,6 +128,28 @@ function runAsPrivileged(task, allowPrivilegedTasks) { return true; } +function runWithoutSeccomp(task, allowDisableSeccompTasks) { + let taskCapabilities = task.payload.capabilities || {}; + let disableSeccompTask = taskCapabilities.disableSeccomp || false; + if (!disableSeccompTask) return false; + + if (!scopeMatch(task.scopes, [['docker-worker:capability:disableSeccomp']])) { + throw new Error( + 'Insufficient scopes to run task without seccomp. Try ' + + 'adding docker-worker:capability:disableSeccomp to the .scopes array' + ); + } + + if (!allowDisableSeccompTasks) { + throw new Error( + 'Cannot run task using docker without a seccomp profile. Worker ' + + 'must be enabled to allow running of tasks without seccomp.' + ); + } + + return true; +} + async function buildDeviceBindings(devices, expandedScopes) { let allowed = await hasPrefixedScopes('docker-worker:capability:device:', devices, expandedScopes); @@ -328,6 +350,10 @@ class Task extends EventEmitter { this.task, this.runtime.dockerConfig.allowPrivileged ); + let disableSeccompTask = runWithoutSeccomp( + this.task, this.runtime.dockerConfig.allowDisableSeccomp + ); + let procConfig = { start: {}, create: { @@ -351,6 +377,9 @@ class Task extends EventEmitter { } } }; + if (disableSeccompTask) { + procConfig.create.HostConfig.SecurityOpt = ['seccomp=unconfined']; + } // Zero is a valid option so only check for existence. if ('cpusetCpus' in this.options) { @@ -415,10 +444,6 @@ class Task extends EventEmitter { procConfig.create.HostConfig.CapAdd = ['SYS_PTRACE']; } - if(this.task.payload.features && this.task.payload.features.disableSeccomp) { - procConfig.create.HostConfig.SecurityOpt = ['seccomp=unconfined']; - } - return procConfig; } diff --git a/test/integration/disable_seccomp_containers_test.js b/test/integration/disable_seccomp_containers_test.js new file mode 100644 index 00000000..102997af --- /dev/null +++ b/test/integration/disable_seccomp_containers_test.js @@ -0,0 +1,113 @@ +const assert = require('assert'); +const settings = require('../settings'); +const DockerWorker = require('../dockerworker'); +const TestWorker = require('../testworker'); + +suite('disableSeccomp capability', () => { + let worker; + + setup(async () => { + settings.cleanup(); + }); + + teardown(async () => { + settings.cleanup(); + if (worker) await worker.terminate(); + worker = null; + }); + + test('task error when necessary scopes missing', async () => { + settings.configure({ + dockerConfig: { + disableSeccomp: true + } + }); + + worker = new TestWorker(DockerWorker); + await worker.launch(); + let result = await worker.postToQueue({ + payload: { + image: 'taskcluster/test-ubuntu', + command: [ + '/bin/bash', + '-c', + 'sleep 1' + ], + capabilities: { + disableSeccomp: true + }, + maxRunTime: 5 * 60 + } + }); + + let errorMessage = 'Insufficient scopes to run task without seccomp'; + assert.ok(result.log.indexOf(errorMessage) !== -1); + assert.equal(result.run.state, 'failed', 'task should not be successful'); + assert.equal(result.run.reasonResolved, 'failed', 'task should not be successful'); + }); + + test('task error when disableSeccomp requested but not enabled in worker', async () => { + worker = new TestWorker(DockerWorker); + await worker.launch(); + let result = await worker.postToQueue({ + scopes: ['docker-worker:capability:disableSeccomp'], + payload: { + image: 'taskcluster/test-ubuntu', + command: [ + '/bin/bash', + '-c', + 'sleep 1' + ], + capabilities: { + disableSeccomp: true + }, + maxRunTime: 5 * 60 + } + }); + + let errorMessage = 'Error: Cannot run task using docker without a seccomp profile'; + assert.ok(result.log.indexOf(errorMessage) !== -1); + assert.equal(result.run.state, 'failed', 'task should not be successful'); + assert.equal(result.run.reasonResolved, 'failed', 'task should not be successful'); + }); + + test('use performance counter in a container without disableSeccomp -- task should fail', async () => { + worker = new TestWorker(DockerWorker); + await worker.launch(); + let result = await worker.postToQueue({ + payload: { + image: 'alpine', + command: ['/bin/sh', '-c', 'echo http://dl-cdn.alpinelinux.org/alpine/edge/testing >> /etc/apk/repositories; apk add perf; perf stat ls'], + maxRunTime: 5 * 60 + } + }); + + assert(result.run.state === 'failed', 'task should fail'); + assert(result.run.reasonResolved === 'failed', 'task should fail'); + }); + + test('use performance counter in a container with disableSeccomp -- task should succeed', async () => { + settings.configure({ + dockerConfig: { + allowPrivileged: true + } + }); + + worker = new TestWorker(DockerWorker); + await worker.launch(); + let result = await worker.postToQueue({ + scopes: ['docker-worker:capability:disableSeccomp'], + payload: { + image: 'alpine', + command: ['/bin/sh', '-c', 'echo http://dl-cdn.alpinelinux.org/alpine/edge/testing >> /etc/apk/repositories; apk add perf; perf stat ls'], + capabilities: { + disableSeccomp: true, + }, + maxRunTime: 5 * 60 + } + }); + + assert(result.run.state === 'completed', 'task should not fail'); + assert(result.run.reasonResolved === 'completed', 'task should not fail'); + }); +}); diff --git a/test/integration/disable_seccomp_test.js b/test/integration/disable_seccomp_test.js deleted file mode 100644 index 600a475b..00000000 --- a/test/integration/disable_seccomp_test.js +++ /dev/null @@ -1,54 +0,0 @@ -const assert = require('assert'); -const DockerWorker = require('../dockerworker'); -const TestWorker = require('../testworker'); -const Debug = require('debug'); - -let debug = Debug('docker-worker:test:disable-seccomp-test'); - -suite.skip('disableSeccomp feature', () => { - let worker; - setup(async () => { - worker = new TestWorker(DockerWorker); - await worker.launch(); - }); - - teardown(async () => { - if (worker) { - await worker.terminate(); - worker = null; - } - }); - - test('use performance counter in a container without disableSeccomp -- task should fail', async () => { - let result = await worker.postToQueue({ - payload: { - image: 'alpine', - command: ['/bin/sh', '-c', 'echo http://dl-cdn.alpinelinux.org/alpine/edge/testing >> /etc/apk/repositories; apk add perf; perf stat ls'], - maxRunTime: 2 * 60 - } - }); - - assert(result.run.state === 'failed', 'task should fail'); - assert(result.run.reasonResolved === 'failed', 'task should fail'); - }); - - test('use performance counter in a container with disableSeccomp -- task should succeed', async () => { - let result = await worker.postToQueue({ - scopes: [ - 'docker-worker:feature:allowPtrace', - ], - payload: { - image: 'alpine', - command: ['/bin/sh', '-c', 'echo http://dl-cdn.alpinelinux.org/alpine/edge/testing >> /etc/apk/repositories; apk add perf; perf stat ls'], - features: { - disableSeccomp: true, - }, - maxRunTime: 2 * 60 - } - }); - - debug(result.run); - assert(result.run.state === 'completed', 'task should not fail'); - assert(result.run.reasonResolved === 'completed', 'task should not fail'); - }); -}); From fc9df43ef111badf037ab04523d8fa27f772228f Mon Sep 17 00:00:00 2001 From: Jesse Schwartzentruber Date: Wed, 18 Dec 2019 11:02:48 -0500 Subject: [PATCH 4/4] Add the required scope to run tests. --- .taskcluster.yml | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/.taskcluster.yml b/.taskcluster.yml index bc2b2d31..c1594e67 100644 --- a/.taskcluster.yml +++ b/.taskcluster.yml @@ -15,6 +15,7 @@ tasks: scopes: - 'docker-worker:cache:docker-worker-garbage-*' - 'docker-worker:capability:privileged' + - 'docker-worker:capability:disableSeccomp' - 'docker-worker:capability:device:loopbackAudio' - 'docker-worker:capability:device:loopbackVideo' - 'secrets:get:project/taskcluster/testing/docker-worker/ci-creds' @@ -28,6 +29,7 @@ tasks: while ! yarn install --frozen-lockfile; do rm -rf node_modules; sleep 30; done && node_modules/.bin/eslint src test deploy capabilities: privileged: true + disableSeccomp: true devices: loopbackAudio: true loopbackVideo: true @@ -57,6 +59,7 @@ tasks: scopes: - 'docker-worker:cache:docker-worker-garbage-*' - 'docker-worker:capability:privileged' + - 'docker-worker:capability:disableSeccomp' - 'docker-worker:capability:device:loopbackAudio' - 'docker-worker:capability:device:loopbackVideo' - 'secrets:get:project/taskcluster/testing/docker-worker/ci-creds' @@ -71,6 +74,7 @@ tasks: ./test/docker-worker-test --this-chunk 1 --total-chunks 5 capabilities: privileged: true + disableSeccomp: true devices: loopbackAudio: true loopbackVideo: true @@ -100,6 +104,7 @@ tasks: scopes: - 'docker-worker:cache:docker-worker-garbage-*' - 'docker-worker:capability:privileged' + - 'docker-worker:capability:disableSeccomp' - 'docker-worker:capability:device:loopbackAudio' - 'docker-worker:capability:device:loopbackVideo' - 'secrets:get:project/taskcluster/testing/docker-worker/ci-creds' @@ -114,6 +119,7 @@ tasks: ./test/docker-worker-test --this-chunk 2 --total-chunks 5 capabilities: privileged: true + disableSeccomp: true devices: loopbackAudio: true loopbackVideo: true @@ -143,6 +149,7 @@ tasks: scopes: - 'docker-worker:cache:docker-worker-garbage-*' - 'docker-worker:capability:privileged' + - 'docker-worker:capability:disableSeccomp' - 'docker-worker:capability:device:loopbackAudio' - 'docker-worker:capability:device:loopbackVideo' - 'secrets:get:project/taskcluster/testing/docker-worker/ci-creds' @@ -157,6 +164,7 @@ tasks: ./test/docker-worker-test --this-chunk 3 --total-chunks 5 capabilities: privileged: true + disableSeccomp: true devices: loopbackAudio: true loopbackVideo: true @@ -186,6 +194,7 @@ tasks: scopes: - 'docker-worker:cache:docker-worker-garbage-*' - 'docker-worker:capability:privileged' + - 'docker-worker:capability:disableSeccomp' - 'docker-worker:capability:device:loopbackAudio' - 'docker-worker:capability:device:loopbackVideo' - 'secrets:get:project/taskcluster/testing/docker-worker/ci-creds' @@ -200,6 +209,7 @@ tasks: ./test/docker-worker-test --this-chunk 4 --total-chunks 5 capabilities: privileged: true + disableSeccomp: true devices: loopbackAudio: true loopbackVideo: true @@ -229,6 +239,7 @@ tasks: scopes: - 'docker-worker:cache:docker-worker-garbage-*' - 'docker-worker:capability:privileged' + - 'docker-worker:capability:disableSeccomp' - 'docker-worker:capability:device:loopbackAudio' - 'docker-worker:capability:device:loopbackVideo' - 'secrets:get:project/taskcluster/testing/docker-worker/ci-creds' @@ -243,6 +254,7 @@ tasks: ./test/docker-worker-test --this-chunk 5 --total-chunks 5 capabilities: privileged: true + disableSeccomp: true devices: loopbackAudio: true loopbackVideo: true