Путаница в CVE-2009-0029: Linux Kernel небезопасно 64-битный системный вызов

Вот обзор CVE-2009-0029:

ABI в ядре Linux 2.6.28 и более ранних версиях на 64-разрядных платформах s390, powerpc, sparc64 и mips требует, чтобы 32-разрядный аргумент в 64-разрядном регистре был надлежащим образом расшифрован при отправке из приложения пользовательского режима, но не может проверить это, что позволяет местным пользователям вызвать отказ в обслуживании (сбой) или, возможно, получить привилегии с помощью обработанного системного вызова.

И как это может произойти? Почему ошибка не влияет на x86_64 или Intel Itanium?

И ядро Linux исправляет этот недостаток, заменяя определение marco __SYSCALL_DEFINEx ниже

#define __SYSCALL_DEFINEx(x, name, ...) \
 asmlinkage long sys##name(__SC_DECL##x(__VA_ARGS__))

в

#define __SYSCALL_DEFINEx(x, name, ...) \
 asmlinkage long sys##name(__SC_DECL##x(__VA_ARGS__)); \
 static inline long SYSC##name(__SC_DECL##x(__VA_ARGS__)); \
 asmlinkage long SyS##name(__SC_LONG##x(__VA_ARGS__)) \
 { \
 __SC_TEST##x(__VA_ARGS__); \
 return (long) SYSC##name(__SC_CAST##x(__VA_ARGS__)); \
 } \
 SYSCALL_ALIAS(sys##name, SyS##name); \
 static inline long SYSC##name(__SC_DECL##x(__VA_ARGS__))

Я действительно не знаю, как он может решить эту проблему?

1 ответ

На этих архитектурах 32-разрядные значения обрабатываются с 64-разрядными регистрами. Поэтому, если функция имеет 32-битный параметр int, злоумышленник может поместить значение в этот регистр, что будет больше, чем это возможно для int.

Кроме того, поскольку компилятор "знает", что int не может иметь значение, которое не вписывается в переменную int, нелегко проверить, находится ли значение вне диапазона, потому что компилятор может оптимизировать эту проверку.

Чтобы обойти эту проблему, то SyS_xxx функция сначала предполагает, что все его параметры являются 64-битными long значениями, а затем явно преобразует их к фактическому типу.

В x86_64 и Itanium процессор игнорирует верхние биты регистра при доступе к 32-битным значениям.

licensed under cc by-sa 3.0 with attribution.