Skip to content

Commit

Permalink
Test file override outside of model directory (#6516)
Browse files Browse the repository at this point in the history
* Add boost-filesystem
  • Loading branch information
rmccorm4 authored Nov 7, 2023
1 parent 53b2fac commit d893ca1
Show file tree
Hide file tree
Showing 4 changed files with 90 additions and 1 deletion.
2 changes: 1 addition & 1 deletion Dockerfile.win10.min
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ RUN git clone --single-branch --depth=1 -b %VCPGK_VERSION% https://github.com/mi
WORKDIR /vcpkg
RUN bootstrap-vcpkg.bat
RUN vcpkg.exe update
RUN vcpkg.exe install openssl:x64-windows openssl-windows:x64-windows rapidjson:x64-windows re2:x64-windows boost-interprocess:x64-windows boost-stacktrace:x64-windows zlib:x64-windows pthread:x64-windows b64:x64-windows
RUN vcpkg.exe install openssl:x64-windows openssl-windows:x64-windows rapidjson:x64-windows re2:x64-windows boost-filesystem:x64-windows boost-interprocess:x64-windows boost-stacktrace:x64-windows zlib:x64-windows pthread:x64-windows b64:x64-windows
RUN vcpkg.exe integrate install

LABEL VCPGK_VERSION=${VCPGK_VERSION}
Expand Down
9 changes: 9 additions & 0 deletions build.py
Original file line number Diff line number Diff line change
Expand Up @@ -1034,6 +1034,7 @@ def create_dockerfile_buildbase(ddir, dockerfile_name, argmap):
RUN wget -O /tmp/boost.tar.gz \
https://boostorg.jfrog.io/artifactory/main/release/1.80.0/source/boost_1_80_0.tar.gz && \
(cd /tmp && tar xzf boost.tar.gz) && \
cd /tmp/boost_1_80_0 && ./bootstrap.sh --prefix=/usr && ./b2 install && \
mv /tmp/boost_1_80_0/boost /usr/include/boost
# Server build requires recent version of CMake (FetchContent required)
Expand Down Expand Up @@ -1257,6 +1258,14 @@ def dockerfile_prepare_container_linux(argmap, backends, enable_gpu, target_mach
{backend_dependencies} && \
rm -rf /var/lib/apt/lists/*
# Install boost version >= 1.78 for boost::span
# Current libboost-dev apt packages are < 1.78, so install from tar.gz
RUN wget -O /tmp/boost.tar.gz \
https://boostorg.jfrog.io/artifactory/main/release/1.80.0/source/boost_1_80_0.tar.gz && \
(cd /tmp && tar xzf boost.tar.gz) && \
cd /tmp/boost_1_80_0 && ./bootstrap.sh --prefix=/usr && ./b2 install && \
rm -rf /tmp/boost*
# Set TCMALLOC_RELEASE_RATE for users setting LD_PRELOAD with tcmalloc
ENV TCMALLOC_RELEASE_RATE 200
""".format(
Expand Down
78 changes: 78 additions & 0 deletions qa/L0_lifecycle/lifecycle_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@

sys.path.append("../common")

import base64
import concurrent.futures
import json
import os
Expand Down Expand Up @@ -2554,6 +2555,83 @@ def test_file_override(self):
model_shape,
)

# Test that model load API file override can't be used to create files
# outside of any model directory.
def test_file_override_security(self):
# When using model load API, temporary model directories are created in
# a randomly generated /tmp/folderXXXXXX directory for the life of the
# model, and cleaned up on model unload.
model_basepath = "/tmp/folderXXXXXX"
if os.path.exists(model_basepath) and os.path.isdir(model_basepath):
shutil.rmtree(model_basepath)
os.makedirs(model_basepath)

# Set file override paths that try to escape out of model directory,
# and test both pre-existing and non-existent files.
root_home_dir = "/root"

# Relative paths
escape_dir_rel = os.path.join("..", "..", "root")
escape_dir_full = os.path.join(model_basepath, escape_dir_rel)
self.assertEqual(os.path.abspath(escape_dir_full), root_home_dir)

new_file_rel = os.path.join(escape_dir_rel, "new_dir", "test.txt")
self.assertFalse(os.path.exists(os.path.join(model_basepath, new_file_rel)))
existing_file_rel = os.path.join(escape_dir_rel, ".bashrc")
self.assertTrue(os.path.exists(os.path.join(model_basepath, existing_file_rel)))

# Symlinks
## No easy way to inject symlink into generated temp model dir, so for
## testing sake, make a fixed symlink path in /tmp.
escape_dir_symlink_rel = os.path.join("..", "escape_symlink")
escape_dir_symlink_full = "/tmp/escape_symlink"
self.assertEqual(
os.path.abspath(os.path.join(model_basepath, escape_dir_symlink_rel)),
escape_dir_symlink_full,
)
if os.path.exists(escape_dir_symlink_full):
os.unlink(escape_dir_symlink_full)
os.symlink(root_home_dir, escape_dir_symlink_full)
self.assertTrue(os.path.abspath(escape_dir_symlink_full), root_home_dir)

symlink_new_file_rel = os.path.join(
escape_dir_symlink_rel, "new_dir", "test.txt"
)
self.assertFalse(
os.path.exists(os.path.join(model_basepath, symlink_new_file_rel))
)
symlink_existing_file_rel = os.path.join(escape_dir_symlink_rel, ".bashrc")
self.assertTrue(
os.path.exists(os.path.join(model_basepath, symlink_existing_file_rel))
)

# Contents to try writing to file, though it should fail to be written
new_contents = "This shouldn't exist"
new_contents_b64 = base64.b64encode(new_contents.encode())

new_files = [new_file_rel, symlink_new_file_rel]
existing_files = [existing_file_rel, symlink_existing_file_rel]
all_files = new_files + existing_files
for filepath in all_files:
# minimal config to create a new model
config = json.dumps({"backend": "identity"})
files = {f"file:{filepath}": new_contents_b64}
with httpclient.InferenceServerClient("localhost:8000") as client:
with self.assertRaisesRegex(InferenceServerException, "failed to load"):
client.load_model("new_model", config=config, files=files)

for rel_path in new_files:
# Assert new file wasn't created
self.assertFalse(os.path.exists(os.path.join(model_basepath, rel_path)))

for rel_path in existing_files:
# Read the existing file and make sure it's contents weren't overwritten
existing_file = os.path.join(model_basepath, rel_path)
self.assertTrue(os.path.exists(existing_file))
with open(existing_file) as f:
contents = f.read()
self.assertNotEqual(contents, new_contents)

def test_shutdown_dynamic(self):
model_shape = (1, 1)
input_data = np.ones(shape=(1, 1), dtype=np.float32)
Expand Down
2 changes: 2 additions & 0 deletions qa/L0_lifecycle/test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -1533,6 +1533,8 @@ rm -f $CLIENT_LOG
set +e
python $LC_TEST LifeCycleTest.test_file_override >>$CLIENT_LOG 2>&1
check_unit_test
python $LC_TEST LifeCycleTest.test_file_override_security >>$CLIENT_LOG 2>&1
check_unit_test
set -e

kill $SERVER_PID
Expand Down

0 comments on commit d893ca1

Please sign in to comment.