8000 fix: fix oom_score adjustments failing if caps set by sreya · Pull Request #15758 · coder/coder · GitHub
[go: up one dir, main page]

Skip to content

fix: fix oom_score adjustments failing if caps set #15758

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 10 commits into from
Dec 5, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
drop caps
  • Loading branch information
sreya committed Dec 4, 2024
commit 2bd0372a2ffe8570e4651910adcd5d29be21838b
60 changes: 31 additions & 29 deletions agent/agentexec/cli_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,14 @@ import (

"golang.org/x/sys/unix"
"golang.org/x/xer 8000 rors"
"kernel.org/pub/linux/libs/security/libcap/cap"
)

func init() {
p := cap.GetProc()
fmt.Println(p.String())
}

// CLI runs the agent-exec command. It should only be called by the cli package.
func CLI() error {
// We lock the OS thread here to avoid a race condition where the nice priority
Expand All @@ -37,12 +43,17 @@ func CLI() error {
}

// Parse everything after "coder agent-exec".
var err error
err = fs.Parse(os.Args[2:])
err := fs.Parse(os.Args[2:])
if err != nil {
return xerrors.Errorf("parse flags: %w", err)
}

// Get everything after "coder agent-exec --"
args := execArgs(os.Args)
if len(args) == 0 {
return xerrors.Errorf("no exec command provided %+v", os.Args)
}

if *oom == unset {
// If an explicit oom score isn't set, we use the default.
*oom, err = defaultOOMScore()
Expand All @@ -51,15 +62,21 @@ func CLI() error {
}
}

// We drop effective caps prior to setting dumpable so that we limit the
// impact of someone attempting to hijack the process (i.e. with a debugger)
// to take advantage of the capabilities of the agent process.
err = dropEffectiveCaps()
if err != nil {
printfStdErr("failed to drop effective caps: %v", err)
}

// err = unix.Prctl(unix.PR_SET_DUMPABLE, 1, 0, 0, 0)
// if err != nil {
// printfStdErr("failed to set dumpable: %v", err)
// }
// Set dumpable to 1 so that we can adjust the oom score. If the process
// doesn't have capabilities or has an suid/sgid bit set, this is already
// set.
err = unix.Prctl(unix.PR_SET_DUMPABLE, 1, 0, 0, 0)
if err != nil {
printfStdErr("failed to set dumpable: %v", err)
}

err = writeOOMScoreAdj(*oom)
if err != nil {
Expand All @@ -69,17 +86,12 @@ func CLI() error {
printfStdErr("failed to adjust oom score to %d for cmd %+v: %v", *oom, execArgs(os.Args), err)
}

// Set dumpable back to 0 just to be safe. It's not inherited for execve anyways.
err = unix.Prctl(unix.PR_SET_DUMPABLE, 0, 0, 0, 0)
if err != nil {
printfStdErr("failed to unset dumpable: %v", err)
}

// Get everything after "coder agent-exec --"
args := execArgs(os.Args)
if len(args) == 0 {
return xerrors.Errorf("no exec command provided %+v", os.Args)
}

if *nice == unset {
// If an explicit nice score isn't set, we use the default.
*nice, err = defaultNiceScore()
Expand Down Expand Up @@ -169,24 +181,14 @@ func printfStdErr(format string, a ...any) {
}

func dropEffectiveCaps() error {
// Get the current capabilities
var header unix.CapUserHeader
var data unix.CapUserData

header.Version = unix.LINUX_CAPABILITY_VERSION_3
header.Pid = 0 // 0 means current process

// Get current caps
if err := unix.Capget(&header, &data); err != nil {
return xerrors.Errorf("capget failed: %v", err)
proc := cap.GetProc()
err := proc.ClearFlag(cap.Effective)
if err != nil {
return xerrors.Errorf("failed to drop effective caps: %w", err)
}

// Clear the effective set by setting it to 0
data.Effective = 0

// Set the new capabilities
if err := unix.Capset(&header, &data); err != nil {
return xerrors.Errorf("capset failed: %v", err)
err = proc.SetProc()
if err != nil {
return xerrors.Errorf("failed to set proc: %w", err)
}
return nil
}
2 changes: 2 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,7 @@ require (
github.com/google/go-github/v61 v61.0.0
github.com/mocktools/go-smtp-mock/v2 v2.4.0
github.com/natefinch/atomic v1.0.1
kernel.org/pub/linux/libs/security/libcap/cap v1.2.73
)

require (
Expand Down Expand Up @@ -248,6 +249,7 @@ require (
github.com/vmihailenco/msgpack/v5 v5.4.1 // indirect
github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.54.0 // indirect
kernel.org/pub/linux/libs/security/libcap/psx v1.2.73 // indirect
)

require (
Expand Down
4 changes: 4 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -1266,6 +1266,10 @@ howett.net/plist v1.0.0 h1:7CrbWYbPPO/PyNy38b2EB/+gYbjCe2DXBxgtOOZbSQM=
howett.net/plist v1.0.0/go.mod h1:lqaXoTrLY4hg8tnEzNru53gicrbv7rrk+2xJA/7hw9g=
inet.af/peercred v0.0.0-20210906144145-0893ea02156a h1:qdkS8Q5/i10xU2ArJMKYhVa1DORzBfYS/qA2UK2jheg=
inet.af/peercred v0.0.0-20210906144145-0893ea02156a/go.mod h1:FjawnflS/udxX+SvpsMgZfdqx2aykOlkISeAsADi5IU=
kernel.org/pub/linux/libs/security/libcap/cap v1.2.73 h1:Th2b8jljYqkyZKS3aD3N9VpYsQpHuXLgea+SZUIfODA=
kernel.org/pub/linux/libs/security/libcap/cap v1.2.73/go.mod h1:hbeKwKcboEsxARYmcy/AdPVN11wmT/Wnpgv4k4ftyqY=
kernel.org/pub/linux/libs/security/libcap/psx v1.2.73 h1:SEAEUiPVylTD4vqqi+vtGkSnXeP2FcRO3FoZB1MklMw=
kernel.org/pub/linux/libs/security/libcap/psx v1.2.73/go.mod h1:+l6Ee2F59XiJ2I6WR5ObpC1utCQJZ/VLsEbQCD8RG24=
lukechampine.com/uint128 v1.3.0 h1:cDdUVfRwDUDovz610ABgFD17nXD4/uDgVHl2sC3+sbo=
lukechampine.com/uint128 v1.3.0/go.mod h1:c4eWIwlEGaxC/+H1VguhU4PHXNWDCDMUlWdIWl2j1gk=
modernc.org/cc/v3 v3.41.0 h1:QoR1Sn3YWlmA1T4vLaKZfawdVtSiGx8H+cEojbC7v1Q=
Expand Down
Loading
0