1570af302Sopenharmony_ci/* 2570af302Sopenharmony_ci * Copyright (C) 2022 Huawei Device Co., Ltd. 3570af302Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4570af302Sopenharmony_ci * you may not use this file except in compliance with the License. 5570af302Sopenharmony_ci * You may obtain a copy of the License at 6570af302Sopenharmony_ci * 7570af302Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8570af302Sopenharmony_ci * 9570af302Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10570af302Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 11570af302Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12570af302Sopenharmony_ci * See the License for the specific language governing permissions and 13570af302Sopenharmony_ci * limitations under the License. 14570af302Sopenharmony_ci */ 15570af302Sopenharmony_ci 16570af302Sopenharmony_ci#include <stdlib.h> 17570af302Sopenharmony_ci#include <unistd.h> 18570af302Sopenharmony_ci#include <sys/wait.h> 19570af302Sopenharmony_ci#include <signal.h> 20570af302Sopenharmony_ci#include <errno.h> 21570af302Sopenharmony_ci#include <string.h> 22570af302Sopenharmony_ci#include "test.h" 23570af302Sopenharmony_ci 24570af302Sopenharmony_cistatic void handler(int s) 25570af302Sopenharmony_ci{ 26570af302Sopenharmony_ci} 27570af302Sopenharmony_ci 28570af302Sopenharmony_ciuint8_t *p0; 29570af302Sopenharmony_ciuint8_t *p1; 30570af302Sopenharmony_ci 31570af302Sopenharmony_ci#define UNIT 16 32570af302Sopenharmony_ci#define OFF_OFFSET 2 33570af302Sopenharmony_ci#define FIRST_OFFSET (-4) 34570af302Sopenharmony_ci#define FIRST_OFF_OFFSET 8 35570af302Sopenharmony_ci#define MALLOC_SIZE_S (10 * sizeof(uintptr_t)) 36570af302Sopenharmony_ci#define TEST_NUM 512 37570af302Sopenharmony_ci 38570af302Sopenharmony_civolatile void *tmp[TEST_NUM]; 39570af302Sopenharmony_ci 40570af302Sopenharmony_cistruct meta_in { 41570af302Sopenharmony_ci struct meta_in *prev, *next; 42570af302Sopenharmony_ci uintptr_t *mem; 43570af302Sopenharmony_ci}; 44570af302Sopenharmony_ci 45570af302Sopenharmony_cistruct group_in { 46570af302Sopenharmony_ci struct meta_in *meta; 47570af302Sopenharmony_ci}; 48570af302Sopenharmony_ci 49570af302Sopenharmony_cistatic struct group_in *get_group(uint8_t *p) 50570af302Sopenharmony_ci{ 51570af302Sopenharmony_ci int offset = *(uint16_t *)(p - OFF_OFFSET); 52570af302Sopenharmony_ci 53570af302Sopenharmony_ci if (p[FIRST_OFFSET]) { 54570af302Sopenharmony_ci offset = *(uint32_t *)(p - FIRST_OFF_OFFSET); 55570af302Sopenharmony_ci } 56570af302Sopenharmony_ci 57570af302Sopenharmony_ci struct group_in *base = (void *)(p - UNIT*offset - UNIT); 58570af302Sopenharmony_ci return base; 59570af302Sopenharmony_ci} 60570af302Sopenharmony_ci 61570af302Sopenharmony_ci 62570af302Sopenharmony_cistatic int child(void) 63570af302Sopenharmony_ci{ 64570af302Sopenharmony_ci struct group_in *g = NULL; 65570af302Sopenharmony_ci 66570af302Sopenharmony_ci p0 = (uint8_t *)malloc(MALLOC_SIZE_S); 67570af302Sopenharmony_ci if (!p0) { 68570af302Sopenharmony_ci t_error("Malloc failed:%s\n", strerror(errno)); 69570af302Sopenharmony_ci return -1; 70570af302Sopenharmony_ci } 71570af302Sopenharmony_ci /* Malloc a dividing chunk to avoid combination of neighbouring freed chunk */ 72570af302Sopenharmony_ci tmp[0] = malloc(MALLOC_SIZE_S); 73570af302Sopenharmony_ci 74570af302Sopenharmony_ci g = get_group(p0); 75570af302Sopenharmony_ci free((void *)tmp[0]); 76570af302Sopenharmony_ci g->meta += 1; 77570af302Sopenharmony_ci 78570af302Sopenharmony_ci for (int i = 0; i < TEST_NUM; ++i) { 79570af302Sopenharmony_ci tmp[i] = malloc(MALLOC_SIZE_S); 80570af302Sopenharmony_ci } 81570af302Sopenharmony_ci 82570af302Sopenharmony_ci for (int i = 0; i < TEST_NUM; ++i) { 83570af302Sopenharmony_ci free((void *)tmp[i]); 84570af302Sopenharmony_ci } 85570af302Sopenharmony_ci return 0; 86570af302Sopenharmony_ci} 87570af302Sopenharmony_ci 88570af302Sopenharmony_cistatic pid_t start_child(void) 89570af302Sopenharmony_ci{ 90570af302Sopenharmony_ci pid_t pid; 91570af302Sopenharmony_ci int ret; 92570af302Sopenharmony_ci pid = fork(); 93570af302Sopenharmony_ci if (pid == 0) { 94570af302Sopenharmony_ci ret = child(); 95570af302Sopenharmony_ci t_error("child process normally out with %d\n", ret); 96570af302Sopenharmony_ci return ret; 97570af302Sopenharmony_ci } 98570af302Sopenharmony_ci return pid; 99570af302Sopenharmony_ci} 100570af302Sopenharmony_ci 101570af302Sopenharmony_ciint main(int argc, char *argv[]) 102570af302Sopenharmony_ci{ 103570af302Sopenharmony_ci sigset_t set; 104570af302Sopenharmony_ci int status; 105570af302Sopenharmony_ci pid_t pid; 106570af302Sopenharmony_ci int flag = 0; 107570af302Sopenharmony_ci 108570af302Sopenharmony_ci sigemptyset(&set); 109570af302Sopenharmony_ci sigaddset(&set, SIGCHLD); 110570af302Sopenharmony_ci sigprocmask(SIG_BLOCK, &set, 0); 111570af302Sopenharmony_ci signal(SIGCHLD, handler); 112570af302Sopenharmony_ci signal(SIGILL, SIG_DFL); 113570af302Sopenharmony_ci 114570af302Sopenharmony_ci pid = start_child(); 115570af302Sopenharmony_ci if (pid == -1) { 116570af302Sopenharmony_ci t_error("%s fork failed: %s\n", argv[0], strerror(errno)); 117570af302Sopenharmony_ci return -1; 118570af302Sopenharmony_ci } 119570af302Sopenharmony_ci if (sigtimedwait(&set, 0, &(struct timespec){5, 0}) == -1) { /* Wait for 5 seconds */ 120570af302Sopenharmony_ci if (errno == EAGAIN) 121570af302Sopenharmony_ci flag = 1; 122570af302Sopenharmony_ci else 123570af302Sopenharmony_ci t_error("%s sigtimedwait failed: %s\n", argv[0], strerror(errno)); 124570af302Sopenharmony_ci if (kill(pid, SIGKILL) == -1) 125570af302Sopenharmony_ci t_error("%s kill failed: %s\n", argv[0], strerror(errno)); 126570af302Sopenharmony_ci } 127570af302Sopenharmony_ci 128570af302Sopenharmony_ci if (waitpid(pid, &status, 0) != pid) { 129570af302Sopenharmony_ci t_error("%s waitpid failed: %s\n", argv[0], strerror(errno)); 130570af302Sopenharmony_ci return -1; 131570af302Sopenharmony_ci } 132570af302Sopenharmony_ci 133570af302Sopenharmony_ci if (flag) { 134570af302Sopenharmony_ci t_error("Child process time out\n"); 135570af302Sopenharmony_ci } 136570af302Sopenharmony_ci 137570af302Sopenharmony_ci if (WIFSIGNALED(status)) { 138570af302Sopenharmony_ci if (WTERMSIG(status) != SIGSEGV && WTERMSIG(status) != SIGILL) { 139570af302Sopenharmony_ci t_error("%s child process out with %s\n", argv[0], strsignal(WTERMSIG(status))); 140570af302Sopenharmony_ci return -1; 141570af302Sopenharmony_ci } 142570af302Sopenharmony_ci } else { 143570af302Sopenharmony_ci t_error("%s child process finished normally\n", argv[0]); 144570af302Sopenharmony_ci } 145570af302Sopenharmony_ci return 0; 146570af302Sopenharmony_ci} 147