add Lua sandbox with timer system (milestones 1-5 complete)
This commit is contained in:
101
src/main/cpp/sandbox/lua_sandbox.h
Normal file
101
src/main/cpp/sandbox/lua_sandbox.h
Normal file
@@ -0,0 +1,101 @@
|
||||
#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;
|
||||
Reference in New Issue
Block a user