mirror of
https://github.com/bytecodealliance/wasm-micro-runtime.git
synced 2026-04-18 18:18:44 +00:00
Refactoring enclave sample (#4828)
* refactor(ci): production-ready SGX install script with logging and idempotency - Add comprehensive logging infrastructure to /tmp/install_sgx.log - Implement idempotency checks for SGX packages and SDK - Modularize into functions: platform_detect, install_packages, validate_installation, cleanup - Add strict error handling with set -euo pipefail and error traps - Replace FIXME with proper environment sourcing documentation - Add dynamic platform detection for Ubuntu 20+/Debian 11/12 - Ensure minimal console output (final status only) with all details in log - Verify all acceptance scenarios pass with comprehensive testing * Refactoring enclave-sample aligning sgx BKM. - Buffer interface redesign to separate input and output - prevent untrusted pointer - add module and instance handle release functions for better resource management
This commit is contained in:
parent
723398263f
commit
0ec91cee50
6
.gitignore
vendored
6
.gitignore
vendored
|
|
@ -21,9 +21,9 @@ core/iwasm/libraries/lib-wasi-threads/test/*.wasm
|
||||||
core/iwasm/libraries/lib-socket/test/*.wasm
|
core/iwasm/libraries/lib-socket/test/*.wasm
|
||||||
|
|
||||||
product-mini/app-samples/hello-world/test.wasm
|
product-mini/app-samples/hello-world/test.wasm
|
||||||
product-mini/platforms/linux-sgx/enclave-sample/App/
|
product-mini/platforms/linux-sgx/enclave-sample/
|
||||||
product-mini/platforms/linux-sgx/enclave-sample/Enclave/
|
!product-mini/platforms/linux-sgx/enclave-sample/App/App.*
|
||||||
product-mini/platforms/linux-sgx/enclave-sample/iwasm
|
!product-mini/platforms/linux-sgx/enclave-sample/Enclave/Enclave.*
|
||||||
|
|
||||||
build_out
|
build_out
|
||||||
tests/wamr-test-suites/workspace
|
tests/wamr-test-suites/workspace
|
||||||
|
|
|
||||||
400
ci/install_sgx_for_applicaiton_developer.sh
Executable file
400
ci/install_sgx_for_applicaiton_developer.sh
Executable file
|
|
@ -0,0 +1,400 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Reference:
|
||||||
|
# https://cc-enabling.trustedservices.intel.com/intel-sgx-sw-installation-guide-linux/02/installation_instructions/#intel-sgx-application-developer
|
||||||
|
|
||||||
|
#TODO:
|
||||||
|
# report error when curl fails to download files, e.g. due to network issues or incorrect URLs
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
if [ "${DEBUG:-0}" -eq 1 ]; then
|
||||||
|
set -o xtrace
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Error trap handler - logs failure details and calls cleanup before exit
|
||||||
|
error_handler() {
|
||||||
|
local exit_code=$?
|
||||||
|
local line_number=${1:-$LINENO}
|
||||||
|
local bash_lineno=${2:-$BASH_LINENO}
|
||||||
|
local last_command=${3:-$BASH_COMMAND}
|
||||||
|
local function_stack=${4:-${FUNCNAME[*]}}
|
||||||
|
|
||||||
|
# Log error context to file
|
||||||
|
{
|
||||||
|
echo "=== ERROR OCCURRED ==="
|
||||||
|
echo "Exit Code: $exit_code"
|
||||||
|
echo "Line Number: $line_number"
|
||||||
|
echo "Bash Line: $bash_lineno"
|
||||||
|
echo "Failed Command: $last_command"
|
||||||
|
echo "Function Stack: $function_stack"
|
||||||
|
echo "Timestamp: $(date '+%Y-%m-%d %H:%M:%S')"
|
||||||
|
echo "======================"
|
||||||
|
} >> "${LOG_FILE:-/tmp/install_sgx.log}" 2>/dev/null || true
|
||||||
|
|
||||||
|
# Print concise error to stderr
|
||||||
|
echo "ERROR: Script failed at line $line_number with exit code $exit_code" >&2
|
||||||
|
echo "Failed command: $last_command" >&2
|
||||||
|
echo "Check log file: ${LOG_FILE:-/tmp/install_sgx.log}" >&2
|
||||||
|
|
||||||
|
# Call cleanup function if it exists
|
||||||
|
if type cleanup >/dev/null 2>&1; then
|
||||||
|
cleanup || true
|
||||||
|
fi
|
||||||
|
|
||||||
|
exit $exit_code
|
||||||
|
}
|
||||||
|
|
||||||
|
# Set up error trap
|
||||||
|
trap 'error_handler $LINENO $BASH_LINENO "$BASH_COMMAND" "${FUNCNAME[*]}"' ERR
|
||||||
|
|
||||||
|
# Platform will be detected dynamically by platform_detect() function
|
||||||
|
# Supported platforms: Debian12, Debian11, Ubuntu22.04-server, Ubuntu20.04-server
|
||||||
|
PLATFORM=""
|
||||||
|
|
||||||
|
# Logging infrastructure
|
||||||
|
LOG_FILE="/tmp/install_sgx.log"
|
||||||
|
|
||||||
|
# Initialize log file with timestamp
|
||||||
|
init_log() {
|
||||||
|
echo "=== Intel SGX Installation Log - $(date) ===" > "${LOG_FILE}"
|
||||||
|
echo "Platform: ${PLATFORM}" >> "${LOG_FILE}"
|
||||||
|
echo "Script: $0" >> "${LOG_FILE}"
|
||||||
|
echo "Started at: $(date '+%Y-%m-%d %H:%M:%S')" >> "${LOG_FILE}"
|
||||||
|
echo "" >> "${LOG_FILE}"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Log message with timestamp
|
||||||
|
log_info() {
|
||||||
|
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $*" >> "${LOG_FILE}"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Execute command with output redirected to log
|
||||||
|
log_exec() {
|
||||||
|
log_info "Executing: $*"
|
||||||
|
"$@" >>"$LOG_FILE" 2>&1
|
||||||
|
}
|
||||||
|
|
||||||
|
# Print environment sourcing instructions
|
||||||
|
print_env_instructions() {
|
||||||
|
log_info "Printing environment setup instructions"
|
||||||
|
|
||||||
|
echo "========================================================================"
|
||||||
|
echo " IMPORTANT: Before building or running SGX applications, you must run:"
|
||||||
|
echo " source /opt/intel/sgxsdk/environment"
|
||||||
|
echo " in your current shell to activate SGX SDK environment variables."
|
||||||
|
echo "========================================================================"
|
||||||
|
|
||||||
|
log_info "Environment setup instructions displayed to user"
|
||||||
|
}
|
||||||
|
|
||||||
|
check_sgx_packages() {
|
||||||
|
log_info "Checking for existing SGX packages..."
|
||||||
|
|
||||||
|
local packages=("libsgx-quote-ex" "libsgx-dcap-ql" "libsgx-enclave-common-dev" "libsgx-dcap-ql-dev" "libsgx-dcap-default-qpl-dev" "tee-appraisal-tool")
|
||||||
|
local missing_packages=()
|
||||||
|
|
||||||
|
for package in "${packages[@]}"; do
|
||||||
|
if ! dpkg -l "$package" >> "${LOG_FILE}" 2>&1; then
|
||||||
|
missing_packages+=("$package")
|
||||||
|
log_info "Package $package not installed"
|
||||||
|
else
|
||||||
|
log_info "Package $package already installed"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
if [ ${#missing_packages[@]} -eq 0 ]; then
|
||||||
|
log_info "All SGX packages are already installed"
|
||||||
|
return 0
|
||||||
|
else
|
||||||
|
log_info "Missing SGX packages: ${missing_packages[*]}"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
check_sgx_sdk() {
|
||||||
|
log_info "Checking for existing SGX SDK..."
|
||||||
|
|
||||||
|
if [ -d "/opt/intel/sgxsdk" ] && [ -f "/opt/intel/sgxsdk/environment" ]; then
|
||||||
|
log_info "SGX SDK already installed at /opt/intel/sgxsdk"
|
||||||
|
|
||||||
|
# Validate SDK installation by checking key components
|
||||||
|
if [ -f "/opt/intel/sgxsdk/bin/sgx-gdb" ] && [ -d "/opt/intel/sgxsdk/include" ]; then
|
||||||
|
log_info "SGX SDK installation appears complete"
|
||||||
|
return 0
|
||||||
|
else
|
||||||
|
log_info "SGX SDK installation incomplete - missing key components"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
log_info "SGX SDK not found"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
check_sgx_repo() {
|
||||||
|
log_info "Checking for existing SGX local repository..."
|
||||||
|
|
||||||
|
if [ -d "/opt/intel/sgx_debian_local_repo" ] && [ -f "/etc/apt/sources.list.d/sgx_debian_local_repo.list" ]; then
|
||||||
|
log_info "SGX local repository already configured"
|
||||||
|
return 0
|
||||||
|
else
|
||||||
|
log_info "SGX local repository not configured"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Modular installation functions
|
||||||
|
|
||||||
|
# Platform detection and configuration
|
||||||
|
platform_detect() {
|
||||||
|
log_info "Entering platform_detect() function"
|
||||||
|
|
||||||
|
if [ ! -f "/etc/os-release" ]; then
|
||||||
|
log_info "ERROR: /etc/os-release not found - cannot detect OS"
|
||||||
|
echo "ERROR: Cannot detect operating system. /etc/os-release not found." >&2
|
||||||
|
log_info "Exiting platform_detect() function"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Parse OS information from /etc/os-release
|
||||||
|
local os_id=$(grep '^ID=' /etc/os-release | cut -d'=' -f2 | tr -d '"')
|
||||||
|
local version_id=$(grep '^VERSION_ID=' /etc/os-release | cut -d'=' -f2 | tr -d '"')
|
||||||
|
|
||||||
|
log_info "Raw OS detection: ID=${os_id}, VERSION_ID=${version_id}"
|
||||||
|
|
||||||
|
# Determine platform string based on OS and version
|
||||||
|
case "${os_id}" in
|
||||||
|
"ubuntu")
|
||||||
|
case "${version_id}" in
|
||||||
|
"20.04")
|
||||||
|
PLATFORM="Ubuntu20.04-server"
|
||||||
|
;;
|
||||||
|
"22.04")
|
||||||
|
PLATFORM="Ubuntu22.04-server"
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
log_info "ERROR: Unsupported Ubuntu version ${version_id}. Supported: 20.04, 22.04"
|
||||||
|
echo "ERROR: Unsupported Ubuntu version ${version_id}. This script supports Ubuntu 20.04 and 22.04 only." >&2
|
||||||
|
log_info "Exiting platform_detect() function"
|
||||||
|
return 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
;;
|
||||||
|
"debian")
|
||||||
|
case "${version_id}" in
|
||||||
|
"11")
|
||||||
|
PLATFORM="Debian11"
|
||||||
|
;;
|
||||||
|
"12")
|
||||||
|
PLATFORM="Debian12"
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
log_info "ERROR: Unsupported Debian version ${version_id}. Supported: 11, 12"
|
||||||
|
echo "ERROR: Unsupported Debian version ${version_id}. This script supports Debian 11 and 12 only." >&2
|
||||||
|
log_info "Exiting platform_detect() function"
|
||||||
|
return 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
log_info "ERROR: Unsupported OS ${os_id}. Supported: ubuntu, debian"
|
||||||
|
echo "ERROR: Unsupported operating system '${os_id}'. This script supports Ubuntu and Debian only." >&2
|
||||||
|
log_info "Exiting platform_detect() function"
|
||||||
|
return 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
log_info "Successfully detected platform: ${PLATFORM}"
|
||||||
|
echo "Detected platform: ${PLATFORM}"
|
||||||
|
|
||||||
|
log_info "Exiting platform_detect() function"
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
# Install SGX packages and SDK
|
||||||
|
install_packages() {
|
||||||
|
log_info "Entering install_packages() function"
|
||||||
|
|
||||||
|
# Skip repo setup if already configured
|
||||||
|
if ! check_sgx_repo; then
|
||||||
|
log_info "Setting up SGX local repository..."
|
||||||
|
|
||||||
|
pushd /tmp >> "${LOG_FILE}" 2>&1
|
||||||
|
log_exec curl -fsSLO \
|
||||||
|
https://download.01.org/intel-sgx/latest/linux-latest/distro/${PLATFORM}/sgx_debian_local_repo.tgz
|
||||||
|
|
||||||
|
local_sum=$(sha256sum sgx_debian_local_repo.tgz | awk '{print $1}')
|
||||||
|
remote_sum=$(curl -s https://download.01.org/intel-sgx/latest/dcap-latest/linux/SHA256SUM_dcap_1.24.cfg | grep "distro/${PLATFORM}/sgx_debian_local_repo.tgz" | awk '{print $1}')
|
||||||
|
if [[ "$local_sum" == "$remote_sum" ]]; then
|
||||||
|
log_info "Checksum matches"
|
||||||
|
else
|
||||||
|
log_info "Checksum mismatch!"
|
||||||
|
fi
|
||||||
|
|
||||||
|
log_exec sudo mkdir -p /opt/intel
|
||||||
|
log_exec sudo tar xzf sgx_debian_local_repo.tgz -C /opt/intel
|
||||||
|
|
||||||
|
echo 'deb [signed-by=/etc/apt/keyrings/intel-sgx-keyring.asc arch=amd64] file:///opt/intel/sgx_debian_local_repo bookworm main' \
|
||||||
|
| sudo tee /etc/apt/sources.list.d/sgx_debian_local_repo.list | tee -a "${LOG_FILE}" > /dev/null
|
||||||
|
|
||||||
|
log_exec sudo cp /opt/intel/sgx_debian_local_repo/keys/intel-sgx.key /etc/apt/keyrings/intel-sgx-keyring.asc
|
||||||
|
popd >> "${LOG_FILE}" 2>&1
|
||||||
|
else
|
||||||
|
log_info "SGX repository already configured, skipping setup"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Install SGX packages only if missing
|
||||||
|
if ! check_sgx_packages; then
|
||||||
|
log_info "Installing missing SGX packages..."
|
||||||
|
log_exec sudo apt-get update
|
||||||
|
log_exec sudo apt-get install -y libsgx-quote-ex libsgx-dcap-ql
|
||||||
|
else
|
||||||
|
log_info "SGX packages already installed, skipping"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Install build dependencies
|
||||||
|
log_exec sudo apt-get update --quiet
|
||||||
|
log_exec sudo apt-get install --quiet -y build-essential python3
|
||||||
|
log_exec sudo update-alternatives --install /usr/bin/python python /usr/bin/python3 1
|
||||||
|
|
||||||
|
# Install Intel SGX SDK only if missing
|
||||||
|
if ! check_sgx_sdk; then
|
||||||
|
log_info "Installing Intel SGX SDK for Application Developer..."
|
||||||
|
|
||||||
|
pushd /opt/intel >> "${LOG_FILE}" 2>&1
|
||||||
|
log_exec sudo curl -fsSLo sgx_linux_x64_sdk.bin \
|
||||||
|
https://download.01.org/intel-sgx/latest/linux-latest/distro/${PLATFORM}/sgx_linux_x64_sdk_2.27.100.1.bin
|
||||||
|
log_exec sudo chmod +x sgx_linux_x64_sdk.bin
|
||||||
|
log_exec sudo ./sgx_linux_x64_sdk.bin --prefix /opt/intel
|
||||||
|
|
||||||
|
# Log environment setup instructions for user
|
||||||
|
log_info "SGX SDK installation completed successfully."
|
||||||
|
log_info "IMPORTANT: To use the SGX SDK in your development session:"
|
||||||
|
log_info " 1. Run: source /opt/intel/sgxsdk/environment"
|
||||||
|
log_info " 2. This must be done in each shell session where you use SGX"
|
||||||
|
log_info " 3. Environment variables are session-specific and cannot be exported by this script"
|
||||||
|
log_info " 4. Consider adding 'source /opt/intel/sgxsdk/environment' to your ~/.bashrc for automatic setup"
|
||||||
|
popd >> "${LOG_FILE}" 2>&1
|
||||||
|
else
|
||||||
|
log_info "SGX SDK already installed, skipping"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Install Developer packages for Intel SGX only if missing
|
||||||
|
if ! check_sgx_packages; then
|
||||||
|
log_info "Installing Intel SGX Developer packages..."
|
||||||
|
|
||||||
|
log_exec sudo apt-get install -y libsgx-enclave-common-dev \
|
||||||
|
libsgx-dcap-ql-dev \
|
||||||
|
libsgx-dcap-default-qpl-dev \
|
||||||
|
tee-appraisal-tool
|
||||||
|
else
|
||||||
|
log_info "SGX Developer packages already installed, skipping"
|
||||||
|
fi
|
||||||
|
|
||||||
|
log_info "Exiting install_packages() function"
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
# Validate the installation was successful
|
||||||
|
validate_installation() {
|
||||||
|
log_info "Entering validate_installation() function"
|
||||||
|
|
||||||
|
local validation_failed=0
|
||||||
|
|
||||||
|
# Re-check all components after installation
|
||||||
|
if ! check_sgx_packages; then
|
||||||
|
log_info "VALIDATION FAILED: SGX packages not properly installed"
|
||||||
|
validation_failed=1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if ! check_sgx_sdk; then
|
||||||
|
log_info "VALIDATION FAILED: SGX SDK not properly installed"
|
||||||
|
validation_failed=1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if ! check_sgx_repo; then
|
||||||
|
log_info "VALIDATION FAILED: SGX repository not properly configured"
|
||||||
|
validation_failed=1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ $validation_failed -eq 0 ]; then
|
||||||
|
log_info "VALIDATION SUCCESS: All SGX components properly installed"
|
||||||
|
else
|
||||||
|
log_info "VALIDATION FAILED: Some SGX components failed installation"
|
||||||
|
log_info "Exiting validate_installation() function"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
log_info "Exiting validate_installation() function"
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
# Clean up temporary files
|
||||||
|
cleanup() {
|
||||||
|
log_info "Entering cleanup() function"
|
||||||
|
|
||||||
|
# Clean up any temporary files in /tmp related to SGX installation
|
||||||
|
if [ -f "/tmp/sgx_debian_local_repo.tgz" ]; then
|
||||||
|
log_info "Removing temporary SGX repository archive"
|
||||||
|
rm -f /tmp/sgx_debian_local_repo.tgz
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Additional cleanup can be added here as needed
|
||||||
|
log_info "Temporary file cleanup completed"
|
||||||
|
|
||||||
|
log_info "Exiting cleanup() function"
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
# Initialize logging
|
||||||
|
init_log
|
||||||
|
|
||||||
|
log_info "Starting idempotency checks..."
|
||||||
|
|
||||||
|
# Check if everything is already installed
|
||||||
|
if check_sgx_packages && check_sgx_sdk && check_sgx_repo; then
|
||||||
|
log_info "Complete SGX installation detected - no action needed"
|
||||||
|
echo "Intel SGX for Application Developer is already installed and configured."
|
||||||
|
print_env_instructions
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
log_info "Partial or missing SGX installation detected - proceeding with installation"
|
||||||
|
|
||||||
|
# Main installation flow using modular functions
|
||||||
|
|
||||||
|
log_info "Starting Intel SGX for Application Developer installation..."
|
||||||
|
|
||||||
|
# Execute installation steps in modular fashion
|
||||||
|
platform_detect
|
||||||
|
if [ $? -ne 0 ]; then
|
||||||
|
log_info "Platform detection failed"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
install_packages
|
||||||
|
if [ $? -ne 0 ]; then
|
||||||
|
log_info "Package installation failed"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
validate_installation
|
||||||
|
if [ $? -ne 0 ]; then
|
||||||
|
log_info "Installation validation failed"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
cleanup
|
||||||
|
if [ $? -ne 0 ]; then
|
||||||
|
log_info "Cleanup failed"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
cleanup
|
||||||
|
if [ $? -ne 0 ]; then
|
||||||
|
log_info "Cleanup failed"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Intel SGX for Application Developer installation completed."
|
||||||
|
print_env_instructions
|
||||||
|
|
@ -8,7 +8,8 @@
|
||||||
<ReservedMemExecutable>1</ReservedMemExecutable>
|
<ReservedMemExecutable>1</ReservedMemExecutable>
|
||||||
<TCSNum>10</TCSNum>
|
<TCSNum>10</TCSNum>
|
||||||
<TCSPolicy>1</TCSPolicy>
|
<TCSPolicy>1</TCSPolicy>
|
||||||
<DisableDebug>0</DisableDebug>
|
<!-- Debug mode disabled for production enclave security -->
|
||||||
|
<DisableDebug>1</DisableDebug>
|
||||||
<MiscSelect>0</MiscSelect>
|
<MiscSelect>0</MiscSelect>
|
||||||
<MiscMask>0xFFFFFFFF</MiscMask>
|
<MiscMask>0xFFFFFFFF</MiscMask>
|
||||||
</EnclaveConfiguration>
|
</EnclaveConfiguration>
|
||||||
|
|
|
||||||
|
|
@ -81,6 +81,171 @@ static EnclaveModule *enclave_module_list = NULL;
|
||||||
static korp_mutex enclave_module_list_lock = OS_THREAD_MUTEX_INITIALIZER;
|
static korp_mutex enclave_module_list_lock = OS_THREAD_MUTEX_INITIALIZER;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* Handle table for secure EnclaveModule reference management */
|
||||||
|
#define MAX_MODULES 128
|
||||||
|
typedef struct HandleTableEntry {
|
||||||
|
uint32 id;
|
||||||
|
EnclaveModule *module_ref;
|
||||||
|
bool in_use;
|
||||||
|
} HandleTableEntry;
|
||||||
|
|
||||||
|
static HandleTableEntry module_table[MAX_MODULES] = { 0 };
|
||||||
|
static uint32 next_module_id = 1;
|
||||||
|
static korp_mutex module_table_lock = OS_THREAD_MUTEX_INITIALIZER;
|
||||||
|
|
||||||
|
/* : Allocate secure handle for EnclaveModule, preventing pointer
|
||||||
|
* exposure */
|
||||||
|
static uint32
|
||||||
|
allocate_module_handle(EnclaveModule *module)
|
||||||
|
{
|
||||||
|
uint32 handle_id = 0;
|
||||||
|
|
||||||
|
os_mutex_lock(&module_table_lock);
|
||||||
|
|
||||||
|
/* Find free slot */
|
||||||
|
for (uint32 i = 0; i < MAX_MODULES; i++) {
|
||||||
|
if (!module_table[i].in_use) {
|
||||||
|
module_table[i].id = next_module_id++;
|
||||||
|
module_table[i].module_ref = module;
|
||||||
|
module_table[i].in_use = true;
|
||||||
|
handle_id = module_table[i].id;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
os_mutex_unlock(&module_table_lock);
|
||||||
|
|
||||||
|
if (handle_id == 0) {
|
||||||
|
int bytes_written = 0;
|
||||||
|
ocall_print(&bytes_written,
|
||||||
|
"SECURITY WARNING: Module handle table full\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
return handle_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Lookup EnclaveModule by handle ID, preventing direct pointer access */
|
||||||
|
static EnclaveModule *
|
||||||
|
lookup_module_by_handle(uint32 handle_id)
|
||||||
|
{
|
||||||
|
EnclaveModule *module = NULL;
|
||||||
|
|
||||||
|
if (handle_id == 0)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
os_mutex_lock(&module_table_lock);
|
||||||
|
|
||||||
|
for (uint32 i = 0; i < MAX_MODULES; i++) {
|
||||||
|
if (module_table[i].in_use && module_table[i].id == handle_id) {
|
||||||
|
module = module_table[i].module_ref;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
os_mutex_unlock(&module_table_lock);
|
||||||
|
|
||||||
|
return module;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
release_module_handle(uint32 handle_id)
|
||||||
|
{
|
||||||
|
os_mutex_lock(&module_table_lock);
|
||||||
|
|
||||||
|
for (uint32 i = 0; i < MAX_MODULES; i++) {
|
||||||
|
if (module_table[i].in_use && module_table[i].id == handle_id) {
|
||||||
|
module_table[i].id = 0;
|
||||||
|
module_table[i].module_ref = NULL;
|
||||||
|
module_table[i].in_use = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
os_mutex_unlock(&module_table_lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Handle table for secure wasm_module_inst_t reference management */
|
||||||
|
#define MAX_INSTANCES 128
|
||||||
|
typedef struct InstanceTableEntry {
|
||||||
|
uint32 id;
|
||||||
|
wasm_module_inst_t inst_ref;
|
||||||
|
bool in_use;
|
||||||
|
} InstanceTableEntry;
|
||||||
|
|
||||||
|
static InstanceTableEntry instance_table[MAX_INSTANCES] = { 0 };
|
||||||
|
static uint32 next_instance_id = 1;
|
||||||
|
static korp_mutex instance_table_lock = OS_THREAD_MUTEX_INITIALIZER;
|
||||||
|
|
||||||
|
/*Allocate secure handle for wasm_module_inst_t, preventing pointer exposure */
|
||||||
|
static uint32
|
||||||
|
allocate_instance_handle(wasm_module_inst_t inst)
|
||||||
|
{
|
||||||
|
uint32 handle_id = 0;
|
||||||
|
|
||||||
|
os_mutex_lock(&instance_table_lock);
|
||||||
|
|
||||||
|
for (uint32 i = 0; i < MAX_INSTANCES; i++) {
|
||||||
|
if (!instance_table[i].in_use) {
|
||||||
|
instance_table[i].id = next_instance_id++;
|
||||||
|
instance_table[i].inst_ref = inst;
|
||||||
|
instance_table[i].in_use = true;
|
||||||
|
handle_id = instance_table[i].id;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
os_mutex_unlock(&instance_table_lock);
|
||||||
|
|
||||||
|
if (handle_id == 0) {
|
||||||
|
int bytes_written = 0;
|
||||||
|
ocall_print(&bytes_written,
|
||||||
|
"SECURITY WARNING: Instance handle table full\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
return handle_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* SECURITY: Lookup wasm_module_inst_t by handle ID, preventing direct pointer
|
||||||
|
* access */
|
||||||
|
static wasm_module_inst_t
|
||||||
|
lookup_instance_by_handle(uint32 handle_id)
|
||||||
|
{
|
||||||
|
wasm_module_inst_t inst = NULL;
|
||||||
|
|
||||||
|
if (handle_id == 0)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
os_mutex_lock(&instance_table_lock);
|
||||||
|
|
||||||
|
for (uint32 i = 0; i < MAX_INSTANCES; i++) {
|
||||||
|
if (instance_table[i].in_use && instance_table[i].id == handle_id) {
|
||||||
|
inst = instance_table[i].inst_ref;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
os_mutex_unlock(&instance_table_lock);
|
||||||
|
|
||||||
|
return inst;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
release_instance_handle(uint32 handle_id)
|
||||||
|
{
|
||||||
|
os_mutex_lock(&instance_table_lock);
|
||||||
|
|
||||||
|
for (uint32 i = 0; i < MAX_INSTANCES; i++) {
|
||||||
|
if (instance_table[i].in_use && instance_table[i].id == handle_id) {
|
||||||
|
instance_table[i].id = 0;
|
||||||
|
instance_table[i].inst_ref = NULL;
|
||||||
|
instance_table[i].in_use = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
os_mutex_unlock(&instance_table_lock);
|
||||||
|
}
|
||||||
|
|
||||||
#if WASM_ENABLE_GLOBAL_HEAP_POOL != 0
|
#if WASM_ENABLE_GLOBAL_HEAP_POOL != 0
|
||||||
static char global_heap_buf[WASM_GLOBAL_HEAP_SIZE] = { 0 };
|
static char global_heap_buf[WASM_GLOBAL_HEAP_SIZE] = { 0 };
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -277,7 +442,17 @@ handle_cmd_load_module(uint64 *args, uint32 argc)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
*(EnclaveModule **)args_org = enclave_module;
|
uint32 enclave_module_id = allocate_module_handle(enclave_module);
|
||||||
|
if (enclave_module_id == 0) {
|
||||||
|
/* Handle table full - cleanup and return error */
|
||||||
|
if (!enclave_module->is_xip_file)
|
||||||
|
wasm_runtime_free(enclave_module);
|
||||||
|
else
|
||||||
|
os_munmap(enclave_module, (uint32)total_size);
|
||||||
|
*(void **)args_org = NULL;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
*(uint32 *)args_org = enclave_module_id;
|
||||||
|
|
||||||
#if WASM_ENABLE_LIB_RATS != 0
|
#if WASM_ENABLE_LIB_RATS != 0
|
||||||
/* Calculate the module hash */
|
/* Calculate the module hash */
|
||||||
|
|
@ -299,7 +474,8 @@ handle_cmd_load_module(uint64 *args, uint32 argc)
|
||||||
static void
|
static void
|
||||||
handle_cmd_unload_module(uint64 *args, uint32 argc)
|
handle_cmd_unload_module(uint64 *args, uint32 argc)
|
||||||
{
|
{
|
||||||
EnclaveModule *enclave_module = *(EnclaveModule **)args++;
|
uint32 module_handle_id = *(uint32 *)args++;
|
||||||
|
EnclaveModule *enclave_module = lookup_module_by_handle(module_handle_id);
|
||||||
|
|
||||||
bh_assert(argc == 1);
|
bh_assert(argc == 1);
|
||||||
|
|
||||||
|
|
@ -328,6 +504,9 @@ handle_cmd_unload_module(uint64 *args, uint32 argc)
|
||||||
os_mutex_unlock(&enclave_module_list_lock);
|
os_mutex_unlock(&enclave_module_list_lock);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* Release module handle */
|
||||||
|
release_module_handle(module_handle_id);
|
||||||
|
|
||||||
/* Destroy enclave module resources */
|
/* Destroy enclave module resources */
|
||||||
if (enclave_module->wasi_arg_buf)
|
if (enclave_module->wasi_arg_buf)
|
||||||
wasm_runtime_free(enclave_module->wasi_arg_buf);
|
wasm_runtime_free(enclave_module->wasi_arg_buf);
|
||||||
|
|
@ -368,7 +547,8 @@ static void
|
||||||
handle_cmd_instantiate_module(uint64 *args, uint32 argc)
|
handle_cmd_instantiate_module(uint64 *args, uint32 argc)
|
||||||
{
|
{
|
||||||
uint64 *args_org = args;
|
uint64 *args_org = args;
|
||||||
EnclaveModule *enclave_module = *(EnclaveModule **)args++;
|
uint32 module_handle_id = *(uint32 *)args++;
|
||||||
|
EnclaveModule *enclave_module = lookup_module_by_handle(module_handle_id);
|
||||||
uint32 stack_size = *(uint32 *)args++;
|
uint32 stack_size = *(uint32 *)args++;
|
||||||
uint32 heap_size = *(uint32 *)args++;
|
uint32 heap_size = *(uint32 *)args++;
|
||||||
char *error_buf = *(char **)args++;
|
char *error_buf = *(char **)args++;
|
||||||
|
|
@ -377,7 +557,7 @@ handle_cmd_instantiate_module(uint64 *args, uint32 argc)
|
||||||
|
|
||||||
bh_assert(argc == 5);
|
bh_assert(argc == 5);
|
||||||
|
|
||||||
if (!runtime_inited) {
|
if (!runtime_inited || !enclave_module) {
|
||||||
*(void **)args_org = NULL;
|
*(void **)args_org = NULL;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -389,7 +569,13 @@ handle_cmd_instantiate_module(uint64 *args, uint32 argc)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
*(wasm_module_inst_t *)args_org = module_inst;
|
uint32 instance_id = allocate_instance_handle(module_inst);
|
||||||
|
if (instance_id == 0) {
|
||||||
|
wasm_runtime_deinstantiate(module_inst);
|
||||||
|
*(void **)args_org = NULL;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
*(uint32 *)args_org = instance_id;
|
||||||
|
|
||||||
LOG_VERBOSE("Instantiate module success.\n");
|
LOG_VERBOSE("Instantiate module success.\n");
|
||||||
}
|
}
|
||||||
|
|
@ -397,7 +583,9 @@ handle_cmd_instantiate_module(uint64 *args, uint32 argc)
|
||||||
static void
|
static void
|
||||||
handle_cmd_deinstantiate_module(uint64 *args, uint32 argc)
|
handle_cmd_deinstantiate_module(uint64 *args, uint32 argc)
|
||||||
{
|
{
|
||||||
wasm_module_inst_t module_inst = *(wasm_module_inst_t *)args++;
|
uint32 instance_handle_id = *(uint32 *)args++;
|
||||||
|
wasm_module_inst_t module_inst =
|
||||||
|
lookup_instance_by_handle(instance_handle_id);
|
||||||
|
|
||||||
bh_assert(argc == 1);
|
bh_assert(argc == 1);
|
||||||
|
|
||||||
|
|
@ -407,6 +595,8 @@ handle_cmd_deinstantiate_module(uint64 *args, uint32 argc)
|
||||||
|
|
||||||
wasm_runtime_deinstantiate(module_inst);
|
wasm_runtime_deinstantiate(module_inst);
|
||||||
|
|
||||||
|
release_instance_handle(instance_handle_id);
|
||||||
|
|
||||||
LOG_VERBOSE("Deinstantiate module success.\n");
|
LOG_VERBOSE("Deinstantiate module success.\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -414,7 +604,9 @@ static void
|
||||||
handle_cmd_get_exception(uint64 *args, uint32 argc)
|
handle_cmd_get_exception(uint64 *args, uint32 argc)
|
||||||
{
|
{
|
||||||
uint64 *args_org = args;
|
uint64 *args_org = args;
|
||||||
wasm_module_inst_t module_inst = *(wasm_module_inst_t *)args++;
|
uint32 instance_handle_id = *(uint32 *)args++;
|
||||||
|
wasm_module_inst_t module_inst =
|
||||||
|
lookup_instance_by_handle(instance_handle_id);
|
||||||
char *exception = *(char **)args++;
|
char *exception = *(char **)args++;
|
||||||
uint32 exception_size = *(uint32 *)args++;
|
uint32 exception_size = *(uint32 *)args++;
|
||||||
const char *exception1;
|
const char *exception1;
|
||||||
|
|
@ -438,7 +630,9 @@ handle_cmd_get_exception(uint64 *args, uint32 argc)
|
||||||
static void
|
static void
|
||||||
handle_cmd_exec_app_main(uint64 *args, int32 argc)
|
handle_cmd_exec_app_main(uint64 *args, int32 argc)
|
||||||
{
|
{
|
||||||
wasm_module_inst_t module_inst = *(wasm_module_inst_t *)args++;
|
uint32 instance_handle_id = *(uint32 *)args++;
|
||||||
|
wasm_module_inst_t module_inst =
|
||||||
|
lookup_instance_by_handle(instance_handle_id);
|
||||||
uint32 app_argc = *(uint32 *)args++;
|
uint32 app_argc = *(uint32 *)args++;
|
||||||
char **app_argv = NULL;
|
char **app_argv = NULL;
|
||||||
uint64 total_size;
|
uint64 total_size;
|
||||||
|
|
@ -471,7 +665,9 @@ handle_cmd_exec_app_main(uint64 *args, int32 argc)
|
||||||
static void
|
static void
|
||||||
handle_cmd_exec_app_func(uint64 *args, int32 argc)
|
handle_cmd_exec_app_func(uint64 *args, int32 argc)
|
||||||
{
|
{
|
||||||
wasm_module_inst_t module_inst = *(wasm_module_inst_t *)args++;
|
uint32 instance_handle_id = *(uint32 *)args++;
|
||||||
|
wasm_module_inst_t module_inst =
|
||||||
|
lookup_instance_by_handle(instance_handle_id);
|
||||||
char *func_name = *(char **)args++;
|
char *func_name = *(char **)args++;
|
||||||
uint32 app_argc = *(uint32 *)args++;
|
uint32 app_argc = *(uint32 *)args++;
|
||||||
char **app_argv = NULL;
|
char **app_argv = NULL;
|
||||||
|
|
@ -515,7 +711,8 @@ static void
|
||||||
handle_cmd_set_wasi_args(uint64 *args, int32 argc)
|
handle_cmd_set_wasi_args(uint64 *args, int32 argc)
|
||||||
{
|
{
|
||||||
uint64 *args_org = args;
|
uint64 *args_org = args;
|
||||||
EnclaveModule *enclave_module = *(EnclaveModule **)args++;
|
uint32 module_handle_id = *(uint32 *)args++;
|
||||||
|
EnclaveModule *enclave_module = lookup_module_by_handle(module_handle_id);
|
||||||
char **dir_list = *(char ***)args++;
|
char **dir_list = *(char ***)args++;
|
||||||
uint32 dir_list_size = *(uint32 *)args++;
|
uint32 dir_list_size = *(uint32 *)args++;
|
||||||
char **env_list = *(char ***)args++;
|
char **env_list = *(char ***)args++;
|
||||||
|
|
@ -533,7 +730,48 @@ handle_cmd_set_wasi_args(uint64 *args, int32 argc)
|
||||||
|
|
||||||
bh_assert(argc == 10);
|
bh_assert(argc == 10);
|
||||||
|
|
||||||
if (!runtime_inited) {
|
if (!runtime_inited || !enclave_module) {
|
||||||
|
*args_org = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Validate all pointer arrays before use */
|
||||||
|
if (dir_list_size > 0
|
||||||
|
&& (!dir_list
|
||||||
|
|| !sgx_is_outside_enclave(dir_list,
|
||||||
|
sizeof(char *) * dir_list_size))) {
|
||||||
|
int bytes_written = 0;
|
||||||
|
ocall_print(&bytes_written, "SECURITY ERROR: Invalid dir_list\n");
|
||||||
|
*args_org = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (env_list_size > 0
|
||||||
|
&& (!env_list
|
||||||
|
|| !sgx_is_outside_enclave(env_list,
|
||||||
|
sizeof(char *) * env_list_size))) {
|
||||||
|
int bytes_written = 0;
|
||||||
|
ocall_print(&bytes_written, "SECURITY ERROR: Invalid env_list\n");
|
||||||
|
*args_org = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (wasi_argc > 0
|
||||||
|
&& (!wasi_argv
|
||||||
|
|| !sgx_is_outside_enclave(wasi_argv,
|
||||||
|
sizeof(char *) * wasi_argc))) {
|
||||||
|
int bytes_written = 0;
|
||||||
|
ocall_print(&bytes_written, "SECURITY ERROR: Invalid wasi_argv\n");
|
||||||
|
*args_org = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (addr_pool_list_size > 0
|
||||||
|
&& (!addr_pool_list
|
||||||
|
|| !sgx_is_outside_enclave(addr_pool_list,
|
||||||
|
sizeof(char *) * addr_pool_list_size))) {
|
||||||
|
int bytes_written = 0;
|
||||||
|
ocall_print(&bytes_written, "SECURITY ERROR: Invalid addr_pool_list\n");
|
||||||
*args_org = false;
|
*args_org = false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -695,9 +933,38 @@ void
|
||||||
ecall_handle_command(unsigned cmd, unsigned char *cmd_buf,
|
ecall_handle_command(unsigned cmd, unsigned char *cmd_buf,
|
||||||
unsigned cmd_buf_size)
|
unsigned cmd_buf_size)
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
|
* Validate buffer before processing
|
||||||
|
* cmd_buf can be NULL if cmd_buf_size is 0, but if cmd_buf_size is
|
||||||
|
* non-zero, cmd_buf must be valid
|
||||||
|
*/
|
||||||
|
if ((!cmd_buf && cmd_buf_size > 0) || (cmd_buf && cmd_buf_size == 0)) {
|
||||||
|
int bytes_written = 0;
|
||||||
|
ocall_print(&bytes_written,
|
||||||
|
"SECURITY ERROR: Invalid buffer parameters\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Because of [in, out] cmd_buf in edl, it is allocated inside enclave.
|
||||||
|
if (cmd_buf && sgx_is_outside_enclave(cmd_buf, cmd_buf_size)) {
|
||||||
|
int bytes_written = 0;
|
||||||
|
ocall_print(&bytes_written,
|
||||||
|
"SECURITY ERROR: Buffer should be inside enclave\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cmd_buf_size % sizeof(uint64) != 0) {
|
||||||
|
int bytes_written = 0;
|
||||||
|
ocall_print(&bytes_written,
|
||||||
|
"SECURITY ERROR: Buffer alignment invalid\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
uint64 *args = (uint64 *)cmd_buf;
|
uint64 *args = (uint64 *)cmd_buf;
|
||||||
uint32 argc = cmd_buf_size / sizeof(uint64);
|
uint32 argc = cmd_buf_size / sizeof(uint64);
|
||||||
|
|
||||||
|
LOG_VERBOSE("Received command %d with %u arguments.\n", cmd, argc);
|
||||||
|
|
||||||
switch (cmd) {
|
switch (cmd) {
|
||||||
case CMD_INIT_RUNTIME:
|
case CMD_INIT_RUNTIME:
|
||||||
handle_cmd_init_runtime(args, argc);
|
handle_cmd_init_runtime(args, argc);
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,7 @@ enclave {
|
||||||
from "sgx_tprotected_fs.edl" import *;
|
from "sgx_tprotected_fs.edl" import *;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
//TODO: replace void with an int as error code
|
||||||
trusted {
|
trusted {
|
||||||
/* define ECALLs here. */
|
/* define ECALLs here. */
|
||||||
public void ecall_handle_command(unsigned cmd,
|
public void ecall_handle_command(unsigned cmd,
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user