-
Notifications
You must be signed in to change notification settings - Fork 67
[ML] Generate syscall policies from one declaration; fail-closed degraded seccomp #3182
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
valeriy42
wants to merge
1
commit into
feature/sandbox2-pr-a-foundation
from
feature/sandbox2-pr-b-seccomp-policy
Open
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,128 @@ | ||
| /* | ||
| * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one | ||
| * or more contributor license agreements. Licensed under the Elastic License | ||
| * 2.0 and the following additional limitation. Functionality enabled by the | ||
| * files subject to the Elastic License 2.0 may only be used in production when | ||
| * invoked by an Elasticsearch process with a license key installed that permits | ||
| * use of machine learning features. You may not use this file except in | ||
| * compliance with the Elastic License 2.0 and the foregoing additional | ||
| * limitation. | ||
| */ | ||
| #ifndef INCLUDED_ml_seccomp_CPytorchInferenceSyscallAllowlist_h | ||
| #define INCLUDED_ml_seccomp_CPytorchInferenceSyscallAllowlist_h | ||
|
|
||
| #include <vector> | ||
|
|
||
| #ifdef __linux__ | ||
| #include <sys/syscall.h> | ||
| #endif | ||
|
|
||
| namespace ml { | ||
| namespace seccomp { | ||
| namespace pytorch_inference { | ||
|
|
||
| #ifdef __linux__ | ||
|
|
||
| // statx, rseq and clone3 won't be defined on a RHEL/CentOS 7 build machine, | ||
| // but might exist on the kernel we run on, so fall back to the raw numbers. | ||
| #if defined(__x86_64__) | ||
| #ifndef __NR_statx | ||
| #define ML_NR_statx 332 | ||
| #else | ||
| #define ML_NR_statx __NR_statx | ||
| #endif | ||
| #ifndef __NR_rseq | ||
| #define ML_NR_rseq 334 | ||
| #else | ||
| #define ML_NR_rseq __NR_rseq | ||
| #endif | ||
| #elif defined(__aarch64__) | ||
| #ifndef __NR_statx | ||
| #define ML_NR_statx 291 | ||
| #else | ||
| #define ML_NR_statx __NR_statx | ||
| #endif | ||
| #ifndef __NR_rseq | ||
| #define ML_NR_rseq 293 | ||
| #else | ||
| #define ML_NR_rseq __NR_rseq | ||
| #endif | ||
| #endif | ||
| #ifndef __NR_clone3 | ||
| #define ML_NR_clone3 435 | ||
| #else | ||
| #define ML_NR_clone3 __NR_clone3 | ||
| #endif | ||
|
|
||
| //! Syscalls permitted by the legacy in-process BPF filter | ||
| //! (CSystemCallFilter_Linux.cc) for every process that installs it, currently | ||
| //! shared by pytorch_inference, autodetect, categorize, normalize and | ||
| //! data_frame_analyzer. This is the single machine-readable declaration that | ||
| //! the applied BPF program is generated from: CSystemCallFilter_Linux.cc | ||
| //! contains no independent syscall list and no manually maintained jump | ||
| //! offsets. A future Sandbox2 policy is expected to consume the same | ||
| //! declaration for its explicit grants, so both mechanisms stay in sync. | ||
| //! | ||
| //! Carry-forward note: PR #2873 fixed several pytorch_inference/libtorch | ||
| //! compatibility gaps the hard way, and this declaration is a rewrite from | ||
| //! scratch rather than a copy of that work, so it deliberately keeps two of | ||
| //! them. ML_NR_clone3 (see 57f00ed1b) and __NR_prlimit64 (see 03b1ee4a) are | ||
| //! carried into this shared declaration so a future Sandbox2 policy | ||
| //! inherits them automatically instead of rediscovering them the same way; | ||
| //! CSeccompFilterBuilderTest.cc asserts both stay present. The x86_64 | ||
| //! legacy filesystem syscalls below (see ec7d3ed85) were already part of | ||
| //! this filter's syscall set prior to this declaration and remain | ||
| //! unchanged. PR #2873's futex-op broadening (see d9a856d5f) and CI | ||
| //! link-order/test-bundle packaging fixes (see 730933db, f8b0a534) apply to | ||
| //! the Sandbox2 policy and its Buildkite pipeline respectively, not to this | ||
| //! file — carry those forward when that code is written instead of | ||
| //! rediscovering them. | ||
| inline std::vector<int> legacyBpfAllowedSyscalls() { | ||
| std::vector<int> syscalls { | ||
| #if defined(__x86_64__) | ||
| __NR_access, __NR_open, __NR_dup2, __NR_unlink, __NR_stat, __NR_lstat, | ||
| __NR_time, __NR_readlink, __NR_getdents, // for forecast temp storage | ||
| __NR_rmdir, // for forecast temp storage | ||
| __NR_mkdir, // for forecast temp storage | ||
| __NR_mknod, | ||
| #elif defined(__aarch64__) | ||
| __NR_faccessat, | ||
| #endif | ||
| __NR_fcntl, // for fdopendir | ||
| __NR_getrusage, | ||
| __NR_getpid, // for pthread_kill | ||
| ML_NR_statx, // for create_directories | ||
| __NR_getrandom, // for unique_path | ||
| __NR_mknodat, __NR_newfstatat, __NR_readlinkat, __NR_dup3, | ||
| __NR_getpriority, // for nice | ||
| __NR_setpriority, // for nice | ||
| __NR_read, __NR_write, __NR_writev, __NR_lseek, __NR_clock_gettime, | ||
| __NR_gettimeofday, __NR_fstat, __NR_close, __NR_connect, | ||
| ML_NR_clone3, __NR_clone, __NR_statfs, | ||
| __NR_mkdirat, // for forecast temp storage | ||
| __NR_unlinkat, // for forecast temp storage | ||
| __NR_getdents64, // for forecast temp storage | ||
| __NR_openat, // for forecast temp storage | ||
| __NR_tgkill, // for the crash handler | ||
| __NR_rt_sigaction, // for the crash handler | ||
| __NR_rt_sigreturn, | ||
| __NR_rt_sigprocmask, // for recent pthread_create | ||
| ML_NR_rseq, // for recent pthread_create | ||
| __NR_futex, __NR_madvise, __NR_nanosleep, __NR_set_robust_list, | ||
| __NR_mprotect, // for malloc arenas and pthread stacks | ||
| __NR_mremap, // for malloc arenas | ||
| __NR_munmap, // for malloc arenas | ||
| __NR_mmap, // for malloc arenas | ||
| __NR_getuid, __NR_exit_group, __NR_brk, __NR_exit, | ||
| __NR_prlimit64, // libtorch/Sandbox2-monitor query rlimits under load (03b1ee4a) | ||
| }; | ||
| return syscalls; | ||
| } | ||
|
|
||
| #endif // __linux__ | ||
|
|
||
| } // namespace pytorch_inference | ||
| } // namespace seccomp | ||
| } // namespace ml | ||
|
|
||
| #endif // INCLUDED_ml_seccomp_CPytorchInferenceSyscallAllowlist_h | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,39 @@ | ||
| /* | ||
| * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one | ||
| * or more contributor license agreements. Licensed under the Elastic License | ||
| * 2.0 and the following additional limitation. Functionality enabled by the | ||
| * files subject to the Elastic License 2.0 may only be used in production when | ||
| * invoked by an Elasticsearch process with a license key installed that permits | ||
| * use of machine learning features. You may not use this file except in | ||
| * compliance with the Elastic License 2.0 and the foregoing additional | ||
| * limitation. | ||
| */ | ||
| #ifndef INCLUDED_ml_seccomp_CSeccompFilterBuilder_h | ||
| #define INCLUDED_ml_seccomp_CSeccompFilterBuilder_h | ||
|
|
||
| #ifdef __linux__ | ||
|
|
||
| #include <linux/filter.h> | ||
|
|
||
| #include <vector> | ||
|
|
||
| namespace ml { | ||
| namespace seccomp { | ||
|
|
||
| //! Builds a seccomp BPF program that allows exactly allowedSyscalls, on the | ||
| //! native architecture only, and denies everything else with EACCES. | ||
| //! | ||
| //! The caller supplies allowedSyscalls in any order: every generated jump | ||
| //! offset is derived from the vector's size and the row's own index, so | ||
| //! adding, removing or reordering a syscall never requires updating any | ||
| //! other row. This is the mechanism that lets CSystemCallFilter_Linux.cc | ||
| //! apply CPytorchInferenceSyscallAllowlist.h's declaration directly, instead | ||
| //! of maintaining a second, hand-written BPF program with manual jump | ||
| //! offsets that can silently drift from the declaration. | ||
| std::vector<sock_filter> buildSyscallAllowlistProgram(const std::vector<int>& allowedSyscalls); | ||
| } | ||
| } | ||
|
|
||
| #endif // __linux__ | ||
|
|
||
| #endif // INCLUDED_ml_seccomp_CSeccompFilterBuilder_h |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think that both the name and the
pytorch_inferencenamespace are misleading here. The header comment notes this allowlist is shared by all five ML binaries (pytorch_inference, autodetect, categorize, normalize, data_frame_analyzer), but the name implies it is exclusive to pytorch_inference. A reader ofautodetect/Main.cchas no way to know thatinstallSystemCallFilter()internally callspytorch_inference::legacyBpfAllowedSyscalls().I get the forward-looking intention (that the Sandbox2 policy will eventually consume this declaration specifically for pytorch_inference), but that makes the naming more load-bearing, not less. When the other four binaries eventually get their own policies the name will actively mislead. Something like
CMlLegacyBpfSyscallAllowlist.hwith the function inml::seccomp(not apytorch_inferencesub-namespace) would still be accurate today while keeping the door open for the future split.