Skip to content

Commit

Permalink
AP_Scripting: add checksum of running and loaded scripts with arming …
Browse files Browse the repository at this point in the history
…check
  • Loading branch information
IamPete1 committed Nov 25, 2023
1 parent 18c4b6a commit ad15e41
Show file tree
Hide file tree
Showing 4 changed files with 83 additions and 2 deletions.
33 changes: 33 additions & 0 deletions libraries/AP_Scripting/AP_Scripting.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,18 @@ const AP_Param::GroupInfo AP_Scripting::var_info[] = {
// @User: Advanced
AP_GROUPINFO("DIR_DISABLE", 9, AP_Scripting, _dir_disable, 0),

// @Param: LD_CHECKSUM
// @DisplayName: Loaded script checksum
// @Description: Required XOR of CRC32 checksum of loaded scripts, vehicle will not arm with incorrect scripts loaded, -1 disables
// @User: Advanced
AP_GROUPINFO("LD_CHECKSUM", 12, AP_Scripting, _required_loaded_checksum, -1),

// @Param: RUN_CHECKSUM
// @DisplayName: Running script checksum
// @Description: Required XOR of CRC32 checksum of running scripts, vehicle will not arm with incorrect scripts running, -1 disables
// @User: Advanced
AP_GROUPINFO("RUN_CHECKSUM", 13, AP_Scripting, _required_running_checksum, -1),

AP_GROUPEND
};

Expand Down Expand Up @@ -357,6 +369,27 @@ bool AP_Scripting::arming_checks(size_t buflen, char *buffer) const
}
lua_scripts::get_last_error_semaphore()->give();

// Use -1 for disabled, this means we don't have to avoid 0 in the CRC
// We mask off that the sign bit anyway to deal with the float transport of parameters
const uint32_t mask = 0x000FFFFF;
if (_required_loaded_checksum != -1) {
const uint32_t expected_loaded = (uint32_t)_required_loaded_checksum.get() & mask;
const uint32_t loaded = lua_scripts::get_loaded_checksum() & mask;
if (expected_loaded != loaded) {
hal.util->snprintf(buffer, buflen, "Scripting: loaded CRC incorrect want: 0x%x", (unsigned int)loaded);
return false;
}
}

if (_required_running_checksum != -1) {
const uint32_t expected_running = (uint32_t)_required_running_checksum.get() & mask;
const uint32_t running = lua_scripts::get_running_checksum() & mask;
if (expected_running != running) {
hal.util->snprintf(buffer, buflen, "Scripting: running CRC incorrect want: 0x%x", (unsigned int)running);
return false;
}
}

return true;
}

Expand Down
5 changes: 3 additions & 2 deletions libraries/AP_Scripting/AP_Scripting.h
Original file line number Diff line number Diff line change
Expand Up @@ -134,15 +134,16 @@ class AP_Scripting
bool repl_start(void);
void repl_stop(void);

void load_script(const char *filename); // load a script from a file

void thread(void); // main script execution thread

AP_Int8 _enable;
AP_Int32 _script_vm_exec_count;
AP_Int32 _script_heap_size;
AP_Int8 _debug_options;
AP_Int16 _dir_disable;
AP_Int32 _required_loaded_checksum;
AP_Int32 _required_running_checksum;


bool _thread_failed; // thread allocation failed
bool _init_failed; // true if memory allocation failed
Expand Down
37 changes: 37 additions & 0 deletions libraries/AP_Scripting/lua_scripts.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,10 @@ HAL_Semaphore lua_scripts::error_msg_buf_sem;
uint8_t lua_scripts::print_error_count;
uint32_t lua_scripts::last_print_ms;

uint32_t lua_scripts::loaded_checksum;
uint32_t lua_scripts::running_checksum;
HAL_Semaphore lua_scripts::crc_sem;

lua_scripts::lua_scripts(const AP_Int32 &vm_steps, const AP_Int32 &heap_size, const AP_Int8 &debug_options, struct AP_Scripting::terminal_s &_terminal)
: _vm_steps(vm_steps),
_debug_options(debug_options),
Expand Down Expand Up @@ -199,6 +203,19 @@ lua_scripts::script_info *lua_scripts::load_script(lua_State *L, char *filename)
new_script->lua_ref = luaL_ref(L, LUA_REGISTRYINDEX); // cache the reference
new_script->next_run_ms = AP_HAL::millis64() - 1; // force the script to be stale

// Get checksum of file
uint32_t crc = 0;
if (AP::FS().crc32(filename, crc)) {
// Record crc of this script
new_script->crc = crc;
{
// Apply crc to checksum of all scripts
WITH_SEMAPHORE(crc_sem);
loaded_checksum ^= crc;
running_checksum ^= crc;
}
}

return new_script;
}

Expand Down Expand Up @@ -391,6 +408,13 @@ void lua_scripts::remove_script(lua_State *L, script_info *script) {
}
_heap.deallocate(script->name);
_heap.deallocate(script);

{
// Remove from running checksum
WITH_SEMAPHORE(crc_sem);
running_checksum ^= script->crc;
}

}

void lua_scripts::reschedule_script(script_info *script) {
Expand Down Expand Up @@ -606,4 +630,17 @@ void lua_scripts::run(void) {
error_msg_buf_sem.give();
}

// Return the file checksums of running and loaded scripts
uint32_t lua_scripts::get_loaded_checksum()
{
WITH_SEMAPHORE(crc_sem);
return loaded_checksum;
}

uint32_t lua_scripts::get_running_checksum()
{
WITH_SEMAPHORE(crc_sem);
return running_checksum;
}

#endif // AP_SCRIPTING_ENABLED
10 changes: 10 additions & 0 deletions libraries/AP_Scripting/lua_scripts.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ class lua_scripts
typedef struct script_info {
int lua_ref; // reference to the loaded script object
uint64_t next_run_ms; // time (in milliseconds) the script should next be run at
uint32_t crc; // crc32 checksum
char *name; // filename for the script // FIXME: This information should be available from Lua
script_info *next;
} script_info;
Expand Down Expand Up @@ -125,6 +126,11 @@ class lua_scripts
static uint32_t last_print_ms;
int current_ref;

// XOR of crc32 of running scripts
static uint32_t loaded_checksum;
static uint32_t running_checksum;
static HAL_Semaphore crc_sem;

public:
// must be static for use in atpanic, public to allow bindings to issue none fatal warnings
static void set_and_print_new_error_message(MAV_SEVERITY severity, const char *fmt, ...) FMT_PRINTF(2,3);
Expand All @@ -135,6 +141,10 @@ class lua_scripts
// get semaphore for above error buffer
static AP_HAL::Semaphore* get_last_error_semaphore() { return &error_msg_buf_sem; }

// Return the file checksums of running and loaded scripts
static uint32_t get_loaded_checksum();
static uint32_t get_running_checksum();

};

#endif // AP_SCRIPTING_ENABLED

0 comments on commit ad15e41

Please sign in to comment.