Language: C
Label: vulnerable
CWE: CWE-22 \u2014 Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal')
The product uses external input to construct a pathname that is intended to identify a file or directory that is located underneath a restricted parent directory, but the product does not properly neutralize special elements within the pathname that can cause the pathname to resolve to a location that is outside of the restricted directory.

Code:
static int action_getconfig(struct mansession *s, const struct message *m)
{
	struct ast_config *cfg;
	const char *fn = astman_get_header(m, "Filename");
	const char *category = astman_get_header(m, "Category");
	const char *filter = astman_get_header(m, "Filter");
	const char *category_name;
	int catcount = 0;
	int lineno = 0;
	struct ast_category *cur_category = NULL;
	struct ast_variable *v;
	struct ast_flags config_flags = { CONFIG_FLAG_WITHCOMMENTS | CONFIG_FLAG_NOCACHE };

	if (ast_strlen_zero(fn)) {
		astman_send_error(s, m, "Filename not specified");
		return 0;
	}

	if (restrictedFile(fn)) {
		astman_send_error(s, m, "File requires escalated priveledges");
		return 0;
	}

	cfg = ast_config_load2(fn, "manager", config_flags);
	if (cfg == CONFIG_STATUS_FILEMISSING) {
		astman_send_error(s, m, "Config file not found");
		return 0;
	} else if (cfg == CONFIG_STATUS_FILEINVALID) {
		astman_send_error(s, m, "Config file has invalid format");
		return 0;
	}

	astman_start_ack(s, m);
	while ((cur_category = ast_category_browse_filtered(cfg, category, cur_category, filter))) {
		struct ast_str *templates;

		category_name = ast_category_get_name(cur_category);
		lineno = 0;
		astman_append(s, "Category-%06d: %s\r\n", catcount, category_name);

		if (ast_category_is_template(cur_category)) {
			astman_append(s, "IsTemplate-%06d: %d\r\n", catcount, 1);
		}

		if ((templates = ast_category_get_templates(cur_category))
			&& ast_str_strlen(templates) > 0) {
			astman_append(s, "Templates-%06d: %s\r\n", catcount, ast_str_buffer(templates));
			ast_free(templates);
		}

		for (v = ast_category_first(cur_category); v; v = v->next) {
			astman_append(s, "Line-%06d-%06d: %s=%s\r\n", catcount, lineno++, v->name, v->value);
		}

		catcount++;
	}

	if (!ast_strlen_zero(category) && catcount == 0) { /* TODO: actually, a config with no categories doesn't even get loaded */
		astman_append(s, "No categories found\r\n");
	}

	ast_config_destroy(cfg);
	astman_append(s, "\r\n");

	return 0;
}