From f63a48deff9c3b4839e39afb9165c0f4d6ab9ba1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gustavo=20I=C3=B1iguez=20Goia?= Date: Tue, 15 Oct 2024 00:49:58 +0200 Subject: [PATCH] calculate the ram usage of a process in the daemon - Calculate the ram usage of a process in the daemon, using the page size of the system. - Added new functions to read some details of a process, so we can use them in other parts of the code. --- daemon/procmon/details.go | 54 +++++++++++++++++++------ ui/opensnitch/dialogs/processdetails.py | 12 +++--- 2 files changed, 46 insertions(+), 20 deletions(-) diff --git a/daemon/procmon/details.go b/daemon/procmon/details.go index 3090e4c6..b1e4aabf 100644 --- a/daemon/procmon/details.go +++ b/daemon/procmon/details.go @@ -15,6 +15,7 @@ import ( "strconv" "strings" "time" + "unsafe" "github.com/evilsocket/opensnitch/daemon/core" "github.com/evilsocket/opensnitch/daemon/dns" @@ -24,6 +25,7 @@ import ( ) var socketsRegex, _ = regexp.Compile(`socket:\[([0-9]+)\]`) +var pageSize = int64(os.Getpagesize()) // GetParent obtains the information of this process' parent. func (p *Process) GetParent() { @@ -182,6 +184,42 @@ func (p *Process) ReadEnv() { } } +// ReadMaps reads the /proc//maps file. +func (p *Process) ReadMaps() { + data, err := ioutil.ReadFile(p.pathMaps) + if err != nil { + return + } + p.Maps = unsafe.String(unsafe.SliceData(data), len(data)) +} + +// ReadStatm reads and parses the /proc//statm file. +// Memory usage is measured in pages. +func (p *Process) ReadStatm() { + if data, err := ioutil.ReadFile(p.pathStatm); err == nil { + p.Statm = &procStatm{} + fmt.Sscanf(string(data), "%d %d %d %d %d %d %d", &p.Statm.Size, &p.Statm.Resident, &p.Statm.Shared, &p.Statm.Text, &p.Statm.Lib, &p.Statm.Data, &p.Statm.Dt) + p.Statm.Size = p.Statm.Size * pageSize + p.Statm.Resident = p.Statm.Resident * pageSize + p.Statm.Shared = p.Statm.Shared * pageSize + p.Statm.Text = p.Statm.Text * pageSize + p.Statm.Lib = p.Statm.Lib * pageSize + p.Statm.Data = p.Statm.Data * pageSize + p.Statm.Dt = p.Statm.Dt * int(pageSize) + } +} + +// ReadExeLink reads the link that /proc//exe points to. +// This is the real path to the path that was executed and loaded in memory. +// It may or not be the same binary that exists on disk (for example when a +// binary is executed, and later updated or deleted). +// If a process is launched from a chroot, this link will point to the absolute +// path, including the host path to the chroot. +func (p *Process) ReadExeLink() (string, error) { + // FIXME: this reading can give error: file name too long + return os.Readlink(p.pathExe) +} + // ReadPath reads the symbolic link that /proc//exe points to. // Note 1: this link might not exist on the root filesystem, it might // have been executed from a container, so the real path would be: @@ -209,12 +247,7 @@ func (p *Process) ReadPath() error { } }() - if _, err := os.Lstat(p.pathExe); err != nil { - return err - } - - // FIXME: this reading can give error: file name too long - link, err := os.Readlink(p.pathExe) + link, err := p.ReadExeLink() if err != nil { return err } @@ -351,13 +384,8 @@ func (p *Process) readStatus() { if data, err := ioutil.ReadFile(core.ConcatStrings("/proc/", strconv.Itoa(p.ID), "/stack")); err == nil { p.Stack = string(data) } - if data, err := ioutil.ReadFile(p.pathMaps); err == nil { - p.Maps = string(data) - } - if data, err := ioutil.ReadFile(p.pathStatm); err == nil { - p.Statm = &procStatm{} - fmt.Sscanf(string(data), "%d %d %d %d %d %d %d", &p.Statm.Size, &p.Statm.Resident, &p.Statm.Shared, &p.Statm.Text, &p.Statm.Lib, &p.Statm.Data, &p.Statm.Dt) - } + p.ReadMaps() + p.ReadStatm() } // CleanPath applies fixes on the path to the binary: diff --git a/ui/opensnitch/dialogs/processdetails.py b/ui/opensnitch/dialogs/processdetails.py index 1167023a..8e079589 100644 --- a/ui/opensnitch/dialogs/processdetails.py +++ b/ui/opensnitch/dialogs/processdetails.py @@ -369,14 +369,12 @@ class ProcessDetailsDialog(QtWidgets.QDialog, uic.loadUiType(DIALOG_UI_PATH)[0]) self.textIOStats.appendHtml(ioText) def _load_mem_data(self, mem): - # assuming page size == 4096 - pagesize = 4096 memText = "VIRT: %dMB, RSS: %dMB, Libs: %dMB, Data: %dMB, Text: %dMB" % ( - ((mem['Size'] * pagesize) / 1024) / 1024, - ((mem['Resident'] * pagesize) / 1024) / 1024, - ((mem['Lib'] * pagesize) / 1024) / 1024, - ((mem['Data'] * pagesize) / 1024) / 1024, - ((mem['Text'] * pagesize) / 1024) / 1024 + (mem['Size'] / 1024) / 1024, + (mem['Resident'] / 1024) / 1024, + (mem['Lib'] / 1024) / 1024, + (mem['Data'] / 1024) / 1024, + (mem['Text'] / 1024) / 1024 ) self.labelStatm.setText(memText)