php扩展开发笔记(7) 错误使用 php_base64_decode 导致内存溢出
在开发解密函数的时候,因为调用了 php_base64_decode 内核自带的扩展函数,导致内存溢出,而且是在某些情况下溢出。经排查是由于忽略了 php_base64_decode 的参数,先来看看这个函数的原型
PHPAPI unsigned char *php_base64_decode(const unsigned char *str, int length, int *ret_length) /* {{{ */
{
return php_base64_decode_ex(str, length, ret_length, 0);
}
/* }}} */
PHPAPI unsigned char *php_base64_decode_ex(const unsigned char *str, int length, int *ret_length, zend_bool strict) /* {{{ */
{
const unsigned char *current = str;
int ch, i = 0, j = 0, k;
/* this sucks for threaded environments */
unsigned char *result;
result = (unsigned char *)safe_emalloc(length, 1, 1);
/* run through the whole string, converting as we go */
while ((ch = *current++) != " " && length-- > 0) {
if (ch == base64_pad) {
if (*current != "=" && ((i % 4) == 1 || (strict && length > 0))) {
if ((i % 4) != 1) {
while (isspace(*(++current))) {
continue;
}
if (*current == " ") {
continue;
}
}
efree(result);
return NULL;
}
continue;
}
ch = base64_reverse_table[ch];
if ((!strict && ch < 0) || ch == -1) { /* a space or some other separator character, we simply skip over */
continue;
} else if (ch == -2) {
efree(result);
return NULL;
}
switch(i % 4) {
case 0:
result[j] = ch << 2;
break;
case 1:
result[j++] |= ch >> 4;
result[j] = (ch & 0x0f) << 4;
break;
case 2:
result[j++] |= ch >>2;
result[j] = (ch & 0x03) << 6;
break;
case 3:
result[j++] |= ch;
break;
}
i++;
}
k = j;
/* mop things up if we ended on a boundary */
if (ch == base64_pad) {
switch(i % 4) {
case 1:
efree(result);
return NULL;
case 2:
k++;
case 3:
result[k] = 0;
}
}
if(ret_length) {
*ret_length = j;
}
result[j] = " ";
return result;
}
/* }}} */
这个函数返回一个 char * 类型,并且给返回值计算了长度 ret_length,下面是调用代码
char *str_decode = (char *) php_base64_decode((unsigned char *) str_to_decode, strlen(str_to_decode), &str_decode_len);
因为解密的时候,需要计算 str_decode 这个变量的长度,我使用了 strlen(str_decode) ,这样带来的结果就是 strlen(str_decode) 和 ret_length 这个值在有些情况下是不想等的,具体在哪些情况下不想等,大家可以看上面贴出来的代码。
所以,就是因为这个 strlen(str_decode) 使用不当,导致了内存溢出。
声明:该文观点仅代表作者本人,牛骨文系教育信息发布平台,牛骨文仅提供信息存储空间服务。