Difference between revisions of "Ej-suid-container"
(progress...) |
(...) |
||
(4 intermediate revisions by the same user not shown) | |||
Line 46: | Line 46: | ||
программы файловая система хост-системы модифицируется следующим образом: | программы файловая система хост-системы модифицируется следующим образом: | ||
− | * Демонтируются все файловые системы типов < | + | * Демонтируются все файловые системы типов <code>fusectl</code>, <code>rpc_pipefs</code>, <code>securityfs</code> и аналогичных, которые могут использоваться для доступа к системной информации. |
− | < | ||
− | которые могут использоваться для доступа к системной информации. | ||
− | * Рабочий каталог запускаемой программы монтируется в < | + | * Рабочий каталог запускаемой программы монтируется в <code>/sandbox</code>. Он будет установлен как текущий каталог при запуске. |
− | Он будет установлен как текущий каталог при запуске. | ||
− | * Каталог < | + | * Каталог <code>/proc</code> перекрывается пустым каталогом. |
− | * Каталог < | + | * Каталог <code>/sys</code> перекрывается пустым каталогом. |
− | * Каталог < | + | * Каталог <code>/boot</code> перекрывается пустым каталогом. |
− | * | + | * Каталог <code>/srv</code> перекрывается пустым каталогом. |
− | |||
− | * | + | * Каталог <code>/data</code> перекрывается пустым каталогом. |
− | |||
− | |||
− | * Если подготовлен образ каталога | + | * Если подготовлен образ каталога /root, то этот образ перекрывает каталог <code>/root</code>. |
− | каталог < | ||
− | * Если подготовлен образ каталога < | + | * Если подготовлен образ каталога /etc, этот образ перекрывает каталог <code>/etc</code>, однако <code>/etc/alternatives</code> и <code>/etc/java</code> монтируется с файловой системы хоста. |
− | |||
− | * | + | * Если подготовлен образ каталога <code>/var</code>, этот образ перекрывает каталог <code>/var</code> файловой системы. |
− | |||
− | |||
− | * Если подготовлен образ каталога < | + | * Если подготовлен образ каталога <code>/dev</code>, этот образ перекрывает каталог <code>/dev</code> файловой системы. |
− | перекрывает каталог < | + | |
− | каталога < | + | * Каталоги <code>/tmp</code>, <code>/run</code>, <code>/dev/mqueue</code>, <code>/dev/shm</code> инициализируются как пустые каталоги для временных файлов (файловая система tmpfs). |
− | системы хоста. В противном случае каталоги | + | |
− | /home/judges/data и /home/judges/var перекрываются пустыми каталогами. | + | * Если подготовлен образ каталога <code>/home</code>, этот образ перекрывает каталог <code>/home</code> файловой системы, за исключеним каталога <code>/home/judges/compile</code>, который монтируется с файловой системы хоста. В противном случае каталоги /home/judges/data и /home/judges/var перекрываются пустыми каталогами. |
Подготовленные образы каталогов должны располагаться в каталоге | Подготовленные образы каталогов должны располагаться в каталоге | ||
− | < | + | <code>EJUDGE_PREFIX_DIR/share/ejudge/container</code>. Eсли |
− | EJUDGE_PREFIX_DIR установлен в < | + | EJUDGE_PREFIX_DIR установлен в <code>/opt/ejudge</code>, то каталог |
должен выглядеть так: | должен выглядеть так: | ||
Line 107: | Line 97: | ||
ej-suid-container [OPTIONS] PROGRAM [ARGUMENTS] | ej-suid-container [OPTIONS] PROGRAM [ARGUMENTS] | ||
− | Здесь < | + | Здесь <code>OPTIONS</code> — дополнительные опции для настройки |
− | контейнеров. < | + | контейнеров. <code>PROGRAM</code> — запускаемая программа, |
− | < | + | <code>ARGUMENTS</code> — аргументы для запускаемой программы. |
Все опции для ej-suid-container задаются в одном аргументе командной строки. | Все опции для ej-suid-container задаются в одном аргументе командной строки. | ||
Между опциями отсутствуют разделители, но может использоваться символ | Между опциями отсутствуют разделители, но может использоваться символ | ||
− | '< | + | '<code>,</code>' (запятая), который в опциях игнорируется. |
Опции начинаются со знака "минус". | Опции начинаются со знака "минус". | ||
Если опция требует целого параметра, параметр записывается сразу после опции | Если опция требует целого параметра, параметр записывается сразу после опции | ||
− | без разделителя, например < | + | без разделителя, например <code>lo10</code>. |
Если опция требует параметра-размера, то после целого числа может | Если опция требует параметра-размера, то после целого числа может | ||
Line 126: | Line 116: | ||
Если опция требует параметр-строку, сразу же после опции записывается | Если опция требует параметр-строку, сразу же после опции записывается | ||
длина строки, затем символ "запятая", затем строка-параметр, | длина строки, затем символ "запятая", затем строка-параметр, | ||
− | например, < | + | например, <code>ri10,/tmp/a.txt</code>. Либо сразу после опции записывается |
символ-терминатор строки, а далее идет строка до этого символа-терминатора, | символ-терминатор строки, а далее идет строка до этого символа-терминатора, | ||
− | например, < | + | например, <code>ri|/tmp/a.txt|</code>. |
{| | {| | ||
− | | < | + | | <code>f<FD></code> |
− | | файловый дескриптор | + | | файловый дескриптор - целое число |
| задать ф. д. для получения результата выполнения программы Если опция отсутствует, то строка результата выводится на stderr | | задать ф. д. для получения результата выполнения программы Если опция отсутствует, то строка результата выводится на stderr | ||
|- | |- | ||
− | | < | + | | <code>mg</code> |
| | | | ||
| не создавать linux control group (не использовать!) | | не создавать linux control group (не использовать!) | ||
|- | |- | ||
− | | < | + | | <code>mi</code> |
| | | | ||
| не создавать пространство имен IPC, запускаемая программа будет иметь доступ к объектам IPC хост-системы | | не создавать пространство имен IPC, запускаемая программа будет иметь доступ к объектам IPC хост-системы | ||
|- | |- | ||
− | | < | + | | <code>mn</code> |
| | | | ||
| не создавать пространство имен сетевых интерфейсов, запускаемая программа будет иметь неограниченный доступ к сети | | не создавать пространство имен сетевых интерфейсов, запускаемая программа будет иметь неограниченный доступ к сети | ||
|- | |- | ||
− | | < | + | | <code>ml</code> |
+ | | | ||
+ | | в изолированном пространстве сетевых интерфейсов поднять интерфейс lo (loopback) и настроить его на адрес 127.0.0.1 ([[Изменения в версии 3.11.0|3.11.0]]) | ||
+ | |- | ||
+ | | <code>mm</code> | ||
| | | | ||
| не создавать пространство имен файловой системы, запускаемая программа будет иметь доступ ко всей файловой системе хост-системы | | не создавать пространство имен файловой системы, запускаемая программа будет иметь доступ ко всей файловой системе хост-системы | ||
|- | |- | ||
− | | < | + | | <code>mp</code> |
| | | | ||
| не создавать пространство имен процессов, запускаемая программа будет иметь идентификатор процесса среди процессов хост-системы (не использовать!) | | не создавать пространство имен процессов, запускаемая программа будет иметь идентификатор процесса среди процессов хост-системы (не использовать!) | ||
|- | |- | ||
− | | < | + | | <code>mP</code> |
| | | | ||
| не перекрывать файловую систему /proc, хотя в ней будут отображаться только процессы из пространства имен процессов, но общесистемные файлы, например, /proc/sys будут доступны | | не перекрывать файловую систему /proc, хотя в ней будут отображаться только процессы из пространства имен процессов, но общесистемные файлы, например, /proc/sys будут доступны | ||
|- | |- | ||
− | | < | + | | <code>mS</code> |
| | | | ||
| не перекрывать доступ к файловой системе /sys | | не перекрывать доступ к файловой системе /sys | ||
|- | |- | ||
− | | < | + | | <code>mv</code> |
| | | | ||
| не подменять файловую систему /var, запускаемая программа будет иметь доступ к каталогу /var хост-системы | | не подменять файловую систему /var, запускаемая программа будет иметь доступ к каталогу /var хост-системы | ||
|- | |- | ||
− | | < | + | | <code>me</code> |
| | | | ||
| не подменять файловую систему /etc, запускаемая программа будет иметь доступ к каталогу /etc хост-системы | | не подменять файловую систему /etc, запускаемая программа будет иметь доступ к каталогу /etc хост-системы | ||
|- | |- | ||
− | | < | + | | <code>ms</code> |
| | | | ||
| не привязывать рабочий каталог программы к каталогу /sandbox | | не привязывать рабочий каталог программы к каталогу /sandbox | ||
|- | |- | ||
− | | < | + | | <code>mh</code> |
| | | | ||
| не подменять файловую систему /home, запускаемая программа будет иметь доступ к каталогу /home хост-системы | | не подменять файловую систему /home, запускаемая программа будет иметь доступ к каталогу /home хост-системы | ||
|- | |- | ||
− | | < | + | | <code>md</code> |
| | | | ||
| не подменять файловую систему /dev, запускаемая программа будет иметь доступ к каталогу /dev хост-системы | | не подменять файловую систему /dev, запускаемая программа будет иметь доступ к каталогу /dev хост-системы | ||
|- | |- | ||
− | | < | + | | <code>mr</code> |
+ | | | ||
+ | | не подменять файловую систему /run, запускаемая программа будет иметь доступ к каталогу /run хост-системы ([[Изменения в версии 3.11.0|3.11.0]]) | ||
+ | |- | ||
+ | | <code>mo</code> | ||
| | | | ||
| не менять пользователя на ejexec/ejcompile (не использовать!) | | не менять пользователя на ejexec/ejcompile (не использовать!) | ||
|- | |- | ||
− | | < | + | | <code>mG</code> |
| | | | ||
| не создавать новую группу процессов (не использовать!) | | не создавать новую группу процессов (не использовать!) | ||
|- | |- | ||
− | | < | + | | <code>mc</code> |
| | | | ||
| после завершения запущенной программы посчитать количество оставшихся незавершенных процессов. Может быть полезно, когда запускаемая программа создает другие процессы и необходимо проконтролировать, что все запущенные процессы были завершены перед завершением основной программы. Независимо от значения этой опции все такие процессы будут принудительно завершены, эта опция позволяет получить их количество. | | после завершения запущенной программы посчитать количество оставшихся незавершенных процессов. Может быть полезно, когда запускаемая программа создает другие процессы и необходимо проконтролировать, что все запущенные процессы были завершены перед завершением основной программы. Независимо от значения этой опции все такие процессы будут принудительно завершены, эта опция позволяет получить их количество. | ||
|- | |- | ||
− | | < | + | | <code>mI</code> |
| | | | ||
| посчитать количество объектов IPC, оставшихся неудаленными после завершения программы. | | посчитать количество объектов IPC, оставшихся неудаленными после завершения программы. | ||
|- | |- | ||
− | | < | + | | <code>ma</code> |
| | | | ||
| не ограничивать процессорное время для запускаемой программы | | не ограничивать процессорное время для запускаемой программы | ||
|- | |- | ||
− | | < | + | | <code>mb</code> |
| | | | ||
| не ограничивать реальное время для запускаемой программы | | не ограничивать реальное время для запускаемой программы | ||
|- | |- | ||
− | | < | + | | <code>mD</code> |
| | | | ||
− | | переносить в контейнер не сам рабочий каталог, а его родительский каталог. Используется когда при тестировании в ejudge установлена опция < | + | | переносить в контейнер не сам рабочий каталог, а его родительский каталог. Используется когда при тестировании в ejudge установлена опция <code>use_tgz</code>. |
|- | |- | ||
− | | < | + | | <code>mC</code> |
| | | | ||
| запускать программу в режиме контейнера для компиляции | | запускать программу в режиме контейнера для компиляции | ||
|- | |- | ||
− | | < | + | | <code>mV</code> |
+ | | | ||
+ | | отменить установку значения по умолчанию для лимита виртуальной памяти | ||
+ | |- | ||
+ | | <code>mE</code> | ||
+ | | | ||
+ | | включить определение ошибки "security violation" | ||
+ | |- | ||
+ | | <code>mM</code> | ||
+ | | | ||
+ | | включить эвристическое определение ошибки превышения лимита памяти | ||
+ | |- | ||
+ | | <code>w<DIR></code> | ||
| путь к каталогу - строка | | путь к каталогу - строка | ||
| задать рабочий каталог для запускаемой программы | | задать рабочий каталог для запускаемой программы | ||
|- | |- | ||
− | | < | + | | <code>rn</code> |
| | | | ||
| перенаправить stdin, stdout и stderr на /dev/null | | перенаправить stdin, stdout и stderr на /dev/null | ||
|- | |- | ||
− | | < | + | | <code>rm</code> |
| | | | ||
| слить вывод на stdout и stderr в один поток, задаваемый спецификацией перенаправления для stdout | | слить вывод на stdout и stderr в один поток, задаваемый спецификацией перенаправления для stdout | ||
|- | |- | ||
− | | < | + | | <code>ri<FILE></code> |
| путь к файлу - строка | | путь к файлу - строка | ||
| перенаправить stdin из файла FILE | | перенаправить stdin из файла FILE | ||
|- | |- | ||
− | | < | + | | <code>ro<FILE></code> |
| путь к файлу - строка | | путь к файлу - строка | ||
| перенаправить stdout в файл FILE в режиме перезаписи | | перенаправить stdout в файл FILE в режиме перезаписи | ||
|- | |- | ||
− | | < | + | | <code>rO<FILE></code> |
| путь к файлу - строка | | путь к файлу - строка | ||
| перенаправить stdout в файл FILE в режиме добавления | | перенаправить stdout в файл FILE в режиме добавления | ||
|- | |- | ||
− | | < | + | | <code>re<FILE></code> |
| путь к файлу - строка | | путь к файлу - строка | ||
| перенаправить stderr в файл FILE в режиме перезаписи | | перенаправить stderr в файл FILE в режиме перезаписи | ||
|- | |- | ||
− | | < | + | | <code>rE<FILE></code> |
| путь к файлу - строка | | путь к файлу - строка | ||
| перенаправить stderr в файл FILE в режиме добавления | | перенаправить stderr в файл FILE в режиме добавления | ||
|- | |- | ||
− | | < | + | | <code>rp<FILE></code> |
| путь к файлу - строка | | путь к файлу - строка | ||
| запускать на выполнение файл FILE, а не файл, имя которого указано в командной строке. Опция используется, когда у запускаемой программы имя запускаемого файла отличается от argv[0]. | | запускать на выполнение файл FILE, а не файл, имя которого указано в командной строке. Опция используется, когда у запускаемой программы имя запускаемого файла отличается от argv[0]. | ||
|- | |- | ||
− | | < | + | | <code>ra<FD></code> |
| ф.д. - целое число | | ф.д. - целое число | ||
| перенаправить stdin из заданного открытого файлового дескриптора | | перенаправить stdin из заданного открытого файлового дескриптора | ||
|- | |- | ||
− | | < | + | | <code>rb<FD></code> |
| ф.д. - целое число | | ф.д. - целое число | ||
| перенаправить stdout в заданный открытый файловый дескриптор | | перенаправить stdout в заданный открытый файловый дескриптор | ||
|- | |- | ||
− | | < | + | | <code>lt<T></code> |
| миллисекунды - целое число | | миллисекунды - целое число | ||
| установить ограничение на процессорное время в миллисекундах | | установить ограничение на процессорное время в миллисекундах | ||
|- | |- | ||
− | | < | + | | <code>lr<T></code> |
| миллисекунды - целое число | | миллисекунды - целое число | ||
| установить ограничение на реальное время в миллисекундах | | установить ограничение на реальное время в миллисекундах | ||
|- | |- | ||
− | | < | + | | <code>lm<M></code> |
| восьмеричное число | | восьмеричное число | ||
| установить параметр umask для запускаемой программы | | установить параметр umask для запускаемой программы | ||
|- | |- | ||
− | | < | + | | <code>lo<N></code> |
| целое число | | целое число | ||
| установить лимит на количество открытых файловых дескрипторов | | установить лимит на количество открытых файловых дескрипторов | ||
|- | |- | ||
− | | < | + | | <code>lu<N></code> |
| целое число | | целое число | ||
| установить лимит на количество процессов | | установить лимит на количество процессов | ||
|- | |- | ||
− | | < | + | | <code>ls<Z></code> |
| размер | | размер | ||
| установить лимит на размер стека в байтах | | установить лимит на размер стека в байтах | ||
|- | |- | ||
− | | < | + | | <code>lv<Z></code> |
| размер | | размер | ||
| установить лимит на размер виртуального адресного пространства в байтах | | установить лимит на размер виртуального адресного пространства в байтах | ||
|- | |- | ||
− | | < | + | | <code>lR<Z></code> |
| размер | | размер | ||
| установить лимит на размер потребленной оперативной памяти (RSS) в байтах | | установить лимит на размер потребленной оперативной памяти (RSS) в байтах | ||
|- | |- | ||
− | | < | + | | <code>lf<Z></code> |
| размер | | размер | ||
| установить лимит на размер файлов, создаваемых запускаемой программой в байтах | | установить лимит на размер файлов, создаваемых запускаемой программой в байтах | ||
|- | |- | ||
− | | < | + | | <code>ol<S></code> |
| имя языка - строка | | имя языка - строка | ||
| задать язык программирования, на котором написана запускаемая программа | | задать язык программирования, на котором написана запускаемая программа | ||
|- | |- | ||
− | | < | + | | <code>s0</code> |
| | | | ||
| отключить фильтрацию системных вызовов | | отключить фильтрацию системных вызовов | ||
|- | |- | ||
− | | < | + | | <code>se</code> |
| | | | ||
| разрешить системные вызовы семейства exec | | разрешить системные вызовы семейства exec | ||
|- | |- | ||
− | | < | + | | <code>sf</code> |
| | | | ||
| разрешить системные вызовы семейства fork | | разрешить системные вызовы семейства fork | ||
|- | |- | ||
− | | < | + | | <code>su</code> |
+ | | | ||
+ | | разрешить системный вызов <code>unshare</code> | ||
+ | |- | ||
+ | | <code>sm</code> | ||
+ | | | ||
+ | | разрешить системный вызов <code>memfd_create</code> | ||
+ | |- | ||
+ | | <code>cf<FD></code> | ||
| ф.д. - целое число | | ф.д. - целое число | ||
| задать файловый дескриптор для управляющего сокета для управления выполняющейся программой извне | | задать файловый дескриптор для управляющего сокета для управления выполняющейся программой извне | ||
|- | |- | ||
− | | < | + | | <code>cu<N></code> |
| целое число | | целое число | ||
| задать последовательный номер пользователя, под которым выполнять запущенную программу | | задать последовательный номер пользователя, под которым выполнять запущенную программу | ||
Line 321: | Line 339: | ||
Не гарантируется корректная работа программы при использовании | Не гарантируется корректная работа программы при использовании | ||
− | опций < | + | опций <code>mo</code>, <code>mG</code>, <code>mp</code>. FIXME: удалить их? |
==== Режим компиляции ==== | ==== Режим компиляции ==== | ||
− | Опция < | + | Опция <code>mC</code> определяет, что программа должна запускаться в режиме "компилятора". |
Этот режим предназначен для использования при компиляции программ. Компилятор ограничивается | Этот режим предназначен для использования при компиляции программ. Компилятор ограничивается | ||
в доступе к различным важным с точки зрения безопасности файлам файловой системы хоста. | в доступе к различным важным с точки зрения безопасности файлам файловой системы хоста. | ||
В режиме компиляции: | В режиме компиляции: | ||
− | * отключается фильтрация системных вызовов (< | + | * отключается фильтрация системных вызовов (<code>s0</code>) |
− | * отключается перекрытие файловой системы /proc (< | + | * отключается перекрытие файловой системы /proc (<code>mP</code>) |
− | * отключается перекрытие файловой системы /sys (< | + | * отключается перекрытие файловой системы /sys (<code>mS</code>) |
− | * отключается перекрытие файловой системы /dev (< | + | * отключается перекрытие файловой системы /dev (<code>md</code>) |
* лимит количества процессов устанавливается в 100 | * лимит количества процессов устанавливается в 100 | ||
* отключается лимит размера виртуальной памяти | * отключается лимит размера виртуальной памяти | ||
* отключается лимит реального времени | * отключается лимит реального времени | ||
* лимит процессорного времени устанавливается в 60000 мс | * лимит процессорного времени устанавливается в 60000 мс | ||
− | * для запуска программы используется пользователь < | + | * для запуска программы используется пользователь <code>ejcompile</code> |
==== Настройка исходного языка программирования ==== | ==== Настройка исходного языка программирования ==== | ||
− | Опция < | + | Опция <code>ol</code> позволяет указать, на каком языке программирования была написана запускаемая программа. |
В зависимости от этого выполняется донастройка параметров запуска программы. | В зависимости от этого выполняется донастройка параметров запуска программы. | ||
Это сделано для того, чтобы запуск программ на разных языках программирования не требовал | Это сделано для того, чтобы запуск программ на разных языках программирования не требовал | ||
Line 422: | Line 440: | ||
* <code>t</code> (одна буква 't') — исчерпан лимит процессорного времени | * <code>t</code> (одна буква 't') — исчерпан лимит процессорного времени | ||
* <code>r</code> — исчерпан лимит реального времени | * <code>r</code> — исчерпан лимит реального времени | ||
+ | * <code>m</code> — исчерпан лимит памяти | ||
+ | * <code>v</code> — нарушение ограничений безопасности | ||
* <code>e<N></code> (буква 'e', за которой следует число) — программа завершилась с кодом завершения N | * <code>e<N></code> (буква 'e', за которой следует число) — программа завершилась с кодом завершения N | ||
* <code>s<N></code> (буква 's', за которой следует число) — программа завершилась из-за сигнала N | * <code>s<N></code> (буква 's', за которой следует число) — программа завершилась из-за сигнала N |
Latest revision as of 06:54, 8 January 2024
Навигация: Главная страница/Система ejudge/Использование/Общая архитектура системы/ej-suid-container
Программа доступна с версии 3.9.0.
Данная программа реализует защищенный запуск программ на выполнение с использованием контейнеров Linux. Для программы создается изолированное окружение, в котором недоступна сеть, не видны другие процессы в системе, и скрыты некоторые каталоги файловой системы, а вместо некоторых других каталогов отображаются специально подготовленные образы. По умолчанию тестируемой программе запрещено исполнять некоторые системные вызовы.
Для правильной работы программа должна быть установлена как suid root программа. Она заменяет собой программы ej-suid-chown, ej-suid-exec, ej-suid-ipcrm, ej-suid-kill, то есть при использовании ej-suid-container данные программы могут быть удалены.
В текущей версии программа предназначена прежде всего для использования из других программ, поэтому не ставит целью вернуть информацию о завершившейся программе в человеко-читаемом виде или принимать аргументы командной строки в удобном для человека виде.
Contents
Изоляция запускаемой программы
Программа запускается в новом пространстве идентификаторов процессов Linux (pid namespaces). Идентификатор процесса 1 имеет процесс, который мониторит поведение выполняющейся программы. Он играет роль локального процесса init. Запускаемая программа получает идентификатор процесса 2. Если программа будет создавать новые процессы, им будут выдаваться последовательные идентификаторы. По умолчанию для пользователя, под которым выполняется запускаемая программа, устанавливается ограничение в 5 процессов.
Программа запускается в новом пространстве имен для объектов IPC. Все семафоры, сегменты разделяемой памяти, очереди сообщений, которые были созданы программой, будут уничтожены автоматически при ее завершении. Запускаемая программа не имеет доступ к объектам IPC на хост-системе.
Программа запускается в новом пространстве имен сетевой подсистемы. В этом пространстве имен не создаются никакие сетевые интерфейсы, то есть запускаемая программа работает с отключенной сетью. Она не имеет доступа к сетевым интерфейсам хост-системы.
Программа запускается в новом пространстве имен монтируемых каталогов файловой системы (mount namespace). Для запускаемой программы файловая система хост-системы модифицируется следующим образом:
- Демонтируются все файловые системы типов
fusectl
,rpc_pipefs
,securityfs
и аналогичных, которые могут использоваться для доступа к системной информации.
- Рабочий каталог запускаемой программы монтируется в
/sandbox
. Он будет установлен как текущий каталог при запуске.
- Каталог
/proc
перекрывается пустым каталогом.
- Каталог
/sys
перекрывается пустым каталогом.
- Каталог
/boot
перекрывается пустым каталогом.
- Каталог
/srv
перекрывается пустым каталогом.
- Каталог
/data
перекрывается пустым каталогом.
- Если подготовлен образ каталога /root, то этот образ перекрывает каталог
/root
.
- Если подготовлен образ каталога /etc, этот образ перекрывает каталог
/etc
, однако/etc/alternatives
и/etc/java
монтируется с файловой системы хоста.
- Если подготовлен образ каталога
/var
, этот образ перекрывает каталог/var
файловой системы.
- Если подготовлен образ каталога
/dev
, этот образ перекрывает каталог/dev
файловой системы.
- Каталоги
/tmp
,/run
,/dev/mqueue
,/dev/shm
инициализируются как пустые каталоги для временных файлов (файловая система tmpfs).
- Если подготовлен образ каталога
/home
, этот образ перекрывает каталог/home
файловой системы, за исключеним каталога/home/judges/compile
, который монтируется с файловой системы хоста. В противном случае каталоги /home/judges/data и /home/judges/var перекрываются пустыми каталогами.
Подготовленные образы каталогов должны располагаться в каталоге
EJUDGE_PREFIX_DIR/share/ejudge/container
. Eсли
EJUDGE_PREFIX_DIR установлен в /opt/ejudge
, то каталог
должен выглядеть так:
[~]$ ls /opt/ejudge/share/ejudge/container dev empty etc home root var
У запускаемой программы блокируется возможность выполнения "небезопасных" системных вызовов. В текущей версии — это системные вызовы семейства fork (то есть fork, vfork, clone, clone3) и системные вызовы семейства exec (то есть execve, execveat). В дальнейшем список блокируемых системных вызовов может быть расширен. Если программа пытается выполнить запрещенный системный вызов, она получит сигнал SIGSYS (Bad system call).
У запускаемой программы блокируется возможность повышения привилегий с помощью исполнения suid-программ.
Использование
Использование:
ej-suid-container [OPTIONS] PROGRAM [ARGUMENTS]
Здесь OPTIONS
— дополнительные опции для настройки
контейнеров. PROGRAM
— запускаемая программа,
ARGUMENTS
— аргументы для запускаемой программы.
Все опции для ej-suid-container задаются в одном аргументе командной строки.
Между опциями отсутствуют разделители, но может использоваться символ
',
' (запятая), который в опциях игнорируется.
Опции начинаются со знака "минус".
Если опция требует целого параметра, параметр записывается сразу после опции
без разделителя, например lo10
.
Если опция требует параметра-размера, то после целого числа может следовать суффикс 'k', 'm' или 'g', задающий соответствующий множитель. Чтобы отделить значение с суффиксом от следующей опции можно использовать запятую.
Если опция требует параметр-строку, сразу же после опции записывается
длина строки, затем символ "запятая", затем строка-параметр,
например, ri10,/tmp/a.txt
. Либо сразу после опции записывается
символ-терминатор строки, а далее идет строка до этого символа-терминатора,
например, ri|/tmp/a.txt|
.
f<FD>
|
файловый дескриптор - целое число | задать ф. д. для получения результата выполнения программы Если опция отсутствует, то строка результата выводится на stderr |
mg
|
не создавать linux control group (не использовать!) | |
mi
|
не создавать пространство имен IPC, запускаемая программа будет иметь доступ к объектам IPC хост-системы | |
mn
|
не создавать пространство имен сетевых интерфейсов, запускаемая программа будет иметь неограниченный доступ к сети | |
ml
|
в изолированном пространстве сетевых интерфейсов поднять интерфейс lo (loopback) и настроить его на адрес 127.0.0.1 (3.11.0) | |
mm
|
не создавать пространство имен файловой системы, запускаемая программа будет иметь доступ ко всей файловой системе хост-системы | |
mp
|
не создавать пространство имен процессов, запускаемая программа будет иметь идентификатор процесса среди процессов хост-системы (не использовать!) | |
mP
|
не перекрывать файловую систему /proc, хотя в ней будут отображаться только процессы из пространства имен процессов, но общесистемные файлы, например, /proc/sys будут доступны | |
mS
|
не перекрывать доступ к файловой системе /sys | |
mv
|
не подменять файловую систему /var, запускаемая программа будет иметь доступ к каталогу /var хост-системы | |
me
|
не подменять файловую систему /etc, запускаемая программа будет иметь доступ к каталогу /etc хост-системы | |
ms
|
не привязывать рабочий каталог программы к каталогу /sandbox | |
mh
|
не подменять файловую систему /home, запускаемая программа будет иметь доступ к каталогу /home хост-системы | |
md
|
не подменять файловую систему /dev, запускаемая программа будет иметь доступ к каталогу /dev хост-системы | |
mr
|
не подменять файловую систему /run, запускаемая программа будет иметь доступ к каталогу /run хост-системы (3.11.0) | |
mo
|
не менять пользователя на ejexec/ejcompile (не использовать!) | |
mG
|
не создавать новую группу процессов (не использовать!) | |
mc
|
после завершения запущенной программы посчитать количество оставшихся незавершенных процессов. Может быть полезно, когда запускаемая программа создает другие процессы и необходимо проконтролировать, что все запущенные процессы были завершены перед завершением основной программы. Независимо от значения этой опции все такие процессы будут принудительно завершены, эта опция позволяет получить их количество. | |
mI
|
посчитать количество объектов IPC, оставшихся неудаленными после завершения программы. | |
ma
|
не ограничивать процессорное время для запускаемой программы | |
mb
|
не ограничивать реальное время для запускаемой программы | |
mD
|
переносить в контейнер не сам рабочий каталог, а его родительский каталог. Используется когда при тестировании в ejudge установлена опция use_tgz .
| |
mC
|
запускать программу в режиме контейнера для компиляции | |
mV
|
отменить установку значения по умолчанию для лимита виртуальной памяти | |
mE
|
включить определение ошибки "security violation" | |
mM
|
включить эвристическое определение ошибки превышения лимита памяти | |
w<DIR>
|
путь к каталогу - строка | задать рабочий каталог для запускаемой программы |
rn
|
перенаправить stdin, stdout и stderr на /dev/null | |
rm
|
слить вывод на stdout и stderr в один поток, задаваемый спецификацией перенаправления для stdout | |
ri<FILE>
|
путь к файлу - строка | перенаправить stdin из файла FILE |
ro<FILE>
|
путь к файлу - строка | перенаправить stdout в файл FILE в режиме перезаписи |
rO<FILE>
|
путь к файлу - строка | перенаправить stdout в файл FILE в режиме добавления |
re<FILE>
|
путь к файлу - строка | перенаправить stderr в файл FILE в режиме перезаписи |
rE<FILE>
|
путь к файлу - строка | перенаправить stderr в файл FILE в режиме добавления |
rp<FILE>
|
путь к файлу - строка | запускать на выполнение файл FILE, а не файл, имя которого указано в командной строке. Опция используется, когда у запускаемой программы имя запускаемого файла отличается от argv[0]. |
ra<FD>
|
ф.д. - целое число | перенаправить stdin из заданного открытого файлового дескриптора |
rb<FD>
|
ф.д. - целое число | перенаправить stdout в заданный открытый файловый дескриптор |
lt<T>
|
миллисекунды - целое число | установить ограничение на процессорное время в миллисекундах |
lr<T>
|
миллисекунды - целое число | установить ограничение на реальное время в миллисекундах |
lm<M>
|
восьмеричное число | установить параметр umask для запускаемой программы |
lo<N>
|
целое число | установить лимит на количество открытых файловых дескрипторов |
lu<N>
|
целое число | установить лимит на количество процессов |
ls<Z>
|
размер | установить лимит на размер стека в байтах |
lv<Z>
|
размер | установить лимит на размер виртуального адресного пространства в байтах |
lR<Z>
|
размер | установить лимит на размер потребленной оперативной памяти (RSS) в байтах |
lf<Z>
|
размер | установить лимит на размер файлов, создаваемых запускаемой программой в байтах |
ol<S>
|
имя языка - строка | задать язык программирования, на котором написана запускаемая программа |
s0
|
отключить фильтрацию системных вызовов | |
se
|
разрешить системные вызовы семейства exec | |
sf
|
разрешить системные вызовы семейства fork | |
su
|
разрешить системный вызов unshare
| |
sm
|
разрешить системный вызов memfd_create
| |
cf<FD>
|
ф.д. - целое число | задать файловый дескриптор для управляющего сокета для управления выполняющейся программой извне |
cu<N>
|
целое число | задать последовательный номер пользователя, под которым выполнять запущенную программу |
Не гарантируется корректная работа программы при использовании
опций mo
, mG
, mp
. FIXME: удалить их?
Режим компиляции
Опция mC
определяет, что программа должна запускаться в режиме "компилятора".
Этот режим предназначен для использования при компиляции программ. Компилятор ограничивается
в доступе к различным важным с точки зрения безопасности файлам файловой системы хоста.
В режиме компиляции:
- отключается фильтрация системных вызовов (
s0
) - отключается перекрытие файловой системы /proc (
mP
) - отключается перекрытие файловой системы /sys (
mS
) - отключается перекрытие файловой системы /dev (
md
) - лимит количества процессов устанавливается в 100
- отключается лимит размера виртуальной памяти
- отключается лимит реального времени
- лимит процессорного времени устанавливается в 60000 мс
- для запуска программы используется пользователь
ejcompile
Настройка исходного языка программирования
Опция ol
позволяет указать, на каком языке программирования была написана запускаемая программа.
В зависимости от этого выполняется донастройка параметров запуска программы.
Это сделано для того, чтобы запуск программ на разных языках программирования не требовал
бы указания различных опций настройки, зависящих от языка, то есть чтобы любые поддерживаемые языки
программирования работали "из коробки".
В таблице перечислены дополнительные настройки для поддерживаемых языков программирования.
языки | настройки | комментарий |
javac7, javac, kotlin, scala | s0mPls1M,lu40lv-1
|
отключается лимит размера виртуальной памяти, ограничение размера выполняется средствами jvm |
mcs, vbnc, pasabc-linux | s0mPls1M
|
если задано ограничение размера виртуальной памяти, оно переустанавливается на ограничение RSS. Ограничение VM снимается. |
pypy, pypy3 | mP
|
|
gcc-vg, g++-vg | s0mP
|
если задано ограничение размера виртуальной памяти, оно переустанавливается на ограничение RSS. Ограничение VM снимается. |
dotnet-cs, dotnet-vb | s0mPls1M,lu40
|
если задано ограничение размера виртуальной памяти, оно переустанавливается на ограничение RSS. Ограничение VM снимается. |
make | s0mP
|
|
make-vg | s0mP
|
если задано ограничение размера виртуальной памяти, оно переустанавливается на ограничение RSS. Ограничение VM снимается. |
gccgo | s0mPlu20
|
если задано ограничение размера виртуальной памяти, оно переустанавливается на ограничение RSS. Ограничение VM снимается. |
node | s0mPls1M,lu20
|
если задано ограничение размера виртуальной памяти, оно переустанавливается на ограничение RSS. Ограничение VM снимается. |
Настройка пользователя, под которым выполняется программа
Опция cu
позволяет модифицировать пользователя, под которым запускается программа.
Если опция не указана, то используется пользователь ejexec
. Если указан номер, например, cu1
,
то используется пользователь ejexec1
. Соответствующий пользователь должен быть создан.
Внешнее управление выполняющейся программой
Опция cf
позволяет задать файловый дескриптор, с помощью которого внешняя программа может
управлять выполняющейся программой. Этот файловый дескриптор должен быть двусторонним UNIX-сокетом.
Его следует создавать с помощью системного вызова socketpair
.
Команда занимает 4 байта и передается в бинарном виде. Поддерживается следующие команды.
0xe00001SS
- отправить в тестируемую программу сигнал SS.
Номер сигнала занимает младший байт сообщения.
Возвращаемая информация о работе программы
Программа ej-suid-container завершается с кодом 0, если процесс для запуска указанной программы был создан. В случае фатальной ошибки при создании процесса возвращается код 1.
Информация о выполнении запускаемой программы выводится в файловый дескриптор, переданный с опцией f
,
либо на стандартный поток ошибок, если опция не задана. Информация выводится в виде закодированной строки
в следующем формате.
Сначала идет информация о том, как завершилась программа:
t
(одна буква 't') — исчерпан лимит процессорного времениr
— исчерпан лимит реального времениm
— исчерпан лимит памятиv
— нарушение ограничений безопасностиe<N>
(буква 'e', за которой следует число) — программа завершилась с кодом завершения Ns<N>
(буква 's', за которой следует число) — программа завершилась из-за сигнала N
Далее в произвольном порядке идет детальная информация о завершении программы:
T<T>
— затраченное процессорное время в микросекундахR<T>
— затраченное астрономическое время в микросекундахu<T>
— затраченное пользовательское время в микросекундахs<T>
— затраченное системное время в микросекундахv<Z>
— максимальный размер виртуальной памяти в байтах (неточно)e<Z>
— максимальный размер использованной оперативной памяти (RSS) в байтахa<N>
— поле ru_nvcswb<N>
— поле ru_nivcswi<N>
— количество объектов IPC, оставшихся после завершенияo<N>
— количество процессов-сирот, оставшихся после завершенияct<T>
— затраченное процессорное время в микросекундах по всем процессам в совокупностиcu<T>
— затраченное пользовательское время в микросекундах по всем процессам в совокупностиcs<T>
— затраченное системное время в микросекундах по всем процессам в совокупностиL<S>
— дополнительные сообщения - строка в формате, описанном выше (длина - запятая - содержимое)
FIXME: выводить на stderr в JSON-формате?