summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCorey Farrell <git@cfware.com>2018-01-12 19:37:43 -0500
committerCorey Farrell <git@cfware.com>2018-01-12 19:57:38 -0500
commitde7f2a6cb4c17c1aefa5c71228fa9a299591d92c (patch)
tree87514f04fab72e41ba76bb86faed0d0bb827b11a
parent516ab38df6ee2a196a54768e983f741f3bfc5fcb (diff)
res_stasis_recording: Allow symbolic links in configured recordings dir.
If any component of ast_config_AST_RECORDING_DIR is a symbolic link we would incorrectly assume the ARI user was trying to escape the recording path. Create additional check to check the recording directory's realpath, only deny access if both do not match. This is needed by the testsuite when run by 'run-local'. Change-Id: I9145e841865edadcb5f75cead3471ad06bbb56c0
-rw-r--r--res/stasis_recording/stored.c25
1 files changed, 18 insertions, 7 deletions
diff --git a/res/stasis_recording/stored.c b/res/stasis_recording/stored.c
index 9df5d75dc..ac216ff8c 100644
--- a/res/stasis_recording/stored.c
+++ b/res/stasis_recording/stored.c
@@ -330,6 +330,7 @@ struct stasis_app_stored_recording *stasis_app_stored_recording_find_by_name(
RAII_VAR(char *, file_with_ext, NULL, ast_free);
int res;
struct stat file_stat;
+ int prefix_len = strlen(ast_config_AST_RECORDING_DIR);
errno = 0;
@@ -350,18 +351,28 @@ struct stasis_app_stored_recording *stasis_app_stored_recording_find_by_name(
ast_string_field_build(recording, file, "%s/%s", dir, file);
if (!ast_begins_with(dir, ast_config_AST_RECORDING_DIR)) {
- /* Attempt to escape the recording directory */
- ast_log(LOG_WARNING, "Attempt to access invalid recording %s\n",
- name);
- errno = EACCES;
- return NULL;
+ /* It's possible that one or more component of the recording path is
+ * a symbolic link, this would prevent dir from ever matching. */
+ char *real_basedir = realpath(ast_config_AST_RECORDING_DIR, NULL);
+
+ if (!real_basedir || !ast_begins_with(dir, real_basedir)) {
+ /* Attempt to escape the recording directory */
+ ast_log(LOG_WARNING, "Attempt to access invalid recording directory %s\n",
+ dir);
+ ast_std_free(real_basedir);
+ errno = EACCES;
+
+ return NULL;
+ }
+
+ prefix_len = strlen(real_basedir);
+ ast_std_free(real_basedir);
}
/* The actual name of the recording is file with the config dir
* prefix removed.
*/
- ast_string_field_set(recording, name,
- recording->file + strlen(ast_config_AST_RECORDING_DIR) + 1);
+ ast_string_field_set(recording, name, recording->file + prefix_len + 1);
file_with_ext = find_recording(dir, file);
if (!file_with_ext) {