首页 > 解决方案 > 无法将字符串与 eBPF 进行比较

问题描述

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

#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 来挂钩该函数。

谢谢!

标签: bpfebpfbcc-bpf

解决方案


问题是您正在使用strcmp. BPF 程序不能使用 libc 中的函数。

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

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


推荐阅读