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_ci#define UNIT 16 25570af302Sopenharmony_ci#define OFF_OFFSET 2 26570af302Sopenharmony_ci#define FIRST_OFFSET (-4) 27570af302Sopenharmony_ci#define FIRST_OFF_OFFSET 8 28570af302Sopenharmony_ci#define MALLOC_SIZE_S 50 29570af302Sopenharmony_ci#define MALLOC_SIZE_L 100 30570af302Sopenharmony_ci#define TEST_NUM 512 31570af302Sopenharmony_ci 32570af302Sopenharmony_cistruct meta_in { 33570af302Sopenharmony_ci struct meta_in *prev, *next; 34570af302Sopenharmony_ci uintptr_t *mem; 35570af302Sopenharmony_ci}; 36570af302Sopenharmony_ci 37570af302Sopenharmony_cistruct group_in { 38570af302Sopenharmony_ci struct meta_in *meta; 39570af302Sopenharmony_ci}; 40570af302Sopenharmony_ci 41570af302Sopenharmony_cistatic struct group_in *get_group(const uint8_t *p) 42570af302Sopenharmony_ci{ 43570af302Sopenharmony_ci int offset = *(const uint16_t *)(p - OFF_OFFSET); 44570af302Sopenharmony_ci 45570af302Sopenharmony_ci if (p[FIRST_OFFSET]) { 46570af302Sopenharmony_ci offset = *(uint32_t *)(p - FIRST_OFF_OFFSET); 47570af302Sopenharmony_ci } 48570af302Sopenharmony_ci struct group_in *base = (void *)(p - UNIT*offset - UNIT); 49570af302Sopenharmony_ci return base; 50570af302Sopenharmony_ci} 51570af302Sopenharmony_ci 52570af302Sopenharmony_cistatic void handler(int s) 53570af302Sopenharmony_ci{ 54570af302Sopenharmony_ci} 55570af302Sopenharmony_ci 56570af302Sopenharmony_civolatile void *tmp; 57570af302Sopenharmony_ci 58570af302Sopenharmony_ciint set_devide_chunk(size_t size) 59570af302Sopenharmony_ci{ 60570af302Sopenharmony_ci if (!(tmp = malloc(size))) { 61570af302Sopenharmony_ci t_error("Malloc failed: %s\n", strerror(errno)); 62570af302Sopenharmony_ci return -1; 63570af302Sopenharmony_ci } 64570af302Sopenharmony_ci return 0; 65570af302Sopenharmony_ci} 66570af302Sopenharmony_ci 67570af302Sopenharmony_cistatic int child(void) 68570af302Sopenharmony_ci{ 69570af302Sopenharmony_ci uint8_t *c1; 70570af302Sopenharmony_ci uint8_t *c2; 71570af302Sopenharmony_ci 72570af302Sopenharmony_ci uint8_t *temp; 73570af302Sopenharmony_ci struct group_in *g1 = NULL; 74570af302Sopenharmony_ci struct group_in *g2 = NULL; 75570af302Sopenharmony_ci 76570af302Sopenharmony_ci for (int i = 0; i < TEST_NUM; ++i) { 77570af302Sopenharmony_ci c1 = (uint8_t *)malloc(MALLOC_SIZE_S); 78570af302Sopenharmony_ci if (!c1) { 79570af302Sopenharmony_ci t_error("Malloc failed: %s\n", strerror(errno)); 80570af302Sopenharmony_ci return -1; 81570af302Sopenharmony_ci } 82570af302Sopenharmony_ci g1 = get_group(c1); 83570af302Sopenharmony_ci c2 = (uint8_t *)malloc(MALLOC_SIZE_L); 84570af302Sopenharmony_ci if (!c2) { 85570af302Sopenharmony_ci t_error("Malloc failed: %s\n", strerror(errno)); 86570af302Sopenharmony_ci return -1; 87570af302Sopenharmony_ci } 88570af302Sopenharmony_ci g2 = get_group(c2); 89570af302Sopenharmony_ci g2->meta = g1->meta; 90570af302Sopenharmony_ci free(c2); 91570af302Sopenharmony_ci free(c1); 92570af302Sopenharmony_ci } 93570af302Sopenharmony_ci 94570af302Sopenharmony_ci return 0; 95570af302Sopenharmony_ci} 96570af302Sopenharmony_ci 97570af302Sopenharmony_cistatic pid_t start_child(void) 98570af302Sopenharmony_ci{ 99570af302Sopenharmony_ci pid_t pid; 100570af302Sopenharmony_ci int ret; 101570af302Sopenharmony_ci pid = fork(); 102570af302Sopenharmony_ci if (pid == 0) { 103570af302Sopenharmony_ci ret = child(); 104570af302Sopenharmony_ci t_error("child process normally out with %d\n", ret); 105570af302Sopenharmony_ci return ret; 106570af302Sopenharmony_ci } 107570af302Sopenharmony_ci return pid; 108570af302Sopenharmony_ci} 109570af302Sopenharmony_ci 110570af302Sopenharmony_ciint main(int argc, char *argv[]) 111570af302Sopenharmony_ci{ 112570af302Sopenharmony_ci sigset_t set; 113570af302Sopenharmony_ci int status; 114570af302Sopenharmony_ci pid_t pid; 115570af302Sopenharmony_ci int flag = 0; 116570af302Sopenharmony_ci 117570af302Sopenharmony_ci sigemptyset(&set); 118570af302Sopenharmony_ci sigaddset(&set, SIGCHLD); 119570af302Sopenharmony_ci sigprocmask(SIG_BLOCK, &set, 0); 120570af302Sopenharmony_ci signal(SIGCHLD, handler); 121570af302Sopenharmony_ci signal(SIGILL, SIG_DFL); 122570af302Sopenharmony_ci 123570af302Sopenharmony_ci pid = start_child(); 124570af302Sopenharmony_ci if (pid == -1) { 125570af302Sopenharmony_ci t_error("%s fork failed: %s\n", argv[0], strerror(errno)); 126570af302Sopenharmony_ci return -1; 127570af302Sopenharmony_ci } 128570af302Sopenharmony_ci if (sigtimedwait(&set, 0, &(struct timespec){5, 0}) == -1) { /* Wait for 5 seconds */ 129570af302Sopenharmony_ci if (errno == EAGAIN) 130570af302Sopenharmony_ci flag = 1; 131570af302Sopenharmony_ci else 132570af302Sopenharmony_ci t_error("%s sigtimedwait failed: %s\n", argv[0], strerror(errno)); 133570af302Sopenharmony_ci if (kill(pid, SIGKILL) == -1) 134570af302Sopenharmony_ci t_error("%s kill failed: %s\n", argv[0], strerror(errno)); 135570af302Sopenharmony_ci } 136570af302Sopenharmony_ci 137570af302Sopenharmony_ci if (waitpid(pid, &status, 0) != pid) { 138570af302Sopenharmony_ci t_error("%s waitpid failed: %s\n", argv[0], strerror(errno)); 139570af302Sopenharmony_ci return -1; 140570af302Sopenharmony_ci } 141570af302Sopenharmony_ci 142570af302Sopenharmony_ci if (flag) { 143570af302Sopenharmony_ci t_error("Child process time out\n"); 144570af302Sopenharmony_ci } 145570af302Sopenharmony_ci 146570af302Sopenharmony_ci if (WIFSIGNALED(status)) { 147570af302Sopenharmony_ci if (WTERMSIG(status) != SIGSEGV && WTERMSIG(status) != SIGILL) { 148570af302Sopenharmony_ci t_error("%s child process out with %s\n", argv[0], strsignal(WTERMSIG(status))); 149570af302Sopenharmony_ci return -1; 150570af302Sopenharmony_ci } 151570af302Sopenharmony_ci } else { 152570af302Sopenharmony_ci t_error("%s child process finished normally\n", argv[0]); 153570af302Sopenharmony_ci } 154570af302Sopenharmony_ci return 0; 155570af302Sopenharmony_ci} 156