diff --git a/other/docker/sparse/local.mk b/other/docker/sparse/local.mk new file mode 100644 index 00000000000..b67f33b8b05 --- /dev/null +++ b/other/docker/sparse/local.mk @@ -0,0 +1 @@ +CFLAGS=-O3 -g -Wno-discarded-qualifiers -Wno-format-truncation -Wno-stringop-truncation -Wno-uninitialized -Wno-unused -Wno-unused-result diff --git a/other/docker/sparse/run b/other/docker/sparse/run new file mode 100755 index 00000000000..6b87e91b8a1 --- /dev/null +++ b/other/docker/sparse/run @@ -0,0 +1,6 @@ +#!/bin/sh + +set -eux +BUILD=sparse +other/docker/sources/build +docker build -t "toxchat/c-toxcore:$BUILD" -f "other/docker/$BUILD/$BUILD.Dockerfile" . diff --git a/other/docker/sparse/sparse.Dockerfile b/other/docker/sparse/sparse.Dockerfile new file mode 100644 index 00000000000..e4e185a89e8 --- /dev/null +++ b/other/docker/sparse/sparse.Dockerfile @@ -0,0 +1,35 @@ +FROM toxchat/c-toxcore:sources AS sources +FROM ubuntu:22.04 + +RUN apt-get update && \ + DEBIAN_FRONTEND="noninteractive" apt-get install -y --no-install-recommends \ + ca-certificates \ + creduce \ + g++ \ + gcc \ + git \ + libc-dev \ + libopus-dev \ + libsodium-dev \ + libsqlite3-dev \ + libssl-dev \ + libvpx-dev \ + llvm-dev \ + make \ + pkg-config \ + && apt-get clean \ + && rm -rf /var/lib/apt/lists/* + +WORKDIR /work/smatch +RUN git clone --depth=1 https://repo.or.cz/smatch.git /work/smatch +COPY other/docker/sparse/local.mk /work/smatch/local.mk +RUN make install -j4 PREFIX=/usr/local + +WORKDIR /work/c-toxcore +COPY --from=sources /src/ /work/c-toxcore +#COPY other/make_single_file /work/c-toxcore/other/ +#RUN other/make_single_file auto_tests/tox_new_test.c > crash.c +#RUN sparsec $(pkg-config --cflags --libs libsodium opus vpx) crash.c + +COPY other/docker/sparse/Makefile /work/c-toxcore/ +RUN make -j4 diff --git a/third_party/cmp b/third_party/cmp index cc67a0eab0a..643e6a62d4e 160000 --- a/third_party/cmp +++ b/third_party/cmp @@ -1 +1 @@ -Subproject commit cc67a0eab0a7579dcb12ce1072066275d49787bf +Subproject commit 643e6a62d4eb0ec2277de269cda33da02cba2756 diff --git a/toxcore/LAN_discovery.c b/toxcore/LAN_discovery.c index bf3ec98b151..5478ebea84e 100644 --- a/toxcore/LAN_discovery.c +++ b/toxcore/LAN_discovery.c @@ -148,7 +148,7 @@ static Broadcast_Info *fetch_broadcast_info(const Network *ns) ifc.ifc_buf = (char *)i_faces; ifc.ifc_len = sizeof(i_faces); - if (ioctl(sock.sock, SIOCGIFCONF, &ifc) < 0) { + if (ioctl(net_socket_to_system(sock), SIOCGIFCONF, &ifc) < 0) { kill_sock(ns, sock); free(broadcast); return nullptr; @@ -163,7 +163,7 @@ static Broadcast_Info *fetch_broadcast_info(const Network *ns) for (int i = 0; i < n; ++i) { /* there are interfaces with are incapable of broadcast */ - if (ioctl(sock.sock, SIOCGIFBRDADDR, &i_faces[i]) < 0) { + if (ioctl(net_socket_to_system(sock), SIOCGIFBRDADDR, &i_faces[i]) < 0) { continue; } diff --git a/toxcore/TCP_server.c b/toxcore/TCP_server.c index 3ce72e8e705..9df7a792b9f 100644 --- a/toxcore/TCP_server.c +++ b/toxcore/TCP_server.c @@ -1009,9 +1009,9 @@ TCP_Server *new_tcp_server(const Logger *logger, const Memory *mem, const Random struct epoll_event ev; ev.events = EPOLLIN | EPOLLET; - ev.data.u64 = sock.sock | ((uint64_t)TCP_SOCKET_LISTENING << 32); + ev.data.u64 = net_socket_to_system(sock) | ((uint64_t)TCP_SOCKET_LISTENING << 32); - if (epoll_ctl(temp->efd, EPOLL_CTL_ADD, sock.sock, &ev) == -1) { + if (epoll_ctl(temp->efd, EPOLL_CTL_ADD, net_socket_to_system(sock), &ev) == -1) { continue; } @@ -1248,7 +1248,7 @@ static bool tcp_epoll_process(TCP_Server *tcp_server, const Mono_Time *mono_time #undef MAX_EVENTS for (int n = 0; n < nfds; ++n) { - const Socket sock = {(int)(events[n].data.u64 & 0xFFFFFFFF)}; + const Socket sock = net_socket_from_system((int)(events[n].data.u64 & 0xFFFFFFFF)); const int status = (events[n].data.u64 >> 32) & 0xFF; const int index = events[n].data.u64 >> 40; @@ -1306,9 +1306,9 @@ static bool tcp_epoll_process(TCP_Server *tcp_server, const Mono_Time *mono_time ev.events = EPOLLIN | EPOLLET | EPOLLRDHUP; - ev.data.u64 = sock_new.sock | ((uint64_t)TCP_SOCKET_INCOMING << 32) | ((uint64_t)index_new << 40); + ev.data.u64 = net_socket_to_system(sock_new) | ((uint64_t)TCP_SOCKET_INCOMING << 32) | ((uint64_t)index_new << 40); - if (epoll_ctl(tcp_server->efd, EPOLL_CTL_ADD, sock_new.sock, &ev) == -1) { + if (epoll_ctl(tcp_server->efd, EPOLL_CTL_ADD, net_socket_to_system(sock_new), &ev) == -1) { LOGGER_DEBUG(tcp_server->logger, "new connection %d was dropped due to epoll error %d", index, net_error()); kill_tcp_secure_connection(&tcp_server->incoming_connection_queue[index_new]); continue; @@ -1324,9 +1324,9 @@ static bool tcp_epoll_process(TCP_Server *tcp_server, const Mono_Time *mono_time if (index_new != -1) { LOGGER_TRACE(tcp_server->logger, "incoming connection %d was accepted as %d", index, index_new); events[n].events = EPOLLIN | EPOLLET | EPOLLRDHUP; - events[n].data.u64 = sock.sock | ((uint64_t)TCP_SOCKET_UNCONFIRMED << 32) | ((uint64_t)index_new << 40); + events[n].data.u64 = net_socket_to_system(sock) | ((uint64_t)TCP_SOCKET_UNCONFIRMED << 32) | ((uint64_t)index_new << 40); - if (epoll_ctl(tcp_server->efd, EPOLL_CTL_MOD, sock.sock, &events[n]) == -1) { + if (epoll_ctl(tcp_server->efd, EPOLL_CTL_MOD, net_socket_to_system(sock), &events[n]) == -1) { LOGGER_DEBUG(tcp_server->logger, "incoming connection %d was dropped due to epoll error %d", index, net_error()); kill_tcp_secure_connection(&tcp_server->unconfirmed_connection_queue[index_new]); break; @@ -1342,9 +1342,9 @@ static bool tcp_epoll_process(TCP_Server *tcp_server, const Mono_Time *mono_time if (index_new != -1) { LOGGER_TRACE(tcp_server->logger, "unconfirmed connection %d was confirmed as %d", index, index_new); events[n].events = EPOLLIN | EPOLLET | EPOLLRDHUP; - events[n].data.u64 = sock.sock | ((uint64_t)TCP_SOCKET_CONFIRMED << 32) | ((uint64_t)index_new << 40); + events[n].data.u64 = net_socket_to_system(sock) | ((uint64_t)TCP_SOCKET_CONFIRMED << 32) | ((uint64_t)index_new << 40); - if (epoll_ctl(tcp_server->efd, EPOLL_CTL_MOD, sock.sock, &events[n]) == -1) { + if (epoll_ctl(tcp_server->efd, EPOLL_CTL_MOD, net_socket_to_system(sock), &events[n]) == -1) { // remove from confirmed connections LOGGER_DEBUG(tcp_server->logger, "unconfirmed connection %d was dropped due to epoll error %d", index, net_error()); kill_accepted(tcp_server, index_new); diff --git a/toxcore/attributes.h b/toxcore/attributes.h index f37b5ce515f..087efe20dcb 100644 --- a/toxcore/attributes.h +++ b/toxcore/attributes.h @@ -26,6 +26,14 @@ #define nullable(...) +#ifdef SPARSE +#define bitwise __attribute__((bitwise)) +#define force __attribute__((force)) +#else +#define bitwise +#define force +#endif + //!TOKSTYLE+ #endif /* C_TOXCORE_TOXCORE_ATTRIBUTES_H */ diff --git a/toxcore/network.c b/toxcore/network.c index 05b1400a5a7..24940a6fedc 100644 --- a/toxcore/network.c +++ b/toxcore/network.c @@ -368,10 +368,19 @@ IP6 get_ip6_loopback(void) #define INVALID_SOCKET (-1) #endif /* OS_WIN32 */ +int net_socket_to_system(Socket sock) +{ + return (force int)sock; +} + +Socket net_socket_from_system(int sock) +{ + return (force Socket)sock; +} + Socket net_invalid_socket(void) { - const Socket invalid_socket = { (int)INVALID_SOCKET }; - return invalid_socket; + return net_socket_from_system(INVALID_SOCKET); } Family net_family_unspec(void) @@ -466,8 +475,7 @@ bool net_family_is_tox_tcp_ipv6(Family family) bool sock_valid(Socket sock) { - const Socket invalid_socket = net_invalid_socket(); - return sock.sock != invalid_socket.sock; + return sock != net_invalid_socket(); } struct Network_Addr { @@ -623,13 +631,13 @@ void os_network_deinit(const Network *ns) non_null() static int net_setsockopt(const Network *ns, Socket sock, int level, int optname, const void *optval, size_t optlen) { - return ns->funcs->setsockopt(ns->obj, sock.sock, level, optname, optval, optlen); + return ns->funcs->setsockopt(ns->obj, net_socket_to_system(sock), level, optname, optval, optlen); } non_null() static int net_getsockopt(const Network *ns, Socket sock, int level, int optname, void *optval, size_t *optlen) { - return ns->funcs->getsockopt(ns->obj, sock.sock, level, optname, optval, optlen); + return ns->funcs->getsockopt(ns->obj, net_socket_to_system(sock), level, optname, optval, optlen); } non_null() @@ -804,7 +812,7 @@ static void loglogdata(const Logger *log, const char *message, const uint8_t *bu int net_send(const Network *ns, const Logger *log, Socket sock, const uint8_t *buf, size_t len, const IP_Port *ip_port) { - const int res = ns->funcs->send(ns->obj, sock.sock, buf, len); + const int res = ns->funcs->send(ns->obj, net_socket_to_system(sock), buf, len); loglogdata(log, "T=>", buf, len, ip_port, res); return res; } @@ -814,13 +822,13 @@ static int net_sendto( const Network *ns, Socket sock, const uint8_t *buf, size_t len, const Network_Addr *addr, const IP_Port *ip_port) { - return ns->funcs->sendto(ns->obj, sock.sock, buf, len, addr); + return ns->funcs->sendto(ns->obj, net_socket_to_system(sock), buf, len, addr); } int net_recv(const Network *ns, const Logger *log, Socket sock, uint8_t *buf, size_t len, const IP_Port *ip_port) { - const int res = ns->funcs->recv(ns->obj, sock.sock, buf, len); + const int res = ns->funcs->recv(ns->obj, net_socket_to_system(sock), buf, len); loglogdata(log, "=>T", buf, len, ip_port, res); return res; } @@ -829,35 +837,34 @@ non_null() static int net_recvfrom(const Network *ns, Socket sock, uint8_t *buf, size_t len, Network_Addr *addr) { - return ns->funcs->recvfrom(ns->obj, sock.sock, buf, len, addr); + return ns->funcs->recvfrom(ns->obj, net_socket_to_system(sock), buf, len, addr); } int net_listen(const Network *ns, Socket sock, int backlog) { - return ns->funcs->listen(ns->obj, sock.sock, backlog); + return ns->funcs->listen(ns->obj, net_socket_to_system(sock), backlog); } non_null() static int net_bind(const Network *ns, Socket sock, const Network_Addr *addr) { - return ns->funcs->bind(ns->obj, sock.sock, addr); + return ns->funcs->bind(ns->obj, net_socket_to_system(sock), addr); } Socket net_accept(const Network *ns, Socket sock) { - const Socket newsock = {ns->funcs->accept(ns->obj, sock.sock)}; - return newsock; + return net_socket_from_system(ns->funcs->accept(ns->obj, net_socket_to_system(sock))); } /** Close the socket. */ void kill_sock(const Network *ns, Socket sock) { - ns->funcs->close(ns->obj, sock.sock); + ns->funcs->close(ns->obj, net_socket_to_system(sock)); } bool set_socket_nonblock(const Network *ns, Socket sock) { - return ns->funcs->socket_nonblock(ns->obj, sock.sock, true) == 0; + return ns->funcs->socket_nonblock(ns->obj, net_socket_to_system(sock), true) == 0; } bool set_socket_nosigpipe(const Network *ns, Socket sock) @@ -1946,10 +1953,10 @@ bool net_connect(const Memory *mem, const Logger *log, Socket sock, const IP_Por Ip_Ntoa ip_str; LOGGER_DEBUG(log, "connecting socket %d to %s:%d", - (int)sock.sock, net_ip_ntoa(&ip_port->ip, &ip_str), net_ntohs(ip_port->port)); + net_socket_to_system(sock), net_ip_ntoa(&ip_port->ip, &ip_str), net_ntohs(ip_port->port)); errno = 0; - if (connect(sock.sock, (struct sockaddr *)&addr, addrsize) == -1) { + if (connect(net_socket_to_system(sock), (struct sockaddr *)&addr, addrsize) == -1) { const int error = net_error(); // Non-blocking socket: "Operation in progress" means it's connecting. @@ -2109,13 +2116,12 @@ Socket net_socket(const Network *ns, Family domain, int type, int protocol) const int platform_domain = make_family(domain); const int platform_type = make_socktype(type); const int platform_prot = make_proto(protocol); - const Socket sock = {ns->funcs->socket(ns->obj, platform_domain, platform_type, platform_prot)}; - return sock; + return net_socket_from_system(ns->funcs->socket(ns->obj, platform_domain, platform_type, platform_prot)); } uint16_t net_socket_data_recv_buffer(const Network *ns, Socket sock) { - const int count = ns->funcs->recvbuf(ns->obj, sock.sock); + const int count = ns->funcs->recvbuf(ns->obj, net_socket_to_system(sock)); return (uint16_t)max_s32(0, min_s32(count, UINT16_MAX)); } diff --git a/toxcore/network.h b/toxcore/network.h index f174ef9ebc2..8ebc0e7574c 100644 --- a/toxcore/network.h +++ b/toxcore/network.h @@ -211,9 +211,10 @@ typedef struct IP_Port { uint16_t port; } IP_Port; -typedef struct Socket { - int sock; -} Socket; +typedef bitwise int Socket; + +int net_socket_to_system(Socket sock); +Socket net_socket_from_system(int sock); non_null() Socket net_socket(const Network *ns, Family domain, int type, int protocol);