LINUX.ORG.RU

о баге в openssl и прочих переполнениях буфера


1

2

Помнится, на архитектуре i386 была возможнсть использовать не только страничную, но и сегментную организацию памяти, а за счет таблицы LDT можно в каждой программе иметь кажется 4096 (или сколько-то там) сегментов памяти. Вылезание за их пределы приводило к ошибке. По-идее, это позволяет существенно ограничить ущерб от переполнения буфера.

почему же от этого отказались?

Перемещено beastie из talks

★★★★★

за счет таблицы LDT можно в каждой программе иметь кажется 4096 (или сколько-то там) сегментов памяти

Ты правда думаешь, что всем программам хватит 4096 сегментов (или даже 65536)?

tailgunner ★★★★★
()
Ответ на: комментарий от tailgunner

Для буферов, в которые читается извне и есть шанс использования переполнения буфера - вполне должно хватить большинству.

cvs-255 ★★★★★
() автор топика
Ответ на: комментарий от cvs-255

сколько нужно одному приложению буферов для I/O?

Из-за твоей общей упоротости я не стану спрашивать, почему ты решил контролировать только I/O.

tailgunner ★★★★★
()
Ответ на: комментарий от tailgunner

Удаленный злоумышленник сперва взаимодействует с I/O программы.

Баг в openssl был именно такой, емнип.

cvs-255 ★★★★★
() автор топика

В malloc-е уже есть защита от переполнения буфера. OpenSSL предусмотрительно написал workaround, чтобы эта защита не работала. Уж насколько я скептичен по отношению к теориям заговора, но это или крайняя степень безалаберности, или нет.

LibreSSL пока что видится интересной альтернативой. Если его разработчики будут разумны, то OpenSSL умрёт, как в своё время умер XFree и туда ему и дорога.

Legioner ★★★★★
()

\\вернул ТСу к нику комментарий, который был ранее.

dk-
()
Ответ на: комментарий от Legioner

В malloc-е уже есть защита от переполнения буфера.

как именно реализовано?

cvs-255 ★★★★★
() автор топика
Ответ на: комментарий от Legioner

В malloc-е уже есть защита от переполнения буфера.

#include <stdlib.h>
#include <stdio.h>

int main(void)
{
        char *a=malloc(4);
        a[4] = 'q';
        a[5] = 'q';
        a[6] = 0;

        printf("%s\n", &(a[4]));

        free(a);
        return 0;
}

что у тебя пишет

cvs-255 ★★★★★
() автор топика
Ответ на: комментарий от Legioner

В malloc-е уже есть защита от переполнения буфера. OpenSSL предусмотрительно написал workaround, чтобы эта защита не работала

Еще одному Мойша напел Шаляпина.

tailgunner ★★★★★
()
Ответ на: комментарий от tailgunner

"...workaround, одним из побочных эффектов которого было выключение защиты malloc в системах, где такая она предусмотрена и работает."

Так лучше?

Arrest
()
Ответ на: комментарий от Arrest

"...workaround, одним из побочных эффектов которого было выключение защиты malloc в системах, где такая она предусмотрена и работает."

Так лучше?

Нет. Во-первых, по уверениям разрабов OpenSSL, этот workaround обычно отключен; во-вторых, сабжевая уязвимость - это не совсем переполнение буфера, это доступ за границу буфера _на чтение_ - мне неизвестны malloc, которые это блокируют.

tailgunner ★★★★★
()
Ответ на: комментарий от tailgunner

доступ за границу буфера _на чтение_ - мне неизвестны malloc, которые это блокируют

#include <sys/param.h>
#include <assert.h>
#include <stdlib.h>
#include <stdio.h>

int 
main(void)
{
        char *s;

        s = malloc(PAGE_SIZE);
        assert(s);

        printf("%x\n", s[PAGE_SIZE]);

        free(s);

        return 0;
}
$ make m && ./m
cc -O2 -pipe -o m m.c 
Segmentation fault (core dumped)
beastie ★★★★★
()
Ответ на: комментарий от Arrest

Guard page без доступа на чтение может поймать и это.

Может. Но AFAIK даже в OpenBSD эта опция по умолчанию отключена, и в любом случае данные от конца блока до начала guard page доступны.

tailgunner ★★★★★
()
Ответ на: комментарий от tailgunner

Нету его, нету. ;) Это per-default.

$ env | grep -c MALLOC_OPTIONS
0
$ stat /etc/malloc.conf
stat: cannot stat `/etc/malloc.conf': No such file or directory

Но был всё равно уязвим, т.к. это работает только на границах страниц, если я ничего не путаю.

beastie ★★★★★
()
Ответ на: комментарий от Legioner

тогда я вывалюсь за пределы страницы и получу segfault. Это с самим malloc никак не связано, а реализовано в менеджере памяти в ядре.

cvs-255 ★★★★★
() автор топика

потому что пришлось бы работать с 48 битными указателями и вообще неудобно

Harald ★★★★★
()
Ответ на: комментарий от cvs-255

И в тоже время OpenBSD это ловит, а Linux вот нет.

UPD: обновил для портабельности:

#include <assert.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>

int 
main(void)
{
        char *s;
        size_t sz = sysconf(_SC_PAGESIZE);

        s = malloc(sz);
        assert(s);

        printf("%x\n", s[sz]);

        free(s);

        return 0;
}

$ uname -a && make m && ./m 
OpenBSD dim13.org 5.4 GENERIC.MP#41 amd64
cc -O2 -pipe -o m m.c 
Segmentation fault (core dumped)
$ uname -a && make m && ./m
Linux otto 3.2.0-4-amd64 #1 SMP Debian 3.2.51-1 x86_64 GNU/Linux
cc     m.c   -o m
0

Вот так то.

beastie ★★★★★
()
Последнее исправление: beastie (всего исправлений: 1)
Ответ на: комментарий от tailgunner

Это было поведение по умолчанию. Заметь, что я аллоцировал целую страницу (4096 байт), вышел за пределы и уткнулся в guard-page. Но опциями можно повключать гораздо больше и ловить оно будет соответственно больше.

beastie ★★★★★
()
Ответ на: комментарий от beastie

Ты хочешь сказать, что в linux не ловится доступ к несуществующей странице?

Скорее всего в linux идет несколько страниц подряд, а в openbsd нет, потому в linux и не вываливаешься за пределы доступного адресного пространства.

cvs-255 ★★★★★
() автор топика
Ответ на: комментарий от ncrmnt

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

cvs-255 ★★★★★
() автор топика
Ответ на: комментарий от cvs-255

Скорее всего в linux идет несколько страниц подряд, а в openbsd нет, потому в linux и не вываливаешься за пределы доступного адресного пространства.

Даже если это так — то это уже жирный bug.

beastie ★★★★★
()
Ответ на: комментарий от beastie

если это и bug, то баг архитектуры x86(-64). Так как других способов отловить переполнение, кроме как если оно приведет к вываливанию за пределы доступного адресного пространства процесса, нет.

cvs-255 ★★★★★
() автор топика
Ответ на: комментарий от cvs-255

Эм? Но другие ведь это ловят? Ловят! Дак при чём тут архитектура? Отмазка не засчитанна. На пересдачу. ☺

beastie ★★★★★
()
Ответ на: комментарий от beastie

Они точно также плохо ловят, только когда вываливается за пределы адресного пространства. Оно у них чуть по другому организовано, так что «порог срабатывания» ниже, но нормальной защиты буфера от переполнения там не реализовано и не может быть реализовано, т.к. это должно делаться на уровне MMU, который есть часть процессора.

Может быть, это возможно сделать через команды виртуализации, но это само по себе серьезно усложнит дело

Кстати, я слышал, что в эльбрусах это таки сделали.

cvs-255 ★★★★★
() автор топика
Последнее исправление: cvs-255 (всего исправлений: 1)
Ответ на: комментарий от tailgunner

С какого времени?

# ./m      
Segmentation fault (core dumped) 
# uname -a 
OpenBSD <censored> 4.6 GENERIC.MP#89 i386
# env | grep MALLOC_OPTIONS
# stat /etc/malloc.conf     
stat: /etc/malloc.conf: No such file or directory
OpenBSD 4.6
Released Oct 18, 2009
Deleted
()
Ответ на: комментарий от Deleted

Даже еще раньше

# ./m
Segmentation fault (core dumped) 
# uname -a             
OpenBSD <censored> 3.9 GENERIC#617 i386
OpenBSD 3.9
Released May 1, 2006
Deleted
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.