1 /*
2 * Copyright (c) 2022 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include <stdio.h>
17 #include <dlfcn.h>
18 #include <stdbool.h>
19 #include <stdlib.h>
20 #include <string.h>
21 #include <sys/prctl.h>
22 #include <sys/types.h>
23 #include <sys/stat.h>
24 #include <unistd.h>
25
26 static void* (*real_dlopen)(const char *file, int mode);
27 static bool g_isAsan = false;
28 static bool g_enableRandomDelay = false;
29
init(void)30 static void __attribute__((constructor)) init(void)
31 {
32 real_dlopen = dlsym(RTLD_NEXT, "dlopen");
33 FILE *mapsFile = fopen("/proc/self/maps", "r");
34 if (mapsFile != NULL) {
35 char *line = NULL;
36 size_t len = 0;
37 while (-1 != getline(&line, &len, mapsFile)) {
38 char *p = strstr(line, "/ld-musl-");
39 if (p && strstr(p, "-asan.so.1")) {
40 g_isAsan = true;
41 break;
42 }
43 }
44 free(line);
45 fclose(mapsFile);
46 }
47 char *env = getenv("LD_RANDOM_DELAY");
48 if ((env != NULL) && (env[0] == '1')) {
49 srand((unsigned)getpid());
50 g_enableRandomDelay = true;
51 }
52 }
53
dlopen(const char * file,int mode)54 void *dlopen(const char *file, int mode)
55 {
56 if (g_enableRandomDelay) {
57 /* randomly sleep 0-10ms */
58 usleep((useconds_t)rand() % 10000);
59 }
60 if (g_isAsan && file != NULL && file[0] == '/') {
61 char *f = NULL;
62 char *p = strchr(file + 1, '/');
63 asprintf(&f, "/data%s", (p ? p : file));
64 if (f == NULL) {
65 exit(1);
66 }
67 mode_t old = umask(0);
68 FILE *logFile = fopen("/dev/asan/dlopen.log", "a");
69 umask(old);
70 if (logFile != NULL) {
71 char name[16] = {0};
72 prctl(PR_GET_NAME, name);
73 fprintf(logFile, "[%d:%d](%s) dlopen %s --> %s\n", getpid(), gettid(), name, file, f);
74 fclose(logFile);
75 }
76 void *ret = real_dlopen(f, mode);
77 free(f);
78 f = NULL;
79 if (ret != NULL) {
80 return ret;
81 }
82 }
83 return real_dlopen(file, mode);
84 }
85