1 /**
2 * Copyright (c) 2023 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include <stdio.h>
17 #include <string.h>
18 #include <dirent.h>
19 #include <string>
20
21 extern "C" {
22 #include "test.h"
23 }
24
25 #define UBSAN_LOG_DIR "/data/log/sanitizer/ubsan/"
26 #define FAULTLOG_DIR "/data/log/faultlog/faultlogger/"
27 #define UBSAN_LOG_TAG "ubsan"
28 #define DEBUG 0
29 #define BUFFER_SIZE 4096
30
31 static void ClearCfiLog(const char *log_tag, const char *log_dir);
32 static void FindAndCheck(const char *pattern, const char *log_tag, const char *log_dir);
33
ShowCfiLogFile()34 static void ShowCfiLogFile()
35 {
36 DIR *dir;
37 struct dirent *ptr;
38 dir = opendir(UBSAN_LOG_DIR);
39 while ((ptr = readdir(dir)) != NULL) {
40 if (strstr(ptr->d_name, UBSAN_LOG_TAG) != NULL) {
41 printf("%s: %s\n", UBSAN_LOG_DIR, ptr->d_name);
42 }
43 }
44 closedir(dir);
45 }
46
ClearCfiLog()47 static void ClearCfiLog()
48 {
49 ClearCfiLog(UBSAN_LOG_TAG, UBSAN_LOG_DIR);
50 }
51
ClearCfiLog(const char * log_tag,const char * log_dir)52 static void ClearCfiLog(const char *log_tag, const char *log_dir)
53 {
54 DIR *dir;
55 struct dirent *ptr;
56 dir = opendir(log_dir);
57 while ((ptr = readdir(dir)) != NULL) {
58 if (strstr(ptr->d_name, log_tag) != NULL) {
59 char tmp[BUFFER_SIZE];
60 snprintf(tmp, BUFFER_SIZE, "%s/%s", log_dir, ptr->d_name);
61 remove(tmp);
62 }
63 }
64 closedir(dir);
65 }
66
CheckCfiLog(char * file,const char * needle)67 static void CheckCfiLog(char *file, const char *needle)
68 {
69 if (DEBUG) {
70 printf("[cfi checking]:%s\n", file);
71 }
72
73 FILE *fp = fopen(file, "r");
74 if (!fp) {
75 return;
76 }
77 if (fseek(fp, 0, SEEK_END) == -1) {
78 return;
79 }
80 int size = ftell(fp);
81 if (size <= 0) {
82 fclose(fp);
83 t_error("FAIL %s size is <=0!\n", file);
84 }
85
86 std::string buffer;
87 buffer.resize(size);
88
89 if (fseek(fp, 0, SEEK_SET) == -1) {
90 fclose(fp);
91 return;
92 }
93 int rsize = fread(&buffer[0], 1, size, fp);
94 if (rsize == 0) {
95 fclose(fp);
96 return;
97 }
98
99 if (buffer.find(needle) != std::string::npos) {
100 printf("[cfi checking] %s is ok.\n", needle);
101 } else {
102 t_error("FAIL %s is failed!\n", needle);
103 }
104
105 fclose(fp);
106 }
107
108 template<typename CallbackT>
FindDirAndCheck(DIR * dir,CallbackT && callback)109 static void FindDirAndCheck(DIR *dir, CallbackT &&callback)
110 {
111 FindDirAndCheck(dir, UBSAN_LOG_TAG, UBSAN_LOG_DIR, callback);
112 }
113
114 template<typename CallbackT>
FindDirAndCheck(DIR * dir,const char * log_tag,const char * log_dir,CallbackT && callback)115 static void FindDirAndCheck(DIR *dir, const char *log_tag, const char *log_dir, CallbackT &&callback)
116 {
117 struct dirent *ptr;
118 while ((ptr = readdir(dir)) != NULL) {
119 if (strstr(ptr->d_name, log_tag) != NULL) {
120 char tmp[BUFFER_SIZE];
121 snprintf(tmp, BUFFER_SIZE, "%s/%s", log_dir, ptr->d_name);
122 callback(tmp);
123 }
124 }
125 }
126
FindAndCheck(const char * pattern)127 static void FindAndCheck(const char *pattern)
128 {
129 DIR *ubsanDir = opendir(UBSAN_LOG_DIR);
130 DIR *faultlogDir = opendir(FAULTLOG_DIR);
131 auto callback = [=](char *file) { CheckCfiLog(file, pattern); };
132 FindDirAndCheck(ubsanDir, callback);
133 FindDirAndCheck(faultlogDir, callback);
134 closedir(ubsanDir);
135 closedir(faultlogDir);
136 }
137
FindAndCheck(const char * pattern,const char * log_tag,const char * log_dir)138 static void FindAndCheck(const char *pattern, const char *log_tag, const char *log_dir)
139 {
140 DIR *faultlogDir = opendir(log_dir);
141 auto callback = [=](char *file) { CheckCfiLog(file, pattern); };
142 FindDirAndCheck(faultlogDir, log_tag, log_dir, callback);
143 closedir(faultlogDir);
144 }
145
ExpectCfiOk()146 static void ExpectCfiOk()
147 {
148 DIR *ubsanDir = opendir(UBSAN_LOG_DIR);
149 DIR *faultlogDir = opendir(FAULTLOG_DIR);
150 auto callback = [](char *file) { t_error("FAIL CFI check failed!\n"); };
151 FindDirAndCheck(ubsanDir, callback);
152 FindDirAndCheck(faultlogDir, callback);
153 closedir(ubsanDir);
154 closedir(faultlogDir);
155 }
156