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