提交 3961dc5b 编写于 作者: Y yinchuang

Add cfi test

Issue:I7R13O
Signed-off-by: Nyinchuang <yinchuang@huawei.com>
Test:libctest
上级 af895a6e
/**
* Copyright (c) 2023 Huawei Device Co., Ltd.
* 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.
*/
#include <stdio.h>
#include <string.h>
#include <dirent.h>
extern "C" {
#include "test.h"
}
#define UBSAN_LOG_DIR "/data/log/sanitizer/ubsan/"
#define UBSAN_LOG_TAG "ubsan"
#define DEBUG 0
#define BUFFER_SIZE 4096
static void ShowCfiLogFile()
{
DIR *dir;
struct dirent *ptr;
dir = opendir(UBSAN_LOG_DIR);
while ((ptr = readdir(dir)) != NULL) {
if (strstr(ptr->d_name, UBSAN_LOG_TAG) != NULL) {
printf("%s: %s\n", UBSAN_LOG_DIR, ptr->d_name);
}
}
closedir(dir);
}
static void ClearCfiLog()
{
DIR *dir;
struct dirent *ptr;
dir = opendir(UBSAN_LOG_DIR);
while ((ptr = readdir(dir)) != NULL) {
if (strstr(ptr->d_name, UBSAN_LOG_TAG) != NULL) {
char tmp[BUFFER_SIZE] = UBSAN_LOG_DIR;
strcat(tmp, ptr->d_name);
remove(tmp);
}
}
closedir(dir);
}
static void CheckCfiLog(char *file, const char *needle)
{
if (DEBUG) {
printf("[cfi checking]:%s\n", file);
}
char buffer[BUFFER_SIZE];
FILE *fp = fopen(file, "r");
if (!fp) {
return;
}
if (fseek(fp, 0, SEEK_END) == -1) {
return;
}
int size = ftell(fp);
if (size <= 0) {
fclose(fp);
t_error("FAIL %s size is <=0!\n", file);
}
if (fseek(fp, 0, SEEK_SET) == -1) {
fclose(fp);
return;
}
int rsize = fread(buffer, 1, size, fp);
if (rsize == 0) {
fclose(fp);
return;
}
if (strstr(buffer, needle) != NULL) {
printf("[cfi checking] %s is ok.\n", needle);
} else {
t_error("FAIL %s is failed!\n", needle);
}
fclose(fp);
}
static void FindAndCheck(const char *pattern)
{
DIR *dir;
struct dirent *ptr;
dir = opendir(UBSAN_LOG_DIR);
while ((ptr = readdir(dir)) != NULL) {
if (strstr(ptr->d_name, UBSAN_LOG_TAG) != NULL) {
char tmp[BUFFER_SIZE] = UBSAN_LOG_DIR;
strcat(tmp, ptr->d_name);
CheckCfiLog(tmp, pattern);
}
}
closedir(dir);
}
\ No newline at end of file
......@@ -16,6 +16,9 @@ import("../../../test_template.gni")
group("ldso_cfi_test") {
testonly = true
deps = [
":cfi_avaiable_schemes_test",
":cfi_cross_dso_test_exe",
":cfi_cross_dso_test_lib",
":ldso_cfi_check",
":ldso_cfi_test_lib",
]
......@@ -44,3 +47,62 @@ ohos_shared_library("ldso_cfi_test_lib") {
subsystem_name = "musl"
part_name = "libc-test-lib"
}
ohos_shared_library("cfi_cross_dso_test_lib") {
sanitize = {
cfi = true
cfi_cross_dso = true
debug = true
}
subsystem_name = "musl"
part_name = "libc-test"
include_dirs = [
"../common",
"//third_party/musl/porting/linux/user/include",
"//third_party/musl/porting/linux/user/ldso",
"//third_party/musl/libc-test/src/common",
]
use_rtti = true
sources = [ "./crossdso/cfi_test_lib.cpp" ]
}
ohos_executable("cfi_cross_dso_test_exe") {
sanitize = {
cfi = true
cfi_cross_dso = true
debug = true
}
subsystem_name = "musl"
part_name = "libc-test"
include_dirs = [
"../common",
"//third_party/musl/porting/linux/user/include",
"//third_party/musl/porting/linux/user/ldso",
"//third_party/musl/libc-test/src/common",
]
use_rtti = true
sources = [ "./crossdso/cfi_test_exe.cpp" ]
configs = [ "//third_party/musl/libc-test/src/common:config_runtest" ]
}
ohos_executable("cfi_avaiable_schemes_test") {
sanitize = {
cfi = true
cfi_cross_dso = true
debug = true
}
subsystem_name = "musl"
part_name = "libc-test"
include_dirs = [
"../common",
"//third_party/musl/porting/linux/user/include",
"//third_party/musl/porting/linux/user/ldso",
"//third_party/musl/libc-test/src/common",
]
use_rtti = true
sources = [ "cfi_avaiable_schemes_test.cpp" ]
configs = [ "//third_party/musl/libc-test/src/common:config_runtest" ]
}
/**
* Copyright (c) 2023 Huawei Device Co., Ltd.
* 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.
*/
#include "cfi_util.h"
struct A {
virtual void Test();
};
void A::Test()
{
printf("A::Test()\n");
}
struct B : A {
virtual void Test();
};
void B::Test()
{
printf("B::Test()\n");
}
struct C : A {
};
struct D {
virtual void Test();
};
void D::Test()
{
printf("D::Test()\n");
}
struct CallTestA {
virtual void VcallFunc();
void CallFunc();
};
void CallTestA::VcallFunc()
{
printf("CallTestA::VcallFunc()\n");
}
void CallTestA::CallFunc()
{
printf("CallTestA::CallFunc()\n");
}
struct CallTestB {
virtual void VcallFunc();
void CallFunc();
};
void CallTestB::VcallFunc()
{
printf("CallTestB::VcallFunc()\n");
}
void CallTestB::CallFunc()
{
printf("CallTestB::CallFunc()\n");
}
void CfiCastStrict()
{
C *c = new C;
A a;
c = static_cast<C *>(&a);
}
void CfiDerivedCast()
{
B *b = new B;
A a;
b = static_cast<B *>(&a);
}
void CfiUnrelatedCast()
{
D *d = new D;
A a;
d = ((D *)&a);
}
void Icall()
{
printf("Icall()\n");
}
void CfiIcall()
{
((void (*)(int))Icall)(42);
}
void CfiVcall()
{
CallTestA *a;
void *p = (void *)(new CallTestB());
memcpy(&a, &p, sizeof(a));
a->VcallFunc();
}
void CfiNvcall()
{
CallTestA *a;
void *p = (void *)(new CallTestB());
memcpy(&a, &p, sizeof(a));
a->CallFunc();
}
int main()
{
if (DEBUG) {
ShowCfiLogFile();
}
ClearCfiLog();
if (DEBUG) {
ShowCfiLogFile();
}
// clang allow it by default. It can be disabled with -fsanitize=cfi-cast-strict.
CfiCastStrict();
CfiDerivedCast();
FindAndCheck("runtime error: control flow integrity check for type 'B' failed during base-to-derived cast");
CfiUnrelatedCast();
FindAndCheck("runtime error: control flow integrity check for type 'D' failed during cast to unrelated type");
CfiNvcall();
FindAndCheck("runtime error: control flow integrity check for type 'CallTestA' failed during non-virtual call");
CfiVcall();
FindAndCheck("runtime error: control flow integrity check for type 'CallTestA' failed during virtual call");
CfiIcall();
FindAndCheck("runtime error: control flow integrity check for type 'void (int)' failed during indirect function call");
if (DEBUG) {
ShowCfiLogFile();
}
}
/**
* Copyright (c) 2023 Huawei Device Co., Ltd.
* 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.
*/
#include <cstdio>
#include <dlfcn.h>
#include <cstring>
#include "cfi_util.h"
struct AA {
virtual void Test();
};
void AA::Test()
{
printf("AA::Test()\n");
}
void ChangeToAnotherObj()
{
AA *a = new AA;
void *handle = dlopen("libcfi_cross_dso_test_lib.z.so", RTLD_NOW);
if (handle == nullptr) {
return;
}
void *(*create_B)() = (void *(*)())dlsym(handle, "CreateObj");
void *p = create_B();
a->Test();
memcpy(&a, &p, sizeof(void *));
a->Test();
}
int main()
{
if (DEBUG) {
ShowCfiLogFile();
}
ClearCfiLog();
if (DEBUG) {
ShowCfiLogFile();
}
ChangeToAnotherObj();
FindAndCheck("runtime error: control flow integrity check for type 'AA' failed during virtual call");
if (DEBUG) {
ShowCfiLogFile();
}
return 0;
}
\ No newline at end of file
/**
* Copyright (c) 2023 Huawei Device Co., Ltd.
* 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.
*/
#include <cstdio>
struct BB {
void Func();
virtual void Test();
};
void BB::Test()
{
printf("BB::Test()\n");
}
void BB::Func()
{
printf("BB::Func()\n");
}
extern"C" void* CreateObj()
{
return new BB;
}
\ No newline at end of file
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册