提交 e7e5c198 编写于 作者: L liyufan

fixed 5b277aab from https://gitee.com/liyufan123/third_party_musl/pulls/768

Add the socket hook function to enable the app to bind to the network

Issue:#I6AIDJ
Test: Build & Boot devices
Signed-off-by: Nliyufan <liyufan5@huawei.com>
上级 43df22c5
......@@ -2072,6 +2072,7 @@ musl_src_porting_file = [
"src/malloc/malloc_random.c",
"src/multibyte/wcsnrtombs.c",
"src/network/inet_legacy.c",
"src/network/socket.c",
"src/passwd/getspnam_r.c",
"src/sched/sched_setparam.c",
"src/sched/sched_getparam.c",
......
......@@ -125,7 +125,10 @@ template("musl_libs") {
]
if (!is_asan) {
cflags_auto += [ "-DHOOK_ENABLE" ]
cflags_auto += [
"-DHOOK_ENABLE",
"-DOHOS_SOCKET_HOOK_ENABLE",
]
}
cflags_auto += [ "-DRESERVE_SIGNAL_STACK" ]
......@@ -195,7 +198,10 @@ template("musl_libs") {
]
if (!is_asan) {
defines += [ "HOOK_ENABLE" ]
defines += [
"HOOK_ENABLE",
"OHOS_SOCKET_HOOK_ENABLE",
]
}
ldflags = [ "-nostdlib" ]
......@@ -700,6 +706,9 @@ template("musl_libs") {
"./porting/linux/user/src/hook/memory_tag.c",
"./porting/linux/user/src/hook/musl_preinit.c",
"./porting/linux/user/src/hook/musl_preinit_common.c",
"./porting/linux/user/src/hook/musl_socket_preinit.c",
"./porting/linux/user/src/hook/musl_socket_preinit_common.c",
"./porting/linux/user/src/hook/socket_common.c",
]
deps = [
......
#ifndef _MUSL_SOCKET_H
#define _MUSL_SOCKET_H
#include <sys/socket.h>
#ifdef __cplusplus
extern "C" {
#endif
#ifdef OHOS_SOCKET_HOOK_ENABLE
#define MuslSocket(func) __libc_ ## func
int __libc_socket(int, int, int);
#else
#define MuslSocket(func) func
#endif
#ifdef __cplusplus
}
#endif
#endif
\ No newline at end of file
#ifndef _MUSL_SOCKET_DISPATCH_H
#define _MUSL_SOCKET_DISPATCH_H
#include <stdbool.h>
#ifdef __cplusplus
extern "C" {
#endif
typedef int (*SocketSocketType)(int, int, int);
typedef bool (*SocketGetHookFlagType)();
typedef bool (*SocketSetHookFlagType)(bool);
struct SocketDispatchType
{
SocketSocketType socket;
SocketGetHookFlagType get_hook_flag;
SocketSetHookFlagType set_hook_flag;
};
#ifdef __cplusplus
}
#endif
#endif
\ No newline at end of file
#ifdef OHOS_SOCKET_HOOK_ENABLE
#include <unistd.h>
#include <signal.h>
#include <stdlib.h>
#include <limits.h>
#include <dlfcn.h>
#include <errno.h>
#include <ctype.h>
#include <assert.h>
#include <string.h>
#include <stdio.h>
#include "musl_socket_preinit_common.h"
static char *__socket_hook_shared_lib = "libfwmark_client.z.so";
static char *__socket_hook_function_prefix = "ohos_socket_hook";
void* shared_lib_func[LAST_FUNC];
long long __ohos_socket_hook_shared_library;
typedef bool (*init_func_type)(const struct SocketDispatchType*, bool*, const char*);
typedef void (*finalize_func_type)();
#define MAX_SYMBOL_SIZE 1000
static bool init_socket_function(void* shared_library_handler, SocketSocketType* func)
{
char symbol[MAX_SYMBOL_SIZE];
(void)snprintf(symbol, sizeof(symbol), "%s_%s", __socket_hook_function_prefix, "socket");
*func = (SocketSocketType)(dlsym(shared_library_handler, symbol));
if (*func == NULL) {
return false;
}
return true;
}
static void clear_socket_function()
{
memset(shared_lib_func, 0, sizeof(shared_lib_func));
}
static void socket_finalize()
{
((finalize_func_type)shared_lib_func[FINALIZE_FUNC])();
__current_dispatch = NULL;
__socket_hook_begin_flag = false;
// Don't dlclose because hidumper crash
}
static bool finish_install_ohos_socket_hooks(const char* options)
{
init_func_type init_func = (init_func_type)(shared_lib_func[INITIALIZE_FUNC]);
if (!init_func(&__libc_socket_default_dispatch, NULL, options)) {
clear_socket_function();
return false;
}
int ret_value = atexit(socket_finalize);
return true;
}
static bool init_socket_hook_shared_library(void* shared_library_handle)
{
static const char* names[] = {
"initialize",
"finalize",
"get_hook_flag",
"set_hook_flag",
};
for (int i = 0; i < LAST_FUNC; i++) {
char symbol[MAX_SYMBOL_SIZE];
(void)snprintf(symbol, sizeof(symbol), "%s_%s", __socket_hook_function_prefix, names[i]);
shared_lib_func[i] = dlsym(shared_library_handle, symbol);
if (shared_lib_func[i] == NULL) {
clear_socket_function();
return false;
}
}
if (!init_socket_function(shared_library_handle, &(__musl_libc_socket_dispatch.socket))) {
clear_socket_function();
return false;
}
return true;
}
static void* load_socket_hook_shared_library()
{
void* shared_library_handle = NULL;
shared_library_handle = dlopen(__socket_hook_shared_lib, RTLD_NOW | RTLD_LOCAL);
if (shared_library_handle == NULL) {
return NULL;
}
if (!init_socket_hook_shared_library(shared_library_handle)) {
dlclose(shared_library_handle);
shared_library_handle = NULL;
}
return shared_library_handle;
}
static void install_ohos_socket_hook()
{
void* shared_library_handle = (void *)__ohos_socket_hook_shared_library;
if (shared_library_handle != NULL && shared_library_handle != (void*)-1) {
return;
}
__current_dispatch = NULL;
shared_library_handle = load_socket_hook_shared_library();
if (shared_library_handle == NULL) {
return;
}
if (finish_install_ohos_socket_hooks(NULL)) {
__ohos_socket_hook_shared_library = (long long)shared_library_handle;
__current_dispatch = (long long)(&__musl_libc_socket_dispatch);
} else {
__ohos_socket_hook_shared_library = NULL;
dlclose((void *)shared_library_handle);
}
}
static void init_ohos_socket_hook()
{
install_ohos_socket_hook();
}
__attribute__((constructor())) static void __musl_socket_initialize()
{
bool begin_flag = __get_socket_hook_begin_flag();
if (!begin_flag) {
__socket_hook_begin_flag = true;
init_ohos_socket_hook();
}
}
#endif
\ No newline at end of file
#ifdef OHOS_SOCKET_HOOK_ENABLE
#include <sys/socket.h>
#include "musl_socket.h"
#include "musl_socket_preinit_common.h"
struct SocketDispatchType __musl_libc_socket_dispatch;
long long __current_dispatch;
struct SocketDispatchType __libc_socket_default_dispatch = {
.socket = MuslSocket(socket),
};
bool __socket_hook_begin_flag;
#endif
\ No newline at end of file
#ifndef _MUSL_SOCKET_PREINIT_COMMON_H
#define _MUSL_SOCKET_PREINIT_COMMON_H
#include <stdio.h>
#include "musl_socket_dispatch.h"
#include "common_def.h"
extern struct SocketDispatchType __musl_libc_socket_dispatch;
extern struct SocketDispatchType __libc_socket_default_dispatch;
enum SocketFuncEnum {
INITIALIZE_FUNC,
FINALIZE_FUNC,
GET_HOOK_FLAG_FUNC,
SET_HOOK_FLAG_FUNC,
LAST_FUNC,
};
#ifdef OHOS_SOCKET_HOOK_ENABLE
extern long long __current_dispatch;
extern bool __socket_hook_begin_flag;
extern long long __ohos_socket_hook_shared_library;
extern void* shared_lib_func[LAST_FUNC];
#endif
#ifdef __cplusplus
extern "C" {
#endif
__attribute__((always_inline))
inline bool __get_socket_hook_begin_flag()
{
#ifdef OHOS_SOCKET_HOOK_ENABLE
return __socket_hook_begin_flag;
#else
return false;
#endif
}
__attribute__((always_inline))
inline bool __get_socket_hook_flag()
{
#ifdef OHOS_SOCKET_HOOK_ENABLE
void* handle = (void *)__ohos_socket_hook_shared_library;
if (handle == NULL) {
return false;
} else if (handle == (void *)-1) {
return true;
} else {
SocketGetHookFlagType get_hook_func_ptr = (SocketGetHookFlagType)(shared_lib_func[GET_HOOK_FLAG_FUNC]);
bool flag = get_hook_func_ptr();
return flag;
}
#else
return false;
#endif
}
__attribute__((always_inline))
inline volatile const struct SocketDispatchType* get_socket_dispatch()
{
#ifdef OHOS_SOCKET_HOOK_ENABLE
volatile const struct SocketDispatchType* ret = (struct SocketDispatchType *)__current_dispatch;
if (ret != NULL) {
if (!__get_socket_hook_begin_flag()) {
ret = NULL;
} else if (!__get_socket_hook_flag()) {
ret = NULL;
} else {
return ret;
}
}
return ret;
#else
return NULL;
#endif
}
#ifdef __cplusplus
}
#endif
#endif
\ No newline at end of file
#ifdef OHOS_SOCKET_HOOK_ENABLE
#include "musl_socket.h"
#include <sys/socket.h>
#include "common_def.h"
#include "musl_socket_preinit_common.h"
int socket(int domain, int type, int protocol)
{
volatile const struct SocketDispatchType* dispatch = get_socket_dispatch();
if (__predict_false(dispatch != NULL)) {
int ret = dispatch->socket(domain, type, protocol);
return ret;
}
int result = MuslSocket(socket)(domain, type, protocol);
return result;
}
#endif
\ No newline at end of file
#include <sys/socket.h>
#include <fcntl.h>
#include <errno.h>
#include <dlfcn.h>
#include <stdint.h>
#include <stddef.h>
#include "syscall.h"
#if OHOS_PERMISSION_INTERNET
typedef uint8_t (*AllowFunc)(void);
static const char *LIB_NETSYS_CLIENT_NAME = "libnetsys_client.z.so";
static const char *ALLOW_SOCKET_FUNC_NAME = "IsAllowInternet";
/*
* Read a flag from netsys_client, there is only one place to set this flag, is the
* founction named DoStartup in startup_appspawn.
* */
uint8_t is_allow_internet(void)
{
static uint8_t first_time = 1;
static uint8_t allow = 1;
if (!first_time) {
return allow;
}
void *handler = dlopen(LIB_NETSYS_CLIENT_NAME, RTLD_LAZY);
if (handler != NULL) {
AllowFunc func = (AllowFunc)dlsym(handler, ALLOW_SOCKET_FUNC_NAME);
if (func != NULL && func() == 0) {
allow = 0;
}
dlclose(handler);
}
first_time = 0;
return allow;
}
#endif
#ifdef OHOS_SOCKET_HOOK_ENABLE
int __libc_socket(int domain, int type, int protocol)
#else
int socket(int domain, int type, int protocol)
#endif
{
#if OHOS_PERMISSION_INTERNET
if ((domain == AF_INET || domain == AF_INET6) && is_allow_internet() == 0) {
errno = EPERM;
return -1;
}
#endif
int s = socketcall(socket, domain, type, protocol, 0, 0, 0);
if (s < 0 && (errno == EINVAL || errno == EPROTONOSUPPORT)
&& (type & (SOCK_CLOEXEC | SOCK_NONBLOCK))) {
s = socketcall(socket, domain,
type & ~(SOCK_CLOEXEC | SOCK_NONBLOCK),
protocol, 0, 0, 0);
if (s < 0) {
return s;
}
if (type & SOCK_CLOEXEC) {
__syscall(SYS_fcntl, s, F_SETFD, FD_CLOEXEC);
}
if (type & SOCK_NONBLOCK) {
__syscall(SYS_fcntl, s, F_SETFL, O_NONBLOCK);
}
}
return s;
}
\ No newline at end of file
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册