Skip to content

Commit

Permalink
Optimize co socket resource security
Browse files Browse the repository at this point in the history
  • Loading branch information
matyhtf committed Jun 11, 2024
1 parent 990d4aa commit 60b17f2
Show file tree
Hide file tree
Showing 5 changed files with 151 additions and 79 deletions.
1 change: 1 addition & 0 deletions ext-src/php_swoole_cxx.h
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,7 @@ extern zend_string **sw_zend_known_strings;
SW_API bool php_swoole_is_enable_coroutine();
SW_API zend_object *php_swoole_create_socket(enum swSocketType type);
SW_API zend_object *php_swoole_create_socket_from_fd(int fd, enum swSocketType type);
SW_API zend_object *php_swoole_create_socket_from_fd(int fd, int _domain, int _type, int _protocol);
SW_API bool php_swoole_export_socket(zval *zobject, swoole::coroutine::Socket *_socket);
SW_API zend_object *php_swoole_dup_socket(int fd, enum swSocketType type);
SW_API void php_swoole_init_socket_object(zval *zobject, swoole::coroutine::Socket *socket);
Expand Down
18 changes: 14 additions & 4 deletions ext-src/php_swoole_thread.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,17 +31,23 @@ bool php_swoole_thread_resource_free(ThreadResourceId resource_id, ThreadResourc
ThreadResource *php_swoole_thread_resource_fetch(ThreadResourceId resource_id);

void php_swoole_thread_start(zend_string *file, zend_string *argv);
zend_string *php_swoole_thread_serialize(zval *zdata);
bool php_swoole_thread_unserialize(zend_string *data, zval *zv);
zend_string *php_swoole_thread_argv_serialize(zval *zdata);
bool php_swoole_thread_argv_unserialize(zend_string *data, zval *zv);
zend_string *php_swoole_serialize(zval *zdata);
bool php_swoole_unserialize(zend_string *data, zval *zv);
void php_swoole_thread_argv_dtor(zval *zdata);
void php_swoole_thread_bailout(void);

zval *php_swoole_thread_get_arguments();

#define EMSG_NO_RESOURCE "resource not found"
#define ECODE_NO_RESOURCE -2

#define IS_STREAM_SOCKET 98
#define IS_SERIALIZED_OBJECT 99
enum {
IS_CO_SOCKET = 97,
IS_STREAM_SOCKET = 98,
IS_SERIALIZED_OBJECT = 99,
};

struct ThreadResource {
uint32_t ref_count;
Expand All @@ -66,6 +72,10 @@ struct ArrayItem {
zend_string *str;
zend_long lval;
double dval;
struct {
int fd;
swSocketType type;
} socket;
zend_string *serialized_object;
} value;

Expand Down
2 changes: 1 addition & 1 deletion ext-src/swoole_server.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2651,7 +2651,7 @@ static PHP_METHOD(swoole_server, start) {

if (!ZVAL_IS_NULL(&server_object->init_arguments)) {
call_user_function(NULL, NULL, &server_object->init_arguments, &thread_argv, 0, NULL);
thread_argv_serialized = php_swoole_thread_serialize(&thread_argv);
thread_argv_serialized = php_swoole_thread_argv_serialize(&thread_argv);
}

serv->worker_thread_start = [bootstrap, thread_argv_serialized](const WorkerFn &fn) {
Expand Down
50 changes: 11 additions & 39 deletions ext-src/swoole_socket_coro.cc
Original file line number Diff line number Diff line change
Expand Up @@ -89,9 +89,6 @@ static PHP_METHOD(swoole_socket_coro, getsockname);
static PHP_METHOD(swoole_socket_coro, getpeername);
static PHP_METHOD(swoole_socket_coro, isClosed);
static PHP_METHOD(swoole_socket_coro, import);
#ifdef SW_THREAD
static PHP_METHOD(swoole_socket_coro, __wakeup);
#endif
SW_EXTERN_C_END

// clang-format off
Expand Down Expand Up @@ -132,9 +129,6 @@ static const zend_function_entry swoole_socket_coro_methods[] =
PHP_ME(swoole_socket_coro, getsockname, arginfo_class_Swoole_Coroutine_Socket_getsockname, ZEND_ACC_PUBLIC)
PHP_ME(swoole_socket_coro, isClosed, arginfo_class_Swoole_Coroutine_Socket_isClosed, ZEND_ACC_PUBLIC)
PHP_ME(swoole_socket_coro, import, arginfo_class_Swoole_Coroutine_Socket_import, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
#ifdef SW_THREAD
PHP_ME(swoole_socket_coro, __wakeup, arginfo_class_Swoole_Coroutine_Socket___wakeup, ZEND_ACC_PUBLIC)
#endif
PHP_FE_END
};
// clang-format on
Expand Down Expand Up @@ -720,9 +714,7 @@ static void socket_coro_register_constants(int module_number) {

void php_swoole_socket_coro_minit(int module_number) {
SW_INIT_CLASS_ENTRY(swoole_socket_coro, "Swoole\\Coroutine\\Socket", "Co\\Socket", swoole_socket_coro_methods);
#ifndef SW_THREAD
SW_SET_CLASS_NOT_SERIALIZABLE(swoole_socket_coro);
#endif
SW_SET_CLASS_CLONEABLE(swoole_socket_coro, sw_zend_class_clone_deny);
SW_SET_CLASS_UNSET_PROPERTY_HANDLER(swoole_socket_coro, sw_zend_class_unset_property_deny);
SW_SET_CLASS_CUSTOM_OBJECT(
Expand Down Expand Up @@ -829,12 +821,12 @@ SW_API void php_swoole_socket_set_error_properties(zval *zobject, Socket *socket
php_swoole_socket_set_error_properties(zobject, socket->errCode, socket->errMsg);
}

SW_API zend_object *php_swoole_create_socket_from_fd(int fd, enum swSocketType type) {
static zend_object *create_socket_object(Socket *socket) {
zval zobject;
zend_object *object = socket_coro_create_object(swoole_socket_coro_ce);
SocketObject *sock = (SocketObject *) socket_coro_fetch_object(object);

sock->socket = new Socket(fd, type);
sock->socket = socket;
if (UNEXPECTED(sock->socket->get_fd() < 0)) {
php_swoole_sys_error(E_WARNING, "new Socket() failed");
delete sock->socket;
Expand All @@ -848,6 +840,14 @@ SW_API zend_object *php_swoole_create_socket_from_fd(int fd, enum swSocketType t
return object;
}

SW_API zend_object *php_swoole_create_socket_from_fd(int fd, enum swSocketType type) {
return create_socket_object(new Socket(fd, type));
}

SW_API zend_object *php_swoole_create_socket_from_fd(int fd, int _domain, int _type, int _protocol) {
return create_socket_object(new Socket(fd, _domain, _type, _protocol));
}

SW_API Socket *php_swoole_get_socket(zval *zobject) {
SW_ASSERT(Z_OBJCE_P(zobject) == swoole_socket_coro_ce);
SocketObject *sock = (SocketObject *) socket_coro_fetch_object(Z_OBJ_P(zobject));
Expand Down Expand Up @@ -2185,7 +2185,7 @@ static PHP_METHOD(swoole_socket_coro, import) {
if (getsockopt(socket_fd, SOL_SOCKET, SO_DOMAIN, &sock_domain, &sock_domain_len) == 0) {
} else
#endif
if (getsockname(socket_fd, (struct sockaddr *) &addr, &addr_len) == 0) {
if (getsockname(socket_fd, (struct sockaddr *) &addr, &addr_len) == 0) {
sock_domain = addr.ss_family;
} else {
php_swoole_sys_error(E_WARNING, "getsockname() failed");
Expand Down Expand Up @@ -2217,31 +2217,3 @@ static PHP_METHOD(swoole_socket_coro, import) {

RETURN_OBJ(object);
}

#ifdef SW_THREAD
static PHP_METHOD(swoole_socket_coro, __wakeup) {
zend_long sockfd = zend::object_get_long(ZEND_THIS, ZEND_STRL("fd"));
if (sockfd < 0) {
zend_throw_exception(swoole_exception_ce, EMSG_NO_RESOURCE, ECODE_NO_RESOURCE);
return;
}

zend_long new_sockfd = dup(sockfd);
if (sockfd < 0) {
zend_throw_exception(swoole_exception_ce, EMSG_NO_RESOURCE, ECODE_NO_RESOURCE);
return;
}

SocketObject *sock = (SocketObject *) socket_coro_fetch_object(Z_OBJ_P(ZEND_THIS));

zend_long domain = zend::object_get_long(ZEND_THIS, ZEND_STRL("domain"));
zend_long type = zend::object_get_long(ZEND_THIS, ZEND_STRL("type"));
zend_long protocol = zend::object_get_long(ZEND_THIS, ZEND_STRL("protocol"));

php_swoole_check_reactor();
sock->socket = new Socket((int) new_sockfd, (int) domain, (int) type, (int) protocol);
sock->socket->set_zero_copy(true);
sock->socket->set_buffer_allocator(sw_zend_string_allocator());
zend_update_property_long(swoole_socket_coro_ce, SW_Z8_OBJ_P(ZEND_THIS), ZEND_STRL("fd"), sock->socket->get_fd());
}
#endif
Loading

0 comments on commit 60b17f2

Please sign in to comment.