Failure to compare strings with eBPF

家住魔仙堡 提交于 2021-02-11 17:01:07

问题


When I run the following code I get an error.

#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;
}

Error:

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.

But this works just fine

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

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

      ...

  }
  return 0;
}

Can anyone tell me why this is happening and how I could go about correcting it ? I am using python bcc to hook the function.

Thanks!


回答1:


The issue is that you are using strcmp. BPF programs cannot use functions from the libc.

Your second example probably works because the compiler is able to optimize it and remove the call to strcmp. Since both arguments are known at compile-time, there's no need to use strcmp to know if they are equal.

As pointed out by @Qeole in comments, you can use __builtin_memcmp() instead, since you know the size of one of your strings and are only trying to know if they are equal.



来源:https://stackoverflow.com/questions/60383861/failure-to-compare-strings-with-ebpf

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!