8000 Fix capabilities initialization by rafaeldtinoco · Pull Request #2380 · aquasecurity/tracee · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

Fix capabilities initialization #2380

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 4 commits into from
Nov 25, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
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
14 changes: 6 additions & 8 deletions pkg/capabilities/capabilities.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,6 @@ import (
var once sync.Once
var caps *Capabilities // singleton for all packages

const pkgName = "capabilities"

//
// "Effective" might be at protection rings 0,1,2,3
// "Permitted" is always at ring0 (so effective can migrate rings)
Expand Down Expand Up @@ -105,13 +103,13 @@ func (c *Capabilities) initialize(bypass bool) error {

paranoid, err := getKernelPerfEventParanoidValue()
if err != nil {
logger.Debug("could not get perf_event_paranoid, assuming highest", "pkg", pkgName)
logger.Debug("could not get perf_event_paranoid, assuming highest")
}

if paranoid > 2 {
logger.Debug("paranoid: Value in /proc/sys/kernel/perf_event_paranoid is > 2", "pkg", pkgName)
logger.Debug("paranoid: Tracee needs CAP_SYS_ADMIN instead of CAP_BPF + CAP_PERFMON", "pkg", pkgName)
logger.Debug("paranoid: To change that behavior set perf_event_paranoid to 2 or less.", "pkg", pkgName)
logger.Debug("paranoid: Value in /proc/sys/kernel/perf_event_paranoid is > 2")
logger.Debug("paranoid: Tracee needs CAP_SYS_ADMIN instead of CAP_BPF + CAP_PERFMON")
logger.Debug("paranoid: To change that behavior set perf_event_paranoid to 2 or less.")
c.Require(cap.SYS_ADMIN)
}

Expand Down Expand Up @@ -305,11 +303,11 @@ func (c *Capabilities) apply(t ringType) error {
return err
}

logger.Debug("capabilities change", "pkg", pkgName)
logger.Debug("capabilities change")

for k, v := range c.all {
if v[t] {
logger.Debug("enabling", "pkg", pkgName, "cap", k)
logger.Debug("enabling cap", "cap", k)
}
err = c.have.SetFlag(cap.Effective, v[t], k)
if err != nil {
Expand Down
19 changes: 17 additions & 2 deletions pkg/ebpf/tracee.go
Original file line number Diff line number Diff line change
Expand Up @@ -409,7 +409,14 @@ func (t *Tracee) Init() error {

// Initialize process tree before receiving events (will use it)

t.procInfo, err = procinfo.NewProcessInfo()
err = capabilities.GetInstance().Requested(func() error {
t.procInfo, err = procinfo.NewProcessInfo()
return err
},
cap.DAC_READ_SEARCH,
cap.IPC_LOCK,
)

if err != nil {
t.Close()
return fmt.Errorf("error creating process tree: %v", err)
Expand Down Expand Up @@ -468,7 +475,15 @@ func (t *Tracee) Init() error {
t.config.maxPidsCache = 5 // default value for config.maxPidsCache
}
t.pidsInMntns.Init(t.config.maxPidsCache)
mntNSProcs, err := proc.GetMountNSFirstProcesses()

var mntNSProcs map[int]int
err = capabilities.GetInstance().Requested(func() error {
mntNSProcs, err = proc.GetMountNSFirstProcesses()
return err
},
cap.DAC_READ_SEARCH,
cap.SYS_PTRACE,
)
if err == nil {
for mountNS, pid := range mntNSProcs {
t.pidsInMntns.AddBucketItem(uint32(mountNS), uint32(pid))
Expand Down
19 changes: 14 additions & 5 deletions pkg/procinfo/procinfo.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
"time"

"github.com/aquasecurity/tracee/pkg/containers"
"github.com/aquasecurity/tracee/pkg/logger"
"github.com/aquasecurity/tracee/types/trace"
)

Expand Down Expand Up @@ -93,8 +94,9 @@ func ParseProcessContext(ctx []byte, containers *containers.Containers) (Process
return procCtx, nil
}

//returns the file creation time
//Note: this is not the real process start time because it's based on the file creation time, but it is a close approximation
// getFileCtime returns the file creation time
// Note: this is not the real process start time because it's based on the file
// creation time, but it is a close approximation
func getFileCtime(path string) (int, error) {
fileInfo, err := os.Stat(path)
if err != nil {
Expand All @@ -105,7 +107,8 @@ func getFileCtime(path string) (int, error) {
return int(ts.Sec)*int(time.Second) + int(ts.Nsec)*int(time.Nanosecond), nil
}

//parse the status file of a process or given task and returns process context struct
// parseProcStatus parses the status file of a process or given task and returns
// process context struct
func parseProcStatus(status []byte, taskStatusPath string) (ProcessCtx, error) {
var processName string
processVals := make(map[string]uint32)
Expand Down Expand Up @@ -149,7 +152,8 @@ func parseProcStatus(status []byte, taskStatusPath string) (ProcessCtx, error) {
return process, nil
}

//gets the namespace data for the process Context struct by parsing the /proc/<Pid>/task directory
// getNsIdData gets the namespace data for the process Context struct by parsing
// the /proc/<pid>/task directory
func getNsIdData(taskStatusPath string) (uint32, uint32, error) {
path := fmt.Sprintf("%s/ns/mnt", taskStatusPath[:len(taskStatusPath)-7])
processMntId, err := os.Readlink(path)
Expand Down Expand Up @@ -177,7 +181,7 @@ func getNsIdData(taskStatusPath string) (uint32, uint32, error) {
return uint32(mntId), uint32(pidId), nil
}

//initialize new process-tree
// NewProcessInfo initializes a new process-tree
func NewProcessInfo() (*ProcInfo, error) {
p := ProcInfo{make(map[int]ProcessCtx), sync.RWMutex{}}
procDir, err := os.Open("/proc")
Expand All @@ -199,11 +203,13 @@ func NewProcessInfo() (*ProcInfo, error) {

taskDir, err := os.Open(fmt.Sprintf("/proc/%d/task", pid))
if err != nil {
logger.Warn("could not read /proc/pid/task file:", "pid", pid, "error", err.Error())
continue
}
defer taskDir.Close()
processTasks, err := taskDir.Readdirnames(-1)
if err != nil {
logger.Warn("could not read task dir", "error", err.Error())
continue
}
for _, task := range processTasks {
Expand All @@ -212,14 +218,17 @@ func NewProcessInfo() (*ProcInfo, error) {
data, err := ioutil.ReadFile(taskStatus)
if err != nil {
// process might have exited - ignore this task
logger.Warn("could not read /proc/pid/task/pid/status file", "error", err.Error())
continue
}
processStatus, err := parseProcStatus(data, taskStatus)
if err != nil {
logger.Warn("could not parse task status", "error", err.Error())
continue
}
containerId, err := containers.GetContainerIdFromTaskDir(taskDir)
if err != nil {
logger.Warn("could not get containerid from task dir", "error", err.Error())
continue
}
processStatus.ContainerID = containerId
Expand Down
4 changes: 2 additions & 2 deletions pkg/utils/proc/ns.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,13 +37,13 @@ func GetMountNSFirstProcesses() (map[int]int, error) {
}
procNS, err := GetProcNS(uint(pid))
if err != nil {
logger.Warn("Failed in fetching process mount namespace", pid, err.Error())
logger.Warn("Failed in fetching process mount namespace", "pid", pid, "error", err.Error())
continue
}

processStartTime, err := GetProcessStartTime(uint(pid))
if err != nil {
logger.Warn("Failed in fetching process start time", pid, err.Error())
logger.Warn("Failed in fetching process start time", "pid", pid, "error", err.Error())
continue
}

Expand Down
0