From ef130a027b37ddb496ee3f6921a36e4661fc9d3a Mon Sep 17 00:00:00 2001 From: Sergey Platonov Date: Sun, 9 Jan 2022 12:52:41 +0100 Subject: [PATCH] libc: fix type handling on socket creation The socket type (in the lower bits) maybe ORed with SOCK_CLOEXEC and SOCK_NONBLOCK options (in the higher bits). Currently, supported values are SOCK_STREAM (1) and SOCK_DGRAM (2), so just take the lower 2 bits. This fixes treating `SOCK_STREAM` sockets as UDP if additional flags were set. Fixes #4370 --- repos/libports/src/lib/libc/socket_fs_plugin.cc | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/repos/libports/src/lib/libc/socket_fs_plugin.cc b/repos/libports/src/lib/libc/socket_fs_plugin.cc index d5db46ff83..d011ea3b84 100644 --- a/repos/libports/src/lib/libc/socket_fs_plugin.cc +++ b/repos/libports/src/lib/libc/socket_fs_plugin.cc @@ -1033,9 +1033,14 @@ extern "C" int socket_fs_socket(int domain, int type, int protocol) error(__func__, ": socket fs not mounted"); return Errno(EACCES); } - - if (((type&7) != SOCK_STREAM || (protocol != 0 && protocol != IPPROTO_TCP)) - && ((type&7) != SOCK_DGRAM || (protocol != 0 && protocol != IPPROTO_UDP))) { + /* + * The socket type (in the lower bits) maybe ORed with SOCK_CLOEXEC and + * SOCK_NONBLOCK options (in the higher bits). Currently, supported values + * are SOCK_STREAM (1) and SOCK_DGRAM (2), so just take the lower 2 bits. + */ + int const sock_type = type & 3; + if ((sock_type != SOCK_STREAM || (protocol != 0 && protocol != IPPROTO_TCP)) + && (sock_type != SOCK_DGRAM || (protocol != 0 && protocol != IPPROTO_UDP))) { error(__func__, ": socket with type=", (Hex)type, " protocol=", (Hex)protocol, " not supported"); @@ -1044,7 +1049,7 @@ extern "C" int socket_fs_socket(int domain, int type, int protocol) /* socket is ensured to be TCP or UDP */ typedef Socket_fs::Context::Proto Proto; - Proto proto = (type == SOCK_STREAM) ? Proto::TCP : Proto::UDP; + Proto proto = (sock_type == SOCK_STREAM) ? Proto::TCP : Proto::UDP; Socket_fs::Context *context = nullptr; try { switch (proto) {