Files
dsh/upstream/container/control-plane/services/access-manager/lib/runtime-capabilities.mjs
T

63 lines
2.2 KiB
JavaScript

import { readFile } from 'node:fs/promises'
function groupId(groupFile, name) {
for (const line of groupFile.split('\n')) {
const fields = line.split(':')
if (fields[0] === name && /^\d+$/.test(fields[2] ?? '')) return Number(fields[2])
}
return null
}
function supplementaryGroups(status) {
const line = status.split('\n').find(value => value.startsWith('Groups:'))
if (line === undefined) return []
return line.slice('Groups:'.length).trim().split(/\s+/).filter(Boolean).map(Number).filter(Number.isInteger)
}
function mountOption(mounts, mountPoint, prefix) {
for (const line of mounts.split('\n')) {
const fields = line.split(' ')
if (fields[1] !== mountPoint) continue
return fields[3]?.split(',').find(value => value.startsWith(prefix)) ?? null
}
return null
}
async function optionalRead(path) {
try { return await readFile(path, 'utf8') } catch { return '' }
}
export async function detectRuntimeCapabilities({
groupPath = '/etc/group',
initStatusPath = '/proc/1/status',
mountsPath = '/proc/mounts',
ptraceScopePath = '/proc/sys/kernel/yama/ptrace_scope',
} = {}) {
const [groupsFile, initStatus, mounts, ptraceScopeValue] = await Promise.all([
optionalRead(groupPath),
optionalRead(initStatusPath),
optionalRead(mountsPath),
optionalRead(ptraceScopePath),
])
const enabledGroup = groupId(groupsFile, 'dsh-sudo-true')
const disabledGroup = groupId(groupsFile, 'dsh-sudo-false')
const initGroups = supplementaryGroups(initStatus)
const dshRootCapabilityEffective = enabledGroup !== null && initGroups.includes(enabledGroup)
const sudoSelection = dshRootCapabilityEffective
? 'enabled'
: (disabledGroup !== null && initGroups.includes(disabledGroup) ? 'disabled' : 'unknown')
const ptraceScope = /^\d+$/.test(ptraceScopeValue.trim()) ? Number(ptraceScopeValue.trim()) : null
const hidepid = mountOption(mounts, '/proc', 'hidepid=')
return {
dshRootCapabilityEffective,
agentIsolationEffective: false,
details: {
sudoSelection,
ptraceScope,
procHidepid: hidepid === null ? null : Number(hidepid.slice('hidepid='.length)),
agentIsolationReason: 'shared-node-process-identity',
},
}
}