Неспособность сравнить строки с eBPF - PullRequest
0 голосов
/ 25 февраля 2020

Когда я запускаю следующий код, я получаю сообщение об ошибке.

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

Может кто-нибудь скажите мне, почему это происходит, и как я мог go исправить это? Я использую python b cc для подключения функции.

Спасибо!

1 Ответ

2 голосов
/ 25 февраля 2020

Проблема в том, что вы используете strcmp. BPF-программы не могут использовать функции из библиотеки c.

Ваш второй пример, вероятно, работает, потому что компилятор может оптимизировать его и удалить вызов strcmp. Поскольку оба аргумента известны во время компиляции, нет необходимости использовать strcmp, чтобы узнать, равны ли они.

Как указано @Qeole в комментариях, вы можете использовать __builtin_memcmp() вместо , поскольку вы знаете размер одной из ваших строк и пытаетесь узнать только, равны ли они.

...