diff --git a/components/gitpod-protocol/data/gitpod-schema.json b/components/gitpod-protocol/data/gitpod-schema.json index 911828bf0c5e3b..fbde44f4d8d743 100644 --- a/components/gitpod-protocol/data/gitpod-schema.json +++ b/components/gitpod-protocol/data/gitpod-schema.json @@ -282,6 +282,25 @@ "type": "boolean", "deprecationMessage": "The 'experimentalNetwork' property is deprecated.", "description": "Experimental network configuration in workspaces (deprecated). Enabled by default" + }, + "coreDump": { + "type": "object", + "description": "Configure the default action of certain signals is to cause a process to terminate and produce a core dump file, a file containing an image of the process's memory at the time of termination. Disabled by default.", + "deprecationMessage": "The 'coreDump' property is experimental.", + "additionalProperties": false, + "properties": { + "enabled": { + "type": "boolean" + }, + "cur": { + "type": "number", + "description": "Cur specifies the soft limit" + }, + "max": { + "type": "number", + "description": "Max specifies the hard limit" + } + } } }, "additionalProperties": false, diff --git a/components/gitpod-protocol/src/protocol.ts b/components/gitpod-protocol/src/protocol.ts index 71b279d38975ec..b5f3987ff33c9b 100644 --- a/components/gitpod-protocol/src/protocol.ts +++ b/components/gitpod-protocol/src/protocol.ts @@ -803,6 +803,12 @@ export interface RepositoryCloneInformation { checkoutLocation?: string; } +export interface CoreDumpConfig { + enabled?: boolean; + cur?: number; + max?: number; +} + export interface WorkspaceConfig { mainConfiguration?: string; additionalRepositories?: RepositoryCloneInformation[]; @@ -815,6 +821,7 @@ export interface WorkspaceConfig { github?: GithubAppConfig; vscode?: VSCodeConfig; jetbrains?: JetBrainsConfig; + coreDump?: CoreDumpConfig; /** deprecated. Enabled by default **/ experimentalNetwork?: boolean; diff --git a/components/server/src/workspace/workspace-starter.ts b/components/server/src/workspace/workspace-starter.ts index b4716842a93f10..ed86e39702358f 100644 --- a/components/server/src/workspace/workspace-starter.ts +++ b/components/server/src/workspace/workspace-starter.ts @@ -1416,6 +1416,17 @@ export class WorkspaceStarter { dotfileEnv.setValue(user.additionalData?.dotfileRepo || ""); envvars.push(dotfileEnv); + if (workspace.config.coreDump.enabled) { + const noLimits:number=18446744073709551615; + + const rLimitCur = new EnvironmentVariable(); + rLimitCur.setName("GITPOD_RLIMIT_CORE"); + rLimitCur.setValue(JSON.stringify({ + cur: workspace.config.coreDump.cur === 0 ? noLimits : workspace.config.coreDump.cur, + max: workspace.config.coreDump.max === 0 ? noLimits : workspace.config.coreDump.max, + })); + } + const createGitpodTokenPromise = (async () => { const scopes = this.createDefaultGitpodAPITokenScopes(workspace, instance); const token = crypto.randomBytes(30).toString("hex"); diff --git a/components/workspacekit/cmd/rings.go b/components/workspacekit/cmd/rings.go index 1fdc2e60af4c6d..a66bb1de6cc813 100644 --- a/components/workspacekit/cmd/rings.go +++ b/components/workspacekit/cmd/rings.go @@ -829,6 +829,25 @@ var ring2Cmd = &cobra.Command{ return } + type fakeRlimit struct { + Cur uint64 `json:"cur"` + Max uint64 `json:"max"` + } + + var rlimit fakeRlimit + err = json.Unmarshal([]byte(os.Getenv("GITPOD_RLIMIT_CORE")), &rlimit) + if err != nil { + log.WithError(err).WithField("data", os.Getenv("RLIMIT_CORE")).Error("cannot deserialize RLIMIT_CORE") + } + + rlimitCore := &syscall.Rlimit{ + Cur: rlimit.Cur, + Max: rlimit.Max, + } + if err := syscall.Setrlimit(syscall.RLIMIT_CORE, rlimitCore); err != nil { + log.WithError(err).Error("cannot disable core dumps") + } + // Now that we're in our new root filesystem, including proc and all, we can load // our seccomp filter, and tell our parent about it. scmpFd, err := seccomp.LoadFilter()