这段代码实现了一个函数 format_url_for_hs,用于将一个字符串格式化为一个用于匹配的正则表达式。代码的逻辑看起来没有问题,但是存在一个潜在的缓冲区溢出风险。

在函数中,使用了 alloca 函数动态分配了一个大小为 total 的缓冲区,用于存储格式化后的字符串。但是,在最后一行代码中,使用了 strlcpy 函数将格式化后的字符串拷贝到了 xfmt 这个由调用者传入的缓冲区中,而没有对拷贝的长度进行检查。如果 dst 字符串的长度超过了 xfmt_len,就会导致缓冲区溢出。

因此,需要在拷贝之前先检查 dst 字符串的长度,如果超过了 xfmt_len,则需要返回错误码。可以使用 strlen 函数获取 dst 字符串的长度,然后和 xfmt_len 进行比较。如果 dst 字符串的长度超过了 xfmt_len,就返回一个错误码。

以下是对代码的修改建议:

static int format_url_for_hs(const char *str, int len, char *xfmt,
	int xfmt_len, int match_method)
{
	unsigned int i = 0;
	unsigned int total;
	const char *now = str;
	char *to, *dst = NULL;

	if (!len)
		return -1;

	total = 2 * len + 4;
	dst = alloca(total);
	if (dst == NULL) {
		strlcpy(xfmt, str, xfmt_len);
		WAF_DBG("alloca len %u failed\n", total);
		return 0;
	}

	to = dst;
	if (str[0] != '*' && match_method == MATCH_ACCURATE) {
		*to = '^';
		to++;
	} else {
		i = 1;
		now++;
	}

	for (; i < len; i++) {
		if (is_metachar(*now)) {
			*to = '\';
			to++;
		} else if (i && *now == '*') {
			*to = '.';
			to++;
		}

		*to++ = *now++;
	}

	if (str[len-1] != '*' && match_method == MATCH_ACCURATE) {
		*to = '$';
		to++;
	}

	*to = '\0';
	assert(to < (dst + total));

	// 检查 dst 字符串长度
	if (strlen(dst) >= xfmt_len) {
		return -1; // 返回错误码
	}

	strlcpy(xfmt, dst, xfmt_len);
	return 0;
}

通过添加长度检查,可以有效避免缓冲区溢出风险,提高代码安全性。

C 代码安全漏洞分析:format_url_for_hs 函数缓冲区溢出风险

原文地址: https://www.cveoy.top/t/topic/mikw 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录