提交 58794811 编写于 作者: W wangjiahui

RM003 commit

Signed-off-by: Nwangjiahui <wangjiahui27@huawei.com>
上级 e93def3a
......@@ -12,6 +12,21 @@ group("musl_all") {
]
}
ohos_prebuilt_etc("ld-musl-namespace-${musl_arch}-test.ini") {
source = "${musl_porting_dir}/config/ld-musl-namespace-${musl_arch}-test.ini"
}
ohos_prebuilt_etc("ld-musl-namespace-${musl_arch}.ini") {
source = "${musl_porting_dir}/config/ld-musl-namespace-${musl_arch}.ini"
}
group("musl_ns_config") {
deps = [
":ld-musl-namespace-${musl_arch}-test.ini",
":ld-musl-namespace-${musl_arch}.ini",
]
}
group("musl_libs") {
deps = [
":${musl_abi_target}_libs",
......@@ -52,6 +67,7 @@ group("musl_headers") {
":musl_copy_inc_scsi",
":musl_copy_inc_sys",
":musl_copy_inc_trace",
":musl_ns_config",
]
}
......
# Copyright (c) 2022 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.
import("../../../test_template.gni")
group("dlns_test") {
testonly = true
deps = [
":dlns_dlopen_test",
":dlns_inherit_test",
":dlns_separated_test",
":dlns_set_fun_test",
":dlns_special_scene_test",
]
}
ohos_unittest("dlns_dlopen_test") {
module_out_path = "libc-test/src/functionalext/dlns"
include_dirs = [
"../common",
"//third_party/musl/porting/linux/user/include",
"//third_party/musl/libc-test/src/common",
]
sources = [ "dlns_dlopen.c" ]
configs = [ "//third_party/musl/libc-test/src/common:config_runtest" ]
}
ohos_unittest("dlns_set_fun_test") {
module_out_path = "libc-test/src/functionalext/dlns"
include_dirs = [
"../common",
"//third_party/musl/porting/linux/user/include",
"//third_party/musl/libc-test/src/common",
]
sources = [ "dlns_set_fun.c" ]
configs = [ "//third_party/musl/libc-test/src/common:config_runtest" ]
}
ohos_unittest("dlns_inherit_test") {
module_out_path = "libc-test/src/functionalext/dlns"
include_dirs = [
"../common",
"//third_party/musl/porting/linux/user/include",
"//third_party/musl/libc-test/src/common",
]
sources = [ "dlns_inherit.c" ]
configs = [ "//third_party/musl/libc-test/src/common:config_runtest" ]
}
ohos_unittest("dlns_separated_test") {
module_out_path = "libc-test/src/functionalext/dlns"
include_dirs = [
"../common",
"//third_party/musl/porting/linux/user/include",
"//third_party/musl/libc-test/src/common",
]
sources = [ "dlns_separated.c" ]
configs = [ "//third_party/musl/libc-test/src/common:config_runtest" ]
}
ohos_unittest("dlns_special_scene_test") {
module_out_path = "libc-test/src/functionalext/dlns"
include_dirs = [
"../common",
"//third_party/musl/porting/linux/user/include",
"//third_party/musl/libc-test/src/common",
]
sources = [ "dlns_special_scene.c" ]
configs = [ "//third_party/musl/libc-test/src/common:config_runtest" ]
}
/**
* Copyright (c) 2022 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 <dlfcn.h>
#include <errno.h>
#include <stdio.h>
#include <string.h>
#include "dlns_test.h"
#include "functionalext.h"
/**
* @tc.name : dlopen_0100
* @tc.desc : Enter a valid path, dlopen compatibility test
* @tc.level : Level 0
*/
void dlopen_0100(void)
{
void* handle = dlopen(dllNamePath, RTLD_LAZY);
EXPECT_TRUE("dlopen_0100", handle);
dlclose(handle);
}
/**
* @tc.name : dlopen_0200
* @tc.desc : Enter invalid path, dlopen compatibility test
* @tc.level : Level 2
*/
void dlopen_0200(void)
{
void* handle = dlopen(errPath_ns, RTLD_LAZY);
EXPECT_FALSE("dlopen_0200", handle);
}
/**
* @tc.name : dlns_init_0100
* @tc.desc : Use a string less than 255 bytes as the dlns_init parameter
* @tc.level : Level 1
*/
void dlns_init_0100(void)
{
Dl_namespace dlns;
char n[] = "dlns_init_0100";
dlns_init(&dlns, n);
EXPECT_EQ("dlns_init_0100", strcmp(dlns.name, n), 0);
}
/**
* @tc.name : dlns_init_0200
* @tc.desc : Use very long strings as dlns_init parameters
* @tc.level : Level 2
*/
void dlns_init_0200(void)
{
Dl_namespace dlns;
int size = 256;
char n[] = "012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 \
012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 \
012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 \
012345678901234567890123456789";
int len = strlen(n);
dlns_init(&dlns, n);
EXPECT_TRUE("dlns_init_0200", size < len);
int dlnslen = strlen(dlns.name);
EXPECT_TRUE("dlns_init_0200", size > dlnslen);
}
/**
* @tc.name : dlns_create_0100
* @tc.desc : Using dlns_create, create a new namespace
* @tc.level : Level 1
*/
void dlns_create_0100(void)
{
Dl_namespace dlns;
dlns_init(&dlns, "dlns_create_0100");
EXPECT_EQ("dlns_create_0100", dlns_create(&dlns, path), EOK);
}
/**
* @tc.name : dlns_create_0200
* @tc.desc : Using dlns_create, create a new namespace
* @tc.level : Level 2
*/
void dlns_create_0200(void)
{
// ns_no_allowed_libs already exists
Dl_namespace dlns;
dlns_init(&dlns, "ns_no_allowed_libs");
EXPECT_EQ("dlns_create_0200", dlns_create(&dlns, NULL), EEXIST);
}
/**
* @tc.name : dlns_create_0300
* @tc.desc : After creating a new namespace, check lib_path validity
* @tc.level : Level 1
*/
void dlns_create_0300(void)
{
// ns_no_allowed_libs already exists
Dl_namespace dlns;
dlns_init(&dlns, "dlns_create_0300");
EXPECT_EQ("dlns_create_0300", dlns_create(&dlns, path), EOK);
void* handle = dlopen_ns(&dlns, dllName, RTLD_LAZY);
EXPECT_TRUE("dlns_create_0300", handle);
dlclose(handle);
}
/**
* @tc.name : dlns_create_0400
* @tc.desc : Namespace creation when dlns=NULL
* @tc.level : Level 2
*/
void dlns_create_0400(void)
{
EXPECT_EQ("dlns_create_0400", dlns_create(NULL, path), EINVAL);
}
/**
* @tc.name : dlns_create_0500
* @tc.desc : Namespace creation when lib_path=NULL
* @tc.level : Level 2
*/
void dlns_create_0500(void)
{
Dl_namespace dlns;
dlns_init(&dlns, "dlns_create_0500");
EXPECT_EQ("dlns_create_0500", dlns_create(&dlns, NULL), EOK);
}
/**
* @tc.name : dlopen_ns_0100
* @tc.desc : dlopen_ns valid full path test
* @tc.level : Level 1
*/
void dlopen_ns_0100(void)
{
Dl_namespace dlns;
dlns_init(&dlns, "ns_no_allowed_libs");
void* handle = dlopen_ns(&dlns, dllNamePath, RTLD_LAZY);
EXPECT_TRUE("dlopen_ns_0100", handle);
dlclose(handle);
}
/**
* @tc.name : dlopen_ns_0200
* @tc.desc : dlopen_ns invalid full path test
* @tc.level : Level 2
*/
void dlopen_ns_0200(void)
{
Dl_namespace dlns;
dlns_init(&dlns, "ns_no_allowed_libs");
void* handle = dlopen_ns(&dlns, errdllNamePath, RTLD_LAZY);
EXPECT_FALSE("dlopen_ns_0200", handle);
}
/**
* @tc.name : dlopen_ns_0300
* @tc.desc : dlopen_ns valid short name test
* @tc.level : Level 1
*/
void dlopen_ns_0300(void)
{
Dl_namespace dlns;
dlns_init(&dlns, "ns_no_allowed_libs");
void* handle = dlopen_ns(&dlns, dllName, RTLD_LAZY);
EXPECT_TRUE("dlopen_ns_0300", handle);
dlclose(handle);
}
/**
* @tc.name : dlopen_ns_0400
* @tc.desc : When dlns=NULL, call dlopen_ns to load the library
* @tc.level : Level 1
*/
void dlopen_ns_0400(void)
{
void* handle = dlopen_ns(NULL, dllNamePath, RTLD_LAZY);
EXPECT_TRUE("dlopen_ns_0400", handle);
dlclose(handle);
}
/**
* @tc.name : dlopen_ns_0500
* @tc.desc : When file=NULL, call dlopen_ns to load the library
* @tc.level : Level 2
*/
void dlopen_ns_0500(void)
{
Dl_namespace dlns;
dlns_init(&dlns, "ns_no_allowed_libs");
void *handle = dlopen_ns(&dlns, NULL, RTLD_LAZY);
EXPECT_TRUE("dlopen_ns_0500", handle);
dlclose(handle);
}
TEST_FUN G_Fun_Array[] = {
dlopen_0100,
dlopen_0200,
dlns_init_0100,
dlns_init_0200,
dlns_create_0100,
dlns_create_0200,
dlns_create_0300,
dlns_create_0400,
dlns_create_0500,
dlopen_ns_0100,
dlopen_ns_0200,
dlopen_ns_0300,
dlopen_ns_0400,
dlopen_ns_0500,
};
int main(void)
{
int num = sizeof(G_Fun_Array)/sizeof(TEST_FUN);
for (int pos = 0; pos < num; ++pos) {
G_Fun_Array[pos]();
}
return t_status;
}
\ No newline at end of file
/**
* Copyright (c) 2022 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 <dlfcn.h>
#include <errno.h>
#include <stdio.h>
#include <string.h>
#include "dlns_test.h"
#include "functionalext.h"
/**
* @tc.name : dlns_inherit_0100
* @tc.desc : Under the INI configuration file, when shared_libs in dlns_inherit is empty,
* all the libraries of the inheritor can be shared by it
* @tc.level : Level 1
*/
void dlns_inherit_0100(void)
{
Dl_namespace dlnsA, dlnsB;
dlns_init(&dlnsA, "for_inherit_A");
dlns_init(&dlnsB, "inherited_class");
EXPECT_EQ("dlns_inherit_0100", dlns_inherit(&dlnsA, &dlnsB, NULL), EOK);
void* handle = dlopen_ns(&dlnsA, dllName, RTLD_LAZY);
EXPECT_TRUE("dlns_inherit_0100", handle);
dlclose(handle);
void* handle1 = dlopen_ns(&dlnsA, sharedLib, RTLD_LAZY);
EXPECT_TRUE("dlns_inherit_0100", handle1);
dlclose(handle1);
}
/**
* @tc.name : dlns_inherit_0200
* @tc.desc : Under the INI configuration file, when shared_libs in dlns_inherit is set, the set shared library
* name can be shared, and other than the shared library name, it will not be shared
* @tc.level : Level 2
*/
void dlns_inherit_0200(void)
{
Dl_namespace dlnsA, dlnsB;
dlns_init(&dlnsA, "for_inherit_A");
dlns_init(&dlnsB, "inherited_class");
EXPECT_EQ("dlns_inherit_0200", dlns_inherit(&dlnsA, &dlnsB, dllName), EOK);
void* handle = dlopen_ns(&dlnsA, dllName, RTLD_LAZY);
EXPECT_TRUE("dlns_inherit_0200", handle);
dlclose(handle);
void* handle1 = dlopen_ns(&dlnsA, sharedLib, RTLD_LAZY);
EXPECT_FALSE("dlns_inherit_0200", handle1);
}
/**
* @tc.name : dlns_inherit_0300
* @tc.desc : Under the INI configuration file, the library that cannot be opened
* by itself is opened through inheritance
* @tc.level : Level 1
*/
void dlns_inherit_0300(void)
{
Dl_namespace dlnsA, dlnsB;
dlns_init(&dlnsA, "inherit_A");
dlns_init(&dlnsB, "inherited_class");
EXPECT_EQ("dlns_inherit_0300", dlns_create(&dlnsA, NULL), EOK);
void* handle1 = dlopen_ns(&dlnsA, dllName_inh_003, RTLD_LAZY);
EXPECT_FALSE("dlns_inherit_0300", handle1);
EXPECT_EQ("dlns_inherit_0300", dlns_inherit(&dlnsA, &dlnsB, dllName_inh_003), EOK);
void* handle = dlopen_ns(&dlnsA, dllName_inh_003, RTLD_LAZY);
EXPECT_TRUE("dlns_inherit_0300", handle);
dlclose(handle);
}
/**
* @tc.name : dlns_inherit_0400
* @tc.desc : In the INI configuration file, inheritance cannot be passed, and cannot be opened after generation
* @tc.level : Level 2
*/
void dlns_inherit_0400(void)
{
Dl_namespace dlnsA, dlnsAA, dlnsB;
dlns_init(&dlnsA, "for_inherit_A");
dlns_init(&dlnsAA, "for_inherit_AA");
dlns_init(&dlnsB, "inherited_class");
EXPECT_EQ("dlns_inherit_0400", dlns_inherit(&dlnsA, &dlnsB, dllName), EOK);
void* handle = dlopen_ns(&dlnsA, dllName, RTLD_LAZY);
EXPECT_NE("dlns_inherit_0300", handle, NULL);
dlclose(handle);
EXPECT_EQ("dlns_inherit_0400", dlns_inherit(&dlnsAA, &dlnsA, NULL), EOK);
void* handle1 = dlopen_ns(&dlnsAA, dllName, RTLD_LAZY);
EXPECT_FALSE("dlns_inherit_0400", handle1);
}
/**
* @tc.name : dlns_inherit_0500
* @tc.desc : Create ns through the interface, when shared_libs in dlns_inherit is empty,
* all the libraries of the inheritor can be shared by it
* @tc.level : Level 1
*/
void dlns_inherit_0500(void)
{
Dl_namespace dlnsA, dlnsB;
dlns_init(&dlnsA, "dlns_inherit_0500_A");
dlns_init(&dlnsB, "dlns_inherit_0500_B");
EXPECT_EQ("dlns_inherit_0500", dlns_create(&dlnsA, NULL), EOK);
EXPECT_EQ("dlns_inherit_0500", dlns_create(&dlnsB, path), EOK);
EXPECT_EQ("dlns_inherit_0500", dlns_set_namespace_separated("dlns_inherit_0500_A", true), EOK);
EXPECT_EQ("dlns_inherit_0500", dlns_set_namespace_separated("dlns_inherit_0500_B", true), EOK);
EXPECT_EQ("dlns_inherit_0500", dlns_inherit(&dlnsA, &dlnsB, NULL), EOK);
void* handle = dlopen_ns(&dlnsA, dllName, RTLD_LAZY);
EXPECT_TRUE("dlns_inherit_0500", handle);
dlclose(handle);
handle = dlopen_ns(&dlnsA, sharedLib, RTLD_LAZY);
EXPECT_TRUE("dlns_inherit_0500", handle);
dlclose(handle);
}
/**
* @tc.name : dlns_inherit_0600
* @tc.desc : Create ns through the interface, when shared_libs in dlns_inherit is set, the set shared
* library name can be shared, other than the shared library name, it will not be shared
* @tc.level : Level 2
*/
void dlns_inherit_0600(void)
{
Dl_namespace dlnsA, dlnsB;
dlns_init(&dlnsA, "dlns_inherit_0600_A");
dlns_init(&dlnsB, "dlns_inherit_0600_B");
EXPECT_EQ("dlns_inherit_0600", dlns_create(&dlnsA, NULL), EOK);
EXPECT_EQ("dlns_inherit_0600", dlns_create(&dlnsB, path), EOK);
EXPECT_EQ("dlns_inherit_0600", dlns_set_namespace_separated("dlns_inherit_0600_A", true), EOK);
EXPECT_EQ("dlns_inherit_0600", dlns_set_namespace_separated("dlns_inherit_0600_B", true), EOK);
EXPECT_EQ("dlns_inherit_0600", dlns_inherit(&dlnsA, &dlnsB, dllName), EOK);
void* handle = dlopen_ns(&dlnsA, dllName, RTLD_LAZY);
EXPECT_TRUE("dlns_inherit_0600", handle);
dlclose(handle);
handle = dlopen_ns(&dlnsA, sharedLib, RTLD_LAZY);
EXPECT_FALSE("dlns_inherit_0600", handle);
}
/**
* @tc.name : dlns_inherit_0700
* @tc.desc : Create ns through interfaces, and open libraries that cannot be
* opened by themselves through inheritance.
* @tc.level : Level 2
*/
void dlns_inherit_0700(void)
{
Dl_namespace dlnsA, dlnsB;
dlns_init(&dlnsA, "dlns_inherit_0700_A");
dlns_init(&dlnsB, "dlns_inherit_0700_B");
EXPECT_EQ("dlns_inherit_0700", dlns_create(&dlnsA, NULL), EOK);
EXPECT_EQ("dlns_inherit_0700", dlns_create(&dlnsB, path), EOK);
EXPECT_EQ("dlns_inherit_0700", dlns_set_namespace_separated("dlns_inherit_0700_A", true), EOK);
EXPECT_EQ("dlns_inherit_0700", dlns_set_namespace_separated("dlns_inherit_0700_B", true), EOK);
EXPECT_EQ("dlns_inherit_0700", dlns_set_namespace_allowed_libs("dlns_inherit_0700_A", dllName2), EOK);
void* handle = dlopen_ns(&dlnsA, dllName_inh_007, RTLD_LAZY);
EXPECT_FALSE("dlns_inherit_0700", handle);
EXPECT_EQ("dlns_inherit_0700", dlns_inherit(&dlnsA, &dlnsB, NULL), EOK);
handle = dlopen_ns(&dlnsA, dllName_inh_007, RTLD_LAZY);
EXPECT_TRUE("dlns_inherit_0700", handle);
dlclose(handle);
}
/**
* @tc.name : dlns_inherit_0800
* @tc.desc : Create ns through an interface, inheritance cannot be passed,
* and cannot be opened between generations.
* @tc.level : Level 2
*/
void dlns_inherit_0800(void)
{
Dl_namespace dlnsA, dlnsB, dlnsC;
dlns_init(&dlnsA, "dlns_inherit_0800_A");
dlns_init(&dlnsB, "dlns_inherit_0800_B");
dlns_init(&dlnsC, "dlns_inherit_0800_C");
EXPECT_EQ("dlns_inherit_0800", dlns_create(&dlnsA, NULL), EOK);
EXPECT_EQ("dlns_inherit_0800", dlns_create(&dlnsB, NULL), EOK);
EXPECT_EQ("dlns_inherit_0800", dlns_create(&dlnsC, path), EOK);
EXPECT_EQ("dlns_inherit_0800", dlns_set_namespace_separated("dlns_inherit_0800_A", true), EOK);
EXPECT_EQ("dlns_inherit_0800", dlns_set_namespace_separated("dlns_inherit_0800_B", true), EOK);
EXPECT_EQ("dlns_inherit_0800", dlns_set_namespace_separated("dlns_inherit_0800_C", true), EOK);
// A继承B, B继承C
EXPECT_EQ("dlns_inherit_0800", dlns_inherit(&dlnsB, &dlnsC, NULL), EOK);
EXPECT_EQ("dlns_inherit_0800", dlns_inherit(&dlnsA, &dlnsB, NULL), EOK);
void* handle = dlopen_ns(&dlnsB, dllName_inh_008, RTLD_LAZY);
EXPECT_TRUE("dlns_inherit_0800", handle);
dlclose(handle);
handle = dlopen_ns(&dlnsA, dllName_inh_008, RTLD_LAZY);
EXPECT_FALSE("dlns_inherit_0800", handle);
}
/**
* @tc.name : dlns_inherit_0900
* @tc.desc : Inherit multiple namespaces
* @tc.level : Level 2
*/
void dlns_inherit_0900(void)
{
Dl_namespace dlnsA, dlnsB, dlnsC, dlnsD;
dlns_init(&dlnsA, "dlns_inherit_0900_A");
dlns_init(&dlnsB, "dlns_inherit_0900_B");
dlns_init(&dlnsC, "dlns_inherit_0900_C");
dlns_init(&dlnsD, "dlns_inherit_0900_D");
EXPECT_EQ("dlns_inherit_0900", dlns_create(&dlnsA, NULL), EOK);
EXPECT_EQ("dlns_inherit_0900", dlns_create(&dlnsB, pathB), EOK);
EXPECT_EQ("dlns_inherit_0900", dlns_create(&dlnsC, pathC), EOK);
EXPECT_EQ("dlns_inherit_0900", dlns_create(&dlnsD, pathD), EOK);
EXPECT_EQ("dlns_inherit_0900", dlns_set_namespace_separated("dlns_inherit_0900_A", true), EOK);
EXPECT_EQ("dlns_inherit_0900", dlns_set_namespace_separated("dlns_inherit_0900_B", true), EOK);
EXPECT_EQ("dlns_inherit_0900", dlns_set_namespace_separated("dlns_inherit_0900_C", true), EOK);
EXPECT_EQ("dlns_inherit_0900", dlns_set_namespace_separated("dlns_inherit_0900_D", true), EOK);
EXPECT_EQ("dlns_inherit_0900", dlns_inherit(&dlnsA, &dlnsB, NULL), EOK);
EXPECT_EQ("dlns_inherit_0900", dlns_inherit(&dlnsA, &dlnsC, NULL), EOK);
EXPECT_EQ("dlns_inherit_0900", dlns_inherit(&dlnsA, &dlnsD, NULL), EOK);
void* handle1 = dlopen_ns(&dlnsA, libB, RTLD_LAZY);
EXPECT_TRUE("dlns_inherit_0900", handle1);
dlclose(handle1);
void* handle2 = dlopen_ns(&dlnsA, libC, RTLD_LAZY);
EXPECT_TRUE("dlns_inherit_0900", handle2);
dlclose(handle2);
void* handle3 = dlopen_ns(&dlnsA, libD, RTLD_LAZY);
EXPECT_TRUE("dlns_inherit_0900", handle3);
dlclose(handle3);
}
/**
* @tc.name : dlns_inherit_1000
* @tc.desc : Inherited by multiple namespaces
* @tc.level : Level 2
*/
void dlns_inherit_1000(void)
{
Dl_namespace dlnsA, dlnsB, dlnsC, dlnsD;
dlns_init(&dlnsA, "dlns_inherit_1000_A");
dlns_init(&dlnsB, "dlns_inherit_1000_B");
dlns_init(&dlnsC, "dlns_inherit_1000_C");
dlns_init(&dlnsD, "dlns_inherit_1000_D");
EXPECT_EQ("dlns_inherit_1000", dlns_create(&dlnsA, path), EOK);
EXPECT_EQ("dlns_inherit_1000", dlns_create(&dlnsB, NULL), EOK);
EXPECT_EQ("dlns_inherit_1000", dlns_create(&dlnsC, NULL), EOK);
EXPECT_EQ("dlns_inherit_1000", dlns_create(&dlnsD, NULL), EOK);
EXPECT_EQ("dlns_inherit_1000", dlns_set_namespace_separated("dlns_inherit_1000_A", true), EOK);
EXPECT_EQ("dlns_inherit_1000", dlns_set_namespace_separated("dlns_inherit_1000_B", true), EOK);
EXPECT_EQ("dlns_inherit_1000", dlns_set_namespace_separated("dlns_inherit_1000_C", true), EOK);
EXPECT_EQ("dlns_inherit_1000", dlns_set_namespace_separated("dlns_inherit_1000_D", true), EOK);
EXPECT_EQ("dlns_inherit_1000", dlns_inherit(&dlnsB, &dlnsA, NULL), EOK);
EXPECT_EQ("dlns_inherit_1000", dlns_inherit(&dlnsC, &dlnsA, NULL), EOK);
EXPECT_EQ("dlns_inherit_1000", dlns_inherit(&dlnsD, &dlnsA, NULL), EOK);
void* handle1 = dlopen_ns(&dlnsB, dllName, RTLD_LAZY);
EXPECT_TRUE("dlns_inherit_1000", handle1);
dlclose(handle1);
void* handle2 = dlopen_ns(&dlnsC, dllName, RTLD_LAZY);
EXPECT_TRUE("dlns_inherit_1000", handle2);
dlclose(handle2);
void* handle3 = dlopen_ns(&dlnsD, dllName, RTLD_LAZY);
EXPECT_TRUE("dlns_inherit_1000", handle3);
dlclose(handle3);
}
/**
* @tc.name : dlns_inherit_1100
* @tc.desc : When repeating inheritance, replace the original inheritance relationship
* @tc.level : Level 2
*/
void dlns_inherit_1100(void)
{
Dl_namespace dlnsA, dlnsB;
dlns_init(&dlnsA, "dlns_inherit_1100_A");
dlns_init(&dlnsB, "dlns_inherit_1100_B");
EXPECT_EQ("dlns_inherit_1100", dlns_create(&dlnsA, NULL), EOK);
EXPECT_EQ("dlns_inherit_1100", dlns_create(&dlnsB, NULL), EOK);
EXPECT_EQ("dlns_inherit_1100", dlns_set_namespace_separated("dlns_inherit_1100_A", true), EOK);
EXPECT_EQ("dlns_inherit_1100", dlns_set_namespace_separated("dlns_inherit_1100_B", true), EOK);
EXPECT_EQ("dlns_inherit_1100", dlns_inherit(&dlnsA, &dlnsB, NULL), EOK);
void* handle = dlopen_ns(&dlnsA, dllName_inh_011, RTLD_LAZY);
EXPECT_FALSE("dlns_inherit_1100", handle);
EXPECT_EQ("dlns_inherit_1100", dlns_set_namespace_allowed_libs("dlns_inherit_1100_B", dllName_inh_011), EOK);
EXPECT_EQ("dlns_inherit_1100", dlns_set_namespace_permitted_paths("dlns_inherit_1100_B", dllNamePath), EOK);
EXPECT_EQ("dlns_inherit_1100", dlns_set_namespace_lib_path("dlns_inherit_1100_B", path), EOK);
// AGIN
EXPECT_EQ("dlns_inherit_1100", dlns_inherit(&dlnsA, &dlnsB, NULL), EOK);
handle = dlopen_ns(&dlnsA, dllName_inh_011, RTLD_LAZY);
EXPECT_TRUE("dlns_inherit_1100", handle);
dlclose(handle);
}
TEST_FUN G_Fun_Array[] = {
dlns_inherit_0100,
dlns_inherit_0200,
dlns_inherit_0300,
dlns_inherit_0400,
dlns_inherit_0500,
dlns_inherit_0600,
dlns_inherit_0700,
dlns_inherit_0800,
dlns_inherit_0900,
dlns_inherit_1000,
dlns_inherit_1100,
};
int main(void)
{
int num = sizeof(G_Fun_Array)/sizeof(TEST_FUN);
for (int pos = 0; pos < num; ++pos) {
G_Fun_Array[pos]();
}
return t_status;
}
\ No newline at end of file
/**
* Copyright (c) 2022 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 <dlfcn.h>
#include <errno.h>
#include <stdio.h>
#include <string.h>
#include "dlns_test.h"
#include "functionalext.h"
/**
* @tc.name : separated_0100
* @tc.desc : When the separated property is false, under non-strict isolation, so can be opened by short name
* @tc.level : Level 1
*/
void separated_0100(void)
{
Dl_namespace dlns;
dlns_init(&dlns, "ns_separated_flase");
void* handle = dlopen_ns(&dlns, dllName, RTLD_LAZY);
EXPECT_TRUE("separated_0100", handle);
dlclose(handle);
}
/**
* @tc.name : separated_0200
* @tc.desc : When the separated property is false, under non-strict isolation, the wrong path cannot open so
* @tc.level : Level 2
*/
void separated_0200(void)
{
Dl_namespace dlns;
dlns_init(&dlns, "ns_separated1");
// 错误短名称
void* handle = dlopen_ns(&dlns, dllName2, RTLD_LAZY);
EXPECT_FALSE("separated_0200", handle);
}
/**
* @tc.name : separated_0300
* @tc.desc : When the separated property is true, under strict isolation, the name of the incoming
* library is under the allowed.libs configuration item, and lib_paths and permitted.paths are configured correctly
* @tc.level : Level 1
*/
void separated_0300(void)
{
Dl_namespace dlns;
dlns_init(&dlns, "ns_normal");
// 长路径
void* handle = dlopen_ns(&dlns, dllNamePath, RTLD_LAZY);
EXPECT_TRUE("separated_0300", handle);
dlclose(handle);
}
/**
* @tc.name : separated_0400
* @tc.desc : When the separated property is true, under strict isolation, the name of the incoming
* library is under the allowed.libs configuration item, and the lib_paths and permitted.paths
* configurations do not match.
* @tc.level : Level 2
*/
void separated_0400(void)
{
Dl_namespace dlns;
dlns_init(&dlns, "ns_wrong_lib_path");
void* handle = dlopen_ns(&dlns, errdllNamePath, RTLD_LAZY);
EXPECT_FALSE("separated_0400", handle);
}
/**
* @tc.name : separated_0500
* @tc.desc : When the separated property is true, under strict isolation, the lib_paths, permitted.paths
* configuration matches,The name of the incoming library is not in the allowed.libs configuration item
* @tc.level : Level 2
*/
void separated_0500(void)
{
Dl_namespace dlns;
dlns_init(&dlns, "ns_normal");
void* handle = dlopen_ns(&dlns, dllNamePath2, RTLD_LAZY);
EXPECT_FALSE("separated_0500", handle);
}
/**
* @tc.name : separated_0600
* @tc.desc : When the separated attribute is false, under non-strict isolation,
* calling dlopen_ns can open so by short name
* @tc.level : Level 2
*/
void separated_0600(void)
{
Dl_namespace dlns;
dlns_init(&dlns, "separated_0600");
EXPECT_EQ("separated_0600", dlns_create(&dlns, path), EOK);
EXPECT_EQ("separated_0600", dlns_set_namespace_separated("separated_0600", false), EOK);
void* handle = dlopen_ns(&dlns, dllName, RTLD_LAZY);
EXPECT_TRUE("separated_0600", handle);
dlclose(handle);
}
/**
* @tc.name : separated_0700
* @tc.desc : When the separated property is false, under non-strict isolation,
* calling dlopen_ns error short name cannot open so
*/
void separated_0700(void)
{
Dl_namespace dlns;
dlns_init(&dlns, "separated_0700");
EXPECT_EQ("separated_0700", dlns_create(&dlns, path), EOK);
EXPECT_EQ("separated_0700", dlns_set_namespace_separated("separated_0700", false), EOK);
void* handle = dlopen_ns(&dlns, errPath_ns, RTLD_LAZY);
EXPECT_FALSE("separated_0700", handle);
}
/**
* @tc.name : separated_0800
* @tc.desc : When the separated property is true, under strict isolation, the name of the incoming library is in
* the allowed.libs configuration item, and the lib_paths and permitted.paths configurations match.
* Calling dlopen_ns can open so through the full path.
* @tc.level : Level 1
*/
void separated_0800(void)
{
Dl_namespace dlns;
dlns_init(&dlns, "separated_0800");
EXPECT_EQ("separated_0800", dlns_create(&dlns, path), EOK);
EXPECT_EQ("separated_0800", dlns_set_namespace_separated("separated_0800", true), EOK);
EXPECT_EQ("separated_0800", dlns_set_namespace_permitted_paths("separated_0800", dllNamePath), EOK);
EXPECT_EQ("separated_0800", dlns_set_namespace_lib_path("separated_0800", path), EOK);
EXPECT_EQ("separated_0800", dlns_set_namespace_allowed_libs("separated_0800", dllName), EOK);
void* handle = dlopen_ns(&dlns, dllNamePath, RTLD_LAZY);
EXPECT_TRUE("separated_0800", handle);
dlclose(handle);
}
/**
* @tc.name : separated_0900
* @tc.desc : When the separated property is true, under strict isolation, the name of the incoming library is
* in the allowed.libs configuration item, and the lib_paths, permitted.paths configuration does not
* match, and calling dlopen_ns cannot open so through the full path
* @tc.level : Level 2
*/
void separated_0900(void)
{
Dl_namespace dlns;
dlns_init(&dlns, "separated_0900");
EXPECT_EQ("separated_0900", dlns_create(&dlns, path), EOK);
EXPECT_EQ("separated_0900", dlns_set_namespace_separated("separated_0900", true), EOK);
EXPECT_EQ("separated_0900", dlns_set_namespace_permitted_paths("separated_0900", errdllNamePath), EOK);
EXPECT_EQ("separated_0900", dlns_set_namespace_lib_path("separated_0900", errPath_ns), EOK);
EXPECT_EQ("separated_0900", dlns_set_namespace_allowed_libs("separated_0900", dllName_sep_009), EOK);
void* handle = dlopen_ns(&dlns, dllName_sep_009, RTLD_LAZY);
EXPECT_FALSE("separated_0900", handle);
}
/**
* @tc.name : separated_1000
* @tc.desc : When the separated property is true, under strict isolation, the lib_paths, permitted.paths
* configuration matches,The name of the incoming library is not in the allowed.libs configuration
* item, calling dlopen_ns cannot open so through the full path
* @tc.level : Level 2
*/
void separated_1000(void)
{
Dl_namespace dlns;
dlns_init(&dlns, "separated_1000");
EXPECT_EQ("separated_1000", dlns_create(&dlns, path), EOK);
EXPECT_EQ("separated_1000", dlns_set_namespace_separated("separated_1000", true), EOK);
EXPECT_EQ("separated_1000", dlns_set_namespace_permitted_paths("separated_1000", dllNamePath), EOK);
EXPECT_EQ("separated_1000", dlns_set_namespace_lib_path("separated_1000", path), EOK);
EXPECT_EQ("separated_1000", dlns_set_namespace_allowed_libs("separated_1000", dllName2), EOK);
void* handle = dlopen_ns(&dlns, dllNamePath, RTLD_LAZY);
EXPECT_FALSE("separated_1000", handle);
}
/**
* @tc.name : separated_1100
* @tc.desc : The asan.lib.paths path will not be used when the Asan function is not enabled
* @tc.level : Level 2
*/
void separated_1100(void)
{
Dl_namespace dlns;
dlns_init(&dlns, "ns_asan_lib_path");
void* handle = dlopen_ns(&dlns, dllName, RTLD_LAZY);
EXPECT_TRUE("separated_1100", handle);
dlclose(handle);
void* handle1 = dlopen_ns(&dlns, libB, RTLD_LAZY);
EXPECT_FALSE("separated_1100", handle1);
}
/**
* @tc.name : separated_1200
* @tc.desc : asan.permitted.paths paths will not be used when the Asan function is not enabled
* @tc.level : Level 2
*/
void separated_1200(void)
{
Dl_namespace dlns;
dlns_init(&dlns, "ns_asan_permit_path");
char *libcc = "/data/tests/libc-test/src/functionalext/dlns/C/libC.so";
void* handle = dlopen_ns(&dlns, libcc, RTLD_LAZY);
EXPECT_TRUE("separated_1200", handle);
dlclose(handle);
char *libbb = "/data/tests/libc-test/src/functionalext/dlns/B/libB.so";
void* handle1 = dlopen_ns(&dlns, libbb, RTLD_LAZY);
EXPECT_FALSE("separated_1200", handle1);
}
TEST_FUN G_Fun_Array[] = {
separated_0100,
separated_0200,
separated_0300,
separated_0400,
separated_0500,
separated_0600,
separated_0700,
separated_0800,
separated_0900,
separated_1000,
separated_1100,
separated_1200,
};
int main(void)
{
int num = sizeof(G_Fun_Array)/sizeof(TEST_FUN);
for (int pos = 0; pos < num; ++pos) {
G_Fun_Array[pos]();
}
return t_status;
}
\ No newline at end of file
/**
* Copyright (c) 2022 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 <dlfcn.h>
#include <errno.h>
#include <stdio.h>
#include <string.h>
#include "dlns_test.h"
#include "functionalext.h"
/**
* @tc.name : dlns_set_namespace_lib_path_0100
* @tc.desc : When name is no namespace created, call dlns_set_namespace_lib_path
* @tc.level : Level 2
*/
void dlns_set_namespace_lib_path_0100(void)
{
EXPECT_EQ("dlns_set_namespace_lib_path_0100",
dlns_set_namespace_lib_path("dlns_set_namespace_lib_path_0100", path), ENOKEY);
}
/**
* @tc.name : dlns_set_namespace_lib_path_0200
* @tc.desc : When name is a created namespace, call dlns_set_namespace_lib_path
* @tc.level : Level 2
*/
void dlns_set_namespace_lib_path_0200(void)
{
Dl_namespace dlns;
dlns_init(&dlns, "dlns_set_namespace_lib_path_0200");
EXPECT_EQ("dlns_set_namespace_lib_path_0200", dlns_create(&dlns, NULL), EOK);
void* handle = dlopen_ns(&dlns, dllName_set_002, RTLD_LAZY);
EXPECT_FALSE("dlns_set_namespace_lib_path_0200", handle);
EXPECT_EQ("dlns_set_namespace_lib_path_0200",
dlns_set_namespace_lib_path("dlns_set_namespace_lib_path_0200", path), EOK);
handle = dlopen_ns(&dlns, dllName_set_002, RTLD_LAZY);
EXPECT_TRUE("dlns_set_namespace_lib_path_0200", handle);
dlclose(handle);
}
/**
* @tc.name : dlns_set_namespace_lib_path_0300
* @tc.desc : When name=NULL, call dlns_set_namespace_lib_path
* @tc.level : Level 2
*/
void dlns_set_namespace_lib_path_0300(void)
{
EXPECT_EQ("dlns_set_namespace_lib_path_0300", dlns_set_namespace_lib_path(NULL, path), EINVAL);
}
/**
* @tc.name : dlns_set_namespace_lib_path_0400
* @tc.desc : When lib_path=NULL, call dlns_set_namespace_lib_path
* @tc.level : Level 2
*/
void dlns_set_namespace_lib_path_0400(void)
{
Dl_namespace dlns;
dlns_init(&dlns, "dlns_set_namespace_lib_path_0400");
EXPECT_EQ("dlns_set_namespace_lib_path_0400", dlns_create(&dlns, NULL), EOK);
EXPECT_EQ("dlns_set_namespace_lib_path_0400",
dlns_set_namespace_lib_path("dlns_set_namespace_lib_path_0400", NULL), EINVAL);
}
/**
* @tc.name : dlns_set_namespace_lib_path_0500
* @tc.desc : When the lib_path parameter is multiple paths, call dlns_set_namespace_lib_path
* @tc.level : Level 1
*/
void dlns_set_namespace_lib_path_0500(void)
{
Dl_namespace dlns;
dlns_init(&dlns, "dlns_set_namespace_lib_path_0500");
EXPECT_EQ("dlns_set_namespace_lib_path_0500", dlns_create(&dlns, NULL), EOK);
char* newlibpath = "/data/tests/libc-test/src/functionalext/dlns:/data/tests/libc-test/src/functionalext/dlns/B";
EXPECT_EQ("dlns_set_namespace_lib_path_0500",
dlns_set_namespace_lib_path("dlns_set_namespace_lib_path_0500", newlibpath), EOK);
void *handle = dlopen_ns(&dlns, dllName, RTLD_LAZY);
EXPECT_TRUE("dlns_set_namespace_lib_path_0500", handle);
dlclose(handle);
void *handle1 = dlopen_ns(&dlns, libB, RTLD_LAZY);
EXPECT_TRUE("dlns_set_namespace_lib_path_0500", handle1);
dlclose(handle1);
}
/**
* @tc.name : dlns_set_namespace_separated_0100
* @tc.desc : When name is no namespace created, call dlns_set_namespace_separated
* @tc.level : Level 2
*/
void dlns_set_namespace_separated_0100(void)
{
EXPECT_EQ("dlns_set_namespace_separated_0100",
dlns_set_namespace_separated("dlns_set_namespace_permitted_paths_0100", true), ENOKEY);
}
/**
* @tc.name : dlns_set_namespace_separated_0200
* @tc.desc : When the name is a created namespace, call dlns_set_namespace_separated
* @tc.level : Level 1
*/
void dlns_set_namespace_separated_0200(void)
{
Dl_namespace dlns;
dlns_init(&dlns, "dlns_set_namespace_separated_0200");
EXPECT_EQ("dlns_set_namespace_separated_0200", dlns_create(&dlns, NULL), EOK);
void* handle = dlopen_ns(&dlns, dllNamePath, RTLD_LAZY);
EXPECT_TRUE("dlns_set_namespace_separated_0200", handle);
dlclose(handle);
EXPECT_EQ("dlns_set_namespace_separated_0200",
dlns_set_namespace_separated("dlns_set_namespace_separated_0200", true), EOK);
void* handle1 = dlopen_ns(&dlns, dllNamePath, RTLD_LAZY);
EXPECT_FALSE("dlns_set_namespace_separated_0200", handle1);
}
/**
* @tc.name : dlns_set_namespace_separated_0300
* @tc.desc : When name=NULL, call dlns_set_namespace_separated
* @tc.level : Level 2
*/
void dlns_set_namespace_separated_0300(void)
{
EXPECT_EQ("dlns_set_namespace_separated_0300", dlns_set_namespace_separated(NULL, true), EINVAL);
}
/**
* @tc.name : dlns_set_namespace_permitted_paths_0100
* @tc.desc : When name is no namespace created, call dlns_set_namespace_permitted_paths
* @tc.level : Level 2
*/
void dlns_set_namespace_permitted_paths_0100(void)
{
EXPECT_EQ("dlns_set_namespace_permitted_paths_0100",
dlns_set_namespace_permitted_paths("dlns_set_namespace_permitted_paths_0100", dllNamePath), ENOKEY);
}
/**
* @tc.name : dlns_set_namespace_permitted_paths_0200
* @tc.desc : name为已创建命名空间时,调用dlns_set_namespace_permitted_paths
* @tc.level : Level 2
*/
void dlns_set_namespace_permitted_paths_0200(void)
{
Dl_namespace dlns;
dlns_init(&dlns, "dlns_set_namespace_permitted_paths_0200");
EXPECT_EQ("dlns_set_namespace_permitted_paths_0200", dlns_create(&dlns, NULL), EOK);
EXPECT_EQ("dlns_set_namespace_permitted_paths_0200",
dlns_set_namespace_separated("dlns_set_namespace_permitted_paths_0200", true), EOK);
void* handle = dlopen_ns(&dlns, dllNamePath, RTLD_LAZY);
EXPECT_FALSE("dlns_set_namespace_permitted_paths_0200", handle);
EXPECT_EQ("dlns_set_namespace_permitted_paths_0200",
dlns_set_namespace_permitted_paths("dlns_set_namespace_permitted_paths_0200", path), EOK);
void* handle1 = dlopen_ns(&dlns, dllNamePath, RTLD_LAZY);
EXPECT_TRUE("dlns_set_namespace_permitted_paths_0200", handle1);
dlclose(handle1);
}
/**
* @tc.name : dlns_set_namespace_permitted_paths_0300
* @tc.desc : When the name is a created namespace, call dlns_set_namespace_permitted_paths
* @tc.level : Level 1
*/
void dlns_set_namespace_permitted_paths_0300(void)
{
Dl_namespace dlns;
dlns_init(&dlns, "dlns_set_namespace_permitted_paths_0300");
char *newLibPath = "/data/tests/libc-test/src/functionalext/dlns/B/libB.so";
EXPECT_EQ("dlns_set_namespace_permitted_paths_0300", dlns_create(&dlns, NULL), EOK);
EXPECT_EQ("dlns_set_namespace_permitted_paths_0300",
dlns_set_namespace_separated("dlns_set_namespace_permitted_paths_0300", true), EOK);
void* handle = dlopen_ns(&dlns, dllNamePath, RTLD_LAZY);
EXPECT_FALSE("dlns_set_namespace_permitted_paths_0300", handle);
EXPECT_EQ("dlns_set_namespace_permitted_paths_0300",
dlns_set_namespace_permitted_paths("dlns_set_namespace_permitted_paths_0300", path), EOK);
void* handle1 = dlopen_ns(&dlns, newLibPath, RTLD_LAZY);
EXPECT_TRUE("dlns_set_namespace_permitted_paths_0300", handle1);
dlclose(handle1);
}
/**
* @tc.name : dlns_set_namespace_permitted_paths_0400
* @tc.desc : When name=NULL, call dlns_set_namespace_permitted_paths
* @tc.level : Level 2
*/
void dlns_set_namespace_permitted_paths_0400(void)
{
EXPECT_EQ("dlns_set_namespace_permitted_paths_0400",
dlns_set_namespace_permitted_paths(NULL, dllNamePath), EINVAL);
}
/**
* @tc.name : dlns_set_namespace_permitted_paths_0500
* @tc.desc : When the permitted_paths parameter is multiple paths, call dlns_set_namespace_permitted_paths
* @tc.level : Level 1
*/
void dlns_set_namespace_permitted_paths_0500(void)
{
Dl_namespace dlns;
dlns_init(&dlns, "dlns_set_namespace_permitted_paths_0500");
char* newPermittPath = "/data/tests/libc-test/src/functionalext";
char* libBpath = "/data/tests/libc-test/src/functionalext/dlns/B/libB.so";
EXPECT_EQ("dlns_set_namespace_permitted_paths_0500", dlns_create(&dlns, NULL), EOK);
EXPECT_EQ("dlns_set_namespace_permitted_paths_0500",
dlns_set_namespace_separated("dlns_set_namespace_permitted_paths_0500", true), EOK);
void* handle = dlopen_ns(&dlns, dllNamePath, RTLD_LAZY);
EXPECT_FALSE("dlns_set_namespace_permitted_paths_0500", handle);
void* handle1 = dlopen_ns(&dlns, libBpath, RTLD_LAZY);
EXPECT_FALSE("dlns_set_namespace_permitted_paths_0500", handle1);
EXPECT_EQ("dlns_set_namespace_permitted_paths_0500",
dlns_set_namespace_permitted_paths("dlns_set_namespace_permitted_paths_0500", newPermittPath), EOK);
void* handle2 = dlopen_ns(&dlns, dllNamePath, RTLD_LAZY);
EXPECT_TRUE("dlns_set_namespace_permitted_paths_0500", handle2);
dlclose(handle2);
void* handle3 = dlopen_ns(&dlns, libBpath, RTLD_LAZY);
EXPECT_TRUE("dlns_set_namespace_permitted_paths_0500", handle3);
dlclose(handle3);
}
/**
* @tc.name : dlns_set_namespace_allowed_libs_0100
* @tc.desc : When name is no namespace created, call dlns_set_namespace_allowed_libs
* @tc.level : Level 2
*/
void dlns_set_namespace_allowed_libs_0100(void)
{
// 未创建的命名空间
EXPECT_EQ("dlns_set_namespace_allowed_libs_0100",
dlns_set_namespace_allowed_libs("dlns_set_namespace_allowed_libs_0100", path), ENOKEY);
}
/**
* @tc.name : dlns_set_namespace_allowed_libs_0200
* @tc.desc : When the name is a created namespace, call dlns_set_namespace_allowed_libs
* @tc.level : Level 1
*/
void dlns_set_namespace_allowed_libs_0200(void)
{
Dl_namespace dlns;
dlns_init(&dlns, "ns_no_allowed_libs");
void* handle = dlopen_ns(&dlns, dllNamePath, RTLD_LAZY);
EXPECT_TRUE("dlns_set_namespace_allowed_libs_0200", handle);
dlclose(handle);
EXPECT_EQ("dlns_set_namespace_allowed_libs_0200",
dlns_set_namespace_allowed_libs("ns_no_allowed_libs", dllName2), EOK);
void* handle1 = dlopen_ns(&dlns, dllNamePath, RTLD_LAZY);
EXPECT_FALSE("dlns_set_namespace_allowed_libs_0200", handle1);
EXPECT_EQ("dlns_set_namespace_allowed_libs_0200",
dlns_set_namespace_allowed_libs("ns_no_allowed_libs", dllName), EOK);
}
/**
* @tc.name : dlns_set_namespace_allowed_libs_0300
* @tc.desc : When name=NULL, call dlns_set_namespace_allowed_libs
* @tc.level : Level 2
*/
void dlns_set_namespace_allowed_libs_0300(void)
{
EXPECT_EQ("dlns_set_namespace_allowed_libs_0300", dlns_set_namespace_allowed_libs(NULL, path), EINVAL);
}
/**
* @tc.name : dlns_set_namespace_allowed_libs_0400
* @tc.desc : When the allowed_libs parameter is multiple file names, call dlns_set_namespace_allowed_libs
* @tc.level : Level 1
*/
void dlns_set_namespace_allowed_libs_0400(void)
{
Dl_namespace dlns;
dlns_init(&dlns, "ns_no_allowed_libs");
void* handle = dlopen_ns(&dlns, dllNamePath, RTLD_LAZY);
EXPECT_TRUE("dlns_set_namespace_allowed_libs_0400", handle);
dlclose(handle);
char* dll4 = "libdlopen_ns_dso.so:libdlopen_dso.so:sharedlibtest.so";
EXPECT_EQ("dlns_set_namespace_allowed_libs_0400",
dlns_set_namespace_allowed_libs("ns_no_allowed_libs", dll4), EOK);
void* handle1 = dlopen_ns(&dlns, dllNamePath, RTLD_LAZY);
EXPECT_TRUE("dlns_set_namespace_allowed_libs_0400", handle1);
dlclose(handle1);
}
TEST_FUN G_Fun_Array[] = {
dlns_set_namespace_lib_path_0100,
dlns_set_namespace_lib_path_0200,
dlns_set_namespace_lib_path_0300,
dlns_set_namespace_lib_path_0400,
dlns_set_namespace_lib_path_0500,
dlns_set_namespace_separated_0100,
dlns_set_namespace_separated_0200,
dlns_set_namespace_separated_0300,
dlns_set_namespace_permitted_paths_0100,
dlns_set_namespace_permitted_paths_0200,
dlns_set_namespace_permitted_paths_0300,
dlns_set_namespace_permitted_paths_0400,
dlns_set_namespace_permitted_paths_0500,
dlns_set_namespace_allowed_libs_0100,
dlns_set_namespace_allowed_libs_0200,
dlns_set_namespace_allowed_libs_0300,
dlns_set_namespace_allowed_libs_0400,
};
int main(void)
{
int num = sizeof(G_Fun_Array)/sizeof(TEST_FUN);
for (int pos = 0; pos < num; ++pos) {
G_Fun_Array[pos]();
}
return t_status;
}
\ No newline at end of file
/**
* Copyright (c) 2022 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 <dlfcn.h>
#include <errno.h>
#include <stdio.h>
#include <string.h>
#include "dlns_test.h"
#include "functionalext.h"
/**
* @tc.name : dlopen_ns_special_0100
* @tc.desc : Loading the same library multiple times from the same namespace.
* @tc.level : Level 2
*/
void dlopen_ns_special_0100(void)
{
Dl_namespace dlns;
dlns_init(&dlns, "ns_no_allowed_libs");
void* handle1 = dlopen_ns(&dlns, dllName, RTLD_LAZY);
EXPECT_TRUE("dlopen_ns_special_0100", handle1);
void* handle2 = dlopen_ns(&dlns, dllName, RTLD_LAZY);
EXPECT_TRUE("dlopen_ns_special_0100", handle2);
void* handle3 = dlopen_ns(&dlns, dllName, RTLD_LAZY);
EXPECT_TRUE("dlopen_ns_special_0100", handle3);
dlclose(handle1);
dlclose(handle2);
dlclose(handle3);
}
/**
* @tc.name : dlopen_ns_special_0200
* @tc.desc : Loading the same library multiple times in different namespaces.
* @tc.level : Level 2
*/
void dlopen_ns_special_0200(void)
{
Dl_namespace dlns_no_allowed_libs, dlns_normal, dlns_wrong_lib_path;
dlns_init(&dlns_no_allowed_libs, "ns_no_allowed_libs");
dlns_init(&dlns_normal, "ns_normal");
dlns_init(&dlns_wrong_lib_path, "inherited_class");
void* handle1 = dlopen_ns(&dlns_no_allowed_libs, dllName, RTLD_LAZY);
EXPECT_TRUE("dlopen_ns_special_0200", handle1);
void* handle2 = dlopen_ns(&dlns_normal, dllName, RTLD_LAZY);
EXPECT_TRUE("dlopen_ns_special_0200", handle2);
void* handle3 = dlopen_ns(&dlns_wrong_lib_path, dllName, RTLD_LAZY);
EXPECT_TRUE("dlopen_ns_special_0200", handle3);
dlclose(handle1);
dlclose(handle2);
dlclose(handle3);
}
/**
* @tc.name : dlopen_ns_sys_path_0100
* @tc.desc : arm platform, lib_paths in the default namespace is the system path
* read in the ld-musl-namespace-arm.ini file
* @tc.level : Level 2
*/
void dlopen_ns_sys_path_0100(void)
{
Dl_namespace dlns;
dlns_init(&dlns, "default");
void* handle = dlopen_ns(&dlns, dllName, RTLD_LAZY);
EXPECT_TRUE("dlopen_ns_sys_path_0100", handle);
dlclose(handle);
}
int main(void)
{
dlopen_ns_special_0100();
dlopen_ns_special_0200();
dlopen_ns_sys_path_0100();
return t_status;
}
\ No newline at end of file
/**
* Copyright (c) 2022 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.
*/
#ifndef LIBC_TEST_SRC_FUNCTIONALEXT_DLNS_DLNS_TEST_H
#define LIBC_TEST_SRC_FUNCTIONALEXT_DLNS_DLNS_TEST_H
static const char* path = "/data/tests/libc-test/src/functionalext/dlns";
static const char* dllName = "libdlopen_ns_dso.so";
static const char* dllNamePath = "/data/tests/libc-test/src/functionalext/dlns/libdlopen_ns_dso.so";
static const char* errdllNamePath = "/etc/test/libdlopen_ns_dso.so";
static const char* dllName2 = "libdlopen_dso.so";
static const char* dllNamePath2 = "/data/tests/libc-test/src/functionalext/dlns/libdlopen_dso.so";
static const char* errPath_ns = "src/test";
static const char* sharedLib = "sharedlibtest.so";
static const char* pathB = "/data/tests/libc-test/src/functionalext/dlns/B";
static const char* pathC = "/data/tests/libc-test/src/functionalext/dlns/C";
static const char* pathD = "/data/tests/libc-test/src/functionalext/dlns/D";
static const char* libB = "libB.so";
static const char* libC = "libC.so";
static const char* libD = "libD.so";
static const char* dllName_sep_009 = "separated_0900.so";
static const char* dllName_set_002 = "set_lib_path_0200.so";
static const char* dllName_inh_003 = "inherit_0300.so";
static const char* dllName_inh_007 = "inherit_0700.so";
static const char* dllName_inh_008 = "inherit_0800.so";
static const char* dllName_inh_011 = "inherit_1100.so";
typedef void(*TEST_FUN)(void);
static const int EOK = 0;
#endif
\ No newline at end of file
# Copyright (c) 2022 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.
functionalext_complex_list = [
"dlns_dlopen",
"dlns_set_fun",
"dlns_inherit",
"dlns_separated",
"dlns_special_scene",
]
......@@ -18,5 +18,6 @@ functionalext_list = [
"tgkill:functionalext_tgkill_test",
"thread:functionalext_thread_test",
"trace:functionalext_trace_test",
"dlns:dlns_test",
"info:functionalext_info_test",
]
......@@ -1915,6 +1915,7 @@ musl_src_porting_file = [
"src/exit/atexit.c",
"crt/arm/crti.s",
"crt/aarch64/crti.s",
"ldso/ld_log.h",
"ldso/namespace.c",
"ldso/ns_config.c",
"ldso/strops.c",
......
[section.dir.map]
acquiescence = /
test = /data/tests/libc-test/src/functionalext:/data/tests/libc-test/src/functionalext/dlns
[acquiescence]
namespace.default.lib.paths = /system/lib64:/vendor/lib64:/vendor/lib64/chipsetsdk:/system/lib64/ndk:/system/lib64/vndk:/system/lib64/platform-vndk:/system/lib64/platformsdk:/system/lib64/priv-platformsdk:/system/lib64/priv-module:/system/lib64/module:/system/lib64/module/data:/system/lib64/module/multimedia:/system/lib:/vendor/lib:/system/lib/ndk:/system/lib/vndk:/system/lib/platform-vndk:/system/lib/platformsdk:/system/lib/priv-platformsdk:/system/lib/priv-module:/system/lib/module:/system/lib/module/data:/system/lib/module/multimedia:/lib64:/lib:/usr/local/lib:/usr/lib
namespace.default.asan.lib.paths = /system/lib64:/system/lib64/module:/vendor/lib64:/vendor/lib64/chipsetsdk:/system/lib64/module/data:/system/lib64/module/multimedia:/system/lib:/system/lib/module:/system/lib/module/data:/system/lib/module/multimedia:/lib64:/lib:/usr/local/lib:/usr/lib
[test]
added.nslist=ns_no_allowed_libs,ns_normal,ns_wrong_lib_path,ns_wrong_allowed_path,for_inherit_A,for_inherit_AA,inherited_class,ns_separated_flase,ns_asan_lib_path,ns_asan_permit_path
#ns_no_allowed_libs 未配 allowed libs
namespace.ns_no_allowed_libs.separated = true
namespace.ns_no_allowed_libs.lib.paths = /data/tests/libc-test/src/functionalext/dlns
#ns_normal 正常的带有visible属性
namespace.ns_normal.separated = true
namespace.ns_normal.visible = true
namespace.ns_normal.lib.paths = /data/tests/libc-test/src/functionalext/dlns
namespace.ns_normal.allowed.libs = libdlopen_ns_dso.so
#ns_wrong_lib_path 在 allowed_libs 内,但是不在 env or lib or permitted Path 不匹配
namespace.ns_wrong_lib_path.separated = true
namespace.ns_wrong_lib_path.lib.paths = src/common/
namespace.ns_wrong_lib_path.allowed.libs = libdlopen_ns_dso.so
namespace.ns_wrong_lib_path.permitted.paths = /data/tests
#ns_wrong_allowed_path 不在 allowed_libs 内
namespace.ns_wrong_allowed_path.separated = true
namespace.ns_wrong_allowed_path.lib.paths = /data/tests/libc-test/src/functionalext/dlns
namespace.ns_wrong_allowed_path.allowed.libs = libdlopen_dso.so
#for testing inheritance
namespace.for_inherit_A.separated = true
#for testing inheritance
namespace.for_inherit_AA.separated = true
#inherited_class 用于测试继承属性
namespace.inherited_class.separated = true
namespace.inherited_class.lib.paths = /data/tests/libc-test/src/functionalext/dlns
namespace.inherited_class.allowed.libs= libdlopen_ns_dso.so:sharedlibtest.so
#ns_separated_flase 不是严格隔离的
namespace.ns_separated_flase.separated = false
namespace.ns_separated_flase.lib.paths = /data/tests/libc-test/src/functionalext/dlns
namespace.ns_separated_flase.allowed.libs = libdlopen_ns_dso.so
#ns_asan_lib_path 测试asan.lib.paths
namespace.ns_asan_lib_path.separated = true
namespace.ns_asan_lib_path.lib.paths = /data/tests/libc-test/src/functionalext/dlns
namespace.ns_asan_lib_path.asan.lib.paths = /data/tests/libc-test/src/functionalext/dlns/B
#ns_asan_permit_path 测试asan.permitted.paths
namespace.ns_asan_permit_path.separated =true
namespace.ns_asan_permit_path.permitted.paths = /data/tests/libc-test/src/functionalext/dlns/C
namespace.ns_asan_permit_path.asan.permitted.paths = /data/tests/libc-test/src/functionalext/dlns/B
[section.dir.map]
acquiescence = /
[acquiescence]
namespace.default.lib.paths = /system/lib64:/vendor/lib64:/vendor/lib64/chipsetsdk:/system/lib64/ndk:/system/lib64/vndk:/system/lib64/platform-vndk:/system/lib64/platformsdk:/system/lib64/priv-platformsdk:/system/lib64/priv-module:/system/lib64/module:/system/lib64/module/data:/system/lib64/module/multimedia:/system/lib:/vendor/lib:/system/lib/ndk:/system/lib/vndk:/system/lib/platform-vndk:/system/lib/platformsdk:/system/lib/priv-platformsdk:/system/lib/priv-module:/system/lib/module:/system/lib/module/data:/system/lib/module/multimedia:/lib64:/lib:/usr/local/lib:/usr/lib
namespace.default.asan.lib.paths = /system/lib64:/system/lib64/module:/vendor/lib64:/vendor/lib64/chipsetsdk:/system/lib64/module/data:/system/lib64/module/multimedia:/system/lib:/system/lib/module:/system/lib/module/data:/system/lib/module/multimedia:/lib64:/lib:/usr/local/lib:/usr/lib
[section.dir.map]
acquiescence = /
test = /data/tests/libc-test/src/functionalext:/data/tests/libc-test/src/functionalext/dlns
[acquiescence]
namespace.default.lib.paths = /system/lib:/vendor/lib:/vendor/lib/chipsetsdk:/system/lib/ndk:/system/lib/vndk:/system/lib/platform-vndk:/system/lib/platformsdk:/system/lib/priv-platformsdk:/system/lib/priv-module:/system/lib/module:/system/lib/module/data:/system/lib/module/multimedia:/lib:/usr/local/lib:/usr/lib
namespace.default.asan.lib.paths = /system/lib:/system/lib/module:/vendor/lib:/vendor/lib/chipsetsdk:/system/lib/module/data:/system/lib/module/multimedia:/lib:/usr/local/lib:/usr/lib
[test]
added.nslist=ns_no_allowed_libs,ns_normal,ns_wrong_lib_path,ns_wrong_allowed_path,for_inherit_A,for_inherit_AA,inherited_class,ns_separated_flase,ns_asan_lib_path,ns_asan_permit_path
#ns_no_allowed_libs 未配 allowed libs
namespace.ns_no_allowed_libs.separated = true
namespace.ns_no_allowed_libs.lib.paths = /data/tests/libc-test/src/functionalext/dlns
#ns_normal 正常的带有visible属性
namespace.ns_normal.separated = true
namespace.ns_normal.visible = true
namespace.ns_normal.lib.paths = /data/tests/libc-test/src/functionalext/dlns
namespace.ns_normal.allowed.libs = libdlopen_ns_dso.so
#ns_wrong_lib_path 在 allowed_libs 内,但是不在 env or lib or permitted Path 不匹配
namespace.ns_wrong_lib_path.separated = true
namespace.ns_wrong_lib_path.lib.paths = src/common/
namespace.ns_wrong_lib_path.allowed.libs = libdlopen_ns_dso.so
namespace.ns_wrong_lib_path.permitted.paths = /data/tests
#ns_wrong_allowed_path 不在 allowed_libs 内
namespace.ns_wrong_allowed_path.separated = true
namespace.ns_wrong_allowed_path.lib.paths = /data/tests/libc-test/src/functionalext/dlns
namespace.ns_wrong_allowed_path.allowed.libs = libdlopen_dso.so
#for testing inheritance
namespace.for_inherit_A.separated = true
#for testing inheritance
namespace.for_inherit_AA.separated = true
#inherited_class 用于测试继承属性
namespace.inherited_class.separated = true
namespace.inherited_class.lib.paths = /data/tests/libc-test/src/functionalext/dlns
namespace.inherited_class.allowed.libs= libdlopen_ns_dso.so:sharedlibtest.so
#ns_separated_flase 不是严格隔离的
namespace.ns_separated_flase.separated = false
namespace.ns_separated_flase.lib.paths = /data/tests/libc-test/src/functionalext/dlns
namespace.ns_separated_flase.allowed.libs = libdlopen_ns_dso.so
#ns_asan_lib_path 测试asan.lib.paths
namespace.ns_asan_lib_path.separated = true
namespace.ns_asan_lib_path.lib.paths = /data/tests/libc-test/src/functionalext/dlns
namespace.ns_asan_lib_path.asan.lib.paths = /data/tests/libc-test/src/functionalext/dlns/B
#ns_asan_permit_path 测试asan.permitted.paths
namespace.ns_asan_permit_path.separated =true
namespace.ns_asan_permit_path.permitted.paths = /data/tests/libc-test/src/functionalext/dlns/C
namespace.ns_asan_permit_path.asan.permitted.paths = /data/tests/libc-test/src/functionalext/dlns/B
[section.dir.map]
acquiescence = /
[acquiescence]
namespace.default.lib.paths = /system/lib:/vendor/lib:/vendor/lib/chipsetsdk:/system/lib/ndk:/system/lib/vndk:/system/lib/platform-vndk:/system/lib/platformsdk:/system/lib/priv-platformsdk:/system/lib/priv-module:/system/lib/module:/system/lib/module/data:/system/lib/module/multimedia:/lib:/usr/local/lib:/usr/lib
namespace.default.asan.lib.paths = /system/lib:/system/lib/module:/vendor/lib:/vendor/lib/chipsetsdk:/system/lib/module/data:/system/lib/module/multimedia:/lib:/usr/local/lib:/usr/lib
#ifndef _DLFCN_H
#define _DLFCN_H
#include <features.h>
#include <stdbool.h>
#ifdef __cplusplus
extern "C" {
#endif
#include <features.h>
#define RTLD_LAZY 1
#define RTLD_NOW 2
#define RTLD_NOLOAD 4
......@@ -30,25 +31,106 @@ typedef struct {
char name[NS_NAME_MAX+1];
} Dl_namespace;
/**
* @brief Initialize a namespace structure for operating namespaces through related functional interfaces.
* @param Dl_namespace * Carry the naming information of the namespace.
* @param char * namespace name.
* @return void.
* @retval none.
*/
void dlns_init(Dl_namespace *, const char *);
/* open dso in given namespace which has own lib search paths
* when namespace is null, it's same to dlopen()
* avoid using "default" as namespace, which is the default namespace */
/**
* @brief open dso in given namespace which has own lib search paths, when namespace is null, it's same to dlopen().
* avoid using "default" as namespace, which is the default namespace.
* @param Dl_namespace * Carry the naming information of the namespace.
* @param char * the name of the so file you want to open.
* @param int open file mode.
* -- RTLD_LAZY.
* -- RTLD_NOW.
* -- RTLD_NOLOAD.
* -- RTLD_NODELETE.
* -- RTLD_GLOBAL.
* -- RTLD_LOCAL.
* @return success: dynamic library handleoid,failed: NULL.
* @retval none.
*/
void *dlopen_ns(Dl_namespace *, const char *, int);
/* create the namespace and set lib search paths of namespace,
* the paths should be splited by ':'. When namespace already exist,
* return error */
/**
* @brief create the namespace and set lib search paths of namespace,
* the paths should be splited by ':'. When namespace already exist,return error.
* avoid using "default" as namespace, which is the default namespace.
* @param Dl_namespace * namespace information.
* @param char * lib path library that can be specified.
* @return return 0 on success,fail other values.
* @retval
* EINVAL(22) Invalid argument.
* EEXIST(17) File exists.
* ENOMEM(12) Out of memory.
*/
int dlns_create(Dl_namespace *, const char *);
/* make one namespace inherit another, and so it can use shared libs by the inherited one.
* param1: namespace, param2: inherited namespace, param3: shared libs.
* the shared libs should be splited by ':'. when it is null or empty, all libs can be shared.
* one namespace can inherit or be inherited by multiple ones.
* When namespaces do not exist, return error */
/**
* @brief make one namespace inherit another, and so it can use shared libs by the inherited one.
* param1: namespace, param2: inherited namespace, param3: shared libs.
* the shared libs should be splited by ':'. when it is null or empty, all libs can be shared.
* one namespace can inherit or be inherited by multiple ones.
* When namespaces do not exist, return error.
* @param Dl_namespace * The first parameter is the namespace to inherit from.
* @param Dl_namespace * The second parameter is the inherited namespace.
* @param char * some library names to inherit.
* @return return 0 on success,fail other values.
* @retval
* EINVAL(22) Invalid argument.
* ENOKEY(126) Required key not available.
*/
int dlns_inherit(Dl_namespace *, Dl_namespace *, const char *);
/**
* @brief Set namespace lib_path.
* @param name namespace name.
* @param lib_path The lib path name that needs to be reset, it can be multiple, link with ":".
* @return Returns 0 on success, other on failure.
* @retval
* EINVAL(22) Invalid argument.
* ENOKEY(126) Required key not available.
*/
int dlns_set_namespace_lib_path(const char *name, const char *lib_path);
/**
* @brief Set namespace separated.
* @param name namespace name.
* @param separated separated.
* @return Returns 0 on success, other on failure.
* @retval
* EINVAL(22) Invalid argument.
* ENOKEY(126) Required key not available.
*/
int dlns_set_namespace_separated(const char *name, const bool separated);
/**
* @brief Set namespace permitted_paths.
* @param name namespace name.
* @param permitted_paths set new permitted_paths.
* @return Returns 0 on success, other on failure.
* @retval
* EINVAL(22) Invalid argument.
* ENOKEY(126) Required key not available.
*/
int dlns_set_namespace_permitted_paths(const char *name, const char *permitted_paths);
/**
* @brief Set namespace allowed_libs.
* @param name namespace name.
* @param allowed_libs set new allowed_libs.
* @return Returns 0 on success, other on failure.
* @retval
* EINVAL(22) Invalid argument.
* ENOKEY(126) Required key not available.
*/
int dlns_set_namespace_allowed_libs(const char *name, const char *allowed_libs);
#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
typedef struct {
const char *dli_fname;
......
## Dynamic Linker Namespace
The dynamic linker provides the namespace mechanism which is based on configures and apis.
Shared libraries can be isolated in different namespaces so that libraries with same library name but with different symbols won't conflict. On the other hand, the namespace mechanism provides the flexibility so that some shared libraries can be exported by a linker namespace and used by another linker namespace.
### How does it work
There are two ways to use the linker namespace:
1. Modify and save the namespace configure file </etc/ld-musl-namespace.ini>. When it does not exist or is filled in, a default namespace will be created.
2. Use the apis of namespace in head file <dlfcn.h>, to create a namespace, to set search paths of library, or to use exported libraries of another namespace by inheriting it.
### Usage example
Test usages show some examples of using the linker namespace. The file <ld-musl-namespace.ini> in current directory is configures for test. The file <libc-test/src/functional/dlopen_ns.c> gives usages of how apis and configures work.
## Dynamic Linker Namespace
The dynamic linker provides the namespace mechanism which is based on configures and apis.
Shared libraries can be isolated in different namespaces so that libraries with same library name but with different symbols won't conflict. On the other hand, the namespace mechanism provides the flexibility so that some shared libraries can be exported by a linker namespace and used by another linker namespace.
### How does it work
There are two ways to use the linker namespace:
1. Modify and save the namespace configure file </etc/ld-musl-namespace-arm.ini> or </etc/ld-musl-namespace-aarch64.ini> base on architecture. When it does not exist or is filled in, a default namespace will be created.
2. Use the apis of namespace in head file <dlfcn.h>, to create a namespace, to set search paths of library, or to use exported libraries of another namespace by inheriting it.
### Usage example
Test usages show some examples of using the linker namespace. The file <ld-musl-namespace.ini> in current directory is configures for test. The file <libc-test/src/functional/dlopen_ns.c> gives usages of how apis and configures work.
此差异已折叠。
[section.dir.map]
test = /data/tests/libc-test/src/functional
system = /usr/bin:/usr/sbin
[test]
added.nslist=ns1,ns2,ns3,ns4,no_inherit_A,inherit_B
namespace.ns1.separated = true
namespace.ns1.lib.paths = src/functional
namespace.ns1.permitted.paths = /usr/bin:/usr/sbin
#separated
#ns2 和 ns3 都是严格隔离
namespace.ns2.separated = true
namespace.ns2.lib.paths = src/functional
namespace.ns2.allowed.libs = libdlopen_ns_dso.so
namespace.ns2.permitted.paths = /data/tests/libc-test/src/functional/libdlopen_ns_dso.so
#ns3 在 allowed_libs 内,但是不在 env or lib or permitted Path 中
namespace.ns3.separated = true
namespace.ns3.lib.paths = src/common
namespace.ns3.allowed.libs = libdlopen_ns_dso.so
namespace.ns3.permitted.paths = src/common/libdlopenns_dso.so
#ns4 不在 allowed_libs 内
namespace.ns4.separated = true
namespace.ns4.lib.paths = src/functional
namespace.ns4.allowed.libs = libdlopen_dso.so
namespace.ns4.permitted.paths = /data/tests/libc-test/src/functional/libdlopen_ns_dso.so
#inherit
namespace.no_inherit_A.separated = true
namespace.no_inherit_A.lib.paths = .
namespace.no_inherit_A.permitted.paths = /data/tests/libc-test/src/functional/libdlopen_ns_dso.so
namespace.inherit_B.separated = true
namespace.inherit_B.lib.paths = .
namespace.inherit_B.inherit = ns2
namespace.inherit_B.inherit.ns2.shared.libs = libdlopen_ns_dso.so
namespace.inherit_B.permitted.paths = src/common/libdlopenns_dso.so
\ No newline at end of file
/*
* Copyright (c) 2022 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 <musl_log.h>
#ifndef LD_LOG_H
#define LD_LOG_H
#define LD_LOG_ERROR 1
#define LD_LOG_WARNING 2
#define LD_LOG_INFO 4
#define LD_LOG_DEBUG 8
#define LD_LOG_LEVEL (LD_LOG_ERROR | LD_LOG_WARNING)
#if (LD_LOG_LEVEL & LD_LOG_ERROR)
#define LD_LOGE(...) MUSL_LOGE(...)
#else
#define LD_LOGE(...)
#endif
#if (LD_LOG_LEVEL & LD_LOG_WARNING)
#define LD_LOGW(...) MUSL_LOGW(...)
#else
#define LD_LOGW(...)
#endif
#if (LD_LOG_LEVEL & LD_LOG_INFO)
#define LD_LOGI(...) MUSL_LOGI(...)
#else
#define LD_LOGI(...)
#endif
#if (LD_LOG_LEVEL & LD_LOG_DEBUG)
#define LD_LOGD(...) MUSL_LOGD(...)
#else
#define LD_LOGD(...)
#endif
#endif // LD_LOG_H
#include "strops.h"
#include "namespace.h"
#include "ld_log.h"
#include "strops.h"
static ns_t g_ns_default;
static nslist g_ns_list;
......@@ -17,6 +19,7 @@ static ns_inherit_list *nsinherits_alloc()
nsinl->size = INHERIT_DEFAULT_SIZE;
nsinl->inherits = (ns_inherit **)calloc(INHERIT_DEFAULT_SIZE, sizeof *nsinl->inherits);
if (!nsinl->inherits) {
LD_LOGW("nsinherits_alloc failed,return NULL!\n");
free(nsinl);
nsinl = NULL;
}
......@@ -26,7 +29,10 @@ static ns_inherit_list *nsinherits_alloc()
static void nsinherits_free(ns_inherit_list *nsinl)
{
if (!nsinl) return;
if (!nsinl) {
LD_LOGW("nsinherits_free failed,nsinl is NULL!\n");
return;
}
for (size_t i=0; i<nsinl->num; i++) {
strlist_free(nsinl->inherits[i]->shared_libs);
free(nsinl->inherits[i]);
......@@ -37,12 +43,18 @@ static void nsinherits_free(ns_inherit_list *nsinl)
static void nsinherits_realloc(ns_inherit_list *nsinl)
{
if (!nsinl) return;
if (!nsinl) {
LD_LOGW("nsinherits_realloc failed,nsinl is NULL!\n");
return;
}
size_t size = 2*nsinl->size;
if (size) {
ns_inherit **inherits;
inherits = (ns_inherit **)realloc(nsinl->inherits, size * (sizeof *nsinl->inherits));
if (!inherits) return;
if (!inherits) {
LD_LOGW("nsinherits_realloc failed!\n");
return;
}
nsinl->size = size;
nsinl->inherits = inherits;
}
......@@ -58,6 +70,7 @@ static dsolist *dsolist_alloc()
dsol->size = DSOLIST_DEFAULT_SIZE ;
dsol->dsos = (struct dso**)calloc(DSOLIST_DEFAULT_SIZE, sizeof *dsol->dsos);
if (!dsol->dsos) {
LD_LOGW("dsolist_alloc failed,return NULL!\n");
free(dsol);
dsol = NULL;
}
......@@ -67,12 +80,18 @@ static dsolist *dsolist_alloc()
static void dsolist_realloc(dsolist *dsol)
{
if (!dsol) return;
if (!dsol) {
LD_LOGW("dsolist_realloc failed,dsol is NULL!\n");
return;
}
size_t size = 2*dsol->size;
if (size) {
struct dso **ds;
ds = (struct dso **)realloc(dsol->dsos, size * (sizeof *dsol->dsos));
if (!ds) return;
if (!ds) {
LD_LOGW("dsolist_realloc failed!\n");
return;
}
dsol->size = size;
dsol->dsos = ds;
}
......@@ -84,6 +103,7 @@ ns_t *ns_alloc()
ns_t *nst = (ns_t *)calloc(1, sizeof *nst);
nst->ns_dsos = dsolist_alloc();
if (!nst->ns_dsos) {
LD_LOGW("ns_alloc failed,return NULL!\n");
free(nst);
nst = NULL;
}
......@@ -92,11 +112,16 @@ ns_t *ns_alloc()
void ns_free(ns_t *ns)
{
if (!ns) return;
if (!ns) {
LD_LOGW("ns_free failed!\n");
return;
}
free(ns->ns_name);
free(ns->env_paths);
free(ns->lib_paths);
free(ns->asan_lib_paths);
strlist_free(ns->permitted_paths);
strlist_free(ns->asan_permitted_paths);
strlist_free(ns->allowed_libs);
nsinherits_free(ns->ns_inherits);
free(ns);
......@@ -104,11 +129,17 @@ void ns_free(ns_t *ns)
void ns_add_dso(ns_t *ns, struct dso *dso)
{
if (!ns||!dso) return;
if (!ns||!dso) {
LD_LOGW("ns_add_dso failed,ns or dso is NULL!\n");
return;
}
if (!ns->ns_dsos) {
ns->ns_dsos = dsolist_alloc();
}
if (!ns->ns_dsos) return;
if (!ns->ns_dsos) {
LD_LOGW("ns_add_dso failed,ns->ns_dsos is NULL!\n");
return;
}
if (ns->ns_dsos->num == ns->ns_dsos->size) {
/* if list is full, realloc size to double*/
dsolist_realloc(ns->ns_dsos);
......@@ -127,6 +158,7 @@ nslist *nslist_init()
g_ns_list.num = 0;
g_ns_list.nss = (ns_t **)calloc(NSLIST_DEFAULT_SIZE, sizeof *g_ns_list.nss);
if (!g_ns_list.nss) {
LD_LOGW("nslist_init failed!\n");
return NULL;
}
return &g_ns_list;
......@@ -138,7 +170,10 @@ static void nslist_realloc()
if (size) {
ns_t **nss;
nss = (ns_t **)realloc(g_ns_list.nss, size * (sizeof *g_ns_list.nss));
if (!nss) return;
if (!nss) {
LD_LOGW("nslist_realloc failed!\n");
return;
}
g_ns_list.size = size;
g_ns_list.nss = nss;
}
......@@ -147,7 +182,10 @@ static void nslist_realloc()
void nslist_add_ns(ns_t *ns)
{
if (!ns) return;
if (!ns) {
LD_LOGW("nslist_add_ns failed,ns is NULL!\n");
return;
}
if (g_ns_list.num == g_ns_list.size) {
/* if list is full, realloc size to double*/
......@@ -169,15 +207,22 @@ ns_t *get_default_ns()
/* set namespace attributes*/
void ns_set_name(ns_t *ns, const char *name)
{
if (!ns || !name) return;
if (!ns || !name) {
LD_LOGW("ns_set_name failed,ns or name is NULL!\n");
return;
}
if (ns->ns_name) free(ns->ns_name);
ns->ns_name = strdup(name);
strtrim(ns->ns_name);
LD_LOGD("ns_set_name ns_name:%s.\n", ns->ns_name);
}
void ns_set_env_paths(ns_t *ns, const char *env_paths)
{
if (!ns) return;
if (!ns) {
LD_LOGW("ns_set_env_paths failed,ns is NULL!\n");
return;
}
if (ns->env_paths) free(ns->env_paths);
if (env_paths) {
ns->env_paths = strdup(env_paths);
......@@ -185,11 +230,15 @@ void ns_set_env_paths(ns_t *ns, const char *env_paths)
} else {
ns->env_paths = NULL;
}
LD_LOGD("ns_set_env_paths ns[%s] env_paths:%s.\n", ns->ns_name, ns->env_paths);
}
void ns_set_lib_paths(ns_t *ns, const char *lib_paths)
{
if (!ns) return;
if (!ns) {
LD_LOGW("ns_set_lib_paths failed,ns is NULL!\n");
return;
}
if (ns->lib_paths) free(ns->lib_paths);
if (lib_paths) {
ns->lib_paths = strdup(lib_paths);
......@@ -197,24 +246,75 @@ void ns_set_lib_paths(ns_t *ns, const char *lib_paths)
} else {
ns->lib_paths = NULL;
}
LD_LOGD("ns_set_lib_paths ns[%s] lib_paths:%s.\n", ns->ns_name, ns->lib_paths);
}
void ns_set_permitted_paths(ns_t *ns,const char *permitted_paths)
void ns_set_asan_lib_paths(ns_t *ns, const char *asan_lib_paths)
{
if (!ns) return;
if (!ns) {
LD_LOGW("ns_set_asan_lib_paths failed,ns is NULL!\n");
return;
}
if (ns->asan_lib_paths) {
free(ns->asan_lib_paths);
}
if (asan_lib_paths) {
ns->asan_lib_paths = strdup(asan_lib_paths);
strtrim(ns->asan_lib_paths);
} else {
ns->asan_lib_paths = NULL;
}
LD_LOGD("ns_set_asan_lib_paths ns[%s] asan_lib_paths:%s.\n", ns->ns_name, ns->asan_lib_paths);
}
void ns_set_permitted_paths(ns_t *ns, const char *permitted_paths)
{
if (!ns) {
LD_LOGW("ns_set_permitted_paths failed,ns is NULL!\n");
return;
}
if (ns->permitted_paths) strlist_free(ns->permitted_paths);
ns->permitted_paths = strsplit(permitted_paths,":");
#if (LD_LOG_LEVEL & LD_LOG_DEBUG)
for (size_t i = 0; i < ns->permitted_paths->num; i++) {
LD_LOGD("ns_set_permitted_paths ns[%s] permitted_paths[%d]:%s.\n", ns->ns_name, i, ns->permitted_paths[i]);
}
#endif
}
void ns_set_separated(ns_t *ns,bool separated)
void ns_set_asan_permitted_paths(ns_t *ns, const char *asan_permitted_paths)
{
if (!ns) return;
if (!ns) {
LD_LOGW("ns_set_asan_permitted_paths failed,ns is NULL!\n");
return;
}
if (ns->asan_permitted_paths) {
strlist_free(ns->asan_permitted_paths);
}
ns->asan_permitted_paths = strsplit(asan_permitted_paths, ":");
#if (LD_LOG_LEVEL & LD_LOG_DEBUG)
for (size_t i = 0; i < ns->asan_permitted_paths->num; i++) {
LD_LOGD("ns_set_asan_permitted_paths ns[%s] asan_permitted_paths[%d]:%s.\n", ns->ns_name, i, ns->asan_permitted_paths[i]);
}
#endif
}
void ns_set_separated(ns_t *ns, bool separated)
{
if (!ns) {
LD_LOGW("ns_set_separated failed,ns is NULL!\n");
return;
}
ns->separated = separated;
LD_LOGD("ns_set_separated ns[%s] separated:%d.\n", ns->ns_name, ns->separated);
}
void ns_set_allowed_libs(ns_t *ns, const char *allowed_libs)
{
if (!ns) return;
if (!ns) {
LD_LOGW("ns_set_allowed_libs failed,ns is NULL!\n");
return;
}
if (ns->allowed_libs) strlist_free(ns->allowed_libs);
ns->allowed_libs = NULL;
......@@ -224,42 +324,61 @@ void ns_set_allowed_libs(ns_t *ns, const char *allowed_libs)
if (strtrim(a_libs) > 0) ns->allowed_libs = strsplit(a_libs,":");
free(a_libs);
}
LD_LOGD("ns_set_allowed_libs ns[%s] allowed_libs:%s.\n", ns->ns_name, ns->allowed_libs);
}
ns_t *find_ns_by_name(const char *ns_name)
{
if (!ns_name) return NULL;
if (strcmp(NS_DEFAULT_NAME, ns_name)==0) return get_default_ns();
if (!ns_name) {
LD_LOGW("find_ns_by_name failed,ns_name is NULL!\n");
return NULL;
}
if (strcmp(NS_DEFAULT_NAME, ns_name)==0) {
LD_LOGD("find_ns_by_name return default namespace!\n");
return get_default_ns();
}
for (size_t i=0; i< g_ns_list.num; i++) {
if (strcmp(g_ns_list.nss[i]->ns_name, ns_name)==0) {
return g_ns_list.nss[i];
}
}
LD_LOGD("find_ns_by_name ns_name[%s] failed,return NULL!\n", ns_name);
return NULL;
}
static ns_inherit *find_ns_inherit(ns_t *ns, ns_t *inherited)
{
if (!ns||!inherited) return NULL;
if (!ns||!inherited) {
LD_LOGW("find_ns_inherit failed,ns or inherited is NULL!\n");
return NULL;
}
if (ns->ns_inherits) {
for (size_t i=0; i<ns->ns_inherits->num; i++) {
if (ns->ns_inherits->inherits[i]->inherited_ns == inherited) return ns->ns_inherits->inherits[i];
}
}
LD_LOGD("find_ns_inherit ns[%s] ns_inherited[%s] failed,return NULL!\n", ns->ns_name, inherited->ns_name);
return NULL;
}
void ns_add_inherit(ns_t *ns, ns_t *ns_inherited, const char *shared_libs)
{
bool need_add = false;
if (!ns||!ns_inherited) return;
if (!ns||!ns_inherited) {
LD_LOGW("ns_add_inherit failed,ns or inherited is NULL!\n");
return;
}
ns_inherit *inherit = find_ns_inherit(ns, ns_inherited);
if (!inherit) {
inherit = calloc(1, sizeof *inherit);
if (!inherit) return;
if (!inherit) {
LD_LOGW("ns_add_inherit ns[%s] ns_inherited[%s] calloc failed!\n", ns->ns_name, ns_inherited->ns_name);
return;
}
inherit->inherited_ns = ns_inherited;
need_add = true;
LD_LOGD("ns_add_inherit ns[%s] ns_inherited[%s] need_add is true.\n", ns->ns_name, ns_inherited->ns_name);
}
if (inherit->shared_libs) {
......@@ -274,7 +393,10 @@ void ns_add_inherit(ns_t *ns, ns_t *ns_inherited, const char *shared_libs)
free(s_libs);
}
if (!need_add) return;
if (!need_add) {
LD_LOGD("ns_add_inherit ns[%s] ns_inherited[%s] not need_add!\n", ns->ns_name, ns_inherited->ns_name);
return;
}
if (!ns->ns_inherits) {
ns->ns_inherits = nsinherits_alloc();
......@@ -282,21 +404,27 @@ void ns_add_inherit(ns_t *ns, ns_t *ns_inherited, const char *shared_libs)
if (!ns->ns_inherits) {
if (inherit->shared_libs) strlist_free(inherit->shared_libs);
LD_LOGD("ns_add_inherit ns[%s] ns_inherited[%s] nsinherits_alloc failed!\n",
ns->ns_name, ns_inherited->ns_name);
free(inherit);
return;
}
if (ns->ns_inherits->num == ns->ns_inherits->size) {
/* if list is full, realloc size to double*/
LD_LOGD("ns_add_inherit ns[%s] ns_inherited[%s] list is full, realloc size to double!\n",
ns->ns_name, ns_inherited->ns_name);
nsinherits_realloc(ns->ns_inherits);
}
if (ns->ns_inherits->num < ns->ns_inherits->size) {
/* realloc succ */
LD_LOGD("ns_add_inherit ns[%s] ns_inherited[%s] realloc success!\n", ns->ns_name, ns_inherited->ns_name);
ns->ns_inherits->inherits[ns->ns_inherits->num] = inherit;
ns->ns_inherits->num++;
} else {
/* realloc failed */
LD_LOGD("ns_add_inherit ns[%s] ns_inherited[%s] realloc failed!\n", ns->ns_name, ns_inherited->ns_name);
if (inherit->shared_libs) strlist_free(inherit->shared_libs);
free(inherit);
}
......@@ -304,9 +432,10 @@ void ns_add_inherit(ns_t *ns, ns_t *ns_inherited, const char *shared_libs)
}
/* check library's pathname if accessible in this namespace */
bool is_accessible(ns_t *ns,const char *lib_pathname)
bool is_accessible(ns_t *ns, const char *lib_pathname, bool is_asan, bool check_inherited)
{
if (!ns->separated) {
if (check_inherited && !ns->separated) {
LD_LOGD("is_accessible ns [%s] is not separated, return true.\n", ns->ns_name);
return true;
}
if (ns->allowed_libs) {
......@@ -319,7 +448,11 @@ bool is_accessible(ns_t *ns,const char *lib_pathname)
break;
}
}
if (i >= ns->allowed_libs->num) return false;
if (i >= ns->allowed_libs->num) {
LD_LOGD("is_accessible ns [%s] lib_pathname [%s] is not in allowed_libs, return false.\n",
ns->ns_name, lib_pathname);
return false;
}
}
}
strlist *paths;
......@@ -329,6 +462,8 @@ bool is_accessible(ns_t *ns,const char *lib_pathname)
if (strncmp(lib_pathname, paths->strs[i], len) == 0 &&
lib_pathname[len] == '/' &&
!strchr(lib_pathname+len +1, '/')) {
LD_LOGD("is_accessible ns [%s] lib_pathname [%s] in env_paths, return true.\n",
ns->ns_name, lib_pathname);
strlist_free(paths);
return true;
}
......@@ -336,6 +471,14 @@ bool is_accessible(ns_t *ns,const char *lib_pathname)
strlist_free(paths);
}
if (is_asan) {
if (check_asan_path(ns, lib_pathname)) {
LD_LOGD("is_accessible ns [%s] lib_pathname [%s] check_asan_path success, return true.\n",
ns->ns_name, lib_pathname);
return true;
}
}
if (ns->lib_paths && (paths = strsplit(ns->lib_paths, ":"))) {
for (size_t i=0; i<paths->num; i++) {
size_t len = strlen(paths->strs[i]);
......@@ -343,22 +486,57 @@ bool is_accessible(ns_t *ns,const char *lib_pathname)
lib_pathname[len] == '/' &&
!strchr(lib_pathname+len +1, '/')) {
strlist_free(paths);
LD_LOGD("is_accessible ns [%s] lib_pathname [%s] in lib_paths, return true.\n",
ns->ns_name, lib_pathname);
return true;
}
}
strlist_free(paths);
strlist_free(paths);
}
if (ns->permitted_paths) {
if (ns->permitted_paths) {
for (size_t i=0; i<ns->permitted_paths->num; i++) {
size_t len = strlen(ns->permitted_paths->strs[i]);
if (strncmp(lib_pathname, ns->permitted_paths->strs[i], len) == 0 &&
lib_pathname[len] == '/') {
LD_LOGD("is_accessible ns [%s] lib_pathname [%s] in permitted_paths, return true.\n",
ns->ns_name, lib_pathname);
return true;
}
}
}
return false;
}
bool check_asan_path(ns_t *ns, const char *lib_pathname)
{
strlist *paths;
if (ns->asan_lib_paths && (paths = strsplit(ns->asan_lib_paths, ":"))) {
for (size_t i = 0; i < paths->num; i++) {
size_t len = strlen(paths->strs[i]);
if (strncmp(lib_pathname, paths->strs[i], len) == 0 &&
lib_pathname[len] == '/' &&
!strchr(lib_pathname+len +1, '/')) {
strlist_free(paths);
LD_LOGD("check_asan_path ns [%s] lib_pathname [%s] in asan_lib_paths, return true.\n",
ns->ns_name, lib_pathname);
return true;
}
}
strlist_free(paths);
}
if (ns->asan_permitted_paths) {
for (size_t i = 0; i < ns->asan_permitted_paths->num; i++) {
size_t len = strlen(ns->asan_permitted_paths->strs[i]);
if (strncmp(lib_pathname, ns->asan_permitted_paths->strs[i], len) == 0 &&
lib_pathname[len] == '/') {
LD_LOGD("check_asan_path ns [%s] lib_pathname [%s] in asan_permitted_paths, return true.\n",
ns->ns_name,lib_pathname);
return true;
}
}
}
LD_LOGD("check_asan_path ns [%s] lib_pathname [%s] failed, return false.\n", ns->ns_name, lib_pathname);
return false;
}
......@@ -367,10 +545,13 @@ bool is_sharable(ns_inherit *inherit, const char *lib_name)
if (inherit && lib_name && inherit->shared_libs) {
for (size_t i=0; i<inherit->shared_libs->num; i++) {
if (strcmp(inherit->shared_libs->strs[i], lib_name)==0) {
LD_LOGD("is_sharable inherit [%s] lib_name [%s] found, return true.\n", inherit->inherited_ns->ns_name, lib_name);
return true;
}
}
LD_LOGD("is_sharable inherit [%s] lib_name [%s] not found, return false.\n", inherit->inherited_ns->ns_name, lib_name);
return false;
}
LD_LOGD("is_sharable shared_libs not config, return true.\n");
return true;
}
......@@ -22,7 +22,10 @@ typedef struct _namespace_t_ {
char *ns_name; /* namespace name */
char *env_paths; /* value of LD_LIBRARY_PATH. splited by ':'. */
char *lib_paths; /* library search paths splited by ':'. */
char *asan_lib_paths; /* when asan is enable, library search paths splited by ':'. */
strlist *permitted_paths; /* when separated, permitted search paths splited by ':', including sub dirs. */
strlist *asan_permitted_paths; /* when asan is enable and separated,the same as above. */
bool separated; /* if separated */
strlist *allowed_libs; /* when separated, allowed library names splited by ':'. */
......@@ -56,10 +59,11 @@ void ns_free(ns_t *ns);
void ns_set_name(ns_t *ns, const char *name);
void ns_set_env_paths(ns_t *ns, const char *env_paths);
void ns_set_lib_paths(ns_t *ns, const char *lib_paths);
void ns_set_asan_lib_paths(ns_t *ns, const char *asan_lib_paths);
void ns_set_permitted_paths(ns_t *ns, const char *permitted_paths);
void ns_set_asan_permitted_paths(ns_t *ns, const char *asan_permitted_paths);
void ns_set_separated(ns_t *ns, bool separated);
void ns_set_allowed_libs(ns_t *ns, const char *allowed_libs);
void ns_add_dso(ns_t *ns, struct dso *dso);
void nslist_add_ns(ns_t *ns);
void ns_add_inherit(ns_t *ns,ns_t *inherited, const char *shared_libs);
......@@ -68,7 +72,10 @@ void ns_add_inherit(ns_t *ns,ns_t *inherited, const char *shared_libs);
ns_t *get_default_ns();
/* check if library pathname is accessible in the namespace */
bool is_accessible(ns_t *ns, const char *lib_pathname);
bool is_accessible(ns_t *ns, const char *lib_pathname, bool is_asan, bool check_inherited);
/* check if asan_lib_paths or asan_permitted_paths pathname is accessible in the namespace */
bool check_asan_path(ns_t *ns, const char *lib_pathname);
/* check if library is sharable in the inherited namespace */
bool is_sharable(ns_inherit *inherit, const char *lib_name);
......
......@@ -4,11 +4,12 @@
@author yangwenjun
@brief deal with ld-musl-namespace.ini file
*/
#include "ns_config.h"
#include <ctype.h>
#include <stdarg.h>
#include "ns_config.h"
#include "ld_log.h"
/*---------------------------- Defines -------------------------------------*/
#define MAX_LINE_SIZE (1024)
#define INI_INVALID_KEY ((char*)-1)
......@@ -48,11 +49,11 @@ static int (*config_error_callback)(const char *, ...) = default_error_callback;
static void config_set_error_callback(int (*errback)(const char *, ...))
{
if (errback) {
config_error_callback = errback;
} else {
config_error_callback = default_error_callback;
}
if (errback) {
config_error_callback = errback;
} else {
config_error_callback = default_error_callback;
}
}
static line_status config_line(char *line, char *section, char *key, char *value)
......@@ -342,17 +343,22 @@ static section_list *config_load(const char *filepath)
static ns_configor g_configor;
/* const define */
#define CONFIG_DEFAULT_FILE "/etc/ld-musl-namespace.ini" /* default config file pathname */
#define CONFIG_DEFAULT_FILE "/etc/ld-musl-namespace-arm.ini" /* default config file pathname */
#define SECTION_DIR_MAP "section.dir.map" /* map of section and directory of app */
#define ATTR_NS_PREFIX "namespace" /* prefix of namespace attribute */
#define ATTR_NS_ASAN "asan" /* asan */
#define ATTR_NS_LIB_PATHS "lib.paths" /* library search paths */
#define ATTR_NS_PERMITTED_PATHS "permitted.paths" /* when separated, permitted dir paths of libs, including sub dirs */
#define ATTR_NS_INHERITS "inherits" /* inherited namespace */
#define ATTR_NS_SEPARATED "separated" /* if separated */
#define ATTR_ADDED_NSLIST "added.nslist" /* all namespace names except default */
#define ATTR_NS_DEFAULT "default" /* default namespace name */
#define ATTR_NS_ACQUIESCENCE "acquiescence" /* acquiescence section name */
#define ATTR_NS_ALLOWED_LIBS "allowed.libs" /* when separated, allowed library names */
#define ATTR_NS_INHERIT_SHARED_LIBS "shared.libs" /* when inherited, shared library names */
#define SECTION_DIR_MAP_SYSTEM "system" /* system path */
#define SECTION_DIR_MAP_ASAN_SYSTEM "asan_system" /* asan system path */
/* get key-value list of section */
static kvlist *config_get_kvs(const char *sname)
{
......@@ -364,10 +370,106 @@ static kvlist *config_get_kvs(const char *sname)
}
return NULL;
}
/* get value by acquiescence */
static char *config_get_value_by_acquiescence(kvlist *acquiescence_kvs, const char *key)
{
if (!acquiescence_kvs) {
LD_LOGW("config_get_value_by_acquiescence acquiescence_kvs is NULL!\n");
return NULL;
}
size_t i;
for (i=0; i<acquiescence_kvs->num; i++) {
if (!strcmp(acquiescence_kvs->key[i], key)) {
return acquiescence_kvs->val[i];
}
}
return NULL;
}
/* get value by acquiescence lib path */
static char *config_get_acquiescence_lib_path(kvlist *acquiescence_kvs)
{
if (!acquiescence_kvs) {
LD_LOGW("config_get_acquiescence_lib_path acquiescence_kvs is NULL!\n");
return NULL;
}
config_key_join(ATTR_NS_PREFIX, true);
config_key_join(".", false);
config_key_join(ATTR_NS_DEFAULT, false);
config_key_join(".", false);
char *key = config_key_join(ATTR_NS_LIB_PATHS, false);
return config_get_value_by_acquiescence(acquiescence_kvs, key);
}
/* get value by acquiescence asan lib path */
static char *config_get_acquiescence_asan_lib_path(kvlist *acquiescence_kvs)
{
if (!acquiescence_kvs) {
LD_LOGW("config_get_acquiescence_asan_lib_path acquiescence_kvs is NULL!\n");
return NULL;
}
config_key_join(ATTR_NS_PREFIX, true);
config_key_join(".", false);
config_key_join(ATTR_NS_DEFAULT, false);
config_key_join(".", false);
config_key_join(ATTR_NS_ASAN, false);
config_key_join(".", false);
char *key = config_key_join(ATTR_NS_LIB_PATHS, false);
return config_get_value_by_acquiescence(acquiescence_kvs, key);
}
/* get value by key */
static char *config_get_value(const char *key)
{
if (!g_configor.kvs) {
LD_LOGW("config_get_value g_configor.kvs is NULL!\n");
return NULL;
}
size_t i;
for (i=0; i<g_configor.kvs->num; i++) {
if (!strcmp(g_configor.kvs->key[i], key)) return g_configor.kvs->val[i];
}
return NULL;
}
/* get library search paths */
static char *config_get_lib_paths(const char *ns_name)
{
if (ns_name == NULL) {
LD_LOGW("config_get_lib_paths ns_name is NULL!\n");
return NULL;
}
config_key_join(ATTR_NS_PREFIX, true);
config_key_join(".", false);
config_key_join(ns_name, false);
config_key_join(".", false);
char *key = config_key_join(ATTR_NS_LIB_PATHS, false);
return config_get_value(key);
}
/* get asan library search paths */
static char *config_get_asan_lib_paths(const char *ns_name)
{
if (ns_name == NULL) {
LD_LOGW("config_get_asan_lib_paths ns_name is NULL!\n");
return NULL;
}
config_key_join(ATTR_NS_PREFIX, true);
config_key_join(".", false);
config_key_join(ns_name, false);
config_key_join(".", false);
config_key_join(ATTR_NS_ASAN, false);
config_key_join(".", false);
char *key = config_key_join(ATTR_NS_LIB_PATHS, false);
return config_get_value(key);
}
/* parse config, success 0, failure <0 */
static int config_parse(const char *file_path, const char *exe_path)
{
kvlist* dirkvs;
kvlist* acquiescence_kvs;
if (!exe_path) return -1;
g_configor.exe_path = strdup(exe_path);
const char * fpath = CONFIG_DEFAULT_FILE;
......@@ -376,10 +478,17 @@ static int config_parse(const char *file_path, const char *exe_path)
g_configor.sections = config_load(fpath);
if (!g_configor.sections) {
LD_LOGE("config_parse load ini config fail!\n");
return -2;
}
dirkvs = config_get_kvs(SECTION_DIR_MAP);
if (!dirkvs) return -3; /* no section directory map found */
acquiescence_kvs = config_get_kvs(ATTR_NS_ACQUIESCENCE);
if (!dirkvs||!acquiescence_kvs) {
LD_LOGE("config_parse get dirkvs or acquiescence_kvs fail!\n");
return -3; /* no section directory map or acquiescence section found */
}
g_configor.config_sys_path = config_get_acquiescence_lib_path(acquiescence_kvs);
g_configor.config_asan_sys_path = config_get_acquiescence_asan_lib_path(acquiescence_kvs);
size_t i;
char * sname = NULL;
for (i=0; i<dirkvs->num; i++) {
......@@ -394,20 +503,30 @@ static int config_parse(const char *file_path, const char *exe_path)
strlist_free(paths);
if (sname) break;
}
if (!sname) return -4;/* no section found */
if (!(g_configor.kvs = config_get_kvs(sname))) return -5;/* no section key-value list found */
return 0;
}
/* get value by key */
static char *config_get_value(const char *key)
{
if (!g_configor.kvs) return NULL;
size_t i;
for (i=0; i<g_configor.kvs->num; i++) {
if (!strcmp(g_configor.kvs->key[i], key)) return g_configor.kvs->val[i];
if (!sname) {
LD_LOGW("config_parse no section found!\n");
return -4;/* no section found */
}
return NULL;
if (!(g_configor.kvs = config_get_kvs(sname))) {
LD_LOGW("config_parse no section key-value list found!\n");
return -5;/* no section key-value list found */
}
char *default_lib_paths = config_get_lib_paths(ATTR_NS_DEFAULT);
if (default_lib_paths) {
g_configor.config_sys_path = default_lib_paths;
} else {
LD_LOGW("config_parse get default lib paths fail! Config namespace default lib paths,please!\n");
}
char *default_asan_lib_paths = config_get_asan_lib_paths(ATTR_NS_DEFAULT);
if (default_asan_lib_paths) {
g_configor.config_asan_sys_path = default_asan_lib_paths;
} else {
LD_LOGW("config_parse get default asan lib paths fail! Config namespace default asan lib paths,please!\n");
}
return 0;
}
/* get namespace names except default */
static strlist *config_get_namespaces()
{
......@@ -415,29 +534,45 @@ static strlist *config_get_namespaces()
char *val = config_get_value(key);
return strsplit(val, ",");
}
/* get library search paths */
static char *config_get_lib_paths(const char *ns_name)
/* get permitted paths */
static char *config_get_permitted_paths(const char *ns_name)
{
if (ns_name == NULL) {
LD_LOGW("config_get_permitted_paths ns_name is NULL!\n");
return NULL;
}
config_key_join(ATTR_NS_PREFIX, true);
config_key_join(".", false);
config_key_join(ns_name, false);
config_key_join(".", false);
char *key = config_key_join(ATTR_NS_LIB_PATHS, false);
char *key = config_key_join(ATTR_NS_PERMITTED_PATHS, false);
return config_get_value(key);
}
/* get permitted paths */
static char *config_get_permitted_paths(const char *ns_name)
/* get asan permitted paths */
static char *config_get_asan_permitted_paths(const char *ns_name)
{
if (ns_name == NULL) {
LD_LOGW("config_get_asan_permitted_paths ns_name is NULL!\n");
return NULL;
}
config_key_join(ATTR_NS_PREFIX, true);
config_key_join(".", false);
config_key_join(ns_name, false);
config_key_join(".", false);
config_key_join(ATTR_NS_ASAN, false);
config_key_join(".", false);
char *key = config_key_join(ATTR_NS_PERMITTED_PATHS, false);
return config_get_value(key);
}
/* get inherited namespace names */
static strlist *config_get_inherits(const char *ns_name)
{
if (ns_name == NULL) {
LD_LOGW("config_get_inherits ns_name is NULL!\n");
return NULL;
}
config_key_join(ATTR_NS_PREFIX, true);
config_key_join(".", false);
config_key_join(ns_name, false);
......@@ -449,6 +584,10 @@ static strlist *config_get_inherits(const char *ns_name)
/* get separated */
static bool config_get_separated(const char *ns_name)
{
if (ns_name == NULL) {
LD_LOGW("config_get_separated ns_name is NULL!\n");
return false;
}
config_key_join(ATTR_NS_PREFIX, true);
config_key_join(".", false);
config_key_join(ns_name, false);
......@@ -459,9 +598,14 @@ static bool config_get_separated(const char *ns_name)
if (val && !strcmp("true", val)) return true;
return false; /* default false */
}
/* get allowed libs */
static char *config_get_allowed_libs(const char *ns_name)
{
if (ns_name == NULL) {
LD_LOGW("config_get_allowed_libs ns_name is NULL!\n");
return NULL;
}
config_key_join(ATTR_NS_PREFIX, true);
config_key_join(".", false);
config_key_join(ns_name, false);
......@@ -472,6 +616,11 @@ static char *config_get_allowed_libs(const char *ns_name)
/* get shared libs by inherited namespace */
static char *config_get_inherit_shared_libs(const char *ns_name, const char *inherited_ns_name)
{
if (ns_name == NULL || inherited_ns_name == NULL) {
LD_LOGW("config_get_inherit_shared_libs ns_name or inherited_ns_name is NULL!\n");
return NULL;
}
config_key_join(ATTR_NS_PREFIX, true);
config_key_join(".", false);
config_key_join(ns_name, false);
......@@ -482,6 +631,15 @@ static char *config_get_inherit_shared_libs(const char *ns_name, const char *inh
return config_get_value(key);
}
/* The call time is after parse */
static char *config_get_sys_paths(void)
{
return g_configor.config_sys_path;
}
static char *config_get_asan_sys_paths(void)
{
return g_configor.config_asan_sys_path;
}
ns_configor *configor_init()
{
memset(&g_configor, 0, sizeof g_configor);
......@@ -489,11 +647,17 @@ ns_configor *configor_init()
g_configor.parse = config_parse;
g_configor.get_namespaces = config_get_namespaces;
g_configor.get_lib_paths = config_get_lib_paths;
g_configor.get_asan_lib_paths = config_get_asan_lib_paths;
g_configor.get_permitted_paths = config_get_permitted_paths;
g_configor.get_asan_permitted_paths = config_get_asan_permitted_paths;
g_configor.get_separated = config_get_separated;
g_configor.get_inherits = config_get_inherits;
g_configor.get_allowed_libs = config_get_allowed_libs;
g_configor.get_inherit_shared_libs = config_get_inherit_shared_libs;
g_configor.get_sys_paths = config_get_sys_paths;
g_configor.get_asan_sys_paths = config_get_asan_sys_paths;
g_configor.config_sys_path = NULL; // init it in config_parse.
g_configor.config_asan_sys_path = NULL; // init it in config_parse.
return &g_configor;
}
......
......@@ -34,6 +34,8 @@ typedef struct _section_list_ {
typedef struct _ns_configor_ {
char *file_path;
char *exe_path;
char *config_sys_path;
char *config_asan_sys_path;
section_list *sections;
kvlist *kvs;
......@@ -41,11 +43,15 @@ typedef struct _ns_configor_ {
int (*parse)(const char *file_path, const char *exe_path);
strlist *(*get_namespaces)(void);
char *(*get_lib_paths)(const char *ns_name);
char *(*get_asan_lib_paths)(const char *ns_name);
char *(*get_permitted_paths)(const char *ns_name);
char *(*get_asan_permitted_paths)(const char *ns_name);
bool (*get_separated)(const char *ns_name);
strlist *(*get_inherits)(const char *ns_name);
char *(*get_allowed_libs)(const char *ns_name);
char *(*get_inherit_shared_libs)(const char *ns_name, const char *inherited_ns_name);
char *(*get_sys_paths)(void);
char *(*get_asan_sys_paths)(void);
} ns_configor;
ns_configor *configor_init();
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册