1 #include <sys/socket.h>
2 #include <fcntl.h>
3 #include <errno.h>
4 #include <dlfcn.h>
5 #include <stdint.h>
6 #include <stddef.h>
7 #include "syscall.h"
8 #ifdef OHOS_FDTRACK_HOOK_ENABLE
9 #include "musl_fdtrack_hook.h"
10 #endif
11
12 #if OHOS_PERMISSION_INTERNET
13 typedef uint8_t (*AllowFunc)(void);
14 static const char *LIB_NETSYS_CLIENT_NAME = "libnetsys_client.z.so";
15 static const char *ALLOW_SOCKET_FUNC_NAME = "IsAllowInternet";
16
17 /*
18 * Read a flag from netsys_client, there is only one place to set this flag, is the
19 * founction named DoStartup in startup_appspawn.
20 * */
is_allow_internet(void)21 uint8_t is_allow_internet(void)
22 {
23 static uint8_t first_time = 1;
24 static uint8_t allow = 1;
25
26 if (!first_time) {
27 return allow;
28 }
29
30 void *handler = dlopen(LIB_NETSYS_CLIENT_NAME, RTLD_LAZY);
31 if (handler != NULL) {
32 AllowFunc func = (AllowFunc)dlsym(handler, ALLOW_SOCKET_FUNC_NAME);
33 if (func != NULL && func() == 0) {
34 allow = 0;
35 }
36 dlclose(handler);
37 }
38 first_time = 0;
39 return allow;
40 }
41 #endif
42
43 #ifdef OHOS_SOCKET_HOOK_ENABLE
__libc_socket(int domain,int type,int protocol)44 int __libc_socket(int domain, int type, int protocol)
45 #else
46 int socket(int domain, int type, int protocol)
47 #endif
48 {
49 #if OHOS_PERMISSION_INTERNET
50 if ((domain == AF_INET || domain == AF_INET6) && is_allow_internet() == 0) {
51 errno = EPERM;
52 return -1;
53 }
54 #endif
55
56 int s = __socketcall(socket, domain, type, protocol, 0, 0, 0);
57 if ((s==-EINVAL || s==-EPROTONOSUPPORT)
58 && (type&(SOCK_CLOEXEC|SOCK_NONBLOCK))) {
59 s = __socketcall(socket, domain,
60 type & ~(SOCK_CLOEXEC|SOCK_NONBLOCK),
61 protocol, 0, 0, 0);
62 if (s < 0) return __syscall_ret(s);
63 if (type & SOCK_CLOEXEC)
64 __syscall(SYS_fcntl, s, F_SETFD, FD_CLOEXEC);
65 if (type & SOCK_NONBLOCK)
66 __syscall(SYS_fcntl, s, F_SETFL, O_NONBLOCK);
67 }
68 #ifdef OHOS_FDTRACK_HOOK_ENABLE
69 return FDTRACK_START_HOOK(__syscall_ret(s));
70 #endif
71 return __syscall_ret(s);
72 }
73