From 971a0f14c5cf6379d1a1fde7d26b853293bced2b Mon Sep 17 00:00:00 2001 From: Necip Fazil Yildiran Date: Tue, 11 Jul 2023 22:24:05 +0000 Subject: 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//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 --- pkg/cover/backend/modules.go | 3 +-- pkg/host/machine_info_linux.go | 46 +++++++++++++++++++++++++++++++++++++----- 2 files changed, 42 insertions(+), 7 deletions(-) (limited to 'pkg') diff --git a/pkg/cover/backend/modules.go b/pkg/cover/backend/modules.go index ac3326236..3a76e607f 100644 --- a/pkg/cover/backend/modules.go +++ b/pkg/cover/backend/modules.go @@ -50,10 +50,9 @@ func discoverModulesLinux(dirs []string, hostModules []host.KernelModule, continue } log.Logf(0, "module %v -> %v", mod.Name, path) - offset := getModuleOffset(path) modules = append(modules, &Module{ Name: mod.Name, - Addr: mod.Addr + offset, + Addr: mod.Addr, Path: path, }) } 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 -- cgit mrf-deployment