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 в полной мере.

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. */
]]

Библиотека ffi также даёт возможность создавать объекты, соответствующие известным типам данных Си, и производить с ними различные манипуляции.

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

Реализация

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

/* 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 */

А также декларации ещё нескольких необходимых структур и типов: Также, 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.

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

Примеры

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

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)

Использование препроцессора для извлечения констант из заголовочных файлов:

ffi = require 'ffi'
f = assert(io.popen([[cpp - «EOF | 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))

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

$ 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 '^#'
#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))

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

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


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

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



Plays:97   Comments:0