Skip to content

Commit

Permalink
Drop drakvuf to v0.8-backports version (#839)
Browse files Browse the repository at this point in the history
* Drop drakvuf to v0.8-backports version

* Adapt ci scripts

* Try --fix-broken

* Do apt update once again, depends.sh clears the apt-lists

* Hack for caching

* I don't have to install bundle at all, let's do first (failing) test without that

* let's try to extract libvmi

* install libvmi so and headers

* Fix test

* Fix caching

* Fix build XTF when cached

* Add missing dependency

* Injector doesn't know what is timeout in this version

* Fix drakrun linting and drakvuf dependencies

* Rollback to snapshot compatible with older Xen

* Backported injector patch

* Update .github/workflows/build.yml

Co-authored-by: msm-cert <[email protected]>

* Update .github/workflows/build.yml

Co-authored-by: msm-cert <[email protected]>

---------

Co-authored-by: msm-cert <[email protected]>
  • Loading branch information
psrok1 and msm-cert authored Jan 19, 2024
1 parent 95d1fa0 commit 23f5b15
Show file tree
Hide file tree
Showing 7 changed files with 81 additions and 76 deletions.
37 changes: 23 additions & 14 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -91,45 +91,54 @@ jobs:
export DRAKVUF_COMMIT=$(git ls-tree HEAD drakvuf | awk '{ print $3 }')
echo "Drakvuf commit is ${DRAKVUF_COMMIT}"
echo "DRAKVUF_COMMIT=$DRAKVUF_COMMIT" >> $GITHUB_ENV
- name: Cache Drakvuf bundle
id: cache-drakvuf-bundle
uses: actions/cache@v3
- name: Restored cached Drakvuf bundle
id: cache-drakvuf-bundle-restore
uses: actions/cache/restore@v3
with:
path: |
/out/drakvuf-bundle*.deb
/out/xen-hypervisor*.deb
/opt/xtf/tests/example/test-hvm64-example
/build/usr/lib/libvmi*
/build/usr/include/libvmi/*
key: drakvuf-bundle-${{ env.DRAKVUF_COMMIT }}-${{ matrix.distro }}-${{ matrix.version }}
- if: ${{ steps.cache-drakvuf-bundle.outputs.cache-hit != 'true' }}
- if: ${{ steps.cache-drakvuf-bundle-restore.outputs.cache-hit != 'true' }}
name: Build Drakvuf bundle
run: |
cp -ra . /build
cd /build
sh drakvuf/package/depends.sh
bash ci/build_bundle.sh "${{ matrix.distro }}:${{matrix.version}}"
- name: Install Drakvuf bundle
run: |
export DEBIAN_FRONTEND=noninteractive
apt install -y /out/drakvuf-bundle*.deb
ls -r /out
- name: Save Drakvuf bundle cache
id: cache-drakvuf-bundle-save
uses: actions/cache/save@v3
with:
path: |
/out/drakvuf-bundle*.deb
/build/usr/lib/libvmi*
/build/usr/include/libvmi/*
key: drakvuf-bundle-${{ env.DRAKVUF_COMMIT }}-${{ matrix.distro }}-${{ matrix.version }}
- if: ${{ steps.cache-drakvuf-bundle.outputs.cache-hit != 'true' }}
name: Build Xen Test Framework
working-directory: /opt
run: |
apt install -y make pkg-config gcc libglib2.0-dev
git clone https://xenbits.xen.org/git-http/xtf.git
cd xtf
git checkout bf1c4eb6cb52785cf539eb83752dfcecfe66c5d1
make -j4
- name: Build draksetup tools
run: |
apt install -y make pkg-config gcc libglib2.0-dev
apt install -y libjson-c-dev
cp -v /build/usr/lib/libvmi* /usr/lib/
mkdir /usr/include/libvmi
cp -v /build/usr/include/libvmi/* /usr/include/libvmi/
make -C ./drakrun/drakrun/tools
cp /opt/xtf/tests/example/test-hvm64-example ./drakrun/drakrun/tools/
- uses: actions/upload-artifact@v3
with:
name: drakvuf-bundle-debs-${{ matrix.distro }}-${{ matrix.version }}
path: |
/out/drakvuf-bundle*.deb
/out/xen-hypervisor*.deb
/out/drakvuf-bundle*.deb
- uses: actions/upload-artifact@v3
with:
name: draksetup-tools-${{ matrix.distro }}-${{ matrix.version }}
Expand Down Expand Up @@ -243,7 +252,7 @@ jobs:
env:
DRAKVUF_DEBS_PATH: "/debs"
BASE_IMAGE: "${{ matrix.distro }}-${{ matrix.version_number }}-generic-amd64"
SNAPSHOT_VERSION: "win7-20230213"
SNAPSHOT_VERSION: "win7-20210922"
MINIO_HOST: "192.168.100.1:8181"
VM_RUNNER_API_URL: "http://127.0.0.1:8080"
VM_SUFFIX: "${{ matrix.distro }}-${{ matrix.version_number }}"
Expand Down
21 changes: 5 additions & 16 deletions ci/build_bundle.sh
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ source $SCRIPTPATH/build_utils.sh

set -e

INSTALL_PATH=/build/drakvuf/usr
# Usage of /build as root is required by DRAKVUF's mkdeb script
INSTALL_PATH=/build/usr
mkdir -p $INSTALL_PATH

# Build Xen
Expand All @@ -31,24 +32,12 @@ popd
# Build dwarf2json
pushd drakvuf/dwarf2json
/usr/local/go/bin/go build
mkdir -p /build/dwarf2json/
mv dwarf2json /build/dwarf2json/
popd

# Package DRAKVUF
pushd drakvuf
mkdir /out

# remove volatility3
sed -i '/volatility3/d' ./package/mkdeb
# change drakvuf build dir
sed -i 's/\/build/\/build\/drakvuf/g' ./package/mkdeb

DISTRO=$1
DRAKVUFVERSION=$(./scripts/version.sh --dev)
XENVERSION=$(./xen/version.sh --full ./xen/xen/Makefile)

echo "DISTRO=$DISTRO"
echo "DRAKVUFVERSION=$DRAKVUFVERSION"
echo "XENVERSION=$XENVERSION"

sh ./package/mkdeb "$DISTRO" "$DRAKVUFVERSION" "$XENVERSION"
sh ./package/mkdeb
popd
4 changes: 0 additions & 4 deletions ci/build_utils.sh
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,6 @@ function build_drakvuf() {
export PKG_CONFIG_PATH="$PREFIX/lib/pkgconfig/"
export LDFLAGS="-L$PREFIX/lib"
export CFLAGS="-I$PREFIX/include"
# Use clang as compiler, otherwise stuff doesn't build
# with drakvuf xen_helpers breaking on -Werror-c++-compat
export CC=clang
export CXX=clang++
autoreconf -vif
./configure --prefix=$PREFIX --enable-debug
make -j$(nproc)
Expand Down
10 changes: 4 additions & 6 deletions ci/custom_bundle.sh
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,8 @@ function setup_repository () {
echo "[+] Setting up repository"
setup_repository

INSTALL_PATH=/build/drakvuf/usr
# Usage of /build as root is required by DRAKVUF's mkdeb script
INSTALL_PATH=/build/usr
mkdir -p $INSTALL_PATH

echo "[+] Building Xen"
Expand All @@ -85,16 +86,13 @@ popd
echo "[+] Building dwarf2json"
pushd $SANDBOX_DIR/drakvuf/dwarf2json
/usr/local/go/bin/go build
mkdir -p /build/dwarf2json/
mv dwarf2json /build/dwarf2json/
popd

echo "[+] Packaging DRAKVUF"
mkdir -p /out
pushd $SANDBOX_DIR/drakvuf

# Remove volatility3
sed -i '/volatility3/d' ./package/mkdeb
# Change drakvuf build dir
sed -i 's/\/build/\/build\/drakvuf/g' ./package/mkdeb

sh ./package/mkdeb
popd
82 changes: 48 additions & 34 deletions drakrun/drakrun/injector.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import subprocess
from typing import List, Optional
from typing import List

from drakrun.util import RuntimeInfo

Expand All @@ -12,7 +12,39 @@ def __init__(self, vm_name: str, runtime_info: RuntimeInfo, kernel_profile: str)
self.kernel_profile = kernel_profile
self.runtime_info = runtime_info

def _get_cmdline_generic(self, method: str, timeout: int) -> List[str]:
def _run_with_timeout(
self,
args: List[str],
timeout: int,
check: bool = False,
capture_output: bool = False,
):
"""
subprocess.run(timeout=...) kills process instead of sending SIGTERM after
reaching timeout. In our case, we want to let injector do a clean termination.
"""
kwargs = {}
if capture_output:
kwargs["stdout"] = subprocess.PIPE
kwargs["stderr"] = subprocess.PIPE
with subprocess.Popen(args, **kwargs) as proc:
try:
outs, errs = proc.communicate(timeout=timeout)
except subprocess.TimeoutExpired:
proc.terminate()
proc.wait(timeout)
raise
finally:
if proc.poll() is None:
proc.kill()
retcode = proc.poll()
if check and retcode:
raise subprocess.CalledProcessError(
retcode, proc.args, output=outs, stderr=errs
)
return subprocess.CompletedProcess(proc.args, retcode, outs, errs)

def _get_cmdline_generic(self, method: str) -> List[str]:
"""Build base command line for all injection methods"""
return [
"injector",
Expand All @@ -28,30 +60,22 @@ def _get_cmdline_generic(self, method: str, timeout: int) -> List[str]:
hex(self.runtime_info.vmi_offsets.kpgd),
"-m",
method,
"--timeout",
str(timeout),
]

def _get_cmdline_writefile(
self, local: str, remote: str, timeout: int = 60
) -> List[str]:
cmd = self._get_cmdline_generic("writefile", timeout=timeout)
def _get_cmdline_writefile(self, local: str, remote: str) -> List[str]:
cmd = self._get_cmdline_generic("writefile")
cmd.extend(["-e", remote])
cmd.extend(["-B", local])
return cmd

def _get_cmdline_readfile(
self, remote: str, local: str, timeout: int = 60
) -> List[str]:
cmd = self._get_cmdline_generic("readfile", timeout=timeout)
def _get_cmdline_readfile(self, remote: str, local: str) -> List[str]:
cmd = self._get_cmdline_generic("readfile")
cmd.extend(["-e", remote])
cmd.extend(["-B", local])
return cmd

def _get_cmdline_createproc(
self, exec_cmd: str, wait: bool = False, timeout: Optional[int] = None
) -> List[str]:
cmd = self._get_cmdline_generic("createproc", timeout=timeout)
def _get_cmdline_createproc(self, exec_cmd: str, wait: bool = False) -> List[str]:
cmd = self._get_cmdline_generic("createproc")
cmd.extend(["-e", exec_cmd])
if wait:
cmd.append("-w")
Expand All @@ -62,38 +86,28 @@ def write_file(
) -> subprocess.CompletedProcess:
"""
Copy local file to the VM
we pass (timeout-5) to drakvuf to give it 5 seconds to finish its loop
"""
drakvuf_timeout = timeout - 5 if timeout > 5 else 0
injector_cmd = self._get_cmdline_writefile(
local_path, remote_path, timeout=drakvuf_timeout
)
return subprocess.run(
injector_cmd, stdout=subprocess.PIPE, timeout=timeout, check=True
injector_cmd = self._get_cmdline_writefile(local_path, remote_path)
return self._run_with_timeout(
injector_cmd, timeout=timeout, check=True, capture_output=True
)

def read_file(
self, remote_path: str, local_path: str, timeout: int = 60
) -> subprocess.CompletedProcess:
"""
Copy VM file to local
we pass (timeout-5) to drakvuf to give it 5 seconds to finish its loop
"""
drakvuf_timeout = timeout - 5 if timeout > 5 else 0
injector_cmd = self._get_cmdline_readfile(
remote_path, local_path, timeout=drakvuf_timeout
injector_cmd = self._get_cmdline_readfile(remote_path, local_path)
return self._run_with_timeout(
injector_cmd, timeout=timeout, capture_output=True
)
return subprocess.run(injector_cmd, timeout=timeout, capture_output=True)

def create_process(
self, cmdline: str, wait: bool = False, timeout: int = 60
) -> subprocess.CompletedProcess:
"""
Create a process inside the VM with given command line
we pass (timeout-5) to drakvuf to give it 5 seconds to finish it's loop
"""
drakvuf_timeout = timeout - 5 if timeout != 0 else 0
injector_cmd = self._get_cmdline_createproc(
cmdline, wait=wait, timeout=drakvuf_timeout
)
return subprocess.run(injector_cmd, timeout=timeout, check=True)
injector_cmd = self._get_cmdline_createproc(cmdline, wait=wait)
return self._run_with_timeout(injector_cmd, timeout=timeout, check=True)
2 changes: 1 addition & 1 deletion drakvuf
Submodule drakvuf updated 395 files
1 change: 0 additions & 1 deletion test/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@

DRAKVUF_DEBS = [
"drakvuf-bundle-*.deb",
"xen-hypervisor-*.deb",
]


Expand Down

0 comments on commit 23f5b15

Please sign in to comment.