Lua-скриптинг в strace (Виктор Крапивенский, OSSDEVCONF-2017)

Материал из 0x1.tv

Докладчик
Виктор Крапивенский.jpg
Виктор Крапивенский

strace — инструмент для отслеживания взаимодействия пользовательских процессов и ядра Linux: системных вызовов, сигналов и изменений состояния процесса. Ранее, в рамках одного из проектов GSoC 2016, в strace была добавлена функция fault injection, которая позволяет подменять результаты системных вызовов.

В рамках проекта GSoC 2017 в strace появилась поддержка Lua-скриптинга, которая позволяет не только производить фильтрацию и подмену системных вызовов с большей гибкостью, но и производить success injection с сохранением семантики системного вызова, которая, в частности, может заключаться в записи определённых данных в адресное пространство процесса.

Видео

on youtube

Посмотрели доклад? Понравился? Напишите комментарий! Не согласны? Тем более напишите.

Презентация

Lua-скриптинг в strace (Виктор Крапивенский, OSSDEVCONF-2017).pdf Lua-скриптинг в strace (Виктор Крапивенский, OSSDEVCONF-2017).pdf Lua-скриптинг в strace (Виктор Крапивенский, OSSDEVCONF-2017).pdf Lua-скриптинг в strace (Виктор Крапивенский, OSSDEVCONF-2017).pdf Lua-скриптинг в strace (Виктор Крапивенский, OSSDEVCONF-2017).pdf Lua-скриптинг в strace (Виктор Крапивенский, OSSDEVCONF-2017).pdf Lua-скриптинг в strace (Виктор Крапивенский, OSSDEVCONF-2017).pdf Lua-скриптинг в strace (Виктор Крапивенский, OSSDEVCONF-2017).pdf Lua-скриптинг в strace (Виктор Крапивенский, OSSDEVCONF-2017).pdf Lua-скриптинг в strace (Виктор Крапивенский, OSSDEVCONF-2017).pdf Lua-скриптинг в strace (Виктор Крапивенский, OSSDEVCONF-2017).pdf Lua-скриптинг в strace (Виктор Крапивенский, OSSDEVCONF-2017).pdf Lua-скриптинг в strace (Виктор Крапивенский, OSSDEVCONF-2017).pdf Lua-скриптинг в strace (Виктор Крапивенский, OSSDEVCONF-2017).pdf Lua-скриптинг в strace (Виктор Крапивенский, OSSDEVCONF-2017).pdf Lua-скриптинг в strace (Виктор Крапивенский, OSSDEVCONF-2017).pdf Lua-скриптинг в strace (Виктор Крапивенский, OSSDEVCONF-2017).pdf Lua-скриптинг в strace (Виктор Крапивенский, OSSDEVCONF-2017).pdf Lua-скриптинг в strace (Виктор Крапивенский, OSSDEVCONF-2017).pdf Lua-скриптинг в strace (Виктор Крапивенский, OSSDEVCONF-2017).pdf Lua-скриптинг в strace (Виктор Крапивенский, OSSDEVCONF-2017).pdf Lua-скриптинг в strace (Виктор Крапивенский, OSSDEVCONF-2017).pdf Lua-скриптинг в strace (Виктор Крапивенский, OSSDEVCONF-2017).pdf Lua-скриптинг в strace (Виктор Крапивенский, OSSDEVCONF-2017).pdf Lua-скриптинг в strace (Виктор Крапивенский, OSSDEVCONF-2017).pdf Lua-скриптинг в strace (Виктор Крапивенский, OSSDEVCONF-2017).pdf Lua-скриптинг в strace (Виктор Крапивенский, OSSDEVCONF-2017).pdf Lua-скриптинг в strace (Виктор Крапивенский, OSSDEVCONF-2017).pdf Lua-скриптинг в strace (Виктор Крапивенский, OSSDEVCONF-2017).pdf Lua-скриптинг в strace (Виктор Крапивенский, OSSDEVCONF-2017).pdf Lua-скриптинг в strace (Виктор Крапивенский, OSSDEVCONF-2017).pdf Lua-скриптинг в strace (Виктор Крапивенский, OSSDEVCONF-2017).pdf Lua-скриптинг в strace (Виктор Крапивенский, OSSDEVCONF-2017).pdf Lua-скриптинг в strace (Виктор Крапивенский, OSSDEVCONF-2017).pdf Lua-скриптинг в strace (Виктор Крапивенский, OSSDEVCONF-2017).pdf Lua-скриптинг в strace (Виктор Крапивенский, OSSDEVCONF-2017).pdf

Thesis

Обзор

В рамках одного из проектов GSoC 2016 в strace была добавлена поддержка подмена кодов возврата системных вызовов.

Была реализована возможность подменять коды возврата произвольного подмножества системных вызовов; при этом, логика ограничивалась лишь счётчиком — можно было подменять результаты всех системных вызовов, только N-ного, либо N-ного и далее каждого K-того.

При этом, не было возможности производить success injection с сохранением семантики системного вызова, которая, в частности, может заключаться в записи определённых данных в адресное пространство процесса.

В этом году, strace получил поддержку Lua(JIT)-скриптинга, что открывает новые возможности в этом направлении.

Lua, LuaJIT и FFI

Lua — легковесный встраиваемый скриптовый язык программирования.

LuaJIT — Just-In-Time компилятор для Lua, называемый «одной из самых производительных реализаций динамических языков программирования».

LuaJIT также предоставляет набор библиотек и расширений, отсутствующих в стандартной поставке Lua.

Наиболее важна для strace библиотека ffi, которая позволяет взаимодействовать с кодом на Си и включает в себя парсер деклараций типов и констант, поддерживающий, за небольшими незначительными исключениями, C99 в полной мере.

<source lang="C"> ffi.cdef[[ typedef struct foo { int a, b; } foo_t; // Declare a struct and typedef. int dofoo(foo_t *f, int n); /* Declare an external C function. */ ]] </source> Библиотека ffi также даёт возможность создавать объекты, соответствующие известным типам данных Си, и производить с ними различные манипуляции.

Существуют также отдельные реализации библиотеки ffi для обычной реализации Lua. Они также поддерживаются strace.

Реализация

strace «скармливает» библиотеке ffi декларацию типа struct tcb — типа, поля которого совпадают с первыми полями структуры, в которой strace хранит информацию о текущем состоянии системного вызова для каждого процесса:

<source lang="C"> /* Trace control block */ struct tcb {

int pid;                             /* Tracee's PID */
unsigned long u_error;               /* Error code */
kernel_ulong_t scno;                 /* System call number */
kernel_ulong_t u_arg[/* MAX_ARGS */];/* System call arguments */
kernel_ulong_t u_rval;               /* Return value */
unsigned int currpers;               /* Current personality */

</source>

А также декларации ещё нескольких необходимых структур и типов: Также, strace, через модуль strace.C, предоставляет функции и константы, необходимые для обеспечения функциональности скриптинга.

После этого загружается библиотека, написанная на Lua, предоставляющая удобные обёртки над этими функциями и константами.

Основное взаимодействие с strace осуществляется через функции strace.next_sc, strace.C.monitor и strace.C.monitor_all.

strace хранит множество тех системных вызовов, которые нужно возвратить из strace.next_sc при входе в системный вызов, и множество тех, которые нужно возвратить по выходу из него.

Изначально оба этих множества пусты; библиотека или пользователь могут выбрать несколько системных вызовов по номеру для мониторинга с помощью strace.C.monitor, или же потребовать информировать скрипт обо всех системных вызовах с помощью strace.C.monitor_all.

Библиотека предоставляет более удобный интерфейс информирования о системных вызовах, а именно возможность повесить функцию-обработчик на вход либо выход из системного вызова по его номеру, имени, либо классу системных вызовов.

Примеры

Подсчёт количества порождённых процессов:

<source lang="C"> n = 0 assert(strace.hook({'clone', 'fork', 'vfork'}, 'exiting', function(tcp)

 if tcp.u_rval  = -1 then
   n = n + 1
 end

end)) strace.at_exit(function() print('Processes spawned:', n) end) </source> Использование препроцессора для извлечения констант из заголовочных файлов:

<source lang="C"> ffi = require 'ffi' f = assert(io.popen( grep -v '^#' #define _GNU_SOURCE #include <fcntl.h> enum { f_setpipe_sz = F_SETPIPE_SZ }; EOF, 'r')) ffi.cdef(f:read('*a')) f:close() assert(strace.hook({'fcntl', 'fcntl64'}, 'entering', function(tcp)

 if tcp.u_arg[1] == ffi.C.f_setpipe_sz then
   assert(strace.inject_error('EPERM'))
 end

end)) </source> Использование препроцессора для извлечения определений структур из заголовочных файлов:

$ uname
Linux
$ strace -l pretend-win.lua -e trace=none uname
Windows
+++ exited with 0 +++
$ cat pretend-win.lua
ffi = require 'ffi'
f = assert(io.popen([[cpp - «EOF | grep -v '^#'

<source lang="C">

  1. include <sys/utsname.h>

EOF]], 'r')) ffi.cdef(f:read('*a')) f:close() assert(strace.hook('uname', 'exiting', function(tcp)

 if tcp.u_rval == -1 then
   return
 end
 local u = assert(strace.read_obj(tcp.u_arg[0], 'struct utsname'))
 local s = 'Windows'
 assert(ffi.sizeof(u.sysname) >= #s + 1)
 ffi.copy(u.sysname, s)
 assert(strace.write_obj(tcp.u_arg[0], u))

end)) </source>

Текущее состояние

Правки пока не приняты в strace; текущее состояние проекта можно отслеживать в репозитории [1].

Примечания и ссылки

Lua-скриптинг в strace (Виктор Крапивенский, OSSDEVCONF-2017)!.jpg

Plays:132   Comments:0