【问题标题】:Failure to compare strings with eBPF无法将字符串与 eBPF 进行比较
【发布时间】:2020-06-08 13:14:59
【问题描述】:

当我运行以下代码时出现错误。

#include <uapi/linux/utsname.h>
#include <linux/pid_namespace.h>

struct uts_namespace {
    struct kref kref;
    struct new_utsname name;
};

static __always_inline char * get_task_uts_name(struct task_struct *task){
    return task->nsproxy->uts_ns->name.nodename;
}

int cmpNamespace(void *ctx) {
  struct task_struct *task;
  task = (struct task_struct *)bpf_get_current_task();

  if (strcmp(get_task_uts_name(task),"namespace")==0){

      ...

  }
  return 0;
}

错误:

bpf: Failed to load program: Invalid argument
unknown opcode 00
processed 0 insns (limit 1000000) max_states_per_insn 0 total_states 0 peak_states 0 mark_read 0

HINT: The 'unknown opcode' can happen if you reference a global or static variable, or data in read-only section. For example, 'char *p = "hello"' will result in p referencing a read-only section, and 'char p[] = "hello"' will have "hello" stored on the stack.

但这很好用

int cmpNamespace(void *ctx) {
  char * test = "aaaa";

  if (strcmp(test,"namespace")==0){

      ...

  }
  return 0;
}

谁能告诉我为什么会发生这种情况以及我该如何纠正它? 我正在使用 python bcc 来挂钩函数。

谢谢!

【问题讨论】:

    标签: bpf ebpf bcc-bpf


    【解决方案1】:

    问题是您使用的是strcmpBPF 程序不能使用 libc 中的函数。

    您的第二个示例可能有效,因为编译器能够对其进行优化并删除对strcmp 的调用。由于这两个参数在编译时都是已知的,因此无需使用strcmp 来知道它们是否相等。

    正如@Qeole 在 cmets 中指出的那样,您可以改用__builtin_memcmp(),因为您知道其中一个字符串的大小,并且只是想知道它们是否相等。 p>

    【讨论】:

    • 感谢@pchaigno 的快速回复,有道理!!是否有其他方法可以将 get_task_uts_name(task) 中的字符串与编译时已知的字符串进行比较?
    • 这在很大程度上取决于您要支持哪个内核,字符串的最大长度是多少等。在最新的内核上,有一些对有界循环的支持,因此您可以编写自己的 @ 987654325@。在较旧的内核 (strcmp,这可能会使您的 BPF 程序太长或太复杂。
    • __builtin_memcmp() 可用,也可能会有所帮助。
    猜你喜欢
    • 2013-07-28
    • 1970-01-01
    • 2021-09-04
    • 2012-10-06
    • 2019-01-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多