Старый 25.03.2013, 14:26   #1
SynQ
 
Регистрация: 11.07.2010
Сообщений: 940
Репутация: 351
По умолчанию Примеры уязвимостей в коде.

Встретил занятный код в ядре линукса, возможно будет интересно.

http://lxr.linux.no/#linux+v3.8/fs/select.c#L816

Код:
 816 int do_sys_poll(struct pollfd __user *ufds, unsigned int nfds,
 817                 struct timespec *end_time)
 818 {
 819        struct poll_wqueues table;
 820        int err = -EFAULT, fdcount, len, size;
 821        /* Allocate small arguments on the stack to save memory and be
 822           faster - use long to make sure the buffer is aligned properly
 823           on 64 bit archs to avoid unaligned access */
 824        long stack_pps[POLL_STACK_ALLOC/sizeof(long)];
 825        struct poll_list *const head = (struct poll_list *)stack_pps;
 826        struct poll_list *walk = head;
 827        unsigned long todo = nfds;
 828
 829        if (nfds > rlimit(RLIMIT_NOFILE))
 830                return -EINVAL;
 831
 832        len = min_t(unsigned int, nfds, N_STACK_PPS);
 833        for (;;) {
 834                walk->next = NULL;
 835                walk->len = len;
 836                if (!len)
 837                        break;
 838
 839                if (copy_from_user(walk->entries, ufds + nfds-todo,
 840                                        sizeof(struct pollfd) * walk->len))
 841                        goto out_fds;
 842
 843                todo -= walk->len;
 844                if (!todo)
 845                        break;
 846
 847                len = min(todo, POLLFD_PER_PAGE);
 848                size = sizeof(struct poll_list) + sizeof(struct pollfd) * len;
 849                walk = walk->next = kmalloc(size, GFP_KERNEL);
 850                if (!walk) {
 851                        err = -ENOMEM;
 852                        goto out_fds;
 853                }
 854        }
 855
 856        poll_initwait(&table);
 857        fdcount = do_poll(nfds, head, &table, end_time);
 858        poll_freewait(&table);
 859
 860        for (walk = head; walk; walk = walk->next) {
 861                struct pollfd *fds = walk->entries;
 862                int j;
 863
 864                for (j = 0; j < walk->len; j++, ufds++)
 865                        if (__put_user(fds[j].revents, &ufds->revents))
 866                                goto out_fds;
 867        }
Вызвав сисколл poll с параметрами ufds (указатель) и nfds (unsigned int), попадаем в функцию do_sys_poll() с этими же параметрами.

Здесь могла бы быть неплохая, пусть и не из легких, бага, если бы строка 835 располагась всего двумя строчками ниже
Тогда при передаче nfds = 0, из цикла сразу бы происходил выход, не вызывая copy_from_user(), которая проверяет "правильность" переданного указателя ufds, и ниже происходил вызов __put_user(), которая такой проверки не делает.

Получили бы запись неопределённых данных (из stack_pps[]) по любому желаемому адресу в ядре.
С неопределённостью можно бороться, например, предварительным массажем стека.
SynQ вне форума   Ответить с цитированием
Старый 09.10.2015, 13:22   #2
SynQ
 
Регистрация: 11.07.2010
Сообщений: 940
Репутация: 351
По умолчанию

Стандартный security баг в модуле ядра:
http://habrahabr.ru/company/ua-hosting/blog/268409/
SynQ вне форума   Ответить с цитированием
Ответ

Метки
bugs, exploitdev, kernel, linux

Опции темы
Опции просмотра

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

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.

Быстрый переход



Powered by vBulletin® Version 3.8.5
Copyright ©2000 - 2018, Jelsoft Enterprises Ltd. Перевод: zCarot