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