Impact
Currently, there is no management of permissions to network socket API file descriptors. Any thread running on the system may read/write a socket file descriptor knowing only the numerical value of the file descriptor.
The initial set of socket system calls contributed to Zephyr did not have this issue. See commit 18cec24
When this was implemented, net_context objects were tracked as kernel objects (K_OBJ_NET_CONTEXT). File descriptors were actually net_context pointers stuffed into an integer. When a socket was opened, the caller making the socket call would be granted permission on the net_context. All socket syscalls performed checks on the supplied file descriptor (really a net_context) to enusre validity and permission:
if (Z_SYSCALL_OBJ(sock, K_OBJ_NET_CONTEXT)) {
errno = EBADF;
return -1;
}
There were no net-specific APIs for managing permissions to other threads, although with some casts APIs like k_object_access_grant() did work.
Change f750ce5 then changed the socket code to use regular integers as file descriptors, with the associated net_contexts looked up in a table. This removed all the Z_SYSCALL_OBJ()
calls which verified access to the file descriptors, allowing any thread in the system to manipulate any file descriptor.
We shouldn't go back to stuffing net_context pointers into file descriptors, for one thing it falls over on 64-bit, but we need to restore the capability to control which threads have access to file descriptors.
On a Linux system, all threads in a process can share file descriptors. Zephyr on MPU-based systems will never have the concept of processes since there is no way to virtualize memory and we need a model different from Linux for managing access. For kernel objects this was solved with the permission system.
A fix might be to restore net_context to kernel object status, and after the file descriptor is looked up to fetch the net_context in the system calls, permission is then verified. We'd need some API to map fds to net_context object pointers for permission management.
Patches
This has been fixed in:
For more information
If you have any questions or comments about this advisory:
embargo: 2020-08-28
zepsec: ZEPSEC-87
thanks: @andrewboie
Impact
Currently, there is no management of permissions to network socket API file descriptors. Any thread running on the system may read/write a socket file descriptor knowing only the numerical value of the file descriptor.
The initial set of socket system calls contributed to Zephyr did not have this issue. See commit 18cec24
When this was implemented, net_context objects were tracked as kernel objects (K_OBJ_NET_CONTEXT). File descriptors were actually net_context pointers stuffed into an integer. When a socket was opened, the caller making the socket call would be granted permission on the net_context. All socket syscalls performed checks on the supplied file descriptor (really a net_context) to enusre validity and permission:
There were no net-specific APIs for managing permissions to other threads, although with some casts APIs like k_object_access_grant() did work.
Change f750ce5 then changed the socket code to use regular integers as file descriptors, with the associated net_contexts looked up in a table. This removed all the
Z_SYSCALL_OBJ()
calls which verified access to the file descriptors, allowing any thread in the system to manipulate any file descriptor.We shouldn't go back to stuffing net_context pointers into file descriptors, for one thing it falls over on 64-bit, but we need to restore the capability to control which threads have access to file descriptors.
On a Linux system, all threads in a process can share file descriptors. Zephyr on MPU-based systems will never have the concept of processes since there is no way to virtualize memory and we need a model different from Linux for managing access. For kernel objects this was solved with the permission system.
A fix might be to restore net_context to kernel object status, and after the file descriptor is looked up to fetch the net_context in the system calls, permission is then verified. We'd need some API to map fds to net_context object pointers for permission management.
Patches
This has been fixed in:
For more information
If you have any questions or comments about this advisory:
embargo: 2020-08-28
zepsec: ZEPSEC-87
thanks: @andrewboie