manager.c: Restrict ModuleLoad to the configured modules directory.

When using the ModuleLoad AMI action, it was possible to traverse
upwards through the directories to files outside of the configured
modules directory. We decided it would be best to restrict access to
modules exclusively in the configured directory. You will now get an
error when the specified module is outside of this limitation.

Fixes: #897

UserNote: The ModuleLoad AMI action now restricts modules to the
configured modules directory.
pull/931/head
Ben Ford 7 months ago committed by asterisk-org-access-app[bot]
parent c0d3fbb5ae
commit e19da5d86f

@ -6682,6 +6682,42 @@ static int manager_modulecheck(struct mansession *s, const struct message *m)
return 0;
}
/**
* \brief Check if the given file path is in the modules dir or not
*
* \note When the module is being loaded / reloaded / unloaded, the modules dir is
* automatically prepended
*
* \return 1 if inside modules dir
* \return 0 if outside modules dir
* \return -1 on failure
*/
static int file_in_modules_dir(const char *filename)
{
char *stripped_filename;
RAII_VAR(char *, path, NULL, ast_free);
RAII_VAR(char *, real_path, NULL, ast_free);
/* Don't bother checking */
if (live_dangerously) {
return 1;
}
stripped_filename = ast_strip(ast_strdupa(filename));
/* Always prepend the modules dir since that is what the code does for ModuleLoad */
if (ast_asprintf(&path, "%s/%s", ast_config_AST_MODULE_DIR, stripped_filename) == -1) {
return -1;
}
real_path = realpath(path, NULL);
if (!real_path) {
return -1;
}
return ast_begins_with(real_path, ast_config_AST_MODULE_DIR);
}
static int manager_moduleload(struct mansession *s, const struct message *m)
{
int res;
@ -6696,6 +6732,15 @@ static int manager_moduleload(struct mansession *s, const struct message *m)
astman_send_error(s, m, "Need module name");
}
res = file_in_modules_dir(module);
if (res == 0) {
astman_send_error(s, m, "Module must be in the configured modules directory.");
return 0;
} else if (res == -1) {
astman_send_error(s, m, "Module not found.");
return 0;
}
if (!strcasecmp(loadtype, "load")) {
res = ast_load_resource(module);
if (res) {
@ -6748,8 +6793,9 @@ static int manager_moduleload(struct mansession *s, const struct message *m)
ast_module_reload(NULL); /* Reload all modules */
astman_send_ack(s, m, "All modules reloaded");
}
} else
} else {
astman_send_error(s, m, "Incomplete ModuleLoad action.");
}
return 0;
}

Loading…
Cancel
Save