问题
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