Advertisement
Advertisement

More Related Content

Slideshows for you(20)

Similar to Как мы учились чинить самолеты в воздухе / Евгений Коломеец (Virtuozzo)(20)

Advertisement

More from Ontico(20)

Recently uploaded(20)

Advertisement

Как мы учились чинить самолеты в воздухе / Евгений Коломеец (Virtuozzo)

  1. Как мы учились чинить самолеты в воздухе Евгений Коломеец eugene.kolomeetz@gmail.com Copyright © 2017 Virtuozzo. All rights reserved.
  2. Обзор ➢ Что такое “Live Patching”? ➢ Для чего это нужно? ➢ Состояние процесса ➢ Что мы можем патчить? ➢ Когда патч может быть приложен? ➢ Структура бинарного патча ➢ Динамические библиотеки ➢ Символы ELF ➢ Приложение патча ➢ Создание патча 2
  3. Что такое “Live Patching”? ➢ Замена части “логики” в процессе ➢ Сохраняя состояние процесса ➢ Делая это безопасно 3
  4. Для чего это нужно? ➢ Уменьшение времени простоя из-за критических уязвимостей за счёт: ➢Отсутствия рестарта сервисов ➢Нет необходимости в миграции ➢ Примеры утилит для live patching: ➢Kpatch, Kgraft, Ksplice для ядра ➢Pannus, Ksplice, LibCare для юзерспейса 4
  5. Состояние процесса ➢ “Карточный домик”: ➢части сильно связаны между собой ➢ Изменяется во время выполнения ➢ Состоит из: ➢Статически выделенных переменных ➢Динамически выделенных переменных ➢Стека 5
  6. Что мы можем патчить? ➢ Не любые изменения кода ➢ Фундаментальные ограничения: ➢Изменившийся размер данных ➢Другой порядок полей в структуре ➢ Требуется ревью кода :( 6
  7. Когда патч может быть приложен? ➢ Требуется остановка процесса ➢ Не в любой момент времени: ➢Изменяемый код может выполняться ➢На него могут быть ссылки на стеке ➢ Необходим анализ стека: ➢ “поймать” процесс в “подходящем” месте 7
  8. Когда патч может быть приложен? 8 g(void) { . . . f(); } f(void) { . . . }
  9. Когда патч может быть приложен? 9 g(void) { . . . f(); } f(void) { . . . } Поток остановлен здесь
  10. Когда патч может быть приложен? 10 g(void) { . . . f(); } f(void) { . . . } Поток остановлен здесь f()Вызывается новая версия
  11. Когда патч может быть приложен? 11 g(void) { . . . f(); } f(void) { . . . } Поток остановлен здесь f()Вызывается новая версия ,Возврат по адресу сохранённому на стеке
  12. Когда патч может быть приложен? 12 g(void) { . . . f(); } f(void) { . . . } Поток остановлен здесь f()Вызывается новая версия Исполняется код старой версии f() ,Возврат по адресу сохранённому на стеке
  13. Структура бинарного патча ➢ Код заменяется на уровне функций: ➢Надёжно ➢Просто ➢ Формат: ELF dynamic shared object ➢Загружается в адресное пространство процесса ➢Дополнительная секция с метаданными ➢ Список адресов символов ➢ build-id 13
  14. Динамическая библиотека: исходный код 14 extern int var; int f(void) { return var + 1; }
  15. Динамическая библиотека: структуры данных ELF 15 Global offset table Code f(void) Address slot
  16. Динамическая библиотека: структуры данных ELF 16 Relocation table Global offset table Symbol table Code f(void) Address slot "var" idx offsetaddend
  17. Символы ELF: static 17 a.c b.c libx.so static int var; static int var; f(void) g(void)
  18. Символы ELF: default 18 libx.so int var; f(void)
  19. Символы ELF: default 19 libx.so int var; f(void) g(void) liby.so
  20. Символы ELF: interposition 20 libx.so int var; f(void) int var; g(void) liby.so
  21. Символы ELF: hidden 21 libx.so int var; f(void) int var __attribute__ ((visibility ("hidden")); g(void) liby.so
  22. Метаданные патча 22 Index in patch symbol table Symbol address in target 1 0x1234 2 0x5678
  23. Метаданные патча 23 Function address in target Function address in patch 0x1234 0x5678 0xABCD 0x4321
  24. Приложение патча 24 Target process f(void) int var
  25. Приложение патча 25 Target process f(void) int var Patch object Address slot f(void)
  26. &var Приложение патча 26 Target process f(void) int var Patch object Address slot f(void)
  27. &var JUMP Приложение патча 27 Target process f(void) int var Patch object Address slot f(void)
  28. Создание патча: исходный код 28 /* Original code, in file a.c */ static int var; static int f(void) { printf("%dn", var); return var--; }
  29. Создание патча: исходный код 29 /* Desired code */ static int var; static int f(void) { printf("%dn", var); return var++; }
  30. Создание патча: исходный код 30 /* Patch code, in file patch.c */ #include <vzp.h> VZP_FILE("a.c") VZP_STATIC_VAR_REF(int, var); static int f(void) { printf("%dn", var); return var++; }
  31. Создание патча: сборка 31 # gcc -fpic -shared -O0 -g patch.c -o libpatch.so
  32. Создание патча: сборка 32 # gcc -fpic -shared -O0 -g patch.c -o libpatch.so # python nsbgen.py generate /path/to/binary libpatch.so
  33. Создание патча: сборка 33 # gcc -fpic -shared -O0 -g patch.c -o libpatch.so # python nsbgen.py generate /path/to/binary libpatch.so # nsb -f libpatch.so -p 1234
  34. Заключение ➢ Требуется ревью кода :) 34
  35. Заключение ➢ Требуется ревью кода :) ➢ Используется стандартное ядро! 35
  36. Заключение ➢ Требуется ревью кода :) ➢ Используется стандартное ядро! ➢ Бинарники собираются как обычно! 36
  37. Заключение ➢ Требуется ревью кода :) ➢ Используется стандартное ядро! ➢ Бинарники собираются как обычно! ➢ Libcompel используется для: ➢Останова процесса ➢Перезапуска процесса ➢Загрузки кода патча ➢Source: https://github.com/xemul/criu/tree/criu-dev 37
  38. Заключение ➢ Требуется ревью кода :) ➢ Используется стандартное ядро! ➢ Бинарники собираются как обычно! ➢ Libcompel используется для: ➢Останова процесса ➢Перезапуска процесса ➢Загрузки кода патча ➢Source: https://github.com/xemul/criu/tree/criu-dev ➢ Libunwind используется для анализа стека ➢Source: http://git.savannah.gnu.org/cgit/libunwind.git 38
  39. Заключение ➢ Требуется ревью кода :) ➢ Используется стандартное ядро! ➢ Бинарники собираются как обычно! ➢ Libcompel используется для: ➢Останова процесса ➢Перезапуска процесса ➢Загрузки кода патча ➢Source: https://github.com/xemul/criu/tree/criu-dev ➢ Libunwind используется для анализа стека ➢Source: http://git.savannah.gnu.org/cgit/libunwind.git ➢ Source: https://github.com/virtuozzo/nsb 39
  40. Thanks for your attention. Q&A. Thanks!
Advertisement