Skip to content

Commit 83b4f9b

Browse files
authored
Fix: Linux kernel from package could not be on a different device
If the Linux kernel provided is was another device than the execution root, creating a hardlink within the jailer directory would fail. Solution: Copy the kernel to the execution root during setup.
1 parent e37bb6f commit 83b4f9b

File tree

2 files changed

+31
-2
lines changed

2 files changed

+31
-2
lines changed

src/aleph/vm/conf.py

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
import logging
33
import os
44
import re
5+
import shutil
56
from collections.abc import Iterable
67
from decimal import Decimal
78
from enum import Enum
@@ -15,7 +16,7 @@
1516
from pydantic.env_settings import DotenvType, env_file_sentinel
1617
from pydantic.typing import StrPath
1718

18-
from aleph.vm.utils import is_command_available
19+
from aleph.vm.utils import file_hashes_differ, is_command_available
1920

2021
logger = logging.getLogger(__name__)
2122

@@ -356,6 +357,18 @@ def setup(self):
356357

357358
os.makedirs(self.EXECUTION_ROOT, exist_ok=True)
358359

360+
# If the Linux kernel provided is on another device than the execution root,
361+
# copy it to the execution root to allow hardlink creation within jailer directories.
362+
if os.stat(self.LINUX_PATH).st_dev != os.stat(self.EXECUTION_ROOT).st_dev:
363+
logger.info("The Linux kernel is on another device than the execution root. Creating a copy.")
364+
linux_path_on_device = self.EXECUTION_ROOT / "vmlinux.bin"
365+
366+
# Only copy if the hash of the file differ.
367+
if file_hashes_differ(self.LINUX_PATH, linux_path_on_device):
368+
shutil.copy(self.LINUX_PATH, linux_path_on_device)
369+
370+
self.LINUX_PATH = linux_path_on_device
371+
359372
os.makedirs(self.EXECUTION_LOG_DIRECTORY, exist_ok=True)
360373
os.makedirs(self.PERSISTENT_VOLUMES_DIR, exist_ok=True)
361374

src/aleph/vm/utils.py

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
from dataclasses import is_dataclass
1111
from pathlib import Path
1212
from shutil import disk_usage
13-
from typing import Any, Dict, Optional
13+
from typing import Any, Callable, Dict, Optional
1414

1515
import aiodns
1616
import msgpack
@@ -195,3 +195,19 @@ def to_normalized_address(value: str) -> HexAddress:
195195
return HexAddress(HexStr(hex_address))
196196
else:
197197
raise ValueError("Unknown format {}, attempted to normalize to {}".format(value, hex_address))
198+
199+
200+
def md5sum(file_path: Path) -> str:
201+
"""Calculate the MD5 hash of a file. Externalize to the `md5sum` command for better performance."""
202+
return subprocess.check_output(["md5sum", file_path], text=True).split()[0]
203+
204+
205+
def file_hashes_differ(source: Path, destination: Path, checksum: Callable[[Path], str] = md5sum) -> bool:
206+
"""Check if the MD5 hash of two files differ."""
207+
if not source.exists():
208+
raise FileNotFoundError("Source file does not exist: {}".format(source))
209+
210+
if not destination.exists():
211+
return True
212+
213+
return checksum(source) != checksum(destination)

0 commit comments

Comments
 (0)