It is easy to craft a config file that loads a profile recursively. To prevent this, not only check the depth of the current inclusion but also ignore already-seen profile names.
Unified · Split
| @@ -986,8 +986,14 @@ static struct m_profile *find_check_profile(struct m_config *config, char *name) · 985 unmodified lines | |||
| 986 | MP_WARN(config, "Unknown profile '%s'.\n", name); | 986 | MP_WARN(config, "Unknown profile '%s'.\n", name); |
| 987 | return NULL; | 987 | return NULL; |
| 988 | } | 988 | } |
| 989 | if (config->profile_depth > MAX_PROFILE_DEPTH) { | 989 | for (size_t i = 0; i < config->profile_stack_depth; ++i) { |
| 990 | MP_WARN(config, "WARNING: Profile inclusion too deep.\n"); | 990 | if (strcmp(config->profile_stack[i], name)) |
| 991 | continue; | ||
| 992 | MP_WARN(config, "Profile '%s' has already been applied.\n", name); | ||
| 993 | return NULL; | ||
| 994 | } | ||
| 995 | if (config->profile_stack_depth > MAX_PROFILE_DEPTH) { | ||
| 996 | MP_WARN(config, "Profile inclusion too deep.\n"); | ||
| 991 | return NULL; | 997 | return NULL; |
| 992 | } | 998 | } |
| 993 | return p; | 999 | return p; |
| @@ -995,11 +1001,6 @@ static struct m_profile *find_check_profile(struct m_config *config, char *name) · 1 unmodified line | |||
| 995 | 1001 | ||
| 996 | int m_config_set_profile(struct m_config *config, char *name, int flags) | 1002 | int m_config_set_profile(struct m_config *config, char *name, int flags) |
| 997 | { | 1003 | { |
| 998 | if ((flags & M_SETOPT_FROM_CONFIG_FILE) && !strcmp(name, "default")) { | ||
| 999 | MP_WARN(config, "Ignoring profile=%s from config file.\n", name); | ||
| 1000 | return 0; | ||
| 1001 | } | ||
| 1002 | |||
| 1003 | MP_VERBOSE(config, "Applying profile '%s'...\n", name); | 1004 | MP_VERBOSE(config, "Applying profile '%s'...\n", name); |
| 1004 | struct m_profile *p = find_check_profile(config, name); | 1005 | struct m_profile *p = find_check_profile(config, name); |
| 1005 | if (!p) | 1006 | if (!p) |
| @@ -1010,14 +1011,18 @@ int m_config_set_profile(struct m_config *config, char *name, int flags) · 4 unmodified lines | |||
| 1010 | config->profile_backup_flags = p->restore_mode == 2 ? BACKUP_NVAL : 0; | 1011 | config->profile_backup_flags = p->restore_mode == 2 ? BACKUP_NVAL : 0; |
| 1011 | } | 1012 | } |
| 1012 | 1013 | ||
| 1013 | config->profile_depth++; | 1014 | char *profile_name = talloc_strdup(NULL, name); |
| 1015 | // Note that we don't check if profile applied correctly, it doesn't matter. | ||
| 1016 | MP_TARRAY_APPEND(config, config->profile_stack, config->profile_stack_depth, profile_name); | ||
| 1017 | talloc_steal(config->profile_stack, profile_name); | ||
| 1014 | for (int i = 0; i < p->num_opts; i++) { | 1018 | for (int i = 0; i < p->num_opts; i++) { |
| 1015 | m_config_set_option_cli(config, | 1019 | m_config_set_option_cli(config, |
| 1016 | bstr0(p->opts[2 * i]), | 1020 | bstr0(p->opts[2 * i]), |
| 1017 | bstr0(p->opts[2 * i + 1]), | 1021 | bstr0(p->opts[2 * i + 1]), |
| 1018 | flags | M_SETOPT_FROM_CONFIG_FILE); | 1022 | flags | M_SETOPT_FROM_CONFIG_FILE); |
| 1019 | } | 1023 | } |
| 1020 | config->profile_depth--; | 1024 | if (MP_TARRAY_POP(config->profile_stack, config->profile_stack_depth, &profile_name)) |
| 1025 | talloc_free(profile_name); | ||
| 1021 | 1026 | ||
| 1022 | if (config->profile_backup_tmp == &p->backups) { | 1027 | if (config->profile_backup_tmp == &p->backups) { |
| 1023 | config->profile_backup_tmp = NULL; | 1028 | config->profile_backup_tmp = NULL; |
| @@ -69,6 +69,8 @@ typedef struct m_config { · 68 unmodified lines | |||
| 69 | struct m_profile *profiles; | 69 | struct m_profile *profiles; |
| 70 | // Depth when recursively including profiles. | 70 | // Depth when recursively including profiles. |
| 71 | int profile_depth; | 71 | int profile_depth; |
| 72 | char **profile_stack; | ||
| 73 | size_t profile_stack_depth; | ||
| 72 | // Temporary during profile application. | 74 | // Temporary during profile application. |
| 73 | struct m_opt_backup **profile_backup_tmp; | 75 | struct m_opt_backup **profile_backup_tmp; |
| 74 | int profile_backup_flags; | 76 | int profile_backup_flags; |