diff --git a/3rd_party/CMakeLists.txt b/3rd_party/CMakeLists.txt index f2b092f913..5d1c612f4e 100644 --- a/3rd_party/CMakeLists.txt +++ b/3rd_party/CMakeLists.txt @@ -39,3 +39,121 @@ execute_process( COMMAND ${CMAKE_COMMAND} -P ./pull-valijson.cmake WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} ) + +# Build Abseil and Sandbox2 on Linux only. MlSandbox (lib/sandbox) is a +# dormant target: it is built everywhere Sandbox2 is available, but nothing +# in the controller/pytorch_inference wiring routes to it yet. The sandbox +# policy, spawner, and controller routing land in follow-up PRs. +if (CMAKE_SYSTEM_NAME STREQUAL "Linux") + include(FetchContent) + + # Save and restore CMake cache state this block flips so it cannot change + # the caller's build configuration for anything outside Sandbox2/Abseil. + set(_saved_BUILD_TESTING ${BUILD_TESTING}) + set(BUILD_TESTING OFF CACHE BOOL "" FORCE) + set(_saved_BUILD_SHARED_LIBS ${BUILD_SHARED_LIBS}) + set(BUILD_SHARED_LIBS OFF CACHE BOOL "" FORCE) + + # The vendored Abseil and Sandboxed API sources are not unity-build safe: + # e.g. absl_time_zone defines kDigits in an anonymous namespace in both + # time_zone_fixed.cc and time_zone_posix.cc, which collide when merged + # into one unity translation unit. The top-level build configures + # -DCMAKE_UNITY_BUILD=ON, so disable it for these third-party targets only. + set(_saved_CMAKE_UNITY_BUILD ${CMAKE_UNITY_BUILD}) + set(CMAKE_UNITY_BUILD OFF) + + set(ABSL_PROPAGATE_CXX_STD ON CACHE INTERNAL "" FORCE) + set(ABSL_USE_EXTERNAL_GOOGLETEST OFF CACHE INTERNAL "" FORCE) + set(ABSL_FIND_GOOGLETEST OFF CACHE INTERNAL "" FORCE) + set(ABSL_ENABLE_INSTALL OFF CACHE INTERNAL "" FORCE) + set(ABSL_BUILD_TESTING OFF CACHE INTERNAL "" FORCE) + set(ABSL_BUILD_TEST_HELPERS OFF CACHE INTERNAL "" FORCE) + set(SAPI_BUILD_EXAMPLES OFF CACHE BOOL "" FORCE) + set(SAPI_BUILD_TESTING OFF CACHE BOOL "" FORCE) + + set(ML_SANDBOXED_API_TAG v20241008) + set(ML_SANDBOXED_API_GIT_SHA 9e07542a03fefa2cf982ba093b099805362df05d) + set(ML_SANDBOXED_API_PATCH_DIR ${CMAKE_CURRENT_SOURCE_DIR}/patches/sandboxed-api) + set(ML_SANDBOXED_API_PATCHES + 0001-abseil-cpp-disable-gtest.patch + 0002-no-fno-exceptions-propagation.patch + 0003-python3-optional.patch + 0004-forkserver-zlib-static-libstdcxx.patch + ) + + FetchContent_Declare( + sandboxed-api + GIT_REPOSITORY https://github.com/google/sandboxed-api.git + GIT_TAG ${ML_SANDBOXED_API_GIT_SHA} + ) + + FetchContent_GetProperties(sandboxed-api) + if(NOT sandboxed-api_POPULATED) + FetchContent_Populate(sandboxed-api) + + find_package(Git REQUIRED) + foreach(_patch ${ML_SANDBOXED_API_PATCHES}) + # Re-running configure in an existing build directory can re-enter this + # block even though the checked-out source was already patched in an + # earlier configure (observed: FetchContent's populated-tracking does + # not reliably short-circuit this across separate `cmake` invocations + # on every CMake/generator combination). `git apply --check` alone + # cannot distinguish "already applied" from "genuinely drifted" - both + # fail to apply cleanly - so try a reverse-check first: if the patch + # reverses cleanly, its change is already present and this is the + # idempotent-rerun case, not drift. + execute_process( + COMMAND ${GIT_EXECUTABLE} apply --reverse --check ${ML_SANDBOXED_API_PATCH_DIR}/${_patch} + WORKING_DIRECTORY ${sandboxed-api_SOURCE_DIR} + RESULT_VARIABLE _patch_already_applied_result + OUTPUT_QUIET + ERROR_QUIET + ) + if(_patch_already_applied_result EQUAL 0) + message(STATUS "sandboxed-api patch already applied (reconfigure): ${_patch}") + continue() + endif() + + execute_process( + COMMAND ${GIT_EXECUTABLE} apply --check ${ML_SANDBOXED_API_PATCH_DIR}/${_patch} + WORKING_DIRECTORY ${sandboxed-api_SOURCE_DIR} + RESULT_VARIABLE _patch_check_result + OUTPUT_QUIET + ERROR_VARIABLE _patch_check_error + ) + if(NOT _patch_check_result EQUAL 0) + message(FATAL_ERROR + "sandboxed-api patch ${_patch} no longer applies to pinned tag " + "${ML_SANDBOXED_API_TAG} (${ML_SANDBOXED_API_GIT_SHA}) - the " + "upstream source has drifted since this patch was written. " + "Regenerate it against the current tag content (see " + "3rd_party/patches/sandboxed-api/README.md).\n" + "${_patch_check_error}") + endif() + execute_process( + COMMAND ${GIT_EXECUTABLE} apply ${ML_SANDBOXED_API_PATCH_DIR}/${_patch} + WORKING_DIRECTORY ${sandboxed-api_SOURCE_DIR} + RESULT_VARIABLE _patch_apply_result + ERROR_VARIABLE _patch_apply_error + ) + if(NOT _patch_apply_result EQUAL 0) + message(FATAL_ERROR "sandboxed-api patch ${_patch} failed to apply: ${_patch_apply_error}") + endif() + message(STATUS "Applied sandboxed-api patch: ${_patch}") + endforeach() + endif() + + add_subdirectory(${sandboxed-api_SOURCE_DIR} ${sandboxed-api_BINARY_DIR} EXCLUDE_FROM_ALL) + + if(TARGET sandbox2::sandbox2) + set(SANDBOX2_LIBRARIES sandbox2::sandbox2 CACHE INTERNAL "Sandbox2 libraries") + message(STATUS "Sandbox2 enabled: using sandbox2::sandbox2") + else() + message(FATAL_ERROR "Sandbox2 required on Linux but sandbox2::sandbox2 was not built") + endif() + + # Restore the caller's settings for the rest of the build. + set(BUILD_TESTING ${_saved_BUILD_TESTING} CACHE BOOL "" FORCE) + set(BUILD_SHARED_LIBS ${_saved_BUILD_SHARED_LIBS} CACHE BOOL "" FORCE) + set(CMAKE_UNITY_BUILD ${_saved_CMAKE_UNITY_BUILD}) +endif() diff --git a/3rd_party/licenses/abseil-INFO.csv b/3rd_party/licenses/abseil-INFO.csv new file mode 100644 index 0000000000..8f3404a519 --- /dev/null +++ b/3rd_party/licenses/abseil-INFO.csv @@ -0,0 +1,2 @@ +name,version,revision,url,license,copyright,sourceURL +abseil-cpp,2024-04-05,61e47a454c81eb07147b0315485f476513cc1230,https://abseil.io,Apache License 2.0,,https://github.com/abseil/abseil-cpp/archive/61e47a454c81eb07147b0315485f476513cc1230.zip diff --git a/3rd_party/licenses/abseil-LICENSE.txt b/3rd_party/licenses/abseil-LICENSE.txt new file mode 100644 index 0000000000..62589edd12 --- /dev/null +++ b/3rd_party/licenses/abseil-LICENSE.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + https://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + https://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/3rd_party/licenses/abseil-NOTICE.txt b/3rd_party/licenses/abseil-NOTICE.txt new file mode 100644 index 0000000000..e69de29bb2 diff --git a/3rd_party/licenses/sandbox2-INFO.csv b/3rd_party/licenses/sandbox2-INFO.csv new file mode 100644 index 0000000000..925a93b13e --- /dev/null +++ b/3rd_party/licenses/sandbox2-INFO.csv @@ -0,0 +1,2 @@ +name,version,revision,url,license,copyright,sourceURL +sandboxed-api,v20241008,9e07542a03fefa2cf982ba093b099805362df05d,https://developers.google.com/code-sandboxing/sandboxed-api,Apache License 2.0,,https://github.com/google/sandboxed-api diff --git a/3rd_party/licenses/sandbox2-LICENSE.txt b/3rd_party/licenses/sandbox2-LICENSE.txt new file mode 100644 index 0000000000..c6b4a3bbcf --- /dev/null +++ b/3rd_party/licenses/sandbox2-LICENSE.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + https://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. \ No newline at end of file diff --git a/3rd_party/licenses/sandbox2-NOTICE.txt b/3rd_party/licenses/sandbox2-NOTICE.txt new file mode 100644 index 0000000000..e69de29bb2 diff --git a/3rd_party/patches/sandboxed-api/0001-abseil-cpp-disable-gtest.patch b/3rd_party/patches/sandboxed-api/0001-abseil-cpp-disable-gtest.patch new file mode 100644 index 0000000000..7510ab6645 --- /dev/null +++ b/3rd_party/patches/sandboxed-api/0001-abseil-cpp-disable-gtest.patch @@ -0,0 +1,15 @@ +diff --git a/cmake/abseil-cpp.cmake b/cmake/abseil-cpp.cmake +index cc9d9fd..d69bfe8 100644 +--- a/cmake/abseil-cpp.cmake ++++ b/cmake/abseil-cpp.cmake +@@ -19,8 +19,8 @@ FetchContent_Declare(absl + set(ABSL_CXX_STANDARD ${SAPI_CXX_STANDARD} CACHE STRING "" FORCE) + set(ABSL_PROPAGATE_CXX_STD ON CACHE BOOL "" FORCE) + set(ABSL_RUN_TESTS OFF CACHE BOOL "" FORCE) +-set(ABSL_BUILD_TEST_HELPERS ON CACHE BOOL "" FORCE) +-set(ABSL_USE_EXTERNAL_GOOGLETEST ON) ++set(ABSL_BUILD_TEST_HELPERS OFF CACHE BOOL "" FORCE) ++set(ABSL_USE_EXTERNAL_GOOGLETEST OFF) + set(ABSL_FIND_GOOGLETEST OFF) + set(ABSL_USE_GOOGLETEST_HEAD OFF CACHE BOOL "" FORCE) + diff --git a/3rd_party/patches/sandboxed-api/0002-no-fno-exceptions-propagation.patch b/3rd_party/patches/sandboxed-api/0002-no-fno-exceptions-propagation.patch new file mode 100644 index 0000000000..0d6a1f4c46 --- /dev/null +++ b/3rd_party/patches/sandboxed-api/0002-no-fno-exceptions-propagation.patch @@ -0,0 +1,17 @@ +diff --git a/CMakeLists.txt b/CMakeLists.txt +index c2b9704..0af9111 100644 +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -111,9 +111,9 @@ target_include_directories(sapi_base PUBLIC + "${SAPI_SOURCE_DIR}" + "${Protobuf_INCLUDE_DIR}" + ) +-target_compile_options(sapi_base PUBLIC +- -fno-exceptions +-) ++# target_compile_options(sapi_base PUBLIC ++# -fno-exceptions ++# ) + if(CMAKE_CXX_COMPILER_ID MATCHES "Clang") + target_compile_options(sapi_base PUBLIC + # The syscall tables in sandbox2/syscall_defs.cc are `std::array`s using diff --git a/3rd_party/patches/sandboxed-api/0003-python3-optional.patch b/3rd_party/patches/sandboxed-api/0003-python3-optional.patch new file mode 100644 index 0000000000..fcbad09cf3 --- /dev/null +++ b/3rd_party/patches/sandboxed-api/0003-python3-optional.patch @@ -0,0 +1,25 @@ +diff --git a/cmake/SapiDeps.cmake b/cmake/SapiDeps.cmake +index 2e595c6..3ee7514 100644 +--- a/cmake/SapiDeps.cmake ++++ b/cmake/SapiDeps.cmake +@@ -104,8 +104,18 @@ if(SAPI_ENABLE_CLANG_TOOL) + else() + # Find Python 3 and add its location to the cache so that its available in + # the add_sapi_library() macro in embedding projects. +- find_package(Python3 COMPONENTS Interpreter REQUIRED) +- set(SAPI_PYTHON3_EXECUTABLE "${Python3_EXECUTABLE}" CACHE INTERNAL "" FORCE) ++ # ++ # ml-cpp patch: made optional. Python3 is only needed for protobuf code ++ # generation; a missing interpreter should not fail configuration when ++ # protobuf sources are already generated or unused by the caller. ++ find_package(Python3 QUIET COMPONENTS Interpreter) ++ if(Python3_Interpreter_FOUND) ++ set(SAPI_PYTHON3_EXECUTABLE "${Python3_EXECUTABLE}" CACHE INTERNAL "" FORCE) ++ else() ++ set(SAPI_PYTHON3_EXECUTABLE "" CACHE INTERNAL "" FORCE) ++ message(STATUS "Python3 interpreter not found - continuing without it " ++ "(protobuf code generation via add_sapi_library() will be unavailable)") ++ endif() + endif() + + # Undo global changes diff --git a/3rd_party/patches/sandboxed-api/0004-forkserver-zlib-static-libstdcxx.patch b/3rd_party/patches/sandboxed-api/0004-forkserver-zlib-static-libstdcxx.patch new file mode 100644 index 0000000000..eb8b5f98ea --- /dev/null +++ b/3rd_party/patches/sandboxed-api/0004-forkserver-zlib-static-libstdcxx.patch @@ -0,0 +1,22 @@ +diff --git a/sandboxed_api/sandbox2/CMakeLists.txt b/sandboxed_api/sandbox2/CMakeLists.txt +index 8246938..0718763 100644 +--- a/sandboxed_api/sandbox2/CMakeLists.txt ++++ b/sandboxed_api/sandbox2/CMakeLists.txt +@@ -245,6 +245,17 @@ target_link_libraries(sandbox2_forkserver_bin PRIVATE + sandbox2::util + sapi::base + sapi::raw_logging ++ # ml-cpp patch: sandbox2::unwind (libunwind_ptrace) calls uncompress(), ++ # which requires libz; link it explicitly instead of relying on transitive ++ # discovery, which --as-needed can drop. ++ z ++) ++# ml-cpp patch: statically link libstdc++/libgcc so the embedded forkserver ++# binary (sandbox2::forkserver_bin_embed below) does not depend on the ++# host's runtime GLIBCXX version at exec time. ++target_link_options(sandbox2_forkserver_bin PRIVATE ++ -static-libstdc++ ++ -static-libgcc + ) + + # sandboxed_api/sandbox2:forkserver_bin_embed diff --git a/3rd_party/patches/sandboxed-api/README.md b/3rd_party/patches/sandboxed-api/README.md new file mode 100644 index 0000000000..e65e971225 --- /dev/null +++ b/3rd_party/patches/sandboxed-api/README.md @@ -0,0 +1,41 @@ +# Sandboxed API source patches + +These patches are applied by [`3rd_party/CMakeLists.txt`](../CMakeLists.txt) +to the vendored `sandboxed-api` checkout (pinned via `FetchContent` to +`GIT_TAG` below) before it is added as a build subdirectory. They replace an +earlier approach that rewrote these files with inline `string(REGEX REPLACE +...)`/`file(WRITE ...)` calls at configure time — fragile because a silent +non-match left the intended change unapplied instead of failing the build. + +Applying via `git apply` instead means a patch that no longer matches the +pinned tag's content **fails the configure step loudly** (`FATAL_ERROR`) +rather than degrading into an unpatched build. + +Pinned tag: `v20241008` at commit `9e07542a03fefa2cf982ba093b099805362df05d` +(see `ML_SANDBOXED_API_TAG` / `ML_SANDBOXED_API_GIT_SHA` in +`3rd_party/CMakeLists.txt`). + +## Patches + +| File | Target | Why | +|---|---|---| +| `0001-abseil-cpp-disable-gtest.patch` | `cmake/abseil-cpp.cmake` | The vendored Abseil `FetchContent` override otherwise builds gtest, which ml-cpp does not vendor and does not need. | +| `0002-no-fno-exceptions-propagation.patch` | `CMakeLists.txt` | `sapi_base` exports `-fno-exceptions` as `PUBLIC`; linking against it would propagate that flag into ml-cpp targets, which use exceptions. | +| `0003-python3-optional.patch` | `cmake/SapiDeps.cmake` | `find_package(Python3 ... REQUIRED)` is only needed for `add_sapi_library()` protobuf code generation, which `MlSandbox` does not use; a missing interpreter should not fail configuration. | +| `0004-forkserver-zlib-static-libstdcxx.patch` | `sandboxed_api/sandbox2/CMakeLists.txt` | `sandbox2::unwind` (`libunwind_ptrace`) calls `uncompress()` from libz, which `--as-needed` can drop without an explicit link; the embedded forkserver binary also needs static `libstdc++`/`libgcc` so it does not depend on the host's runtime GLIBCXX version at exec time. | + +## Bumping the pinned tag + +1. Update `ML_SANDBOXED_API_TAG`, resolve its commit SHA into + `ML_SANDBOXED_API_GIT_SHA`, and update `sandbox2-INFO.csv` `revision` + in `3rd_party/CMakeLists.txt`. +2. Re-run configure. A patch that no longer applies fails with + `FATAL_ERROR: sandboxed-api patch failed to apply` — this is the + version-drift signal. +3. For each failing patch, regenerate it against the new tag's real file + content (clone the tag, make the same edit, `git diff`) rather than + hand-editing the `.patch` file — hand-edited patches drift from what the + new tag's file actually contains. +4. Reconfigure again to confirm every patch now applies cleanly, then + rebuild `lib/sandbox` (`ml_test_sandbox`) to confirm the resulting + Sandbox2 build still passes. diff --git a/include/sandbox/CMlSandboxAvailability.h b/include/sandbox/CMlSandboxAvailability.h new file mode 100644 index 0000000000..1e1075ab58 --- /dev/null +++ b/include/sandbox/CMlSandboxAvailability.h @@ -0,0 +1,43 @@ +/* + * 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_sandbox_CMlSandboxAvailability_h +#define INCLUDED_ml_sandbox_CMlSandboxAvailability_h + +#include + +namespace ml { +namespace sandbox { + +//! \brief +//! Reports whether this binary was built with Sandbox2 support. +//! +//! DESCRIPTION:\n +//! MlSandbox is a dormant dependency foundation: it links Sandbox2/Abseil +//! and builds a runnable forkserver on Linux, but nothing in the controller +//! or pytorch_inference wiring routes to it yet. This query is the only +//! symbol callers outside this library may currently depend on; the actual +//! sandbox policy, spawner, and controller routing land in follow-up PRs. +//! +//! IMPLEMENTATION DECISIONS:\n +//! Backed by the SANDBOX2_AVAILABLE compile definition set in +//! lib/sandbox/CMakeLists.txt, which is only defined when the Sandbox2 +//! FetchContent target built successfully (Linux only). +class CMlSandboxAvailability : private core::CNonInstantiatable { +public: + //! \return true if this binary was compiled with Sandbox2 linked in + //! (Linux builds only); false on macOS/Windows or if the dependency + //! foundation build step did not run. + static bool isCompiledIn(); +}; +} +} + +#endif // INCLUDED_ml_sandbox_CMlSandboxAvailability_h diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt index a740c13ad8..2d790c68ac 100644 --- a/lib/CMakeLists.txt +++ b/lib/CMakeLists.txt @@ -27,4 +27,5 @@ add_subdirectory(api/dump_state EXCLUDE_FROM_ALL) add_subdirectory(test) add_subdirectory(ver) add_subdirectory(seccomp) +add_subdirectory(sandbox) diff --git a/lib/sandbox/CMakeLists.txt b/lib/sandbox/CMakeLists.txt new file mode 100644 index 0000000000..508a46029d --- /dev/null +++ b/lib/sandbox/CMakeLists.txt @@ -0,0 +1,46 @@ +# +# 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. +# + +# MlSandbox is a dormant dependency foundation: it links Sandbox2/Abseil and +# builds/tests a runnable Sandbox2 forkserver on Linux, but no controller or +# pytorch_inference routing depends on it yet. The typed launch policy, +# process spawner, and controller wiring land in follow-up PRs. + +project("ML Sandbox") + +set(ML_LINK_LIBRARIES + MlCore + ) + +set(SRCS + CMlSandboxAvailability.cc + ) + +ml_add_library(MlSandbox STATIC ${SRCS}) + +if(TARGET sandbox2::sandbox2) + target_compile_definitions(MlSandbox PUBLIC SANDBOX2_AVAILABLE) + if(CMAKE_SYSTEM_NAME STREQUAL "Linux") + # libunwind_ptrace (a Sandbox2 dependency, via sandbox2::unwind) calls + # uncompress() from libz. CMake may de-duplicate ZLIB::ZLIB with MlCore + # and place -lz before the sandbox2 archives on the link line; with + # --as-needed that silently drops -lz from downstream executable links + # (observed on aarch64). A raw -Wl group is a distinct link item, so -lz + # stays ordered after sandbox2 regardless of de-duplication. + # sandbox2::sandbox2 is an ALIAS target - do not target_link_libraries + # against the alias name from outside this cache variable. + target_link_libraries(MlSandbox PUBLIC sandbox2::sandbox2) + target_link_libraries(MlSandbox PUBLIC "-Wl,--no-as-needed,-lz,--as-needed") + message(STATUS "MlSandbox: Sandbox2 enabled and linked") + endif() +else() + message(STATUS "MlSandbox: Sandbox2 not available on this platform - building dormant stub only") +endif() diff --git a/lib/sandbox/CMlSandboxAvailability.cc b/lib/sandbox/CMlSandboxAvailability.cc new file mode 100644 index 0000000000..ca6c077e13 --- /dev/null +++ b/lib/sandbox/CMlSandboxAvailability.cc @@ -0,0 +1,24 @@ +/* + * 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. + */ +#include + +namespace ml { +namespace sandbox { + +bool CMlSandboxAvailability::isCompiledIn() { +#ifdef SANDBOX2_AVAILABLE + return true; +#else + return false; +#endif +} +} +} diff --git a/lib/sandbox/unittest/CMakeLists.txt b/lib/sandbox/unittest/CMakeLists.txt new file mode 100644 index 0000000000..ba783acc4f --- /dev/null +++ b/lib/sandbox/unittest/CMakeLists.txt @@ -0,0 +1,62 @@ +# +# 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. +# + +project("ML Sandbox unit tests") + +set(SRCS + Main.cc + CMlSandboxAvailabilityTest.cc + ) + +set(ML_LINK_LIBRARIES + ${Boost_LIBRARIES_WITH_UNIT_TEST} + MlCore + MlSandbox + MlTest + ) + +if(TARGET sandbox2::sandbox2 AND CMAKE_SYSTEM_NAME STREQUAL "Linux") + # The forkserver runtime smoke test links the Sandbox2 API directly (not + # just MlSandbox, which exposes no sandbox2 symbols yet) to prove the + # vendored forkserver - built via 3rd_party/patches/sandboxed-api/ - can + # fork/exec/reap a real child. It is Linux-only and dropped entirely + # elsewhere rather than compiled out with #ifdef, since sandbox2 headers + # are unavailable on non-Linux configure runs. + list(APPEND SRCS CSandboxForkserverSmokeTest.cc) + list(APPEND ML_LINK_LIBRARIES sandbox2::sandbox2) + + # Deliberately-dependency-free sandboxee payload for the smoke test above. + # Built with plain add_executable rather than ml_add_non_distributed_executable: + # it has no ml-cpp library dependencies, no ML_LINK_LIBRARIES, and must not + # be confused with a distributable ml-cpp binary. Dynamically linked (the + # default) - a static build was tried first to sidestep + # PolicyBuilder::AddLibrariesForBinary(), matching upstream sandboxed-api's + # own examples/static/static_bin.cc, but the ml-cpp CI build image + # (docker.elastic.co/ml-dev/ml-linux-build) has no static libc/libm + # archives (`ld: cannot find -lm/-lc`), so the smoke test itself now calls + # AddLibrariesForBinary() on the dynamically-linked payload instead. + add_executable(sandbox2_smoke_payload EXCLUDE_FROM_ALL + payloads/sandbox_smoke_payload.cc + ) + set_target_properties(sandbox2_smoke_payload PROPERTIES + POSITION_INDEPENDENT_CODE TRUE + RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/payloads + ) +endif() + +ml_add_test_executable(sandbox ${SRCS}) + +if(TARGET sandbox2_smoke_payload) + add_dependencies(ml_test_sandbox sandbox2_smoke_payload) + target_compile_definitions(ml_test_sandbox PRIVATE + "ML_SANDBOX2_SMOKE_PAYLOAD=\"$\"" + ) +endif() diff --git a/lib/sandbox/unittest/CMlSandboxAvailabilityTest.cc b/lib/sandbox/unittest/CMlSandboxAvailabilityTest.cc new file mode 100644 index 0000000000..c782e896cc --- /dev/null +++ b/lib/sandbox/unittest/CMlSandboxAvailabilityTest.cc @@ -0,0 +1,25 @@ +/* + * 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. + */ +#include + +#include + +BOOST_AUTO_TEST_SUITE(CMlSandboxAvailabilityTest) + +BOOST_AUTO_TEST_CASE(testMatchesPlatformExpectation) { +#if defined(SANDBOX2_AVAILABLE) + BOOST_TEST_REQUIRE(ml::sandbox::CMlSandboxAvailability::isCompiledIn()); +#else + BOOST_TEST_REQUIRE(!ml::sandbox::CMlSandboxAvailability::isCompiledIn()); +#endif +} + +BOOST_AUTO_TEST_SUITE_END() diff --git a/lib/sandbox/unittest/CSandboxForkserverSmokeTest.cc b/lib/sandbox/unittest/CSandboxForkserverSmokeTest.cc new file mode 100644 index 0000000000..f62ab9db07 --- /dev/null +++ b/lib/sandbox/unittest/CSandboxForkserverSmokeTest.cc @@ -0,0 +1,76 @@ +/* + * 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. + */ + +// Linux-only forkserver runtime smoke test for the dormant MlSandbox +// dependency foundation. This is NOT a security test: it uses +// PolicyBuilder::DangerDefaultAllowAll(), which imposes no seccomp +// restriction. Its only purpose is to prove that the vendored Sandbox2 +// forkserver - built via the checked-in patches under +// 3rd_party/patches/sandboxed-api/ - can actually fork, exec, and reap a +// child process end-to-end. Typed launch policy and syscall filtering are +// out of scope here and land in follow-up PRs. +// +// The payload is dynamically linked, so AddLibrariesForBinary() mounts its +// shared-library dependencies into the sandbox namespace; without it, +// Sandbox2's forkserver fails execveat with ENOENT. A static-linked payload +// (matching upstream sandboxed-api's own examples/static/static_bin.cc, to +// sidestep AddLibrariesForBinary entirely) was tried first, but this CI's +// build image has no static libc/libm archives (`ld: cannot find -lm/-lc`). + +#include + +#include + +#include + +#ifndef ML_SANDBOX2_SMOKE_PAYLOAD +#error "ML_SANDBOX2_SMOKE_PAYLOAD must be defined by lib/sandbox/unittest/CMakeLists.txt" +#endif + +#include "absl/time/time.h" +#include "sandboxed_api/sandbox2/executor.h" +#include "sandboxed_api/sandbox2/policybuilder.h" +#include "sandboxed_api/sandbox2/result.h" +#include "sandboxed_api/sandbox2/sandbox2.h" + +#include +#include + +BOOST_AUTO_TEST_SUITE(CSandboxForkserverSmokeTest_Linux) + +BOOST_AUTO_TEST_CASE(testForkserverRunsPayloadToCompletion) { + BOOST_TEST_REQUIRE(ml::sandbox::CMlSandboxAvailability::isCompiledIn()); + + const std::string payloadPath{ML_SANDBOX2_SMOKE_PAYLOAD}; + std::vector args{payloadPath}; + + auto executor = std::make_unique(payloadPath, args); + executor->limits()->set_rlimit_cpu(10).set_walltime_limit(absl::Seconds(10)); + + // DangerDefaultAllowAll is deliberately permissive: this test exercises + // the forkserver plumbing only, not the (not-yet-implemented) sandbox + // policy. Do not copy this policy into production or security-relevant + // test code. AddLibrariesForBinary mounts the payload's shared-library + // dependencies (ldd-derived) so the dynamic loader can find them inside + // the sandbox namespace. + auto policy = sandbox2::PolicyBuilder() + .DangerDefaultAllowAll() + .AddLibrariesForBinary(payloadPath) + .BuildOrDie(); + + sandbox2::Sandbox2 s2(std::move(executor), std::move(policy)); + sandbox2::Result result = s2.Run(); + + BOOST_TEST_REQUIRE(result.final_status() == sandbox2::Result::OK); + BOOST_TEST_REQUIRE(result.reason_code() == 0); +} + +BOOST_AUTO_TEST_SUITE_END() diff --git a/lib/sandbox/unittest/Main.cc b/lib/sandbox/unittest/Main.cc new file mode 100644 index 0000000000..15b5b5324a --- /dev/null +++ b/lib/sandbox/unittest/Main.cc @@ -0,0 +1,30 @@ +/* + * 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. + */ + +#define BOOST_TEST_MODULE lib.sandbox +// Defining BOOST_TEST_MODULE usually auto-generates main(), but we don't want +// this as we need custom initialisation to allow for output in both console and +// Boost.Test XML formats +#define BOOST_TEST_NO_MAIN + +#include +#include + +#include + +int main(int argc, char** argv) { + ml::test::CTestObserver observer; + boost::unit_test::framework::register_observer(observer); + int result{boost::unit_test::unit_test_main(&ml::test::CBoostTestXmlOutput::init, + argc, argv)}; + boost::unit_test::framework::deregister_observer(observer); + return result; +} diff --git a/lib/sandbox/unittest/payloads/sandbox_smoke_payload.cc b/lib/sandbox/unittest/payloads/sandbox_smoke_payload.cc new file mode 100644 index 0000000000..e092e0ef08 --- /dev/null +++ b/lib/sandbox/unittest/payloads/sandbox_smoke_payload.cc @@ -0,0 +1,26 @@ +/* + * 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. + */ + +// Deliberately dependency-free sandboxee for CSandboxForkserverSmokeTest_Linux. +// It exists only to prove the vendored Sandbox2 forkserver can fork, exec, +// and reap a child through the full pipeline patched in +// 3rd_party/patches/sandboxed-api/0004-forkserver-zlib-static-libstdcxx.patch. +// It carries no ml-cpp library dependencies and no sandbox policy of its +// own - policy design is out of scope for this dormant dependency +// foundation and lands in a follow-up PR. + +#include +#include + +int main() { + std::printf("sandbox2-smoke-ok\n"); + return EXIT_SUCCESS; +} diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index b4d0ea8219..db573082cc 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -17,6 +17,7 @@ ml_add_test(lib/model/unittest model) ml_add_test(lib/api/unittest api) ml_add_test(lib/ver/unittest ver) ml_add_test(lib/seccomp/unittest seccomp) +ml_add_test(lib/sandbox/unittest sandbox) ml_add_test(bin/controller/unittest controller) ml_add_test(bin/pytorch_inference/unittest pytorch_inference)