1570af302Sopenharmony_ci/* 2570af302Sopenharmony_ci * Copyright (c) 2022 Huawei Device Co., Ltd. 3570af302Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4570af302Sopenharmony_ci * you may not use this file except in compliance with the License. 5570af302Sopenharmony_ci * You may obtain a copy of the License at 6570af302Sopenharmony_ci * 7570af302Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8570af302Sopenharmony_ci * 9570af302Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10570af302Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 11570af302Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12570af302Sopenharmony_ci * See the License for the specific language governing permissions and 13570af302Sopenharmony_ci * limitations under the License. 14570af302Sopenharmony_ci */ 15570af302Sopenharmony_ci 16570af302Sopenharmony_ci#include "namespace.h" 17570af302Sopenharmony_ci 18570af302Sopenharmony_ci#include "ld_log.h" 19570af302Sopenharmony_ci#include "strops.h" 20570af302Sopenharmony_ci 21570af302Sopenharmony_cistatic ns_t g_ns_default; 22570af302Sopenharmony_cistatic nslist g_ns_list; 23570af302Sopenharmony_ci 24570af302Sopenharmony_ci#ifndef NSLIST_DEFAULT_SIZE 25570af302Sopenharmony_ci#define NSLIST_DEFAULT_SIZE 16 26570af302Sopenharmony_ci#endif 27570af302Sopenharmony_ci#ifndef DSOLIST_DEFAULT_SIZE 28570af302Sopenharmony_ci#define DSOLIST_DEFAULT_SIZE 16 29570af302Sopenharmony_ci#endif 30570af302Sopenharmony_ci#ifndef INHERIT_DEFAULT_SIZE 31570af302Sopenharmony_ci#define INHERIT_DEFAULT_SIZE 16 32570af302Sopenharmony_ci#endif 33570af302Sopenharmony_ci 34570af302Sopenharmony_ci#ifdef UNIT_TEST_STATIC 35570af302Sopenharmony_ci #define UT_STATIC 36570af302Sopenharmony_ci#else 37570af302Sopenharmony_ci #define UT_STATIC static 38570af302Sopenharmony_ci#endif 39570af302Sopenharmony_ci 40570af302Sopenharmony_ci#define ALLOW_ALL_SHARED_LIBS "allow_all_shared_libs" 41570af302Sopenharmony_ci 42570af302Sopenharmony_cistatic ns_inherit_list *nsinherits_alloc() 43570af302Sopenharmony_ci{ 44570af302Sopenharmony_ci ns_inherit_list *nsinl; 45570af302Sopenharmony_ci nsinl = (ns_inherit_list *)__libc_calloc(1, sizeof *nsinl); 46570af302Sopenharmony_ci 47570af302Sopenharmony_ci if (nsinl) { 48570af302Sopenharmony_ci nsinl->size = INHERIT_DEFAULT_SIZE; 49570af302Sopenharmony_ci nsinl->inherits = (ns_inherit **)__libc_calloc(INHERIT_DEFAULT_SIZE, sizeof *nsinl->inherits); 50570af302Sopenharmony_ci if (!nsinl->inherits) { 51570af302Sopenharmony_ci LD_LOGE("nsinherits_alloc failed,return NULL!"); 52570af302Sopenharmony_ci __libc_free(nsinl); 53570af302Sopenharmony_ci nsinl = NULL; 54570af302Sopenharmony_ci } 55570af302Sopenharmony_ci } 56570af302Sopenharmony_ci return nsinl; 57570af302Sopenharmony_ci} 58570af302Sopenharmony_ci 59570af302Sopenharmony_cistatic void nsinherits_free(ns_inherit_list *nsinl) 60570af302Sopenharmony_ci{ 61570af302Sopenharmony_ci if (!nsinl) { 62570af302Sopenharmony_ci return; 63570af302Sopenharmony_ci } 64570af302Sopenharmony_ci for (size_t i = 0; i < nsinl->num; i++) { 65570af302Sopenharmony_ci strlist_free(nsinl->inherits[i]->shared_libs); 66570af302Sopenharmony_ci __libc_free(nsinl->inherits[i]); 67570af302Sopenharmony_ci } 68570af302Sopenharmony_ci __libc_free(nsinl->inherits); 69570af302Sopenharmony_ci __libc_free(nsinl); 70570af302Sopenharmony_ci} 71570af302Sopenharmony_ci 72570af302Sopenharmony_ciUT_STATIC void nsinherits_realloc(ns_inherit_list *nsinl) 73570af302Sopenharmony_ci{ 74570af302Sopenharmony_ci if (!nsinl) { 75570af302Sopenharmony_ci return; 76570af302Sopenharmony_ci } 77570af302Sopenharmony_ci size_t size = 2 * nsinl->size; 78570af302Sopenharmony_ci if (size) { 79570af302Sopenharmony_ci ns_inherit **inherits; 80570af302Sopenharmony_ci inherits = (ns_inherit **)__libc_realloc(nsinl->inherits, size * (sizeof *nsinl->inherits)); 81570af302Sopenharmony_ci if (!inherits) { 82570af302Sopenharmony_ci LD_LOGE("nsinherits_realloc failed!"); 83570af302Sopenharmony_ci return; 84570af302Sopenharmony_ci } 85570af302Sopenharmony_ci nsinl->size = size; 86570af302Sopenharmony_ci nsinl->inherits = inherits; 87570af302Sopenharmony_ci } 88570af302Sopenharmony_ci return; 89570af302Sopenharmony_ci} 90570af302Sopenharmony_ci 91570af302Sopenharmony_cistatic dsolist *dsolist_alloc() 92570af302Sopenharmony_ci{ 93570af302Sopenharmony_ci dsolist *dsol; 94570af302Sopenharmony_ci dsol = (dsolist *)__libc_calloc(1, sizeof *dsol); 95570af302Sopenharmony_ci 96570af302Sopenharmony_ci if (dsol) { 97570af302Sopenharmony_ci dsol->size = DSOLIST_DEFAULT_SIZE; 98570af302Sopenharmony_ci dsol->dsos = (struct dso **)__libc_calloc(DSOLIST_DEFAULT_SIZE, sizeof *dsol->dsos); 99570af302Sopenharmony_ci if (!dsol->dsos) { 100570af302Sopenharmony_ci LD_LOGE("dsolist_alloc failed,return NULL!"); 101570af302Sopenharmony_ci __libc_free(dsol); 102570af302Sopenharmony_ci dsol = NULL; 103570af302Sopenharmony_ci } 104570af302Sopenharmony_ci } 105570af302Sopenharmony_ci return dsol; 106570af302Sopenharmony_ci} 107570af302Sopenharmony_ci 108570af302Sopenharmony_cistatic void dsolist_realloc(dsolist *dsol) 109570af302Sopenharmony_ci{ 110570af302Sopenharmony_ci if (!dsol) { 111570af302Sopenharmony_ci return; 112570af302Sopenharmony_ci } 113570af302Sopenharmony_ci size_t size = 2 * dsol->size; 114570af302Sopenharmony_ci if (size) { 115570af302Sopenharmony_ci struct dso **ds; 116570af302Sopenharmony_ci ds = (struct dso **)__libc_realloc(dsol->dsos, size * (sizeof *dsol->dsos)); 117570af302Sopenharmony_ci if (!ds) { 118570af302Sopenharmony_ci LD_LOGE("dsolist_realloc failed!"); 119570af302Sopenharmony_ci return; 120570af302Sopenharmony_ci } 121570af302Sopenharmony_ci dsol->size = size; 122570af302Sopenharmony_ci dsol->dsos = ds; 123570af302Sopenharmony_ci } 124570af302Sopenharmony_ci return; 125570af302Sopenharmony_ci} 126570af302Sopenharmony_ci 127570af302Sopenharmony_cins_t *ns_alloc() 128570af302Sopenharmony_ci{ 129570af302Sopenharmony_ci ns_t *nst = (ns_t *)__libc_calloc(1, sizeof *nst); 130570af302Sopenharmony_ci nst->ns_dsos = dsolist_alloc(); 131570af302Sopenharmony_ci if (!nst->ns_dsos) { 132570af302Sopenharmony_ci LD_LOGE("ns_alloc failed,return NULL!"); 133570af302Sopenharmony_ci __libc_free(nst); 134570af302Sopenharmony_ci nst = NULL; 135570af302Sopenharmony_ci } 136570af302Sopenharmony_ci return nst; 137570af302Sopenharmony_ci} 138570af302Sopenharmony_ci 139570af302Sopenharmony_civoid ns_free(ns_t *ns) 140570af302Sopenharmony_ci{ 141570af302Sopenharmony_ci if (!ns) { 142570af302Sopenharmony_ci return; 143570af302Sopenharmony_ci } 144570af302Sopenharmony_ci if (ns->ns_dsos) { 145570af302Sopenharmony_ci __libc_free(ns->ns_dsos); 146570af302Sopenharmony_ci ns->ns_dsos = NULL; 147570af302Sopenharmony_ci } 148570af302Sopenharmony_ci if (ns->ns_name) { 149570af302Sopenharmony_ci __libc_free(ns->ns_name); 150570af302Sopenharmony_ci ns->ns_name = NULL; 151570af302Sopenharmony_ci } 152570af302Sopenharmony_ci if (ns->env_paths) { 153570af302Sopenharmony_ci __libc_free(ns->env_paths); 154570af302Sopenharmony_ci ns->env_paths = NULL; 155570af302Sopenharmony_ci } 156570af302Sopenharmony_ci if (ns->lib_paths) { 157570af302Sopenharmony_ci __libc_free(ns->lib_paths); 158570af302Sopenharmony_ci ns->lib_paths = NULL; 159570af302Sopenharmony_ci } 160570af302Sopenharmony_ci if (ns->asan_lib_paths) { 161570af302Sopenharmony_ci __libc_free(ns->asan_lib_paths); 162570af302Sopenharmony_ci ns->asan_lib_paths = NULL; 163570af302Sopenharmony_ci } 164570af302Sopenharmony_ci strlist_free(ns->permitted_paths); 165570af302Sopenharmony_ci strlist_free(ns->asan_permitted_paths); 166570af302Sopenharmony_ci strlist_free(ns->allowed_libs); 167570af302Sopenharmony_ci nsinherits_free(ns->ns_inherits); 168570af302Sopenharmony_ci __libc_free(ns); 169570af302Sopenharmony_ci} 170570af302Sopenharmony_ci 171570af302Sopenharmony_civoid ns_add_dso(ns_t *ns, struct dso *dso) 172570af302Sopenharmony_ci{ 173570af302Sopenharmony_ci if (!ns || !dso) { 174570af302Sopenharmony_ci return; 175570af302Sopenharmony_ci } 176570af302Sopenharmony_ci if (!ns->ns_dsos) { 177570af302Sopenharmony_ci ns->ns_dsos = dsolist_alloc(); 178570af302Sopenharmony_ci } 179570af302Sopenharmony_ci if (!ns->ns_dsos) { 180570af302Sopenharmony_ci return; 181570af302Sopenharmony_ci } 182570af302Sopenharmony_ci if (ns->ns_dsos->num == ns->ns_dsos->size) { 183570af302Sopenharmony_ci /* if list is full, realloc size to double*/ 184570af302Sopenharmony_ci dsolist_realloc(ns->ns_dsos); 185570af302Sopenharmony_ci } 186570af302Sopenharmony_ci if (ns->ns_dsos->num < ns->ns_dsos->size) { 187570af302Sopenharmony_ci /* realloc succ */ 188570af302Sopenharmony_ci ns->ns_dsos->dsos[ns->ns_dsos->num] = dso; 189570af302Sopenharmony_ci ns->ns_dsos->num++; 190570af302Sopenharmony_ci } 191570af302Sopenharmony_ci return; 192570af302Sopenharmony_ci} 193570af302Sopenharmony_ci 194570af302Sopenharmony_cinslist *nslist_init() 195570af302Sopenharmony_ci{ 196570af302Sopenharmony_ci g_ns_list.size = NSLIST_DEFAULT_SIZE; 197570af302Sopenharmony_ci g_ns_list.num = 0; 198570af302Sopenharmony_ci g_ns_list.nss = (ns_t **)__libc_calloc(NSLIST_DEFAULT_SIZE, sizeof *g_ns_list.nss); 199570af302Sopenharmony_ci if (!g_ns_list.nss) { 200570af302Sopenharmony_ci LD_LOGE("nslist_init failed!"); 201570af302Sopenharmony_ci return NULL; 202570af302Sopenharmony_ci } 203570af302Sopenharmony_ci return &g_ns_list; 204570af302Sopenharmony_ci} 205570af302Sopenharmony_ci 206570af302Sopenharmony_cistatic void nslist_realloc() 207570af302Sopenharmony_ci{ 208570af302Sopenharmony_ci size_t size = 2 * g_ns_list.size; 209570af302Sopenharmony_ci if (size) { 210570af302Sopenharmony_ci ns_t **nss; 211570af302Sopenharmony_ci nss = (ns_t **)__libc_realloc(g_ns_list.nss, size * (sizeof *g_ns_list.nss)); 212570af302Sopenharmony_ci if (!nss) { 213570af302Sopenharmony_ci LD_LOGE("nslist_realloc failed!"); 214570af302Sopenharmony_ci return; 215570af302Sopenharmony_ci } 216570af302Sopenharmony_ci g_ns_list.size = size; 217570af302Sopenharmony_ci g_ns_list.nss = nss; 218570af302Sopenharmony_ci } 219570af302Sopenharmony_ci return; 220570af302Sopenharmony_ci} 221570af302Sopenharmony_ci 222570af302Sopenharmony_civoid nslist_add_ns(ns_t *ns) 223570af302Sopenharmony_ci{ 224570af302Sopenharmony_ci if (!ns) { 225570af302Sopenharmony_ci return; 226570af302Sopenharmony_ci } 227570af302Sopenharmony_ci 228570af302Sopenharmony_ci if (g_ns_list.num == g_ns_list.size) { 229570af302Sopenharmony_ci /* if list is full, realloc size to double*/ 230570af302Sopenharmony_ci nslist_realloc(); 231570af302Sopenharmony_ci } 232570af302Sopenharmony_ci if (g_ns_list.num < g_ns_list.size) { 233570af302Sopenharmony_ci /* realloc succ */ 234570af302Sopenharmony_ci g_ns_list.nss[g_ns_list.num] = ns; 235570af302Sopenharmony_ci g_ns_list.num++; 236570af302Sopenharmony_ci } 237570af302Sopenharmony_ci return; 238570af302Sopenharmony_ci} 239570af302Sopenharmony_ci 240570af302Sopenharmony_cins_t *get_default_ns() 241570af302Sopenharmony_ci{ 242570af302Sopenharmony_ci return &g_ns_default; 243570af302Sopenharmony_ci} 244570af302Sopenharmony_ci 245570af302Sopenharmony_ci/* set namespace attributes*/ 246570af302Sopenharmony_civoid ns_set_name(ns_t *ns, const char *name) 247570af302Sopenharmony_ci{ 248570af302Sopenharmony_ci if (!ns || !name) { 249570af302Sopenharmony_ci return; 250570af302Sopenharmony_ci } 251570af302Sopenharmony_ci if (ns->ns_name) __libc_free(ns->ns_name); 252570af302Sopenharmony_ci ns->ns_name = ld_strdup(name); 253570af302Sopenharmony_ci strtrim(ns->ns_name); 254570af302Sopenharmony_ci LD_LOGD("ns_set_name ns_name:%{public}s.", ns->ns_name); 255570af302Sopenharmony_ci} 256570af302Sopenharmony_ci 257570af302Sopenharmony_civoid ns_set_env_paths(ns_t *ns, const char *env_paths) 258570af302Sopenharmony_ci{ 259570af302Sopenharmony_ci if (!ns) { 260570af302Sopenharmony_ci return; 261570af302Sopenharmony_ci } 262570af302Sopenharmony_ci if (ns->env_paths) __libc_free(ns->env_paths); 263570af302Sopenharmony_ci if (env_paths) { 264570af302Sopenharmony_ci ns->env_paths = ld_strdup(env_paths); 265570af302Sopenharmony_ci strtrim(ns->env_paths); 266570af302Sopenharmony_ci } else { 267570af302Sopenharmony_ci ns->env_paths = NULL; 268570af302Sopenharmony_ci } 269570af302Sopenharmony_ci LD_LOGD("ns_set_env_paths ns[%{public}s] env_paths:%{public}s.", ns->ns_name, ns->env_paths); 270570af302Sopenharmony_ci} 271570af302Sopenharmony_ci 272570af302Sopenharmony_civoid ns_set_lib_paths(ns_t *ns, const char *lib_paths) 273570af302Sopenharmony_ci{ 274570af302Sopenharmony_ci if (!ns) { 275570af302Sopenharmony_ci return; 276570af302Sopenharmony_ci } 277570af302Sopenharmony_ci if (ns->lib_paths) __libc_free(ns->lib_paths); 278570af302Sopenharmony_ci if (lib_paths) { 279570af302Sopenharmony_ci ns->lib_paths = ld_strdup(lib_paths); 280570af302Sopenharmony_ci strtrim(ns->lib_paths); 281570af302Sopenharmony_ci } else { 282570af302Sopenharmony_ci ns->lib_paths = NULL; 283570af302Sopenharmony_ci } 284570af302Sopenharmony_ci LD_LOGD("ns_set_lib_paths ns[%{public}s] lib_paths:%{public}s.", ns->ns_name, ns->lib_paths); 285570af302Sopenharmony_ci} 286570af302Sopenharmony_ci 287570af302Sopenharmony_civoid ns_set_asan_lib_paths(ns_t *ns, const char *asan_lib_paths) 288570af302Sopenharmony_ci{ 289570af302Sopenharmony_ci if (!ns) { 290570af302Sopenharmony_ci return; 291570af302Sopenharmony_ci } 292570af302Sopenharmony_ci if (ns->asan_lib_paths) { 293570af302Sopenharmony_ci __libc_free(ns->asan_lib_paths); 294570af302Sopenharmony_ci } 295570af302Sopenharmony_ci if (asan_lib_paths) { 296570af302Sopenharmony_ci ns->asan_lib_paths = ld_strdup(asan_lib_paths); 297570af302Sopenharmony_ci strtrim(ns->asan_lib_paths); 298570af302Sopenharmony_ci } else { 299570af302Sopenharmony_ci ns->asan_lib_paths = NULL; 300570af302Sopenharmony_ci } 301570af302Sopenharmony_ci LD_LOGD("ns_set_asan_lib_paths ns[%{public}s] asan_lib_paths:%{public}s.", ns->ns_name, ns->asan_lib_paths); 302570af302Sopenharmony_ci} 303570af302Sopenharmony_ci 304570af302Sopenharmony_civoid ns_set_permitted_paths(ns_t *ns, const char *permitted_paths) 305570af302Sopenharmony_ci{ 306570af302Sopenharmony_ci if (!ns) { 307570af302Sopenharmony_ci return; 308570af302Sopenharmony_ci } 309570af302Sopenharmony_ci if (ns->permitted_paths) strlist_free(ns->permitted_paths); 310570af302Sopenharmony_ci ns->permitted_paths = strsplit(permitted_paths, ":"); 311570af302Sopenharmony_ci LD_LOGD("ns_set_permitted_paths ns[%{public}s] permitted_paths:%{public}s.", ns->ns_name, permitted_paths); 312570af302Sopenharmony_ci} 313570af302Sopenharmony_ci 314570af302Sopenharmony_civoid ns_set_asan_permitted_paths(ns_t *ns, const char *asan_permitted_paths) 315570af302Sopenharmony_ci{ 316570af302Sopenharmony_ci if (!ns) { 317570af302Sopenharmony_ci return; 318570af302Sopenharmony_ci } 319570af302Sopenharmony_ci if (ns->asan_permitted_paths) { 320570af302Sopenharmony_ci strlist_free(ns->asan_permitted_paths); 321570af302Sopenharmony_ci } 322570af302Sopenharmony_ci ns->asan_permitted_paths = strsplit(asan_permitted_paths, ":"); 323570af302Sopenharmony_ci LD_LOGD("ns_set_asan_permitted_paths ns[%{public}s] asan_permitted_paths:%{public}s.", 324570af302Sopenharmony_ci ns->ns_name, 325570af302Sopenharmony_ci asan_permitted_paths); 326570af302Sopenharmony_ci} 327570af302Sopenharmony_ci 328570af302Sopenharmony_civoid ns_set_separated(ns_t *ns, bool separated) 329570af302Sopenharmony_ci{ 330570af302Sopenharmony_ci if (!ns) { 331570af302Sopenharmony_ci return; 332570af302Sopenharmony_ci } 333570af302Sopenharmony_ci ns->separated = separated; 334570af302Sopenharmony_ci LD_LOGD("ns_set_separated ns[%{public}s] separated:%{public}d.", ns->ns_name, ns->separated); 335570af302Sopenharmony_ci} 336570af302Sopenharmony_ci 337570af302Sopenharmony_civoid ns_set_allowed_libs(ns_t *ns, const char *allowed_libs) 338570af302Sopenharmony_ci{ 339570af302Sopenharmony_ci if (!ns) { 340570af302Sopenharmony_ci return; 341570af302Sopenharmony_ci } 342570af302Sopenharmony_ci 343570af302Sopenharmony_ci if (ns->allowed_libs) strlist_free(ns->allowed_libs); 344570af302Sopenharmony_ci ns->allowed_libs = NULL; 345570af302Sopenharmony_ci if (allowed_libs) { 346570af302Sopenharmony_ci /* if setted and not empty, split to list. */ 347570af302Sopenharmony_ci char *a_libs = ld_strdup(allowed_libs); 348570af302Sopenharmony_ci if (strtrim(a_libs) > 0) ns->allowed_libs = strsplit(a_libs, ":"); 349570af302Sopenharmony_ci __libc_free(a_libs); 350570af302Sopenharmony_ci } 351570af302Sopenharmony_ci LD_LOGD("ns_set_allowed_libs ns[%{public}s] allowed_libs:%{public}s.", ns->ns_name, allowed_libs); 352570af302Sopenharmony_ci} 353570af302Sopenharmony_ci 354570af302Sopenharmony_cins_t *find_ns_by_name(const char *ns_name) 355570af302Sopenharmony_ci{ 356570af302Sopenharmony_ci if (!ns_name) { 357570af302Sopenharmony_ci return NULL; 358570af302Sopenharmony_ci } 359570af302Sopenharmony_ci if (strcmp(NS_DEFAULT_NAME, ns_name) == 0) { 360570af302Sopenharmony_ci LD_LOGD("find_ns_by_name return default namespace!"); 361570af302Sopenharmony_ci return get_default_ns(); 362570af302Sopenharmony_ci } 363570af302Sopenharmony_ci for (size_t i = 0; i < g_ns_list.num; i++) { 364570af302Sopenharmony_ci if (strcmp(g_ns_list.nss[i]->ns_name, ns_name) == 0) { 365570af302Sopenharmony_ci return g_ns_list.nss[i]; 366570af302Sopenharmony_ci } 367570af302Sopenharmony_ci } 368570af302Sopenharmony_ci LD_LOGD("find_ns_by_name ns_name[%{public}s] failed,return NULL!", ns_name); 369570af302Sopenharmony_ci return NULL; 370570af302Sopenharmony_ci} 371570af302Sopenharmony_ci 372570af302Sopenharmony_cistatic ns_inherit *find_ns_inherit(ns_t *ns, ns_t *inherited) 373570af302Sopenharmony_ci{ 374570af302Sopenharmony_ci if (!ns || !inherited) { 375570af302Sopenharmony_ci return NULL; 376570af302Sopenharmony_ci } 377570af302Sopenharmony_ci if (ns->ns_inherits) { 378570af302Sopenharmony_ci for (size_t i = 0; i < ns->ns_inherits->num; i++) { 379570af302Sopenharmony_ci if (ns->ns_inherits->inherits[i]->inherited_ns == inherited) return ns->ns_inherits->inherits[i]; 380570af302Sopenharmony_ci } 381570af302Sopenharmony_ci } 382570af302Sopenharmony_ci LD_LOGD( 383570af302Sopenharmony_ci "find_ns_inherit ns[%{public}s] ns_inherited[%{public}s] failed,return NULL!", ns->ns_name, inherited->ns_name); 384570af302Sopenharmony_ci return NULL; 385570af302Sopenharmony_ci} 386570af302Sopenharmony_ci 387570af302Sopenharmony_civoid ns_add_inherit(ns_t *ns, ns_t *ns_inherited, const char *shared_libs) 388570af302Sopenharmony_ci{ 389570af302Sopenharmony_ci bool need_add = false; 390570af302Sopenharmony_ci if (!ns || !ns_inherited) { 391570af302Sopenharmony_ci return; 392570af302Sopenharmony_ci } 393570af302Sopenharmony_ci 394570af302Sopenharmony_ci ns_inherit *inherit = find_ns_inherit(ns, ns_inherited); 395570af302Sopenharmony_ci if (!inherit) { 396570af302Sopenharmony_ci inherit = __libc_calloc(1, sizeof *inherit); 397570af302Sopenharmony_ci if (!inherit) { 398570af302Sopenharmony_ci LD_LOGE("ns_add_inherit ns[%{public}s] ns_inherited[%{public}s] calloc failed!", 399570af302Sopenharmony_ci ns->ns_name, 400570af302Sopenharmony_ci ns_inherited->ns_name); 401570af302Sopenharmony_ci return; 402570af302Sopenharmony_ci } 403570af302Sopenharmony_ci inherit->inherited_ns = ns_inherited; 404570af302Sopenharmony_ci need_add = true; 405570af302Sopenharmony_ci LD_LOGD("ns_add_inherit ns[%{public}s] ns_inherited[%{public}s] need_add is true.", 406570af302Sopenharmony_ci ns->ns_name, 407570af302Sopenharmony_ci ns_inherited->ns_name); 408570af302Sopenharmony_ci } 409570af302Sopenharmony_ci 410570af302Sopenharmony_ci if (inherit->shared_libs) { 411570af302Sopenharmony_ci strlist_free(inherit->shared_libs); 412570af302Sopenharmony_ci inherit->shared_libs = NULL; 413570af302Sopenharmony_ci } 414570af302Sopenharmony_ci 415570af302Sopenharmony_ci /* if setted and not empty, split to list. */ 416570af302Sopenharmony_ci if (shared_libs) { 417570af302Sopenharmony_ci char *s_libs = ld_strdup(shared_libs); 418570af302Sopenharmony_ci if (strtrim(s_libs) > 0) inherit->shared_libs = strsplit(shared_libs, ":"); 419570af302Sopenharmony_ci __libc_free(s_libs); 420570af302Sopenharmony_ci } 421570af302Sopenharmony_ci 422570af302Sopenharmony_ci if (!need_add) { 423570af302Sopenharmony_ci LD_LOGD( 424570af302Sopenharmony_ci "ns_add_inherit ns[%{public}s] ns_inherited[%{public}s] not need_add!", ns->ns_name, ns_inherited->ns_name); 425570af302Sopenharmony_ci return; 426570af302Sopenharmony_ci } 427570af302Sopenharmony_ci 428570af302Sopenharmony_ci if (!ns->ns_inherits) { 429570af302Sopenharmony_ci ns->ns_inherits = nsinherits_alloc(); 430570af302Sopenharmony_ci } 431570af302Sopenharmony_ci 432570af302Sopenharmony_ci if (!ns->ns_inherits) { 433570af302Sopenharmony_ci if (inherit->shared_libs) strlist_free(inherit->shared_libs); 434570af302Sopenharmony_ci LD_LOGD("ns_add_inherit ns[%{public}s] ns_inherited[%{public}s] nsinherits_alloc failed!", 435570af302Sopenharmony_ci ns->ns_name, 436570af302Sopenharmony_ci ns_inherited->ns_name); 437570af302Sopenharmony_ci __libc_free(inherit); 438570af302Sopenharmony_ci return; 439570af302Sopenharmony_ci } 440570af302Sopenharmony_ci 441570af302Sopenharmony_ci if (ns->ns_inherits->num == ns->ns_inherits->size) { 442570af302Sopenharmony_ci /* if list is full, realloc size to double*/ 443570af302Sopenharmony_ci LD_LOGD("ns_add_inherit ns[%{public}s] ns_inherited[%{public}s] list is full, realloc size to double!", 444570af302Sopenharmony_ci ns->ns_name, 445570af302Sopenharmony_ci ns_inherited->ns_name); 446570af302Sopenharmony_ci nsinherits_realloc(ns->ns_inherits); 447570af302Sopenharmony_ci } 448570af302Sopenharmony_ci 449570af302Sopenharmony_ci if (ns->ns_inherits->num < ns->ns_inherits->size) { 450570af302Sopenharmony_ci /* realloc succ */ 451570af302Sopenharmony_ci LD_LOGD("ns_add_inherit ns[%{public}s] ns_inherited[%{public}s] realloc success!", 452570af302Sopenharmony_ci ns->ns_name, 453570af302Sopenharmony_ci ns_inherited->ns_name); 454570af302Sopenharmony_ci ns->ns_inherits->inherits[ns->ns_inherits->num] = inherit; 455570af302Sopenharmony_ci ns->ns_inherits->num++; 456570af302Sopenharmony_ci } else { 457570af302Sopenharmony_ci /* realloc failed */ 458570af302Sopenharmony_ci LD_LOGD("ns_add_inherit ns[%{public}s] ns_inherited[%{public}s] realloc failed!", 459570af302Sopenharmony_ci ns->ns_name, 460570af302Sopenharmony_ci ns_inherited->ns_name); 461570af302Sopenharmony_ci if (inherit->shared_libs) strlist_free(inherit->shared_libs); 462570af302Sopenharmony_ci __libc_free(inherit); 463570af302Sopenharmony_ci } 464570af302Sopenharmony_ci return; 465570af302Sopenharmony_ci} 466570af302Sopenharmony_ci 467570af302Sopenharmony_ci/* check library's pathname if accessible in this namespace */ 468570af302Sopenharmony_cibool is_accessible(ns_t *ns, const char *lib_pathname, bool is_asan, bool check_inherited) 469570af302Sopenharmony_ci{ 470570af302Sopenharmony_ci if (check_inherited && !ns->separated) { 471570af302Sopenharmony_ci LD_LOGD("is_accessible ns [%{public}s] is not separated, return true.", ns->ns_name); 472570af302Sopenharmony_ci return true; 473570af302Sopenharmony_ci } 474570af302Sopenharmony_ci if (ns->allowed_libs) { 475570af302Sopenharmony_ci char *shortname = strrchr(lib_pathname, '/'); 476570af302Sopenharmony_ci if (shortname) { 477570af302Sopenharmony_ci shortname += 1; 478570af302Sopenharmony_ci size_t i = 0; 479570af302Sopenharmony_ci for (; i < ns->allowed_libs->num; i++) { 480570af302Sopenharmony_ci if (strcmp(shortname, ns->allowed_libs->strs[i]) == 0) { 481570af302Sopenharmony_ci break; 482570af302Sopenharmony_ci } 483570af302Sopenharmony_ci } 484570af302Sopenharmony_ci if (i >= ns->allowed_libs->num) { 485570af302Sopenharmony_ci LD_LOGD("is_accessible ns [%{public}s] lib_pathname [%{public}s] is not in allowed_libs, return false.", 486570af302Sopenharmony_ci ns->ns_name, 487570af302Sopenharmony_ci lib_pathname); 488570af302Sopenharmony_ci return false; 489570af302Sopenharmony_ci } 490570af302Sopenharmony_ci } 491570af302Sopenharmony_ci } 492570af302Sopenharmony_ci strlist *paths; 493570af302Sopenharmony_ci if (ns->env_paths && (paths = strsplit(ns->env_paths, ":"))) { 494570af302Sopenharmony_ci for (size_t i = 0; i < paths->num; i++) { 495570af302Sopenharmony_ci size_t len = strlen(paths->strs[i]); 496570af302Sopenharmony_ci if (strncmp(lib_pathname, paths->strs[i], len) == 0 && 497570af302Sopenharmony_ci lib_pathname[len] == '/' && 498570af302Sopenharmony_ci !strchr(lib_pathname + len + 1, '/')) { 499570af302Sopenharmony_ci LD_LOGD("is_accessible ns [%{public}s] lib_pathname [%{public}s] in env_paths, return true.", 500570af302Sopenharmony_ci ns->ns_name, 501570af302Sopenharmony_ci lib_pathname); 502570af302Sopenharmony_ci strlist_free(paths); 503570af302Sopenharmony_ci return true; 504570af302Sopenharmony_ci } 505570af302Sopenharmony_ci } 506570af302Sopenharmony_ci strlist_free(paths); 507570af302Sopenharmony_ci } 508570af302Sopenharmony_ci 509570af302Sopenharmony_ci if (is_asan) { 510570af302Sopenharmony_ci if (check_asan_path(ns, lib_pathname)) { 511570af302Sopenharmony_ci LD_LOGD("is_accessible ns [%{public}s] lib_pathname [%{public}s] check_asan_path success, return true.", 512570af302Sopenharmony_ci ns->ns_name, 513570af302Sopenharmony_ci lib_pathname); 514570af302Sopenharmony_ci return true; 515570af302Sopenharmony_ci } 516570af302Sopenharmony_ci } 517570af302Sopenharmony_ci 518570af302Sopenharmony_ci if (ns->lib_paths && (paths = strsplit(ns->lib_paths, ":"))) { 519570af302Sopenharmony_ci for (size_t i = 0; i < paths->num; i++) { 520570af302Sopenharmony_ci size_t len = strlen(paths->strs[i]); 521570af302Sopenharmony_ci if (strncmp(lib_pathname, paths->strs[i], len) == 0 && 522570af302Sopenharmony_ci lib_pathname[len] == '/' && 523570af302Sopenharmony_ci !strchr(lib_pathname + len + 1, '/')) { 524570af302Sopenharmony_ci strlist_free(paths); 525570af302Sopenharmony_ci LD_LOGD("is_accessible ns [%{public}s] lib_pathname [%{public}s] in lib_paths, return true.", 526570af302Sopenharmony_ci ns->ns_name, 527570af302Sopenharmony_ci lib_pathname); 528570af302Sopenharmony_ci return true; 529570af302Sopenharmony_ci } 530570af302Sopenharmony_ci } 531570af302Sopenharmony_ci strlist_free(paths); 532570af302Sopenharmony_ci } 533570af302Sopenharmony_ci 534570af302Sopenharmony_ci if (ns->permitted_paths) { 535570af302Sopenharmony_ci for (size_t i = 0; i < ns->permitted_paths->num; i++) { 536570af302Sopenharmony_ci size_t len = strlen(ns->permitted_paths->strs[i]); 537570af302Sopenharmony_ci if (strncmp(lib_pathname, ns->permitted_paths->strs[i], len) == 0 && 538570af302Sopenharmony_ci lib_pathname[len] == '/') { 539570af302Sopenharmony_ci LD_LOGD("is_accessible ns [%{public}s] lib_pathname [%{public}s] in permitted_paths, return true.", 540570af302Sopenharmony_ci ns->ns_name, 541570af302Sopenharmony_ci lib_pathname); 542570af302Sopenharmony_ci return true; 543570af302Sopenharmony_ci } 544570af302Sopenharmony_ci } 545570af302Sopenharmony_ci } 546570af302Sopenharmony_ci return false; 547570af302Sopenharmony_ci} 548570af302Sopenharmony_ci 549570af302Sopenharmony_cibool check_asan_path(ns_t *ns, const char *lib_pathname) 550570af302Sopenharmony_ci{ 551570af302Sopenharmony_ci strlist *paths; 552570af302Sopenharmony_ci if (ns->asan_lib_paths && (paths = strsplit(ns->asan_lib_paths, ":"))) { 553570af302Sopenharmony_ci for (size_t i = 0; i < paths->num; i++) { 554570af302Sopenharmony_ci size_t len = strlen(paths->strs[i]); 555570af302Sopenharmony_ci if (strncmp(lib_pathname, paths->strs[i], len) == 0 && 556570af302Sopenharmony_ci lib_pathname[len] == '/' && 557570af302Sopenharmony_ci !strchr(lib_pathname + len + 1, '/')) { 558570af302Sopenharmony_ci strlist_free(paths); 559570af302Sopenharmony_ci LD_LOGD("check_asan_path ns [%{public}s] lib_pathname [%{public}s] in asan_lib_paths, return true.", 560570af302Sopenharmony_ci ns->ns_name, 561570af302Sopenharmony_ci lib_pathname); 562570af302Sopenharmony_ci return true; 563570af302Sopenharmony_ci } 564570af302Sopenharmony_ci } 565570af302Sopenharmony_ci strlist_free(paths); 566570af302Sopenharmony_ci } 567570af302Sopenharmony_ci if (ns->asan_permitted_paths) { 568570af302Sopenharmony_ci for (size_t i = 0; i < ns->asan_permitted_paths->num; i++) { 569570af302Sopenharmony_ci size_t len = strlen(ns->asan_permitted_paths->strs[i]); 570570af302Sopenharmony_ci if (strncmp(lib_pathname, ns->asan_permitted_paths->strs[i], len) == 0 && 571570af302Sopenharmony_ci lib_pathname[len] == '/') { 572570af302Sopenharmony_ci LD_LOGD( 573570af302Sopenharmony_ci "check_asan_path ns [%{public}s] lib_pathname [%{public}s] in asan_permitted_paths, return true.", 574570af302Sopenharmony_ci ns->ns_name, 575570af302Sopenharmony_ci lib_pathname); 576570af302Sopenharmony_ci return true; 577570af302Sopenharmony_ci } 578570af302Sopenharmony_ci } 579570af302Sopenharmony_ci } 580570af302Sopenharmony_ci LD_LOGD( 581570af302Sopenharmony_ci "check_asan_path ns [%{public}s] lib_pathname [%{public}s] failed, return false.", ns->ns_name, lib_pathname); 582570af302Sopenharmony_ci return false; 583570af302Sopenharmony_ci} 584570af302Sopenharmony_ci 585570af302Sopenharmony_cibool is_sharable(ns_inherit *inherit, const char *lib_name) 586570af302Sopenharmony_ci{ 587570af302Sopenharmony_ci if (inherit && lib_name && inherit->shared_libs) { 588570af302Sopenharmony_ci for (size_t i = 0; i < inherit->shared_libs->num; i++) { 589570af302Sopenharmony_ci if (strcmp(inherit->shared_libs->strs[i], lib_name) == 0 || 590570af302Sopenharmony_ci strcmp(inherit->shared_libs->strs[i], ALLOW_ALL_SHARED_LIBS) == 0) { 591570af302Sopenharmony_ci LD_LOGD("is_sharable inherit [%{public}s] lib_name [%{public}s] found, return true.", 592570af302Sopenharmony_ci inherit->inherited_ns->ns_name, 593570af302Sopenharmony_ci lib_name); 594570af302Sopenharmony_ci return true; 595570af302Sopenharmony_ci } 596570af302Sopenharmony_ci } 597570af302Sopenharmony_ci LD_LOGD("is_sharable inherit [%{public}s] lib_name [%{public}s] not found, return false.", 598570af302Sopenharmony_ci inherit->inherited_ns->ns_name, 599570af302Sopenharmony_ci lib_name); 600570af302Sopenharmony_ci return false; 601570af302Sopenharmony_ci } 602570af302Sopenharmony_ci LD_LOGD("is_sharable shared_libs not config, return true."); 603570af302Sopenharmony_ci return true; 604570af302Sopenharmony_ci} 605570af302Sopenharmony_ci 606570af302Sopenharmony_civoid ns_set_flag(ns_t *ns, int flag) 607570af302Sopenharmony_ci{ 608570af302Sopenharmony_ci if (!ns) { 609570af302Sopenharmony_ci return; 610570af302Sopenharmony_ci } 611570af302Sopenharmony_ci ns->flag = flag; 612570af302Sopenharmony_ci LD_LOGD("ns_set_flag ns[%{public}s] flag:%{public}d.", ns->ns_name, ns->flag); 613570af302Sopenharmony_ci}