aboutsummaryrefslogtreecommitdiffstats
path: root/pkg/host/machine_info_linux.go
diff options
context:
space:
mode:
authorNecip Fazil Yildiran <necip@google.com>2023-07-11 22:24:05 +0000
committerAlexander Potapenko <glider@google.com>2024-02-22 15:35:18 +0000
commit971a0f14c5cf6379d1a1fde7d26b853293bced2b (patch)
tree77572447f34923979a174c8f145583cf03f59781 /pkg/host/machine_info_linux.go
parent2b876d1039e8c18ba9a1cdbaa7c9c5b6e1bc975d (diff)
pkg/host: get module .text address from /sys/module
The address from /proc/modules is not necessarily the address of .text, e.g., can be the address of .plt. If available, fix up the module address using the address from /sys/module/<module-name>/sections/.text This patch was originally uploaded to https://github.com/google/syzkaller/pull/4025. Additions to the original patch: - fix lint warnings - adjust the module size to account for the diff between the module address and .text address Signed-off-by: Alexander Potapenko <glider@google.com>
Diffstat (limited to 'pkg/host/machine_info_linux.go')
-rw-r--r--pkg/host/machine_info_linux.go46
1 files changed, 41 insertions, 5 deletions
diff --git a/pkg/host/machine_info_linux.go b/pkg/host/machine_info_linux.go
index 980081898..ce4e1dbfa 100644
--- a/pkg/host/machine_info_linux.go
+++ b/pkg/host/machine_info_linux.go
@@ -125,27 +125,63 @@ func readKVMInfo(buffer *bytes.Buffer) error {
return nil
}
+func getModuleTextAddr(moduleName string) (uint64, error) {
+ addrPath := filepath.Join("/sys", "module", moduleName, "sections", ".text")
+ addrContent, err := os.ReadFile(addrPath)
+ if err != nil {
+ return 0, fmt.Errorf("could not read module .text address file: %w", err)
+ }
+ addrString := strings.TrimSpace(string(addrContent))
+ addr, err := strconv.ParseUint(addrString, 0, 64)
+ if err != nil {
+ return 0, fmt.Errorf("address parsing error in %v: %w", moduleName, err)
+ }
+ return addr, nil
+}
+
func getModulesInfo() ([]KernelModule, error) {
modulesText, _ := os.ReadFile("/proc/modules")
- return parseModules(modulesText)
+ modules, err := parseModules(modulesText)
+ if err != nil {
+ return modules, err
+ }
+ // Fix up module addresses to use .text addresses where available.
+ for i, module := range modules {
+ addr, err := getModuleTextAddr(module.Name)
+ if err == nil {
+ offset := addr - modules[i].Addr
+ modules[i].Addr += offset
+ modules[i].Size -= offset
+ }
+ }
+ return modules, nil
}
func parseModules(modulesText []byte) ([]KernelModule, error) {
var modules []KernelModule
re := regexp.MustCompile(`(\w+) ([0-9]+) .*(0[x|X][a-fA-F0-9]+)[^\n]*`)
for _, m := range re.FindAllSubmatch(modulesText, -1) {
- addr, err := strconv.ParseUint(string(m[3]), 0, 64)
+ name := string(m[1])
+ modAddr, err := strconv.ParseUint(string(m[3]), 0, 64)
if err != nil {
+ // /proc/modules is broken, bail out.
return nil, fmt.Errorf("address parsing error in /proc/modules: %w", err)
}
- size, err := strconv.ParseUint(string(m[2]), 0, 64)
+ textAddr, err := getModuleTextAddr(name)
+ if err != nil {
+ // Module address unavailable, .text is probably 0. Skip this module.
+ continue
+ }
+ modSize, err := strconv.ParseUint(string(m[2]), 0, 64)
if err != nil {
+ // /proc/modules is broken, bail out.
return nil, fmt.Errorf("module size parsing error in /proc/modules: %w", err)
}
+ offset := modAddr - textAddr
modules = append(modules, KernelModule{
Name: string(m[1]),
- Addr: addr,
- Size: size,
+ Addr: textAddr,
+ Size: modSize - offset,
})
}
return modules, nil