В ядре Linux обнаружена и устранена уязвимость:
Исправлен двойной сбой SIGFPE на parisc
Camm заметил, что на parisc исключение SIGFPE приводит к краху приложения со вторым SIGFPE в обработчике сигнала. Dave проанализировал это и обнаружил, что это происходит потому, что glibc использует хранилище с плавающей запятой двойного слова для атомарного обновления дескрипторов функций. В результате ленивой привязки мы почти сразу же сталкиваемся с хранилищем с плавающей запятой в fpe_func [1].
Когда установлен бит T, происходит исключение assist exception trap, когда сопроцессор встречает любую инструкцию с плавающей запятой, кроме двойного хранилища регистра %fr0. Последнее отменяет все ожидающие ловушки. Давайте исправим это, очистив бит Trap (T) в регистре статуса FP перед возвратом в обработчик сигнала в пользовательском пространстве.
Проблема может быть воспроизведена с помощью этой тестовой программы:
root@parisc:~# cat fpe.c
static void fpe_func(int sig, siginfo_t *i, void *v) {
sigset_t set;
sigemptyset(&set);
sigaddset(&set, SIGFPE);
sigprocmask(SIG_UNBLOCK, &set, NULL);
printf("GOT signal %d with si_code %ld\n", sig, i->si_code);
}
int main() {
struct sigaction action = {
.sa_sigaction = fpe_func,
.sa_flags = SA_RESTART|SA_SIGINFO };
sigaction(SIGFPE, &action, 0);
feenableexcept(FE_OVERFLOW);
return printf("%lf\n",1.7976931348623158E308*1.7976931348623158E308);
}
root@parisc:~# gcc fpe.c -lm
root@parisc:~# ./a.out
Floating point exception
root@parisc:~# strace -f ./a.out
execve("./a.out", ["./a.out"], 0xf9ac7034 /* 20 vars */) = 0
getrlimit(RLIMIT_STACK, {rlim_cur=8192*1024, rlim_max=RLIM_INFINITY}) = 0
...
rt_sigaction(SIGFPE, {sa_handler=0x1110a, sa_mask=[], sa_flags=SA_RESTART|SA_SIGINFO}, NULL, 8) = 0
--- SIGFPE {si_signo=SIGFPE, si_code=FPE_FLTOVF, si_addr=0x1078f} ---
--- SIGFPE {si_signo=SIGFPE, si_code=FPE_FLTOVF, si_addr=0xf8f21237} ---
+++ killed by SIGFPE +++
Floating point exception
Источники:
- [1] https://git.kernel.org/stable/c/ec4584495868bd465fe60a3f771915c0e7ce7951
- [2] https://git.kernel.org/stable/c/6c639af49e9e5615a8395981eaf5943fb40acd6f
- [3] https://git.kernel.org/stable/c/6a098c51d18ec99485668da44294565c43dbc106
- [4] https://git.kernel.org/stable/c/cf21e890f56b7d0038ddaf25224e4f4c69ecd143
- [5] https://git.kernel.org/stable/c/df3592e493d7f29bae4ffde9a9325de50ddf962e
Нажмите для просмотра деталей