Files
MosisService/src/main/cpp/sandbox/lua_sandbox.h

102 lines
3.0 KiB
C++

#pragma once
#include <string>
#include <vector>
#include <cstdint>
// Forward declare lua_State to avoid including lua.h in header
struct lua_State;
struct lua_Debug;
namespace mosis {
// Resource limits for sandbox
struct SandboxLimits {
size_t memory_bytes = 16 * 1024 * 1024; // 16 MB default
size_t max_string_size = 1 * 1024 * 1024; // 1 MB max string
size_t max_table_entries = 100000; // Prevent hash DoS
uint64_t instructions_per_call = 1000000; // ~10ms execution
int stack_depth = 200; // Recursion limit
};
// Context for sandbox (app identity, permissions, etc.)
struct SandboxContext {
std::string app_id;
std::string app_path;
std::vector<std::string> permissions;
bool is_system_app = false;
};
// Isolated Lua execution environment
class LuaSandbox {
public:
explicit LuaSandbox(const SandboxContext& context,
const SandboxLimits& limits = {});
~LuaSandbox();
// Non-copyable, non-movable
LuaSandbox(const LuaSandbox&) = delete;
LuaSandbox& operator=(const LuaSandbox&) = delete;
LuaSandbox(LuaSandbox&&) = delete;
LuaSandbox& operator=(LuaSandbox&&) = delete;
// Load and execute Lua code (text only, bytecode rejected)
bool LoadString(const std::string& code, const std::string& chunk_name = "chunk");
bool LoadFile(const std::string& path);
// State access
lua_State* GetState() const { return m_L; }
const std::string& GetLastError() const { return m_last_error; }
// Resource usage
size_t GetMemoryUsed() const { return m_memory_used; }
uint64_t GetInstructionsUsed() const { return m_instructions_used; }
// Context access
const SandboxContext& GetContext() const { return m_context; }
const SandboxLimits& GetLimits() const { return m_limits; }
const std::string& app_id() const { return m_context.app_id; }
// Reset instruction counter (call before each event handler)
void ResetInstructionCount();
// Check if sandbox is in valid state
bool IsValid() const { return m_L != nullptr; }
private:
// Setup functions
void SetupSandbox();
void RemoveDangerousGlobals();
void ProtectBuiltinTables();
void SetupInstructionHook();
void SetupSafeGlobals();
void SetupSafeRequire();
// Allocator callback (static for C compatibility)
static void* SandboxAlloc(void* ud, void* ptr, size_t osize, size_t nsize);
// Instruction hook callback (static for C compatibility)
static void InstructionHook(lua_State* L, lua_Debug* ar);
// Safe print function
static int SafePrint(lua_State* L);
// Safe require function
static int SafeRequire(lua_State* L);
lua_State* m_L = nullptr;
SandboxContext m_context;
SandboxLimits m_limits;
size_t m_memory_used = 0;
uint64_t m_instructions_used = 0;
std::string m_last_error;
};
} // namespace mosis
// Convenience alias for tests
using SandboxContext = mosis::SandboxContext;
using SandboxLimits = mosis::SandboxLimits;
using LuaSandbox = mosis::LuaSandbox;