Strace — новые возможности (Дмитрий Левин, OSSDEVCONF-2017) — различия между версиями

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

(Новая страница: «;{{SpeakerInfo}}: {{Speaker|Дмитрий Левин}} <blockquote> Strace — инструмент для отслеживания и влияния на вза…»)
 
== Thesis ==

=== Введение ===

strace как инструмент мониторинга взаимодействия пользовательских процессов с
ядром существует уже почти 26 лет и широко применяется для диагностики, отладки
и изучения поведения ПО.  Многочисленные параметры управления фильтрацией дают
возможность пользователю strace легко и гибко настраивать отображение системных
вызовов и сигналов.  С каждым выпуском strace таких возможностей становится
больше, а точность отображения  выше.

Начиная с версии 4.13, выпущенной летом прошлого года, расписание выпусков
новых версий strace синхронизировано с расписанием выпусков новых версий ядра
linux.  Таким образом новые интерфейсы, добавляемые в релизы ядра linux,
сопровождаются соответствующими парсерами, добавляемыми в релизы strace.

Помимо многочисленных улучшений отображения системных вызовов, за минувший год
в strace было реализовано много нового и интересного.

=== System Call Specification ===
Синтаксис описания множества системных вызовов существенно расширился:

*  В описании имён системных вызовов теперь поддерживаются регулярные выражения: 
  strace -e trace=/<i>regexp</i>
*  В описании множества системных вызовов поддерживаются описания, которым не соответствует ни одного системного вызова: 
  strace -e trace=?<i>set</i>
*  Имена классов системных вызовов теперь начинаются с префикса %: 
  strace -e trace=%<i>class</i> \\
Прежний способ именования классов без префикса % ещё поддерживается, но уже считается устаревшим.
*  Добавлены новые классы системных вызовов:
;%stat: stat, stat64, oldstat и их вариации;
;%lstat: lstat, lstat64, oldlstat и их вариации;
;%fstat: fstat, fstat64, fstatat64, newfstatat, oldfstat и их вариации;
;%%stat: stat, lstat, fstat, fstatat, statx и их вариации;
;%statfs: эквивалент /\textasciicircum(.*_)?statv?fs;
;%fstatfs: эквивалент /fstatv?fs;
;%statfs: эквивалент /statv?fs|fsstat|ustat.

=== System call tampering и fault injection ===
Механизм syscall fault injection, прототип которого подробно рассматривался на
этой конференции год назад, был доработан и включён в strace, начиная с версии
4.15, выпущенной в декабре прошлого года.  По сравнению с прототипом, синтаксис
syscall fault injection изменился и выглядит следующим образом:

 -e fault=<i>set</i>[:error=<i>errno</i>][:when=<i>expr</i>]

Начиная с версии 4.16, выпущенной в феврале прошлого года, реализован более
общий механизм вмешательства в системные вызовы, который, помимо syscall fault
injection, позволяет осуществлять syscall return value injection и signal
injection.  Интерфейс этого нового механизма выглядит следующим образом:

 -e inject=<i>set</i>[:error=<i>errno</i>|:retval=<i>value</i>][:signal=<i>sig</i>][:when=<i>expr</i>]

=== Netlink socket parsers ===
В strace версии 4.19, выпущенной в начале сентября, реализовано детальное
декодирование трафика, проходящего через netlink sockets, что позволяет
использовать strace для отладки приложений, работающих с netlink-протоколами.
Так, например, может выглядеть вывод парсера трафика семейства NETLINK_ROUTE:

<latex>
{\texttt\tiny
\$ hshrun --mount=/proc -- strace -e trace=sendto,recvmsg ip r l t all \\
\fontsize{4pt}{4pt}\selectfont
sendto(3, \{\{len=40, type=RTM_GETROUTE, flags=NLM_F_REQUEST|NLM_F_DUMP, \\seq=1357924680, pid=0\}, \{rtm_family=AF_UNSPEC, rtm_dst_len=0, rtm_src_len=0, rtm_tos=0,\\ rtm_table=RT_TABLE_UNSPEC, rtm_protocol=RTPROT_UNSPEC, \\rtm_scope=RT_SCOPE_UNIVERSE, rtm_type=RTN_UNSPEC, rtm_flags=0\}, \{nla_len=0, \\nla_type=RTA_UNSPEC\}\}, 40, 0, NULL, 0) = 40 \\
recvmsg(3, \{msg_name=\{sa_family=AF_NETLINK, nl_pid=0, nl_groups=00000000\}, \\msg_namelen=12, msg_iov=[\{iov_base=[\{\{len=60, type=RTM_NEWROUTE, flags=NLM_F_MULTI, seq=1357924680, pid=12345\}, \{rtm_family=AF_INET, rtm_dst_len=32, rtm_src_len=0, rtm_tos=0, rtm_table=RT_TABLE_LOCAL, rtm_protocol=RTPROT_KERNEL, rtm_scope=RT_SCOPE_LINK, rtm_type=RTN_BROADCAST, rtm_flags=0\}, [\{\{nla_len=8, nla_type=RTA_TABLE\}, \\RT_TABLE_LOCAL\}, \{\{nla_len=8, nla_type=RTA_DST\}, 127.0.0.0\}, \{\{nla_len=8, nla_type=\\RTA_PREFSRC\}, 127.0.0.1\}, \{\{nla_len=8, nla_type=RTA_OIF\}, if_nametoindex("lo")\}]\}, \{\{len=60, type=RTM_NEWROUTE, flags=NLM_F_MULTI, seq=1357924680, pid=12345\}, \{rtm_family=\\AF_INET, rtm_dst_len=8, rtm_src_len=0, rtm_tos=0, rtm_table=RT_TABLE_LOCAL, \\rtm_protocol=RTPROT_KERNEL, rtm_scope=RT_SCOPE_HOST, rtm_type=RTN_LOCAL, \\rtm_flags=0\}, [\{\{nla_len=8, nla_type=RTA_TABLE\}, RT_TABLE_LOCAL\}, \{\{nla_len=8, nla_type=\\RTA_DST\}, 127.0.0.0\}, \{\{nla_len=8, nla_type=RTA_PREFSRC\}, 127.0.0.1\}, \{\{nla_len=8, nla_type=\\RTA_OIF\}, if_nametoindex("lo")\}]\}, \{\{len=60, type=RTM_NEWROUTE, flags=NLM_F_MULTI, seq=1357924680, pid=12345\}, \{rtm_family=AF_INET, rtm_dst_len=32, rtm_src_len=0, rtm_tos=0, rtm_table=RT_TABLE_LOCAL, rtm_protocol=RTPROT_KERNEL, rtm_scope=RT_SCOPE_HOST, rtm_type=RTN_LOCAL, rtm_flags=0\}, [\{\{nla_len=8, nla_type=RTA_TABLE\}, \\RT_TABLE_LOCAL\}, \{\{nla_len=8, nla_type=RTA_DST\}, 127.0.0.1\}, \{\{nla_len=8, nla_type=\\RTA_PREFSRC\}, 127.0.0.1\}, \{\{nla_len=8, nla_type=RTA_OIF\}, if_nametoindex("lo")\}]\}, \{\{len=60, type=RTM_NEWROUTE, flags=NLM_F_MULTI, seq=1357924680, pid=12345\}, \{rtm_family=\\AF_INET, rtm_dst_len=32, rtm_src_len=0, rtm_tos=0, rtm_table=RT_TABLE_LOCAL, \\rtm_protocol=RTPROT_KERNEL, rtm_scope=RT_SCOPE_LINK, rtm_type=RTN_BROADCAST, rtm_flags=0\}, [\{\{nla_len=8, nla_type=RTA_TABLE\}, RT_TABLE_LOCAL\}, \{\{nla_len=8, nla_type=\\RTA_DST\}, 127.255.255.255\}, \{\{nla_len=8, nla_type=RTA_PREFSRC\}, 127.0.0.1\}, \{\{nla_len=8, nla_type=RTA_OIF\}, if_nametoindex("lo")\}]\}], iov_len=32768\}], msg_iovlen=1, msg_controllen=0, msg_flags=0\}, 0) = 240 \\
broadcast 127.0.0.0 dev lo table local proto kernel scope link src 127.0.0.1  \\
local 127.0.0.0/8 dev lo table local proto kernel scope host src 127.0.0.1 \\
local 127.0.0.1 dev lo table local proto kernel scope host src 127.0.0.1 \\
broadcast 127.255.255.255 dev lo table local proto kernel scope link src 127.0.0.1 \\
recvmsg(3, \{msg_name=\{sa_family=AF_NETLINK, nl_pid=0, nl_groups=00000000\}, \\msg_namelen=12, msg_iov=[\{iov_base=\{\{len=20, type=NLMSG_DONE, flags=NLM_F_MULTI, seq=\\1505349241, pid=12345\}, 0\}, iov_len=32768\}], msg_iovlen=1, msg_controllen=0, msg_flags=0\}, 0) = 20
}
</latex>

=== Advanced syscall filtering syntax ===

В рамках GSoC 2017 Николай Марчук реализовал прототип ещё более гибкого
синтаксиса фильтрации системных вызовов:

[<b><i>action</b></i>(]<b><i>filter_expression</b></i>[;<b><i>arg1</b></i>[;<b><i>arg2</b></i>...]][)]

где
;action: это <b>trace</b>, <b>abbrev</b>, <b>verbose</b>, <b>raw</b>, <b>read</b>, <b>write</b>, <b>fault</b>, <b>inject</b>, или <b>stacktrace</b>;
;arnN: это аргументы <b><i>action</b></i>; 
;filter_expression: состоит из комбинации фильтров, каждый их которых, в свою очередь, состоит из имени фильтра и аргументов фильтра.

Поддерживаются следующие фильтры:
;syscall <i>set</i>: множество системных вызовов, соответствующих описанию <b><i>set</b></i>.
;fd <i>fd1</i>…: множество системных вызовов, оперирующих дескрипторами, соответствующими описанию <b><i>fd1</b></i>…;
;path <i>path</i>: множество системных вызовов, оперирующих файлами, соответствующими описанию <b><i>path</b></i>.

Комбинация фильтров осуществляется с помощью операторов <b>not</b>, <b>and</b>, <b>or</b> и круглых скобок.

Более подробно новый синтаксис описан в strace(1).

=== Advanced syscall tampering and filtering with Lua/LuaJIT ===
В рамках GSoC 2017 Виктор Крапивенский реализовал прототип Lua-скриптинга,
который позволяет не только производить фильтрацию и подмену системных вызовов
с большей гибкостью, но и производить success injection с сохранением семантики
системного вызова, которая, в частности, может заключаться в записи
определённых данных в адресное пространство процесса.
Подробнее об этом расскажет автор в своём докладе.

=== Advanced syscall information tool ===
В рамках GSoC 2017 Эдгар Казиахмедов реализовал прототип новой утилиты asinfo,
предназначенной для получения разнообразной информации о системных вызовых.
Подробнее об этом расскажет автор в своём докладе.

{{LinksSection}}
<!-- <blockquote>[©]</blockquote> -->


<references/>

[[Категория:OSSDEVCONF-2017]]

Версия 19:53, 3 октября 2017

Докладчик
Дмитрий Левин.jpg
Дмитрий Левин

Strace — инструмент для отслеживания и влияния на взаимодействия пользовательских процессов и ядра Linux: системных вызовов, сигналов и изменений состояния процесса.

За минувший год в strace реализовано много нового и интересного.

Видео

Презентация

Strace — новые возможности (Дмитрий Левин, OSSDEVCONF-2017).pdf Strace — новые возможности (Дмитрий Левин, OSSDEVCONF-2017).pdf Strace — новые возможности (Дмитрий Левин, OSSDEVCONF-2017).pdf Strace — новые возможности (Дмитрий Левин, OSSDEVCONF-2017).pdf Strace — новые возможности (Дмитрий Левин, OSSDEVCONF-2017).pdf Strace — новые возможности (Дмитрий Левин, OSSDEVCONF-2017).pdf Strace — новые возможности (Дмитрий Левин, OSSDEVCONF-2017).pdf Strace — новые возможности (Дмитрий Левин, OSSDEVCONF-2017).pdf Strace — новые возможности (Дмитрий Левин, OSSDEVCONF-2017).pdf Strace — новые возможности (Дмитрий Левин, OSSDEVCONF-2017).pdf Strace — новые возможности (Дмитрий Левин, OSSDEVCONF-2017).pdf Strace — новые возможности (Дмитрий Левин, OSSDEVCONF-2017).pdf Strace — новые возможности (Дмитрий Левин, OSSDEVCONF-2017).pdf Strace — новые возможности (Дмитрий Левин, OSSDEVCONF-2017).pdf Strace — новые возможности (Дмитрий Левин, OSSDEVCONF-2017).pdf

Thesis

Введение

strace как инструмент мониторинга взаимодействия пользовательских процессов с ядром существует уже почти 26 лет и широко применяется для диагностики, отладки и изучения поведения ПО. Многочисленные параметры управления фильтрацией дают возможность пользователю strace легко и гибко настраивать отображение системных вызовов и сигналов. С каждым выпуском strace таких возможностей становится больше, а точность отображения — выше.

Начиная с версии 4.13, выпущенной летом прошлого года, расписание выпусков новых версий strace синхронизировано с расписанием выпусков новых версий ядра linux. Таким образом новые интерфейсы, добавляемые в релизы ядра linux, сопровождаются соответствующими парсерами, добавляемыми в релизы strace.

Помимо многочисленных улучшений отображения системных вызовов, за минувший год в strace было реализовано много нового и интересного.

System Call Specification

Синтаксис описания множества системных вызовов существенно расширился:

  • В описании имён системных вызовов теперь поддерживаются регулярные выражения:
 strace -e trace=/regexp
  • В описании множества системных вызовов поддерживаются описания, которым не соответствует ни одного системного вызова:
 strace -e trace=?set
  • Имена классов системных вызовов теперь начинаются с префикса %:
 strace -e trace=%class \\

Прежний способ именования классов без префикса % ещё поддерживается, но уже считается устаревшим.

  • Добавлены новые классы системных вызовов:
%stat
stat, stat64, oldstat и их вариации;
%lstat
lstat, lstat64, oldlstat и их вариации;
%fstat
fstat, fstat64, fstatat64, newfstatat, oldfstat и их вариации;
%%stat
stat, lstat, fstat, fstatat, statx и их вариации;
%statfs
эквивалент /\textasciicircum(.*_)?statv?fs;
%fstatfs
эквивалент /fstatv?fs;
%statfs
эквивалент /statv?fs|fsstat|ustat.

System call tampering и fault injection

Механизм syscall fault injection, прототип которого подробно рассматривался на этой конференции год назад, был доработан и включён в strace, начиная с версии 4.15, выпущенной в декабре прошлого года. По сравнению с прототипом, синтаксис syscall fault injection изменился и выглядит следующим образом:

-e fault=set[:error=errno][:when=expr]

Начиная с версии 4.16, выпущенной в феврале прошлого года, реализован более общий механизм вмешательства в системные вызовы, который, помимо syscall fault injection, позволяет осуществлять syscall return value injection и signal injection. Интерфейс этого нового механизма выглядит следующим образом:

-e inject=set[:error=errno|:retval=value][:signal=sig][:when=expr]

Netlink socket parsers

В strace версии 4.19, выпущенной в начале сентября, реализовано детальное декодирование трафика, проходящего через netlink sockets, что позволяет использовать strace для отладки приложений, работающих с netlink-протоколами. Так, например, может выглядеть вывод парсера трафика семейства NETLINK_ROUTE:

Advanced syscall filtering syntax

В рамках GSoC 2017 Николай Марчук реализовал прототип ещё более гибкого синтаксиса фильтрации системных вызовов:

[action</b>(]<b>filter_expression</b>[;<b>arg1</b>[;<b>arg2</b>...]][)]

где

action
это <b>trace, abbrev, verbose, raw, read, write, fault, inject, или stacktrace;
arnN
это аргументы action</b>;
filter_expression
состоит из комбинации фильтров, каждый их которых, в свою очередь, состоит из имени фильтра и аргументов фильтра.

Поддерживаются следующие фильтры:

syscall set
множество системных вызовов, соответствующих описанию <b>set</b>.
fd fd1
множество системных вызовов, оперирующих дескрипторами, соответствующими описанию <b>fd1</b>…;
path path
множество системных вызовов, оперирующих файлами, соответствующими описанию <b>path</b>.

Комбинация фильтров осуществляется с помощью операторов <b>not, and, or и круглых скобок.

Более подробно новый синтаксис описан в strace(1).

Advanced syscall tampering and filtering with Lua/LuaJIT

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

Advanced syscall information tool

В рамках GSoC 2017 Эдгар Казиахмедов реализовал прототип новой утилиты asinfo, предназначенной для получения разнообразной информации о системных вызовых. Подробнее об этом расскажет автор в своём докладе.

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