.\" -*- coding: UTF-8 -*- .\" Copyright (C) 2014 Kees Cook .\" and Copyright (C) 2012 Will Drewry .\" and Copyright (C) 2008, 2014,2017 Michael Kerrisk .\" and Copyright (C) 2017 Tyler Hicks .\" and Copyright (C) 2020 Tycho Andersen .\" .\" SPDX-License-Identifier: Linux-man-pages-copyleft .\" .\"******************************************************************* .\" .\" This file was generated with po4a. Translate the source file. .\" .\"******************************************************************* .TH seccomp 2 "3 мая 2023 г." "Linux man\-pages 6.05.01" .SH ИМЯ seccomp \- переводит процесс в состояние безопасных вычислений .SH LIBRARY Standard C library (\fIlibc\fP, \fI\-lc\fP) .SH СИНТАКСИС .nf .\" Kees Cook noted: Anything that uses SECCOMP_RET_TRACE returns will .\" need \fB#include \fP /* определения констант \fBSECCOMP_*\fP */ \fB#include \fP /* определения \fBstruct sock_fprog\fP */ \fB#include \fP /* определения констант \fBAUDIT_*\fP */ \fB#include \fP /* определения констант \fBSIG*\fP */ \fB#include \fP /* определения констант \fBPTRACE_*\fP */ \fB#include \fP /* определения констант \fBSYS_*\fP */ \fB#include \fP .PP \fBint syscall(SYS_seccomp, unsigned int \fP\fIoperation\fP\fB, unsigned int \fP\fIflags\fP\fB,\fP \fB void *\fP\fIargs\fP\fB);\fP .fi .PP \fINote\fP: glibc provides no wrapper for \fBseccomp\fP(), necessitating the use of \fBsyscall\fP(2). .SH ОПИСАНИЕ Системный вызов \fBseccomp\fP() переводит вызвавший процесс в состояние безопасных вычислений (Secure Computing, seccomp). .PP В настоящее время в Linux поддерживаются следующие значения \fIoperation\fP: .TP \fBSECCOMP_SET_MODE_STRICT\fP The only system calls that the calling thread is permitted to make are \fBread\fP(2), \fBwrite\fP(2), \fB_exit\fP(2) (but not \fBexit_group\fP(2)), and \fBsigreturn\fP(2). Other system calls result in the termination of the calling thread, or termination of the entire process with the \fBSIGKILL\fP signal when there is only one thread. Strict secure computing mode is useful for number\-crunching applications that may need to execute untrusted byte code, perhaps obtained by reading from a pipe or socket. .IP Заметим, что хотя вызывающая нить больше не вызывает \fBsigprocmask\fP(2), она может использовать \fBsigreturn\fP(2) для блокировки всех сигналов (кроме \fBSIGKILL\fP и \fBSIGSTOP\fP). Это означает, что \fBalarm\fP(2) (например) недостаточно для ограничения времени выполнения процесса. Вместо него для надёжного завершения процесса нужно использовать \fBSIGKILL\fP. Это можно сделать с помощью \fBtimer_create\fP(2) с \fBSIGEV_SIGNAL\fP и \fIsigev_signo\fP равным \fBSIGKILL\fP, или используя \fBsetrlimit\fP(2) для задания жёсткого ограничения по \fBRLIMIT_CPU\fP. .IP Эта операция доступна только, если в ядре включён параметр \fBCONFIG_SECCOMP\fP. .IP Значение \fIflags\fP должно быть равно 0, а \fIargs\fP — NULL. .IP Эта операция функционально идентична вызову: .IP .in +4n .EX prctl(PR_SET_SECCOMP, SECCOMP_MODE_STRICT); .EE .in .TP \fBSECCOMP_SET_MODE_FILTER\fP Разрешённые системные вызовы определяются указателем на Berkeley Packet Filter (BPF), передаваемый через \fIargs\fP. Данный аргумент является указателем на \fIstruct\~sock_fprog\fP; эту структуру можно использовать для отбора произвольных системных вызовов и их аргументов. Если фильтр некорректен, то \fBseccomp\fP() завершается с ошибкой \fBEINVAL\fP в \fIerrno\fP. .IP Если фильтром разрешён \fBfork\fP(2) или \fBclone\fP(2), то все потомки будут ограничены тем же фильтром системных вызовов что и родитель. Если разрешён \fBexecve\fP(2), то существующий фильтр сохраняется и после вызова \fBexecve\fP(2). .IP Чтобы использовать операцию \fBSECCOMP_SET_MODE_FILTER\fP вызывающая нить должна иметь мандат \fBCAP_SYS_ADMIN\fP в своём пространстве имён пользователя или у нити уже должен быть установлен бит \fIno_new_privs\fP. Если этот бит не установлен предком этой нити, то в нити нужно сделать следующий вызов: .IP .in +4n .EX prctl(PR_SET_NO_NEW_PRIVS, 1); .EE .in .IP В противном случае операция \fBSECCOMP_SET_MODE_FILTER\fP завершается ошибкой и возвращает \fBEACCES\fP в \fIerrno\fP. Данное требование гарантирует, что непривилегированный процесс не сможет применить вредоносный фильтр и вызвать программу с set\-user\-ID или другую привилегированную программу с помощью \fBexecve\fP(2), то есть потенциально подвергнуть эту программу опасности (такой вредоносный фильтр может, например, заставить попытаться использовать \fBsetuid\fP(2) для установки ID вызывающего пользователя в ненулевые значения вместо возврата 0 без действительного запуска системного вызова. Таким образом, программа может быть обманута и остаться с правами суперпользователя в окружении, где возможно заставить её сделать что\-то опасное, так как в действительности она не отказалась от своих прав). .IP Если \fBprctl\fP(2) или \fBseccomp\fP() разрешены присоединённым фильтром, то могут быть добавлены дополнительные фильтры. Это увеличит время вычисления, но в дальнейшем позволит сократить область атаки при выполнении нити. .IP Операция \fBSECCOMP_SET_MODE_FILTER\fP доступна только, если в ядре включён параметр \fBCONFIG_SECCOMP_FILTER\fP. .IP Если значение \fIflags\fP равно 0, то эта операция функционально идентична вызову: .IP .in +4n .EX prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, args); .EE .in .IP Возможные значения \fIflags\fP: .RS .TP \fBSECCOMP_FILTER_FLAG_LOG\fP (начиная с Linux 4.14) .\" commit e66a39977985b1e69e17c4042cb290768eca9b02 Все фильтры, возвращающие действия, кроме \fBSECCOMP_RET_ALLOW\fP, должны протоколироваться. Администратор может заменить этот флаг фильтров, предварительно запретив протоколировать определённые действия через файл \fI/proc/sys/kernel/seccomp/actions_logged\fP. .TP \fBSECCOMP_FILTER_FLAG_NEW_LISTENER\fP (начиная с Linux 5.0) .\" commit 6a21cc50f0c7f87dae5259f6cfefe024412313f6 After successfully installing the filter program, return a new user\-space notification file descriptor. (The close\-on\-exec flag is set for the file descriptor.) When the filter returns \fBSECCOMP_RET_USER_NOTIF\fP a notification will be sent to this file descriptor. .IP At most one seccomp filter using the \fBSECCOMP_FILTER_FLAG_NEW_LISTENER\fP flag can be installed for a thread. .IP See \fBseccomp_unotify\fP(2) for further details. .TP \fBSECCOMP_FILTER_FLAG_SPEC_ALLOW\fP (начиная с Linux 4.17) .\" commit 00a02d0c502a06d15e07b857f8ff921e3e402675 Выключить недопущение Speculative Store Bypass. .TP \fBSECCOMP_FILTER_FLAG_TSYNC\fP При добавлении нового фильтра, выполнять синхронизацию с одним деревом фильтров seccomp все нити вызывающего процесса. «Дерево фильтров» — упорядоченный список фильтров, присоединённых к нити (присоединённые одинаковые фильтры отдельными вызовами \fBseccomp\fP() считаются разными фильтрами, с этой точки зрения). .IP Если в какой\-то нити невозможна синхронизация с единым деревом фильтров, то вызов не присоединит новый фильтр seccomp, и завершится с ошибкой, вернув ID первой обнаруженной нити, для которой синхронизация невозможна. Синхронизации не получится, если другая нить того же процесса находится в \fBSECCOMP_MODE_STRICT\fP, или если она присоединила новые фильтры seccomp к самой себе, отличающиеся от дерева фильтров вызывающей нити. .RE .TP \fBSECCOMP_GET_ACTION_AVAIL\fP (начиная с Linux 4.14) .\" commit d612b1fd8010d0d67b5287fe146b8b55bcbb8655 Проверить, поддерживается ли действие ядром. Данная операция помогает убедиться, что ядро знает о самых последних добавленных фильтрах, возвращающих действие, так как ядро считает все неизвестные действия как \fBSECCOMP_RET_KILL_PROCESS\fP. .IP Значение \fIflags\fP должно быть равно 0, а \fIargs\fP должно быть указателем на беззнаковый 32\-битный фильтр, возвращающих действие. .TP \fBSECCOMP_GET_NOTIF_SIZES\fP (начиная с Linux 5.0) .\" commit 6a21cc50f0c7f87dae5259f6cfefe024412313f6 Get the sizes of the seccomp user\-space notification structures. Since these structures may evolve and grow over time, this command can be used to determine how much memory to allocate for sending and receiving notifications. .IP The value of \fIflags\fP must be 0, and \fIargs\fP must be a pointer to a \fIstruct seccomp_notif_sizes\fP, which has the following form: .IP .EX struct seccomp_notif_sizes __u16 seccomp_notif; /* Size of notification structure */ __u16 seccomp_notif_resp; /* Size of response structure */ __u16 seccomp_data; /* Size of \[aq]struct seccomp_data\[aq] */ }; .EE .IP .\" See \fBseccomp_unotify\fP(2) for further details. .SS Фильтры При добавлении фильтров посредством \fBSECCOMP_SET_MODE_FILTER\fP, значение \fIargs\fP указывает на программу фильтрации: .PP .in +4n .EX struct sock_fprog { unsigned short len; /* количество инструкций BPF */ struct sock_filter *filter; /* указатель на массив инструкций BPF */ }; .EE .in .PP В каждой программе должно быть не менее одной инструкции BPF: .PP .in +4n .EX struct sock_filter { /* блок фильтрации */ __u16 code; /* действительный код фильтра */ __u8 jt; /* переход при совпадении */ __u8 jf; /* переход при несовпадении */ __u32 k; /* общее поле для различных целей */ }; .EE .in .PP .\" Quoting Kees Cook: .\" If BPF even allows changing the data, it's not copied back to .\" the syscall when it runs. Anything wanting to do things like .\" that would need to use ptrace to catch the call and directly .\" modify the registers before continuing with the call. При выполнении инструкций информация о системном вызове (когда используется режим адресации \fBBPF_ABS\fP) программе BPF доступна из буфера (только для чтения) в виде: .PP .in +4n .EX struct seccomp_data { int nr; /* номер системного вызова */ __u32 arch; /* значение AUDIT_ARCH_* (смотрите ) */ __u64 instruction_pointer; /* указатель на инструкцию ЦП */ __u64 args[6]; /* до 6 аргументов системного вызова */ }; .EE .in .PP Так как количество системных вызовов различно на разных архитектурах и некоторые архитектуры (например, x86\-64) позволяют коду в пользовательском пространстве использовать соглашения о вызовах нескольких архитектур (и используемое соглашение может меняться на протяжении выполнения процесса, если он использует \fBexecve\fP(2) для запуска выполняемых файлов, которые задействуют другие соглашения), то, обычно, необходимо проверять значение поля \fIarch\fP. .PP It is strongly recommended to use an allow\-list approach whenever possible because such an approach is more robust and simple. A deny\-list will have to be updated whenever a potentially dangerous system call is added (or a dangerous flag or option if those are deny\-listed), and it is often possible to alter the representation of a value without altering its meaning, leading to a deny\-list bypass. See also \fICaveats\fP below. .PP .\" As noted by Dave Drysdale in a note at the end of .\" https://lwn.net/Articles/604515/ .\" One additional detail to point out for the x32 ABI case: .\" the syscall number gets a high bit set (__X32_SYSCALL_BIT), .\" to mark it as an x32 call. .\" .\" If x32 support is included in the kernel, then __SYSCALL_MASK .\" will have a value that is not all-ones, and this will trigger .\" an extra instruction in system_call to mask off the extra bit, .\" so that the syscall table indexing still works. Поле \fIarch\fP не уникально для всех соглашений о вызовах. В x86\-64 ABI и x32 ABI в \fIarch\fP используется \fBAUDIT_ARCH_X86_64\fP, и они запускаются на одних и тех же процессорах. Чтобы отличать один ABI от другого используется маска \fB__X32_SYSCALL_BIT\fP с номером системного вызова. .PP This means that a policy must either deny all syscalls with \fB__X32_SYSCALL_BIT\fP or it must recognize syscalls with and without \fB__X32_SYSCALL_BIT\fP set. A list of system calls to be denied based on \fInr\fP that does not also contain \fInr\fP values with \fB__X32_SYSCALL_BIT\fP set can be bypassed by a malicious program that sets \fB__X32_SYSCALL_BIT\fP. .PP .\" commit 6365b842aae4490ebfafadfc6bb27a6d3cc54757 Additionally, kernels prior to Linux 5.4 incorrectly permitted \fInr\fP in the ranges 512\-547 as well as the corresponding non\-x32 syscalls ORed with \fB__X32_SYSCALL_BIT\fP. For example, \fInr\fP == 521 and \fInr\fP == (101 | \fB__X32_SYSCALL_BIT\fP) would result in invocations of \fBptrace\fP(2) with potentially confused x32\-vs\-x86_64 semantics in the kernel. Policies intended to work on kernels before Linux 5.4 must ensure that they deny or otherwise correctly handle these system calls. On Linux 5.4 and newer, such system calls will fail with the error \fBENOSYS\fP, without doing anything. .PP В поле \fIinstruction_pointer\fP содержится адрес инструкции машинного языка, который запускает системный вызов. Это может быть полезно вместе с \fI/proc/\fPpid\fI/maps\fP для выполнения проверок из какой области (отображение) программы делается системный вызов (вероятно, стоит блокировать системные вызовы \fBmmap\fP(2) и \fBmprotect\fP(2) для запрета программе удалять такие проверки). .PP When checking values from \fIargs\fP, keep in mind that arguments are often silently truncated before being processed, but after the seccomp check. For example, this happens if the i386 ABI is used on an x86\-64 kernel: although the kernel will normally not look beyond the 32 lowest bits of the arguments, the values of the full 64\-bit registers will be present in the seccomp data. A less surprising example is that if the x86\-64 ABI is used to perform a system call that takes an argument of type \fIint\fP, the more\-significant half of the argument register is ignored by the system call, but visible in the seccomp data. .PP Фильтр seccomp возвращает 32\-битное значение, состоящее из двух частей: в старших 16 битах (соответствует маске, определяемой константой \fBSECCOMP_RET_ACTION_FULL\fP) содержится одно из значений «действие», перечисленных далее; в младших 16 битах (определяется константой \fBSECCOMP_RET_DATA\fP) содержатся «данные», связанные с возвращаемым значением. .PP .\" From an Aug 2015 conversation with Kees Cook where I asked why *all* .\" filters are applied even if one of the early filters returns .\" SECCOMP_RET_KILL: .\" .\" It's just because it would be an optimization that would only speed up .\" the RET_KILL case, but it's the uncommon one and the one that doesn't .\" benefit meaningfully from such a change (you need to kill the process .\" really quickly?). We would speed up killing a program at the (albeit .\" tiny) expense to all other filtered programs. Best to keep the filter .\" execution logic clear, simple, and as fast as possible for all .\" filters. If multiple filters exist, they are \fIall\fP executed, in reverse order of their addition to the filter tree\[em]that is, the most recently installed filter is executed first. (Note that all filters will be called even if one of the earlier filters returns \fBSECCOMP_RET_KILL\fP. This is done to simplify the kernel code and to provide a tiny speed\-up in the execution of sets of filters by avoiding a check for this uncommon case.) The return value for the evaluation of a given system call is the first\-seen action value of highest precedence (along with its accompanying data) returned by execution of all of the filters. .PP Значения действий, которые могут возвращаться фильтром seccomp (в порядке уменьшения приоритета): .TP \fBSECCOMP_RET_KILL_PROCESS\fP (начиная с Linux 4.14) .\" commit 4d3b0b05aae9ee9ce0970dc4cc0fb3fad5e85945 .\" commit 0466bdb99e8744bc9befa8d62a317f0fd7fd7421 Это значение возвращается при немедленном завершении процесса с образованием дампа. Системный вызов не выполняется. По сравнению с \fBSECCOMP_RET_KILL_THREAD\fP, описанном далее, завершаются все нити в группе нитей (группы нитей представлены в описании \fBCLONE_THREAD\fP в \fBclone\fP(2)). .IP Процесс завершается \fIдумая\fP, что убит сигналом \fBSIGSYS\fP. Даже если обработчик сигнала \fBSIGSYS\fP был зарегистрирован, в этом случае он будет проигнорирован и процесс всегда прекращает выполнение. Родительскому процессу, который ждёт этот процесс (с помощью \fBwaitpid\fP(2) или подобного вызова) возвращается \fIwstatus\fP, который будет показывать, что потомок завершился по сигналу \fBSIGSYS\fP. .TP \fBSECCOMP_RET_KILL_THREAD\fP (или \fBSECCOMP_RET_KILL\fP) Это значение возвращается при немедленном завершении нити, сделавшей системный вызов. Системный вызов не выполняется. Другие нити в той же группе нитей продолжат выполнение. .IP Нить завершается \fIдумая\fP, что убита сигналом \fBSIGSYS\fP. Смотрите описание \fBSECCOMP_RET_KILL_PROCESS\fP выше. .IP .\" See these commits: .\" seccomp: dump core when using SECCOMP_RET_KILL .\" (b25e67161c295c98acda92123b2dd1e7d8642901) .\" seccomp: Only dump core when single-threaded .\" (d7276e321ff8a53106a59c85ca46d03e34288893) До Linux 4.11 любой процесс, завершавшийся таким образом, не вызывал образование дампа (несмотря на то, что описание \fBSIGSYS\fP в \fBsignal\fP(7) сообщает, что по умолчанию завершение приводит к дампу). Начиная с Linux 4.11 для процесса с единственной нитью будет сделан дамп, если он завершается при таких обстоятельствах. .IP В дополнении к \fBSECCOMP_RET_KILL_PROCESS\fP в Linux 4.14 как синоним \fBSECCOMP_RET_KILL\fP добавлено значение \fBSECCOMP_RET_KILL_THREAD\fP, для более ясного различения двух этих действий. .IP \fBNote\fP: the use of \fBSECCOMP_RET_KILL_THREAD\fP to kill a single thread in a multithreaded process is likely to leave the process in a permanently inconsistent and possibly corrupt state. .TP \fBSECCOMP_RET_TRAP\fP Это значение приводит к отправке ядром направленного в нить сигнала \fBSIGSYS\fP возбудившей нити (системный вызов не выполняется). Заполняются некоторые поля структуры \fIsiginfo_t\fP (смотрите \fBsigaction\fP(2)), связанные с сигналом: .RS .IP \[bu] 3 В \fIsi_signo\fP будет содержаться значение \fBSIGSYS\fP. .IP \[bu] В \fIsi_call_addr\fP будет показан адрес инструкции системного вызова. .IP \[bu] В \fIsi_syscall\fP и \fIsi_arch\fP будет указываться какой системный вызов была попытка запустить. .IP \[bu] В \fIsi_code\fP будет содержаться значение \fBSYS_SECCOMP\fP. .IP \[bu] В \fIsi_errno\fP будет содержаться часть \fBSECCOMP_RET_DATA\fP из возвращаемого значения фильтра. .RE .IP Программный счётчик будет таким же как при системном вызове (т. е., программный счётчик не будет указывать на инструкцию системного вызова). В регистре возвращаемого значения будет содержаться значение, зависящее от архитектуры; если выполнение продолжится, оно равно чему\-нибудь подходящему для системного вызова (зависимость от архитектуры возникает из\-за того, что при замене его на \fBENOSYS\fP может перезаписаться какая\-нибудь полезная информация). .TP \fBSECCOMP_RET_ERRNO\fP Это значение приводит к тому, что часть \fBSECCOMP_RET_DATA\fP возвращаемого значения фильтра передаётся в пространство пользователя в виде значения \fIerrno\fP без выполнения системного вызова. .TP \fBSECCOMP_RET_USER_NOTIF\fP (начиная с Linux 5.0) .\" commit 6a21cc50f0c7f87dae5259f6cfefe024412313f6 Forward the system call to an attached user\-space supervisor process to allow that process to decide what to do with the system call. If there is no attached supervisor (either because the filter was not installed with the \fBSECCOMP_FILTER_FLAG_NEW_LISTENER\fP flag or because the file descriptor was closed), the filter returns \fBENOSYS\fP (similar to what happens when a filter returns \fBSECCOMP_RET_TRACE\fP and there is no tracer). See \fBseccomp_unotify\fP(2) for further details. .IP Note that the supervisor process will not be notified if another filter returns an action value with a precedence greater than \fBSECCOMP_RET_USER_NOTIF\fP. .TP \fBSECCOMP_RET_TRACE\fP При возврате это значение заставит ядро попытаться уведомить трассировщик на основе \fBptrace\fP(2) до выполнения системного вызова. Если трассировщика нет, то системный вызов не выполняется и возвращается состояние ошибки со значением \fIerrno\fP равным \fBENOSYS\fP. .IP Трассировщик будет уведомлён, если он запросил \fBPTRACE_O_TRACESECCOMP\fP посредством \fIptrace(PTRACE_SETOPTIONS)\fP. Трассировщик будет уведомлён о \fBPTRACE_EVENT_SECCOMP\fP, а часть \fBSECCOMP_RET_DATA\fP возвращаемого значения фильтра будет доступна через \fBPTRACE_GETEVENTMSG\fP. .IP Трассировщик может пропустить системный вызов, изменив номер системного вызова на \-1. Или же он может изменить запрашиваемый системный вызов на системный вызов с другим номером. Если трассировщик просит пропустить системный вызов, то системный вызов появится в возвращаемом значении, которое трассировщик помещает в регистр возвращаемого значения. .IP .\" This was changed in ce6526e8afa4. .\" A related hole, using PTRACE_SYSCALL instead of SECCOMP_RET_TRACE, was .\" changed in arch-specific commits, e.g. 93e35efb8de4 for X86 and .\" 0f3912fd934c for ARM. Before Linux 4.8, the seccomp check will not be run again after the tracer is notified. (This means that, on older kernels, seccomp\-based sandboxes \fBmust not\fP allow use of \fBptrace\fP(2)\[em]even of other sandboxed processes\[em]without extreme care; ptracers can use this mechanism to escape from the seccomp sandbox.) .IP Note that a tracer process will not be notified if another filter returns an action value with a precedence greater than \fBSECCOMP_RET_TRACE\fP. .TP \fBSECCOMP_RET_LOG\fP (начиная с Linux 4.14) .\" commit 59f5cf44a38284eb9e76270c786fb6cc62ef8ac4 Это значение приводит к выполнению системного вызова после протоколирования фильтра, возвращающего действие. Администратор может заменить протоколирование этого действия в файле \fI/proc/sys/kernel/seccomp/actions_logged\fP. .TP \fBSECCOMP_RET_ALLOW\fP Это значение приводит к выполнению системного вызова. .PP .\" commit 4d3b0b05aae9ee9ce0970dc4cc0fb3fad5e85945 .\" Если значение действия ни одно из указанных выше, то действием фильтра считается или \fBSECCOMP_RET_KILL_PROCESS\fP (начиная с Linux 4.14), или \fBSECCOMP_RET_KILL_THREAD\fP (в Linux 4.13 и старее). .SS "Интерфейс /proc" Файлы в каталоге \fI/proc/sys/kernel/seccomp\fP предоставляют дополнительную информацию seccomp и настройку: .TP \fIactions_avail\fP (начиная с Linux 4.14) .\" commit 8e5f1ad116df6b0de65eac458d5e7c318d1c05af Доступный только для чтения упорядоченный список возвращаемых действий фильтром seccomp в виде строки. Список упорядочен слева направо в порядке уменьшения приоритета. Представляет собой набор возвращаемых фильтром seccomp действий, поддерживаемых ядром. .TP \fIactions_logged\fP (начиная с Linux 4.14) .\" commit 0ddec0fc8900201c0897b87b762b7c420436662f Доступный для чтения\-записи упорядоченный список возвращаемых действий фильтром seccomp, которые разрешено протоколировать. Записи в файл не нужно упорядочивать, но прочитанные данные будут упорядочены также как в файле \fIactions_avail\fP. .IP Важно отметить, что значение \fIactions_logged\fP не останавливает от протоколирования определённого фильтра возвращаемых действий, если подсистема аудита настроена на аудит задачи. Если действие не найдено в файле \fIactions_logged\fP, то конечное решение об аудите действия для этой задачи, в конечном итоге, основывается на действие подсистемы аудита для всех фильтров возвращающих действия, кроме \fBSECCOMP_RET_ALLOW\fP. .IP .\" Строка «allow» недопустима в файле \fIactions_logged\fP, так как невозможно протоколирование действий \fBSECCOMP_RET_ALLOW\fP. Попытка записи «allow» в файле завершится ошибкой \fBEINVAL\fP. .SS "Ведение журнала контроля действий seccomp" .\" commit 59f5cf44a38284eb9e76270c786fb6cc62ef8ac4 .\" or auditing could be enabled via the netlink API (AUDIT_SET) Начиная с Linux 4.14 ядро позволяет протоколировать действия, возвращаемые фильтрами seccomp в журнал контроля (audit log). Ядро принимает решение о протоколировании действие основываясь на типе действия, имеется ли действие в файле \fIactions_logged\fP и включён ли контроль в ядре (например, посредством параметра загрузки ядра \fIaudit=1\fP). Правила следующие: .IP \[bu] 3 Если действие — \fBSECCOMP_RET_ALLOW\fP, то оно не протоколируется. .IP \[bu] В противном случае, если действие \fBSECCOMP_RET_KILL_PROCESS\fP или \fBSECCOMP_RET_KILL_THREAD\fP, и это действие есть в файле \fIactions_logged\fP, то действие протоколируется. .IP \[bu] В противном случае, если для фильтра запрошено протоколирование (флаг \fBSECCOMP_FILTER_FLAG_LOG\fP) и действие есть в файле \fIactions_logged\fP, то действие протоколируется. .IP \[bu] В противном случае, если включён контроль в ядре и процесс контролируется (\fBautrace\fP(8)), то действие протоколируется. .IP \[bu] В противном случае действие не протоколируется. .SH "ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ" On success, \fBseccomp\fP() returns 0. On error, if \fBSECCOMP_FILTER_FLAG_TSYNC\fP was used, the return value is the ID of the thread that caused the synchronization failure. (This ID is a kernel thread ID of the type returned by \fBclone\fP(2) and \fBgettid\fP(2).) On other errors, \-1 is returned, and \fIerrno\fP is set to indicate the error. .SH ОШИБКИ Функция \fBseccomp\fP() может завершиться с ошибкой по следующим причинам: .TP \fBEACCES\fP У вызывающего нет мандата \fBCAP_SYS_ADMIN\fP в своём пространстве имён пользователя или не установлен \fIno_new_privs\fP до использования \fBSECCOMP_SET_MODE_FILTER\fP. .TP \fBEBUSY\fP While installing a new filter, the \fBSECCOMP_FILTER_FLAG_NEW_LISTENER\fP flag was specified, but a previous filter had already been installed with that flag. .TP \fBEFAULT\fP Аргумент \fIargs\fP не содержит допустимого адреса. .TP \fBEINVAL\fP Аргумент \fIoperation\fP неизвестен или не поддерживается этой версией ядра или из\-за настроек. .TP \fBEINVAL\fP Указанное значение \fIflags\fP некорректно для заданного значения \fIoperation\fP. .TP \fBEINVAL\fP Значение \fIoperation\fP включает \fBBPF_ABS\fP, но указанное смещение не выровнено по 32\-битной границе или превышает \fIsizeof(struct\~seccomp_data)\fP. .TP \fBEINVAL\fP .\" See kernel/seccomp.c::seccomp_may_assign_mode() in Linux 3.18 sources Режим безопасных вычислений уже включён, и значение \fIoperation\fP отличается от существующей настройки. .TP \fBEINVAL\fP В \fIoperation\fP указано \fBSECCOMP_SET_MODE_FILTER\fP, но фильтрующая программа, задаваемая в \fIargs\fP, некорректна или её длина равна 0 или превышает \fBBPF_MAXINSNS\fP (4096) инструкций. .TP \fBENOMEM\fP Не хватает памяти. .TP \fBENOMEM\fP .\" ENOMEM in kernel/seccomp.c::seccomp_attach_filter() in Linux 3.18 sources Общая длина всех фильтрующих программ, присоединённых к вызывающей нити, превысила бы \fBMAX_INSNS_PER_PATH\fP (32768) инструкций. Заметим, что для вычисления этого предела на каждую уже существующую фильтрующую программу прибавляются ещё 4 инструкции. .TP \fBEOPNOTSUPP\fP В \fIoperation\fP указано \fBSECCOMP_GET_ACTION_AVAIL\fP, но ядро не поддерживает фильтр, возвращающий действие, указанное в \fIargs\fP. .TP \fBESRCH\fP Во время синхронизации нити произошла ошибка в другой нити, но её ID невозможно определить. .SH СТАНДАРТЫ Linux. .SH ИСТОРИЯ .\" FIXME . Add glibc version Linux 3.17. .SH ЗАМЕЧАНИЯ Вместо ручного кодирования фильтров seccomp, как показано в примере ниже, вы можете воспользоваться библиотекой \fIlibseccomp\fP, которая предоставляет клиентскую часть для генерации фильтров seccomp. .PP В поле \fISeccomp\fP файла \fI/proc/\fPpid\fI/status\fP отображается метод просмотра режима seccomp в процессе; смотрите \fBproc\fP(5). .PP Вызов \fBseccomp\fP() предоставляет больше возможностей по сравнению с операцией \fBPR_SET_SECCOMP\fP \fBprctl\fP(2) (которая не поддерживает \fIflags\fP). .PP .\" Начиная с Linux 4.4, вызов \fBptrace\fP(2) с операцией \fBPTRACE_SECCOMP_GET_FILTER\fP можно использовать для получения дампа фильтров seccomp процесса. .SS "Архитектурная поддержка seccomp BPF" .\" Check by grepping for HAVE_ARCH_SECCOMP_FILTER in Kconfig files in .\" kernel source. Last checked in Linux 4.16-rc source. Архитектурная поддержка фильтрации seccomp BPF доступна на следующих архитектурах: .IP \[bu] 3 x86\-64, i386, x32 (начиная с Linux 3.5) .PD 0 .IP \[bu] ARM (начиная с Linux 3.8) .IP \[bu] s390 (начиная с Linux 3.8) .IP \[bu] MIPS (начиная с Linux 3.16) .IP \[bu] ARM\-64 (начиная с Linux 3.19) .IP \[bu] PowerPC (начиная с Linux 4.3) .IP \[bu] Tile (начиная с Linux 4.3) .IP \[bu] .\" User mode Linux since Linux 4.6 PA\-RISC (начиная с Linux 4.6) .PD .\" .SS Предостережения Есть различные тонкости, которые нужно учитывать при применении фильтров seccomp к программе: .IP \[bu] 3 На многих архитектурах некоторые обычные системные вызовы реализованы в пользовательском пространстве в \fBvdso\fP(7). Заметными примерами можно считать \fBclock_gettime\fP(2), \fBgettimeofday\fP(2) и \fBtime\fP(2). На таких архитектурах фильтрация seccomp данных системных вызовов не действует (однако, есть случаи где реализации \fBvdso\fP(7) могут вызвать реальный системный вызов и фильтры seccomp filters увидят такое обращение). .IP \[bu] Фильтрация seccomp работает по номерам системных вызовов. Однако, обычно, в приложениях системные вызовы вызываются не напрямую, а через обёрточные функции библиотеки C, которые, в свою очередь, вызывают системные вызовы. Следовательно, нужно учитывать следующее: .RS .IP \[bu] 3 Обёртки glibc некоторых обычных системных вызовов могут использовать системные вызовы ядра с другими именами. Например, обёрточная функция \fBexit\fP(2) использует системный вызов \fBexit_group\fP(2), а обёрточная функция \fBfork\fP(2) в действительности вызывает \fBclone\fP(2). .IP \[bu] Поведение обёрточных функций могут быть различных на разных архитектурах, с учётом диапазона системных вызовов, предоставляемых архитектурой. Другими словами, одна обёрточная функция на разных архитектурах может вызывать разные системные вызовы. .IP \[bu] И наконец, поведение обёрточных функций может различаться в разных версиях glibc. Например, в старых версиях обёрточная функция glibc для \fBopen\fP(2) вызывала системный вызов с тем же именем, но начиная с glibc 2.26, в реализации начал вызываться \fBopenat\fP(2) на всех архитектурах. .RE .PP В следствии вышеупомянутого возможно понадобится фильтровать не тот системный вызов, который ожидался. В различных справочных страницах раздела 2 есть абзац \fIОтличия между библиотекой C и ядром\fP, в котором содержится полезная информация о различиях между оберточными функциями и нижележащими системными вызовами. .PP .\" Кроме того, обратите внимание, что применение фильтров seccomp даже может привести к появлению дефектов приложений, когда фильтры вызывают неожиданные отказы для законных операций, которые приложение, возможно, должно было бы выполнить. Такие дефекты может оказаться нелегко обнаружить при тестировании фильтров seccomp, если дефекты возникают в редко используемых путях кода приложения. .SS "Особенности seccomp в BPF" Заметим, что следующие особенности BPF относятся только к фильтрам seccomp: .IP \[bu] 3 Модификаторы размера \fBBPF_H\fP и \fBBPF_B\fP не поддерживаются: все операции должны загружать и сохранять слова (4\-байта) (\fBBPF_W\fP). .IP \[bu] Для доступа к содержимому буфера \fIseccomp_data\fP используйте модификатор режима адресации \fBBPF_ABS\fP. .IP \[bu] Модификатор режима адресации \fBBPF_LEN\fP выдаёт непосредственный операнд режима, чьё значение равно размеру буфера \fIseccomp_data\fP. .SH ПРИМЕРЫ Программа, показанная далее, обрабатывает четыре и более аргументов. Первые три аргумента — номер системного вызова, числовой идентификатор архитектуры и номер ошибки. Программа использует эти значения для создания фильтра BPF, который используется во время работы для выполнения следующих проверок: .IP \[bu] 3 Если программа не запущена на определённой архитектуре, то фильтр BPF заставляет системные вызовы завершаться с ошибкой \fBENOSYS\fP. .IP \[bu] Если программа попытается выполнить системный вызов с заданным номером, то фильтр BPF заставит системный вызов завершиться с ошибкой, а в \fIerrno\fP будет записан указанный номер ошибки. .PP В оставшихся аргументах командной строки указываются путь и дополнительные аргументы программы, которую программа из примера должна попытаться выполнить с помощью \fBexecv\fP(3) (библиотечной функции, которая использует системный вызов \fBexecve\fP(2)). Несколько примеров запуска программы показаны далее. .PP Сначала мы выведем имя архитектуры, на которой работаем (x86\-64), а затем создадим функцию оболочки, которая выдаёт список номеров системных вызовов этой архитектуры: .PP .in +4n .EX $ \fBuname \-m\fP x86_64 $ \fBsyscall_nr() { cat /usr/src/linux/arch/x86/syscalls/syscall_64.tbl | \e awk \[aq]$2 != "x32" && $3 == "\[aq]$1\[aq]" { print $1 }\[aq] }\fP .EE .in .PP Когда фильтр BPF отклоняет системный вызов (случай [2] выше), системный вызов завершается с номером ошибки, указанной в командной строке. В наших экспериментах используется номер ошибки 99: .PP .in +4n .EX $ \fBerrno 99\fP EADDRNOTAVAIL 99 Cannot assign requested address .EE .in .PP В следующем примере мы пытаемся выполнить команду \fBwhoami\fP(1), но фильтр BPF отклоняет системный вызов \fBexecve\fP(2), и поэтому команда даже не начнёт выполняться: .PP .in +4n .EX $ \fBsyscall_nr execve\fP 59 $ \fB./a.out\fP Использование: ./a.out [] Подсказка для : AUDIT_ARCH_I386: 0x40000003 AUDIT_ARCH_X86_64: 0xC000003E $ \fB./a.out 59 0xC000003E 99 /bin/whoami\fP execv: Cannot assign requested address .EE .in .PP В следующем примере фильтр BPF отклоняет системный вызов \fBwrite\fP(2), и хотя выполнение началось, команда \fBwhoami\fP(1) не может записать в стандартный вывод: .PP .in +4n .EX $ \fBsyscall_nr write\fP 1 $ \fB./a.out 1 0xC000003E 99 /bin/whoami\fP .EE .in .PP В последнем примере фильтр BPF отклоняет системный вызов, который не используется в команде \fBwhoami\fP(1), и поэтому она выполняется без ошибок и выводит: .PP .in +4n .EX $ \fBsyscall_nr preadv\fP 295 $ \fB./a.out 295 0xC000003E 99 /bin/whoami\fP cecilia .EE .in .SS "Исходный код программы" .\" SRC BEGIN (seccomp.c) .EX #include #include #include #include #include #include #include #include #include \& #define X32_SYSCALL_BIT 0x40000000 #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0])) \& static int install_filter(int syscall_nr, unsigned int t_arch, int f_errno) { unsigned int upper_nr_limit = 0xffffffff; \& /* Assume that AUDIT_ARCH_X86_64 means the normal x86\-64 ABI (in the x32 ABI, all system calls have bit 30 set in the \[aq]nr\[aq] field, meaning the numbers are >= X32_SYSCALL_BIT). */ if (t_arch == AUDIT_ARCH_X86_64) upper_nr_limit = X32_SYSCALL_BIT \- 1; \& struct sock_filter filter[] = { /* [0] Load architecture from \[aq]seccomp_data\[aq] buffer into accumulator. */ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, (offsetof(struct seccomp_data, arch))), \& /* [1] Jump forward 5 instructions if architecture does not match \[aq]t_arch\[aq]. */ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, t_arch, 0, 5), \& /* [2] Load system call number from \[aq]seccomp_data\[aq] buffer into accumulator. */ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, (offsetof(struct seccomp_data, nr))), \& /* [3] Check ABI \- only needed for x86\-64 in deny\-list use cases. Use BPF_JGT instead of checking against the bit mask to avoid having to reload the syscall number. */ BPF_JUMP(BPF_JMP | BPF_JGT | BPF_K, upper_nr_limit, 3, 0), \& /* [4] Jump forward 1 instruction if system call number does not match \[aq]syscall_nr\[aq]. */ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, syscall_nr, 0, 1), \& /* [5] Matching architecture and system call: don\[aq]t execute the system call, and return \[aq]f_errno\[aq] in \[aq]errno\[aq]. */ BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_ERRNO | (f_errno & SECCOMP_RET_DATA)), \& /* [6] Destination of system call number mismatch: allow other system calls. */ BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_ALLOW), \& /* [7] Destination of architecture mismatch: kill process. */ BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_KILL_PROCESS), }; \& struct sock_fprog prog = { .len = ARRAY_SIZE(filter), .filter = filter, }; \& if (syscall(SYS_seccomp, SECCOMP_SET_MODE_FILTER, 0, &prog)) { perror("seccomp"); return 1; } \& return 0; } \& int main(int argc, char *argv[]) { if (argc < 5) { fprintf(stderr, "Usage: " "%s []\en" "Hint for : AUDIT_ARCH_I386: 0x%X\en" " AUDIT_ARCH_X86_64: 0x%X\en" "\en", argv[0], AUDIT_ARCH_I386, AUDIT_ARCH_X86_64); exit(EXIT_FAILURE); } \& if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0)) { perror("prctl"); exit(EXIT_FAILURE); } \& if (install_filter(strtol(argv[1], NULL, 0), strtoul(argv[2], NULL, 0), strtol(argv[3], NULL, 0))) exit(EXIT_FAILURE); \& execv(argv[4], &argv[4]); perror("execv"); exit(EXIT_FAILURE); } .EE .\" SRC END .SH "СМ. ТАКЖЕ" \fBbpfc\fP(1), \fBstrace\fP(1), \fBbpf\fP(2), \fBprctl\fP(2), \fBptrace\fP(2), \fBseccomp_unotify\fP(2), \fBsigaction\fP(2), \fBproc\fP(5), \fBsignal\fP(7), \fBsocket\fP(7) .PP Various pages from the \fIlibseccomp\fP library, including: \fBscmp_sys_resolver\fP(1), \fBseccomp_export_bpf\fP(3), \fBseccomp_init\fP(3), \fBseccomp_load\fP(3), and \fBseccomp_rule_add\fP(3). .PP .\" commit c061f33f35be0ccc80f4b8e0aea5dfd2ed7e01a3 Файлы исходного кода ядра \fIDocumentation/networking/filter.txt\fP и \fIDocumentation/userspace\-api/seccomp_filter.rst\fP (до Linux 4.13 файл \fIDocumentation/prctl/seccomp_filter.txt\fP). .PP McCanne, S.\& and Jacobson, V.\& (1992) \fIThe BSD Packet Filter: A New Architecture for User\-level Packet Capture\fP, Proceedings of the USENIX Winter 1993 Conference .UR http://www.tcpdump.org/papers/bpf\-usenix93.pdf .UE .PP .SH ПЕРЕВОД Русский перевод этой страницы руководства был сделан Alexander Golubev , Azamat Hackimov , Hotellook, Nikita , Spiros Georgaras , Vladislav , Yuri Kozlov и Иван Павлов . .PP Этот перевод является бесплатной документацией; прочитайте .UR https://www.gnu.org/licenses/gpl-3.0.html Стандартную общественную лицензию GNU версии 3 .UE или более позднюю, чтобы узнать об условиях авторского права. Мы не несем НИКАКОЙ ОТВЕТСТВЕННОСТИ. .PP Если вы обнаружите ошибки в переводе этой страницы руководства, пожалуйста, отправьте электронное письмо на .MT man-pages-ru-talks@lists.sourceforge.net .ME .