diff options
| author | Necip Fazil Yildiran <necip@google.com> | 2023-07-11 22:24:05 +0000 |
|---|---|---|
| committer | Alexander Potapenko <glider@google.com> | 2024-02-22 15:35:18 +0000 |
| commit | 971a0f14c5cf6379d1a1fde7d26b853293bced2b (patch) | |
| tree | 77572447f34923979a174c8f145583cf03f59781 /pkg/host/machine_info_linux.go | |
| parent | 2b876d1039e8c18ba9a1cdbaa7c9c5b6e1bc975d (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.go | 46 |
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 |
