diff --git a/headers/private/kernel/fs/fd.h b/headers/private/kernel/fs/fd.h index d97d9138cb..8a31fc113f 100644 --- a/headers/private/kernel/fs/fd.h +++ b/headers/private/kernel/fs/fd.h @@ -86,6 +86,8 @@ extern void fd_set_close_on_exec(struct io_context *context, int fd, bool closeF static struct io_context *get_current_io_context(bool kernel); +extern status_t user_fd_kernel_ioctl(int fd, ulong op, void *buffer, size_t length); + /* The prototypes of the (sys|user)_ functions are currently defined in vfs.h */ diff --git a/headers/private/kernel/kernel.h b/headers/private/kernel/kernel.h index 4d20e62ee0..469ed9020f 100644 --- a/headers/private/kernel/kernel.h +++ b/headers/private/kernel/kernel.h @@ -59,7 +59,7 @@ extern bool kernel_startup; extern "C" { #endif -status_t shutdown(bool reboot); +status_t system_shutdown(bool reboot); status_t _user_shutdown(bool reboot); #ifdef __cplusplus diff --git a/headers/private/net/net_stack_driver.h b/headers/private/net/net_stack_driver.h index 7ffd52cef3..591ad5e5b9 100644 --- a/headers/private/net/net_stack_driver.h +++ b/headers/private/net/net_stack_driver.h @@ -23,7 +23,7 @@ enum { // ops not acting on an existing socket NET_STACK_SOCKET = NET_STACK_IOCTL_BASE, // socket_args * - NET_STACK_GET_COOKIE, // void ** + NET_STACK_GET_COOKIE, // void ** NET_STACK_CONTROL_NET_MODULE, // control_net_module_args * NET_STACK_GET_NEXT_STAT, // get_next_stat_args * @@ -72,13 +72,13 @@ struct socket_args { // used by NET_STACK_SOCKET }; struct socketpair_args { // used by NET_STACK_SOCKETPAIR - void *cookie; + int second_socket; }; -struct accept_args { // used by NET_STACK_ACCEPT - void *cookie; - struct sockaddr *address; - socklen_t address_length; +struct accept_args { // used by NET_STACK_ACCEPT + int accept_socket; + struct sockaddr *address; + socklen_t address_length; }; struct get_next_stat_args { // used by NET_STACK_GET_NEXT_STAT diff --git a/src/add-ons/kernel/drivers/network/stack/Jamfile b/src/add-ons/kernel/drivers/network/stack/Jamfile index 168f27da4e..5cc1d408e9 100644 --- a/src/add-ons/kernel/drivers/network/stack/Jamfile +++ b/src/add-ons/kernel/drivers/network/stack/Jamfile @@ -11,6 +11,7 @@ if ( $(TARGET_PLATFORM) != haiku ) { } UsePrivateHeaders kernel net ; +UseHeaders $(TARGET_PRIVATE_KERNEL_HEADERS) : true ; # a) Userland stack version: diff --git a/src/add-ons/kernel/drivers/network/stack/kernel_stack.cpp b/src/add-ons/kernel/drivers/network/stack/kernel_stack.cpp index 1866fb4c9f..b4f9ad390d 100644 --- a/src/add-ons/kernel/drivers/network/stack/kernel_stack.cpp +++ b/src/add-ons/kernel/drivers/network/stack/kernel_stack.cpp @@ -15,6 +15,9 @@ #include #include +#include // IS_KERNEL_ADDRESS +#include // user_fd_kernel_ioctl + #include #include #include @@ -194,6 +197,17 @@ opcode_name(int op) #endif // DEBUG +static status_t +resolve_cookie(int kernel, int socket, net_stack_cookie **cookie) +{ + if (kernel) + return ioctl(socket, NET_STACK_GET_COOKIE, cookie, sizeof(*cookie)); + else + return user_fd_kernel_ioctl(socket, NET_STACK_GET_COOKIE, cookie, + sizeof(*cookie)); +} + + // #pragma mark - device @@ -297,10 +311,10 @@ net_stack_control(void *_cookie, uint32 op, void *data, size_t length) } case NET_STACK_GET_COOKIE: - // This is needed by accept() call, allowing libnet.so accept() to pass back - // in NET_STACK_ACCEPT opcode the cookie (aka the net_stack_cookie!) - // of the file descriptor to use for the new accepted socket - return user_memcpy(data, &cookie, sizeof(void *)); + if (!IS_KERNEL_ADDRESS(data)) + return B_BAD_ADDRESS; + *((net_stack_cookie **)data) = cookie; + return B_OK; case NET_STACK_GET_NEXT_STAT: { @@ -349,18 +363,22 @@ net_stack_control(void *_cookie, uint32 op, void *data, size_t length) case NET_STACK_ACCEPT: { + int kernel = IS_KERNEL_ADDRESS(data); sockaddr_storage address; accept_args args; + status = check_args_and_address(args, address, data, length, false); if (status < B_OK) return status; - // args.cookie is the net_stack_cookie of the already opened socket - // TODO: find a safer way to do this! + net_stack_cookie *accept_cookie; + status = resolve_cookie(kernel, args.accept_socket, + &accept_cookie); + if (status < B_OK) + return status; - net_stack_cookie *acceptCookie = (net_stack_cookie *)args.cookie; status = sSocket->accept(cookie->socket, args.address, - &args.address_length, &acceptCookie->socket); + &args.address_length, &accept_cookie->socket); if (status < B_OK) return status; diff --git a/src/add-ons/kernel/network/socket/socket.cpp b/src/add-ons/kernel/network/socket/socket.cpp index 85f23f1528..251056f04b 100644 --- a/src/add-ons/kernel/network/socket/socket.cpp +++ b/src/add-ons/kernel/network/socket/socket.cpp @@ -84,18 +84,8 @@ accept(int socket, struct sockaddr *address, socklen_t *_addressLength) if (acceptSocket < 0) return -1; - // The network stack driver will need to know to which net_stack_cookie to - // *bind* with the new accepted socket. It can't itself find out, so we need - // to pass it the cookie used internally. - // TODO: change this to a safer approach using IDs! - void *cookie; - if (ioctl(acceptSocket, NET_STACK_GET_COOKIE, &cookie) < 0) { - close(acceptSocket); - return -1; - } - accept_args args; - args.cookie = cookie; + args.accept_socket = acceptSocket; args.address = address; args.address_length = _addressLength ? *_addressLength : 0; @@ -315,14 +305,8 @@ socketpair(int family, int type, int protocol, int socketVector[2]) if (socketVector[1] < 0) goto err1; - // TODO: find a better way to do this! - void *cookie; - if (ioctl(socketVector[1], NET_STACK_GET_COOKIE, &cookie) < 0) - goto err2; - socketpair_args args; - args.cookie = cookie; - // this way driver can use the right fd/cookie! + args.second_socket = socketVector[1]; if (ioctl(socketVector[0], NET_STACK_SOCKETPAIR, &args, sizeof(args)) < 0) goto err2; @@ -330,7 +314,7 @@ socketpair(int family, int type, int protocol, int socketVector[2]) return 0; err2: - close(socketVector[1]); + close(socketVector[1]); err1: close(socketVector[0]); return -1; diff --git a/src/kits/network/socket.cpp b/src/kits/network/socket.cpp index 00f59907e1..3fee76f8ee 100644 --- a/src/kits/network/socket.cpp +++ b/src/kits/network/socket.cpp @@ -249,21 +249,11 @@ accept(int socket, struct sockaddr *address, socklen_t *_addressLength) if (acceptSocket < 0) return -1; - // The network stack driver will need to know to which net_stack_cookie to - // *bind* with the new accepted socket. It can't itself find out, so we need - // to pass it the cookie used internally. - // TODO: change this to a safer approach using IDs! - void *cookie; - if (ioctl(acceptSocket, NET_STACK_GET_COOKIE, &cookie) < 0) { - close(acceptSocket); - return -1; - } - bool r5compatible = check_r5_compatibility(); struct sockaddr r5addr; accept_args args; - args.cookie = cookie; + args.accept_socket = acceptSocket; if (r5compatible && address != NULL) { args.address = &r5addr; @@ -549,14 +539,8 @@ socketpair(int family, int type, int protocol, int socketVector[2]) if (socketVector[1] < 0) goto err1; - // TODO: find a better way to do this! - void *cookie; - if (ioctl(socketVector[1], NET_STACK_GET_COOKIE, &cookie) < 0) - goto err2; - socketpair_args args; - args.cookie = cookie; - // this way driver can use the right fd/cookie! + args.second_socket = socketVector[1]; if (ioctl(socketVector[0], NET_STACK_SOCKETPAIR, &args, sizeof(args)) < 0) goto err2; @@ -564,7 +548,7 @@ socketpair(int family, int type, int protocol, int socketVector[2]) return 0; err2: - close(socketVector[1]); + close(socketVector[1]); err1: close(socketVector[0]); return -1; diff --git a/src/system/kernel/fs/fd.c b/src/system/kernel/fs/fd.c index a040a161ca..e3933d61e4 100644 --- a/src/system/kernel/fs/fd.c +++ b/src/system/kernel/fs/fd.c @@ -956,15 +956,15 @@ _kern_seek(int fd, off_t pos, int seekType) } -status_t -_kern_ioctl(int fd, ulong op, void *buffer, size_t length) +static status_t +_fd_ioctl(bool kernel_fd, int fd, ulong op, void *buffer, size_t length) { struct file_descriptor *descriptor; int status; TRACE(("sys_ioctl: fd %d\n", fd)); - descriptor = get_fd(get_current_io_context(true), fd); + descriptor = get_fd(get_current_io_context(kernel_fd), fd); if (descriptor == NULL) return B_FILE_ERROR; @@ -978,6 +978,20 @@ _kern_ioctl(int fd, ulong op, void *buffer, size_t length) } +status_t +_kern_ioctl(int fd, ulong op, void *buffer, size_t length) +{ + return _fd_ioctl(true, fd, op, buffer, length); +} + + +status_t +user_fd_kernel_ioctl(int fd, ulong op, void *buffer, size_t length) +{ + return _fd_ioctl(false, fd, op, buffer, length); +} + + ssize_t _kern_read_dir(int fd, struct dirent *buffer, size_t bufferSize, uint32 maxCount) { diff --git a/src/system/kernel/shutdown.c b/src/system/kernel/shutdown.c index 1eb40555b7..8821601d44 100644 --- a/src/system/kernel/shutdown.c +++ b/src/system/kernel/shutdown.c @@ -9,7 +9,7 @@ status_t -shutdown(bool reboot) +system_shutdown(bool reboot) { // ToDo: shutdown all system services! @@ -27,6 +27,6 @@ _user_shutdown(bool reboot) { if (geteuid() != 0) return B_NOT_ALLOWED; - return shutdown(reboot); + return system_shutdown(reboot); }