返回

Linux内核 `read_dentry_strings` 函数问题解决:如何避免“未满足的程序引用”错误?

Linux

Linux内核中的 read_dentry_strings 函数问题分析与解决

问题概述

在 Linux 内核编程中,read_dentry_strings 函数用于从目录项(dentry)中读取字符串。然而,在某些情况下,调用此函数时会出现“未满足的程序引用”错误。本文将深入探讨此问题,并提供解决方案。

代码问题分析

read_dentry_strings 函数中的问题代码行尝试读取 d_name.name 成员变量的值。d_name 是一个联合,它可以是字符串指针或内核对象。程序中的代码假设 d_name 始终是一个字符串指针,但在某些情况下它可能是内核对象。

解决方案

要解决此问题,需要根据 d_name.type 成员变量的值动态确定 d_name 的类型。如果它是字符串指针,则可以安全地使用 bpf_probe_read_str 函数。否则,需要使用其他方法来读取内核对象的值。

修改后的代码如下:

int read_dentry_strings(struct dentry *dentry, u8 buf[DEFAULT_SUB_BUF_LEN][DEFAULT_SUB_BUF_SIZE])
{
    struct dentry *curr_dtry = dentry;
    struct dentry *lastdtryp = dentry;
    unsigned int i = 0;

    if (buf)
    {
        for (i = 0; i < DEFAULT_SUB_BUF_LEN; i++)
        {
            struct dentry *parent =  BPF_CORE_READ(curr_dtry, d_parent);
            if (parent != lastdtryp)
            {
                lastdtryp = parent;
                curr_dtry = parent;
                if (BPF_CORE_READ(curr_dtry, d_name.type) == DENTRY_UNKNOWN)
                {
                    break;
                }
                bpf_probe_read_str(buf[i], DEFAULT_SUB_BUF_SIZE, BPF_CORE_READ(curr_dtry, d_name.name));
            }
            else
                break;
        }
    }

    return 0;
}

常见问题解答

  • 为什么会出现“未满足的程序引用”错误?

    • 因为代码假设 d_name 始终是一个字符串指针,但它有时可能是内核对象。
  • 如何解决此问题?

    • 动态检查 d_name.type 成员变量的值,并根据类型使用不同的读取方法。
  • 修改后的代码是否与原始代码兼容?

    • 是的,修改后的代码在所有情况下都能正确处理 d_name 类型。
  • 还有其他避免此问题的方法吗?

    • 避免在代码中对 d_name 类型做出假设,并始终使用动态检查。
  • 此问题只影响特定版本的 Linux 内核吗?

    • 不,此问题可能影响任何版本的 Linux 内核。

结论

理解 read_dentry_strings 函数中的此问题并掌握其解决方案对于 Linux 内核编程非常重要。通过动态确定 d_name 的类型,程序员可以避免“未满足的程序引用”错误,并确保代码的正确性和可靠性。