Tl; dr: Массив char, к которому обращается мой код, который ранее указывал на ожидаемое строковое значение, теперь содержит неожиданные символы перед строкой. Моя текущая теория заключается в том, что это как-то вызвано изменением выравнивания массива символов, и я пытаюсь выяснить, прав ли я и как это исправить.
Я пытаюсь сохранить Linux модуль ядра, написанный на C ++. Прошло много времени с тех пор, как я работал в C ++, поэтому я немного застрял в том, что вижу в данный момент.
У нас есть отдельная утилита вне модуля ядра, которая записывает ключ в связку ключей ядра. Позже модуль ядра проверяет это и сравнивает его с ожидаемым значением ключа. Вот метод поиска:
#include <linux/key.h>
#include <keys/user-type.h>
int read_key(char *key_desc, char *expected_key) {
struct key *key;
struct user_key_payload *key_payload;
key = request_key(&key_type_user, key_desc, NULL);
key_payload = rcu_dereference(key->payload.data[0]);
return strncmp(key_payload->data, expected_key, key_payload->datalen));
}
Этот код в настоящее время работает на большинстве версий ядра, которые мы поддерживаем. Но недавно было обновление ядра в одной конкретной ОС, и теперь мой вызов strncmp не может найти соответствие. Кажется, что данные каким-то образом смещены. Например, если key_payload-> datalen = 16 и Ожидаемый_ключ = "1234567890123456", то key_payload-> data = "abcdef1234567890123456". Что, поскольку я сравниваю первые 16 символов, очевидно, не будет совпадать, но будет, если вместо этого я начну с key_payload-> data [6]. Пока что key_payload-> datalen по-прежнему является правильной ожидаемой длиной строки. Это просто key_payload-> data, которые изменились в новой версии ядра.
Я рассмотрел несколько патчей в новом ядре, я думаю, что это может быть связано с проблемой. Одно очевидное отличие, которое я обнаружил, это это . До патча объект user_key_payload from выглядел следующим образом:
struct user_key_payload {
struct rcu_head rcu; /* RCU destructor */
unsigned short datalen; /* length of this data */
char data[0]; /* actual data */
};
Но после этого он выглядит следующим образом:
struct user_key_payload {
struct rcu_head rcu; /* RCU destructor */
unsigned short datalen; /* length of this data */
char data[0] __aligned(__alignof__(u64)); /* actual data */
};
Я не знаю, действительно ли это является причиной моей проблемы, но кажется, как очевидное место, чтобы начать искать. Я никогда не работал с выровненными или выровненными ключевыми словами прежде. Я прочитал несколько статей о выравнивании, но все это намного ниже, чем то, с чем я работал уже несколько лет. Кто-нибудь знает, есть ли способ, которым выравнивание user_key_payload.data может испортить ожидаемый адрес памяти ключевых данных, и как выяснить, где мои ожидаемые данные на самом деле?